From 1746b64572b04a1259226e83f91d96da3d2fc2ee Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Wed, 7 May 2025 22:35:59 +0500 Subject: [PATCH 01/10] [Feat]: Add tabindex to the input field --- .../lowcoder/src/comps/comps/textInputComp/inputComp.tsx | 7 ++++++- client/packages/lowcoder/src/comps/utils/propertyUtils.tsx | 1 + client/packages/lowcoder/src/i18n/locales/en.ts | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/inputComp.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/inputComp.tsx index 6222fb6de..28626079c 100644 --- a/client/packages/lowcoder/src/comps/comps/textInputComp/inputComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/textInputComp/inputComp.tsx @@ -32,6 +32,8 @@ import { hasIcon } from "comps/utils"; import { InputRef } from "antd/es/input"; import { RefControl } from "comps/controls/refControl"; import { migrateOldData, withDefault } from "comps/generators/simpleGenerators"; +import { numberSimpleControl } from "comps/controls/numberSimpleControl"; +import { NumberControl } from "comps/controls/codeControl"; import React, { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; @@ -55,8 +57,9 @@ const childrenMap = { labelStyle:styleControl(LabelStyle, 'labelStyle'), prefixIcon: IconControl, suffixIcon: IconControl, - inputFieldStyle: styleControl(InputLikeStyle, 'inputFieldStyle') , + inputFieldStyle: styleControl(InputLikeStyle, 'inputFieldStyle'), animationStyle: styleControl(AnimationStyle, 'animationStyle'), + tabIndex: NumberControl, }; let InputBasicComp = new UICompBuilder(childrenMap, (props) => { @@ -72,6 +75,7 @@ let InputBasicComp = new UICompBuilder(childrenMap, (props) => { $style={props.inputFieldStyle} prefix={hasIcon(props.prefixIcon) && props.prefixIcon} suffix={hasIcon(props.suffixIcon) && props.suffixIcon} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> ), style: props.style, @@ -99,6 +103,7 @@ let InputBasicComp = new UICompBuilder(childrenMap, (props) => { {children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })} {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} {children.showCount.propertyView({ label: trans("prop.showCount") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} {allowClearPropertyView(children)} {readOnlyPropertyView(children)} diff --git a/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx b/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx index e361a64cc..5f65242cb 100644 --- a/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx +++ b/client/packages/lowcoder/src/comps/utils/propertyUtils.tsx @@ -40,6 +40,7 @@ export const allowClearPropertyView = (children: { allowClear: InstanceType; }) => children.allowClear.propertyView({ label: trans("prop.showClear") }); + export const showSearchPropertyView = (children: { showSearch: InstanceType; }) => children.showSearch.propertyView({ label: trans("prop.showSearch") }); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index d1eff10d7..50a912523 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -176,6 +176,7 @@ export const en = { "width": "Width", "selectApp": "Select App", "showCount": "Show Count", + "tabIndex": "Tab Index", "textType": "Text Type", "customRule": "Custom Rule", "customRuleTooltip": "Non-empty string indicates an error; empty or null means validation passed. Example: ", From 721a5a8e4bd0bcafa52ad312dee65237494afb6f Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Wed, 7 May 2025 23:00:30 +0500 Subject: [PATCH 02/10] [Feat]: Add tabindex to the password field --- .../lowcoder/src/comps/comps/textInputComp/passwordComp.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/passwordComp.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/passwordComp.tsx index 846a81a7d..434704387 100644 --- a/client/packages/lowcoder/src/comps/comps/textInputComp/passwordComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/textInputComp/passwordComp.tsx @@ -42,6 +42,7 @@ import { RefControl } from "comps/controls/refControl"; import React, { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; import { migrateOldData } from "comps/generators/simpleGenerators"; +import { NumberControl } from "comps/controls/codeControl"; const PasswordStyle = styled(InputPassword)<{ $style: InputLikeStyleType; @@ -63,6 +64,7 @@ let PasswordTmpComp = (function () { labelStyle: styleControl(LabelStyle,'labelStyle'), inputFieldStyle: styleControl(InputLikeStyle , 'inputFieldStyle'), animationStyle: styleControl(AnimationStyle , 'animationStyle'), + tabIndex: NumberControl, }; return new UICompBuilder(childrenMap, (props, dispatch) => { const [inputProps, validateState] = useTextInputProps(props); @@ -76,6 +78,7 @@ let PasswordTmpComp = (function () { ref={props.viewRef} visibilityToggle={props.visibilityToggle} $style={props.inputFieldStyle} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> ), style: props.style, @@ -105,6 +108,7 @@ let PasswordTmpComp = (function () { })} {readOnlyPropertyView(children)} {children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
{requiredPropertyView(children)} {children.showValidationWhenEmpty.propertyView({label: trans("prop.showEmptyValidation")})} From 724514a4a97d8537cead2abb4b2666a95eccfb19 Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Wed, 7 May 2025 23:15:44 +0500 Subject: [PATCH 03/10] [Feat]: Add tabindex to the number input field --- .../src/comps/comps/numberInputComp/numberInputComp.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx index 4f8ad6bce..68ca7d370 100644 --- a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx @@ -272,6 +272,7 @@ const childrenMap = { min: UndefinedNumberControl, max: UndefinedNumberControl, customRule: CustomRuleControl, + tabIndex: NumberControl, ...formDataChildren, }; @@ -330,6 +331,7 @@ const CustomInputNumber = (props: RecordConstructorToView) = precision={props.precision} $style={props.inputFieldStyle} prefix={hasIcon(props.prefixIcon) ? props.prefixIcon : props.prefixText.value} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} onPressEnter={() => { handleFinish(); props.onEvent("submit"); @@ -436,6 +438,7 @@ let NumberInputTmpComp = (function () { })} {children.controls.propertyView({ label: trans("numberInput.controls") })} {readOnlyPropertyView(children)} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
)} From 9fe0f69485f373fc690b019c86f5a218044bed14 Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Thu, 8 May 2025 00:04:03 +0500 Subject: [PATCH 04/10] [Feat]: Add tabindex for input sliders --- .../src/comps/comps/numberInputComp/rangeSliderComp.tsx | 4 ++++ .../lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx index 0c17a5a7f..cbc921508 100644 --- a/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx @@ -6,6 +6,7 @@ import { CommonNameConfig, NameConfig, withExposingConfigs } from "../../generat import { SliderChildren, SliderPropertyView, SliderStyled, SliderWrapper } from "./sliderCompConstants"; import { hasIcon } from "comps/utils"; import { BoolControl } from "comps/controls/boolControl"; +import { NumberControl } from "comps/controls/codeControl"; const RangeSliderBasicComp = (function () { const childrenMap = { @@ -13,6 +14,7 @@ const RangeSliderBasicComp = (function () { start: numberExposingStateControl("start", 10), end: numberExposingStateControl("end", 60), vertical: BoolControl, + tabIndex: NumberControl, }; return new UICompBuilder(childrenMap, (props, dispatch) => { return props.label({ @@ -36,6 +38,7 @@ const RangeSliderBasicComp = (function () { $style={props.inputFieldStyle} style={{ margin: 0 }} $vertical={Boolean(props.vertical) || false} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} onChange={([start, end]) => { props.start.onChange(start); props.end.onChange(end); @@ -60,6 +63,7 @@ const RangeSliderBasicComp = (function () { tooltip: trans("rangeSlider.stepTooltip"), })} {children.vertical.propertyView({ label: trans("slider.vertical") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx index cabda6634..acadbb733 100644 --- a/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx @@ -7,6 +7,7 @@ import { formDataChildren, FormDataPropertyView } from "../formComp/formDataCons import { SliderChildren, SliderPropertyView, SliderStyled, SliderWrapper } from "./sliderCompConstants"; import { hasIcon } from "comps/utils"; import { BoolControl } from "comps/controls/boolControl"; +import { NumberControl } from "comps/controls/codeControl"; const SliderBasicComp = (function () { /** @@ -16,6 +17,7 @@ const SliderBasicComp = (function () { ...SliderChildren, value: numberExposingStateControl("value", 60), vertical: BoolControl, + tabIndex: NumberControl, ...formDataChildren, }; return new UICompBuilder(childrenMap, (props) => { @@ -39,6 +41,7 @@ const SliderBasicComp = (function () { $style={props.inputFieldStyle} style={{margin: 0}} $vertical={Boolean(props.vertical) || false} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} onChange={(e) => { props.value.onChange(e); props.onEvent("change"); @@ -61,6 +64,7 @@ const SliderBasicComp = (function () { tooltip: trans("slider.stepTooltip"), })} {children.vertical.propertyView({ label: trans("slider.vertical") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} From 3ed4c97ebdc32074d37933656405edc18729d72c Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Thu, 8 May 2025 00:10:22 +0500 Subject: [PATCH 05/10] [Feat]: Add tabindex for textarea --- .../lowcoder/src/comps/comps/textInputComp/textAreaComp.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/textAreaComp.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/textAreaComp.tsx index b631d65fb..c8a7582eb 100644 --- a/client/packages/lowcoder/src/comps/comps/textInputComp/textAreaComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/textInputComp/textAreaComp.tsx @@ -33,6 +33,7 @@ import { trans } from "i18n"; import { RefControl } from "comps/controls/refControl"; import { TextAreaRef } from "antd/es/input/TextArea"; import { blurMethod, focusWithOptions } from "comps/utils/methodUtils"; +import { NumberControl } from "comps/controls/codeControl"; import React, { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; @@ -80,7 +81,8 @@ let TextAreaTmpComp = (function () { labelStyle: styleControl(LabelStyle ,'labelStyle' ), textAreaScrollBar: withDefault(BoolControl, false), inputFieldStyle: styleControl(InputLikeStyle , 'inputFieldStyle'), - animationStyle: styleControl(AnimationStyle, 'animationStyle') + animationStyle: styleControl(AnimationStyle, 'animationStyle'), + tabIndex: NumberControl }; return new UICompBuilder(childrenMap, (props) => { const [inputProps, validateState] = useTextInputProps(props); @@ -96,6 +98,7 @@ let TextAreaTmpComp = (function () { allowClear={props.allowClear} style={{ height: "100% !important", resize: "vertical" }} $style={props.inputFieldStyle} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> ), @@ -128,6 +131,7 @@ let TextAreaTmpComp = (function () {
{allowClearPropertyView(children)} {readOnlyPropertyView(children)} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
)} From d62967b5e900aca634fb311822977cee48342ad8 Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Thu, 8 May 2025 00:22:37 +0500 Subject: [PATCH 06/10] [Feat]: Add tabindex for the switch, autocomp and rich editor --- .../comps/autoCompleteComp/autoCompleteComp.tsx | 7 ++++++- .../src/comps/comps/richTextEditorComp.tsx | 15 ++++++++++++++- .../lowcoder/src/comps/comps/switchComp.tsx | 5 ++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx b/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx index 54a269812..f7107f039 100644 --- a/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/autoCompleteComp/autoCompleteComp.tsx @@ -20,7 +20,7 @@ import { import styled, { css } from "styled-components"; import { UICompBuilder } from "../../generators"; import { FormDataPropertyView } from "../formComp/formDataConstants"; -import { jsonControl } from "comps/controls/codeControl"; +import { jsonControl, NumberControl } from "comps/controls/codeControl"; import { dropdownControl } from "comps/controls/dropdownControl"; import { getStyle, @@ -92,6 +92,7 @@ const childrenMap = { inputFieldStyle: styleControl(InputLikeStyle , 'inputFieldStyle'), childrenInputFieldStyle: styleControl(ChildrenMultiSelectStyle, 'childrenInputFieldStyle'), animationStyle: styleControl(AnimationStyle , 'animationStyle'), + tabIndex: NumberControl, }; const getValidate = (value: any): "" | "warning" | "error" | undefined => { @@ -271,6 +272,7 @@ let AutoCompleteCompBase = (function () { suffix={hasIcon(props.suffixIcon) && props.suffixIcon} status={getValidate(validateState)} onPressEnter={undefined} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> @@ -354,6 +356,9 @@ let AutoCompleteCompBase = (function () { > {children.animationStyle.getPropertyView()} +
+ {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} +
); }) diff --git a/client/packages/lowcoder/src/comps/comps/richTextEditorComp.tsx b/client/packages/lowcoder/src/comps/comps/richTextEditorComp.tsx index ed96c3a28..f549dadf3 100644 --- a/client/packages/lowcoder/src/comps/comps/richTextEditorComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/richTextEditorComp.tsx @@ -1,4 +1,4 @@ -import { StringControl } from "comps/controls/codeControl"; +import { StringControl, NumberControl } from "comps/controls/codeControl"; import { BoolControl } from "comps/controls/boolControl"; import { BoolCodeControl } from "../controls/codeControl"; import { stringExposingStateControl } from "comps/controls/codeStateControl"; @@ -180,6 +180,7 @@ const childrenMap = { toolbar: withDefault(StringControl, JSON.stringify(toolbarOptions)), onEvent: ChangeEventHandlerControl, style: styleControl(RichTextEditorStyle , 'style'), + tabIndex: NumberControl, ...formDataChildren, }; @@ -196,6 +197,7 @@ interface IProps { onChange: (value: string) => void; $style: RichTextEditorStyleType; contentScrollBar: boolean; + tabIndex?: number; } const ReactQuillEditor = React.lazy(() => import("react-quill")); @@ -226,6 +228,15 @@ function RichTextEditor(props: IProps) { [props.placeholder] ); + useEffect(() => { + if (editorRef.current && props.tabIndex !== undefined) { + const editor = editorRef.current.getEditor(); + if (editor && editor.scroll && editor.scroll.domNode) { + (editor.scroll.domNode as HTMLElement).tabIndex = props.tabIndex; + } + } + }, [props.tabIndex, key]); // Also re-run when key changes due to placeholder update + const contains = (parent: HTMLElement, descendant: HTMLElement) => { try { // Firefox inserts inaccessible nodes around video elements @@ -316,6 +327,7 @@ const RichTextEditorCompBase = new UICompBuilder(childrenMap, (props) => { onChange={handleChange} $style={props.style} contentScrollBar={props.contentScrollBar} + tabIndex={props.tabIndex} /> ); }) @@ -334,6 +346,7 @@ const RichTextEditorCompBase = new UICompBuilder(childrenMap, (props) => { {children.onEvent.getPropertyView()} {hiddenPropertyView(children)} {readOnlyPropertyView(children)} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} {showDataLoadingIndicatorsPropertyView(children)} )} diff --git a/client/packages/lowcoder/src/comps/comps/switchComp.tsx b/client/packages/lowcoder/src/comps/comps/switchComp.tsx index 730f521df..c4745cc48 100644 --- a/client/packages/lowcoder/src/comps/comps/switchComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/switchComp.tsx @@ -1,5 +1,5 @@ import { default as Switch } from "antd/es/switch"; -import { BoolCodeControl } from "comps/controls/codeControl"; +import { BoolCodeControl, NumberControl } from "comps/controls/codeControl"; import { booleanExposingStateControl } from "comps/controls/codeStateControl"; import { changeEvent, eventHandlerControl } from "comps/controls/eventHandlerControl"; import { LabelControl } from "comps/controls/labelControl"; @@ -104,6 +104,7 @@ let SwitchTmpComp = (function () { ), viewRef: RefControl, inputFieldStyle: migrateOldData(styleControl(SwitchStyle, 'inputFieldStyle'), fixOldData), + tabIndex: NumberControl, ...formDataChildren, }; return new UICompBuilder(childrenMap, (props) => { @@ -125,6 +126,7 @@ let SwitchTmpComp = (function () { checked={value} disabled={props.disabled} ref={props.viewRef} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} onChange={(checked) => { props.value.onChange(checked); props.onEvent("change"); @@ -149,6 +151,7 @@ let SwitchTmpComp = (function () { {children.onEvent.getPropertyView()} {disabledPropertyView(children)} {hiddenPropertyView(children)} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} {showDataLoadingIndicatorsPropertyView(children)} )} From 96b48c82e15b2a0ca0b0297070cd2ab779ea2b5c Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Thu, 8 May 2025 00:34:23 +0500 Subject: [PATCH 07/10] [Feat]: Add tabindex for the checkbox --- .../src/comps/comps/selectInputComp/checkboxComp.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx index f69b69453..d6eb38737 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx @@ -1,6 +1,6 @@ import { default as AntdCheckboxGroup } from "antd/es/checkbox/Group"; import { SelectInputOptionControl } from "comps/controls/optionsControl"; -import { BoolCodeControl } from "../../controls/codeControl"; +import { BoolCodeControl, NumberControl } from "../../controls/codeControl"; import { arrayStringExposingStateControl } from "../../controls/codeStateControl"; import { LabelControl } from "../../controls/labelControl"; import { ChangeEventHandlerControl } from "../../controls/eventHandlerControl"; @@ -115,6 +115,7 @@ export const getStyle = (style: CheckboxStyleType) => { const CheckboxGroup = styled(AntdCheckboxGroup) <{ $style: CheckboxStyleType; $layout: ValueFromOption; + tabIndex?: number; }>` min-height: 32px; ${(props) => props.$style && getStyle(props.$style)} @@ -156,6 +157,7 @@ let CheckboxBasicComp = (function () { viewRef: RefControl, inputFieldStyle: styleControl(CheckboxStyle , 'inputFieldStyle'), animationStyle: styleControl(AnimationStyle , 'animationStyle'), + tabIndex: NumberControl, ...SelectInputValidationChildren, ...formDataChildren, }; @@ -184,6 +186,7 @@ let CheckboxBasicComp = (function () { value: option.value, disabled: option.disabled, }))} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} onChange={(values) => { handleChange(values as string[]); }} From 04e949d7b742e040a9f20b1325d1321735446c54 Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Thu, 8 May 2025 00:46:35 +0500 Subject: [PATCH 08/10] [Feat]: Add tabindex for the radio component --- .../comps/comps/selectInputComp/radioComp.tsx | 20 ++++++++++++++++++- .../selectInputComp/radioCompConstants.tsx | 6 +++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx index 6bc4805cd..742dedb35 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx @@ -13,6 +13,7 @@ import { EllipsisTextCss, ValueFromOption } from "lowcoder-design"; import { trans } from "i18n"; import { fixOldInputCompData } from "../textInputComp/textInputConstants"; import { migrateOldData } from "comps/generators/simpleGenerators"; +import { useEffect, useRef } from "react"; const getStyle = (style: RadioStyleType, inputFieldStyle?:RadioStyleType ) => { return css` @@ -102,6 +103,18 @@ let RadioBasicComp = (function () { validateState, handleChange, ] = useSelectInputValidate(props); + + const radioRef = useRef(null); + + useEffect(() => { + if (radioRef.current && typeof props.tabIndex === 'number') { + const firstRadioInput = radioRef.current.querySelector('input[type="radio"]'); + if (firstRadioInput) { + firstRadioInput.setAttribute('tabindex', props.tabIndex.toString()); + } + } + }, [props.tabIndex, props.options]); + return props.label({ required: props.required, style: props.style, @@ -110,7 +123,12 @@ let RadioBasicComp = (function () { animationStyle:props.animationStyle, children: ( { + if (el) { + props.viewRef(el); + radioRef.current = el; + } + }} disabled={props.disabled} value={props.value.value} $style={props.style} diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx index 2945fec1f..ff2e2893f 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx @@ -1,5 +1,5 @@ import { RecordConstructorToComp } from "lowcoder-core"; -import { BoolCodeControl } from "../../controls/codeControl"; +import { BoolCodeControl, NumberControl } from "../../controls/codeControl"; import { LabelControl } from "../../controls/labelControl"; import { arrayStringExposingStateControl, @@ -43,6 +43,7 @@ export const RadioChildrenMap = { viewRef: RefControl, inputFieldStyle:styleControl(RadioStyle ,'inputFieldStyle' ), animationStyle: styleControl(AnimationStyle , 'animationStyle'), + tabIndex: NumberControl, ...SelectInputValidationChildren, ...formDataChildren, }; @@ -73,6 +74,9 @@ export const RadioPropertyView = ( {disabledPropertyView(children)} {hiddenPropertyView(children)} {showDataLoadingIndicatorsPropertyView(children as any)} + +
+ {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
)} From 29af2c7d609e657f191029a8609f37eca4a119e7 Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Thu, 8 May 2025 01:04:39 +0500 Subject: [PATCH 09/10] [Feat]: Add tabindex for the time component --- .../packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx | 6 ++++++ .../lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx | 1 + .../lowcoder/src/comps/comps/dateComp/timeUIView.tsx | 1 + 3 files changed, 8 insertions(+) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx index 10dc2dc90..101299d23 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx @@ -4,6 +4,7 @@ import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core" import { BoolCodeControl, CustomRuleControl, + NumberControl, RangeControl, StringControl, } from "../../controls/codeControl"; @@ -92,6 +93,7 @@ const commonChildren = { suffixIcon: withDefault(IconControl, "/icon:regular/clock"), timeZone: dropdownControl(timeZoneOptions, Intl.DateTimeFormat().resolvedOptions().timeZone), viewRef: RefControl, + tabIndex: NumberControl, ...validationChildren, }; @@ -212,6 +214,7 @@ const TimePickerTmpCmp = new UICompBuilder(childrenMap, (props) => { onFocus={() => props.onEvent("focus")} onBlur={() => props.onEvent("blur")} suffixIcon={hasIcon(props.suffixIcon) && props.suffixIcon} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> ), showValidationWhenEmpty: props.showValidationWhenEmpty, @@ -263,6 +266,7 @@ const TimePickerTmpCmp = new UICompBuilder(childrenMap, (props) => { {commonAdvanceSection(children)} {children.use12Hours.propertyView({ label: trans("prop.use12Hours") })} {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} )} @@ -368,6 +372,7 @@ const TimeRangeTmpCmp = (function () { onFocus={() => props.onEvent("focus")} onBlur={() => props.onEvent("blur")} suffixIcon={hasIcon(props.suffixIcon) && props.suffixIcon} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> ); @@ -439,6 +444,7 @@ const TimeRangeTmpCmp = (function () { {commonAdvanceSection(children)} {children.use12Hours.propertyView({ label: trans("prop.use12Hours") })} {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })} )} diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx index 44afcc7b3..940a37266 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx @@ -39,6 +39,7 @@ export interface TimeRangeUIViewProps extends TimeCompViewProps { placeholder?: string | [string, string]; onChange: (start?: dayjs.Dayjs | null, end?: dayjs.Dayjs | null) => void; handleTimeRangeZoneChange: (value:any) => void; + tabIndex?: number; } export const TimeRangeUIView = (props: TimeRangeUIViewProps) => { diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx index a04b117e2..891dfc1a4 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx @@ -34,6 +34,7 @@ export interface TimeUIViewProps extends TimeCompViewProps { value: dayjs.Dayjs | null; onChange: (value: dayjs.Dayjs | null) => void; handleTimeZoneChange: (value:any) => void; + tabIndex?: number; } export const TimeUIView = (props: TimeUIViewProps) => { From 41cb3843a46952369144d728cbc7208dc815e2a9 Mon Sep 17 00:00:00 2001 From: Faran Javed Date: Thu, 8 May 2025 01:13:13 +0500 Subject: [PATCH 10/10] [Feat]: Add tabindex for the datecomp --- .../lowcoder/src/comps/comps/dateComp/dateComp.tsx | 10 +++++++++- .../src/comps/comps/dateComp/dateRangeUIView.tsx | 3 ++- .../lowcoder/src/comps/comps/dateComp/dateUIView.tsx | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx index fd2add150..96de04abe 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx @@ -4,6 +4,7 @@ import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core" import { BoolCodeControl, CustomRuleControl, + NumberControl, RangeControl, StringControl, } from "../../controls/codeControl"; @@ -99,6 +100,7 @@ const commonChildren = { childrenInputFieldStyle: styleControl(ChildrenMultiSelectStyle, 'childrenInputFieldStyle'), timeZone: dropdownControl(timeZoneOptions, Intl.DateTimeFormat().resolvedOptions().timeZone), pickerMode: dropdownControl(PickerModeOptions, 'date'), + tabIndex: NumberControl, }; type CommonChildrenType = RecordConstructorToComp; @@ -185,6 +187,7 @@ export type DateCompViewProps = Pick< disabledTime: () => ReturnType; suffixIcon: ReactNode; placeholder?: string | [string, string]; + tabIndex?: number; }; const getFormattedDate = ( @@ -281,6 +284,7 @@ const DatePickerTmpCmp = new UICompBuilder(childrenMap, (props) => { onFocus={() => props.onEvent("focus")} onBlur={() => props.onEvent("blur")} suffixIcon={hasIcon(props.suffixIcon) && props.suffixIcon} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} /> ), showValidationWhenEmpty: props.showValidationWhenEmpty, @@ -340,6 +344,7 @@ const DatePickerTmpCmp = new UICompBuilder(childrenMap, (props) => { <>
{timeFields(children, isMobile)} {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
)} {(useContext(EditorContext).editorModeStatus === "logic" || useContext(EditorContext).editorModeStatus === "both") && !isMobile && commonAdvanceSection(children)} @@ -475,7 +480,9 @@ let DateRangeTmpCmp = (function () { }} onFocus={() => props.onEvent("focus")} onBlur={() => props.onEvent("blur")} - suffixIcon={hasIcon(props.suffixIcon) && props.suffixIcon} /> + suffixIcon={hasIcon(props.suffixIcon) && props.suffixIcon} + tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined} + /> ); const startResult = validate({ ...props, value: props.start }); @@ -553,6 +560,7 @@ let DateRangeTmpCmp = (function () { <>
{timeFields(children, isMobile)} {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} + {children.tabIndex.propertyView({ label: trans("prop.tabIndex") })}
)} {(useContext(EditorContext).editorModeStatus === "logic" || useContext(EditorContext).editorModeStatus === "both") && commonAdvanceSection(children)} diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx index a2c7ba56d..c56ddecb6 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx @@ -44,7 +44,8 @@ export interface DateRangeUIViewProps extends DateCompViewProps { placeholder?: string | [string, string]; onChange: (start?: dayjs.Dayjs | null, end?: dayjs.Dayjs | null) => void; onPanelChange: (value: any, mode: [string, string]) => void; - onClickDateRangeTimeZone:(value:any)=>void + onClickDateRangeTimeZone:(value:any)=>void; + tabIndex?: number; } export const DateRangeUIView = (props: DateRangeUIViewProps) => { diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx b/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx index a5bdea97a..a98a1eaa5 100644 --- a/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx +++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx @@ -39,7 +39,7 @@ export interface DataUIViewProps extends DateCompViewProps { onChange: DatePickerProps['onChange']; onPanelChange: () => void; onClickDateTimeZone:(value:any)=>void; - + tabIndex?: number; } const DateMobileUIView = React.lazy(() =>