diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx index a6d6f8889..bd019ab66 100644 --- a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx @@ -1,4 +1,4 @@ -import { BoolCodeControl, StringControl } from "comps/controls/codeControl"; +import { BoolCodeControl, StringControl, NumberControl } from "comps/controls/codeControl"; import { dropdownControl } from "comps/controls/dropdownControl"; import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl"; import { IconControl } from "comps/controls/iconControl"; @@ -137,7 +137,8 @@ const childrenMap = { disabledStyle: DisabledButtonStyleControl, animationStyle: styleControl(AnimationStyle, 'animationStyle'), viewRef: RefControl, - tooltip: StringControl + tooltip: StringControl, + tabIndex: NumberControl }; type ChildrenType = NewChildren>; @@ -162,8 +163,12 @@ const ButtonPropertyView = React.memo((props: { disabledPropertyView(props.children), hiddenPropertyView(props.children), loadingPropertyView(props.children), + props.children.tabIndex.propertyView({ label: trans("prop.tabIndex") }), ] - : props.children.form.getPropertyView()} + : [ + props.children.form.getPropertyView(), + props.children.tabIndex.propertyView({ label: trans("prop.tabIndex") }), + ]} )} @@ -222,6 +227,7 @@ const ButtonView = React.memo((props: ToViewReturn) => { (!isDefault(props.type) && getForm(editorState, props.form)?.disableSubmit()) } onClick={handleClick} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} > {props.prefixIcon && {props.prefixIcon}} { diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx index 43cb5959a..b96fe77ea 100644 --- a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx @@ -1,6 +1,6 @@ import { default as Button } from "antd/es/button"; import { ButtonCompWrapper, buttonRefMethods } from "comps/comps/buttonComp/buttonCompConstants"; -import { BoolCodeControl, StringControl } from "comps/controls/codeControl"; +import { BoolCodeControl, StringControl, NumberControl } from "comps/controls/codeControl"; import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl"; import { styleControl } from "comps/controls/styleControl"; import { AnimationStyle, AnimationStyleType, LinkStyle, LinkStyleType } from "comps/controls/styleControlConstants"; @@ -91,6 +91,7 @@ const LinkTmpComp = (function () { prefixIcon: IconControl, suffixIcon: IconControl, viewRef: RefControl, + tabIndex: NumberControl, }; return new UICompBuilder(childrenMap, (props) => { // chrome86 bug: button children should not contain only empty span @@ -105,6 +106,7 @@ const LinkTmpComp = (function () { disabled={props.disabled} onClick={() => props.onEvent("click")} type={"link"} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} > {hasChildren && ( @@ -131,6 +133,7 @@ const LinkTmpComp = (function () { {hiddenPropertyView(children)} {loadingPropertyView(children)} {showDataLoadingIndicatorsPropertyView(children)} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
{children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })} diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/toggleButtonComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/toggleButtonComp.tsx index 654ec6659..ce82c9ff5 100644 --- a/client/packages/lowcoder/src/comps/comps/buttonComp/toggleButtonComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/buttonComp/toggleButtonComp.tsx @@ -1,4 +1,4 @@ -import { BoolCodeControl, StringControl } from "comps/controls/codeControl"; +import { BoolCodeControl, StringControl, NumberControl } from "comps/controls/codeControl"; import { withDefault } from "comps/generators"; import { UICompBuilder } from "comps/generators/uiCompBuilder"; import { @@ -68,6 +68,7 @@ const ToggleTmpComp = (function () { showBorder: withDefault(BoolControl, true), viewRef: RefControl, tooltip: StringControl, + tabIndex: NumberControl, }; return new UICompBuilder(childrenMap, (props) => { const text = props.showText @@ -92,6 +93,7 @@ const ToggleTmpComp = (function () { props.onEvent("change"); props.value.onChange(!props.value.value); }} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} > {props.iconPosition === "right" && text} {{props.value.value ? props.trueIcon : props.falseIcon}} @@ -117,6 +119,7 @@ const ToggleTmpComp = (function () { {hiddenPropertyView(children)} {loadingPropertyView(children)} {showDataLoadingIndicatorsPropertyView(children)} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
{children.showText.propertyView({ label: trans("toggleButton.showText") })} diff --git a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx index 543644b55..c5e7709c9 100644 --- a/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx +++ b/client/packages/lowcoder/src/comps/comps/meetingComp/controlButton.tsx @@ -1,4 +1,4 @@ -import { BoolCodeControl, StringControl } from "comps/controls/codeControl"; +import { BoolCodeControl, StringControl, NumberControl } from "comps/controls/codeControl"; import { dropdownControl } from "comps/controls/dropdownControl"; import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl"; import { IconControl } from "comps/controls/iconControl"; @@ -204,7 +204,8 @@ const childrenMap = { style: ButtonStyleControl, viewRef: RefControl, restrictPaddingOnRotation:withDefault(StringControl, 'controlButton'), - tooltip: StringControl + tooltip: StringControl, + tabIndex: NumberControl }; let ButtonTmpComp = (function () { @@ -294,6 +295,7 @@ let ButtonTmpComp = (function () { ? handleClickEvent() : submitForm(editorState, props.form) } + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} > {props.sourceMode === 'standard' && props.prefixIcon && ( )} diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx index 9a7abb8bd..6f3cfec54 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx @@ -214,8 +214,20 @@ let CheckboxBasicComp = (function () { return new UICompBuilder(childrenMap, (props) => { const mountedRef = useRef(true); + const checkboxRef = useRef(null); const [validateState, handleChange] = useSelectInputValidate(props); + useEffect(() => { + if (!mountedRef.current) return; + if (checkboxRef.current && typeof props.tabIndex === 'number') { + const checkboxInputs = checkboxRef.current.querySelectorAll('input[type="checkbox"]'); + checkboxInputs.forEach((input, index) => { + // Set sequential tabindex for each checkbox + input.setAttribute('tabindex', (props.tabIndex + index).toString()); + }); + } + }, [props.tabIndex, props.options]); + useEffect(() => { return () => { mountedRef.current = false; @@ -251,7 +263,13 @@ let CheckboxBasicComp = (function () { layout={props.layout} options={filteredOptions()} onChange={handleValidateChange} - viewRef={props.viewRef} + viewRef={(el) => { + if (!mountedRef.current) return; + if (el) { + props.viewRef(el); + checkboxRef.current = el; + } + }} tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> ), diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx index a5d55ca93..a75b9f05c 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx @@ -6,7 +6,7 @@ import { } from "lowcoder-core"; import { BoolControl } from "../../controls/boolControl"; import { LabelControl } from "../../controls/labelControl"; -import { BoolCodeControl, StringControl } from "../../controls/codeControl"; +import { BoolCodeControl, StringControl, NumberControl } from "../../controls/codeControl"; import { PaddingControl } from "../../controls/paddingControl"; import { MarginControl } from "../../controls/marginControl"; import { @@ -242,6 +242,7 @@ export const SelectChildrenMap = { margin: MarginControl, padding: PaddingControl, inputFieldStyle:styleControl(SelectStyle), + tabIndex: NumberControl, ...SelectInputValidationChildren, ...formDataChildren, }; @@ -269,6 +270,7 @@ export const SelectUIView = ( placeholder={props.placeholder} value={props.value} showSearch={props.showSearch} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} filterOption={(input, option) => { if (!option) return false; return String(option.label ?? option.value ?? "").toLowerCase().includes(input.toLowerCase()); @@ -348,6 +350,7 @@ export const SelectPropertyView = ( {disabledPropertyView(children)} {hiddenPropertyView(children)} {showDataLoadingIndicatorsPropertyView(children as any)} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
)}