From 099a7804e7e1c48aa872b563d3bc770f44fc5f21 Mon Sep 17 00:00:00 2001 From: hbztd <38969912+hbztd@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:50:22 +0800 Subject: [PATCH 1/4] feat(Form): FormInstance add submit method --- packages/core/src/form/form.shared.ts | 2 ++ packages/core/src/form/form.tsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/core/src/form/form.shared.ts b/packages/core/src/form/form.shared.ts index e7f4afa14..8383a7b62 100644 --- a/packages/core/src/form/form.shared.ts +++ b/packages/core/src/form/form.shared.ts @@ -16,6 +16,8 @@ export interface FormInstance { */ getFieldsValue(): V + submit(): void + getErrors(name?: string | string[]): FormValidError[] setErrors(errors: FormValidError[]): void diff --git a/packages/core/src/form/form.tsx b/packages/core/src/form/form.tsx index fc8ca8bcd..7dfcf8881 100644 --- a/packages/core/src/form/form.tsx +++ b/packages/core/src/form/form.tsx @@ -116,6 +116,7 @@ const Form = forwardRef( useImperativeHandle( ref, () => ({ + submit: () => handleSubmit({} as any), getErrors, setErrors, getValues, @@ -136,6 +137,7 @@ const Form = forwardRef( validateFields, }), [ + handleSubmit, delegatingReset, getErrors, getFieldsValue, From 5d9a4e3cc4384f06ad0325b1499c1ae12a602569 Mon Sep 17 00:00:00 2001 From: hbztd <38969912+hbztd@users.noreply.github.com> Date: Sat, 29 Jun 2024 17:09:57 +0800 Subject: [PATCH 2/4] feat(Checkbox.Group): add disabled property --- packages/core/src/checkbox/checkbox-group.context.ts | 2 +- packages/core/src/checkbox/checkbox-group.tsx | 3 +++ packages/core/src/checkbox/checkbox.tsx | 6 ++++-- packages/core/src/radio/radio.tsx | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/core/src/checkbox/checkbox-group.context.ts b/packages/core/src/checkbox/checkbox-group.context.ts index 6ffb5ac51..1f942460e 100644 --- a/packages/core/src/checkbox/checkbox-group.context.ts +++ b/packages/core/src/checkbox/checkbox-group.context.ts @@ -4,7 +4,7 @@ import { CheckboxGroupDirection } from "./checkbox-group.shared" interface CheckboxGroupContextValue { value?: any[] max?: number - + disabled?: boolean direction?: CheckboxGroupDirection onChange?(value: any[]): void diff --git a/packages/core/src/checkbox/checkbox-group.tsx b/packages/core/src/checkbox/checkbox-group.tsx index 8a6068df7..3f3875dd9 100644 --- a/packages/core/src/checkbox/checkbox-group.tsx +++ b/packages/core/src/checkbox/checkbox-group.tsx @@ -11,6 +11,7 @@ import { CheckboxGroupDirection } from "./checkbox-group.shared" export interface CheckboxGroupProps extends ViewProps { defaultValue?: T[] value?: T[] + disabled?: boolean max?: number direction?: CheckboxGroupDirection children?: ReactNode @@ -22,6 +23,7 @@ function CheckboxGroup(props: CheckboxGroupProps) { const { defaultValue, value: valueProp, + disabled, max, direction = "vertical", children, @@ -40,6 +42,7 @@ function CheckboxGroup(props: CheckboxGroupProps) { value={{ value, max, + disabled, direction, onChange: setValue, }} diff --git a/packages/core/src/checkbox/checkbox.tsx b/packages/core/src/checkbox/checkbox.tsx index 2de1d0364..08493d873 100644 --- a/packages/core/src/checkbox/checkbox.tsx +++ b/packages/core/src/checkbox/checkbox.tsx @@ -30,7 +30,7 @@ export default function Checkbox(props: CheckboxProps) { name, defaultChecked, checked: checkedProp, - disabled, + disabled: disabledProp, shape = "round", icon = , size, @@ -39,7 +39,7 @@ export default function Checkbox(props: CheckboxProps) { ...restProps } = props - const { value: names, max: namesMax = 0, direction, onChange: onNamesChange } = useContext( + const { value: names, max: namesMax = 0, direction, onChange: onNamesChange, disabled: disabledGroup } = useContext( CheckboxGroupContext, ) @@ -49,6 +49,8 @@ export default function Checkbox(props: CheckboxProps) { onChange: onChangeProp, }) + const disabled = disabledProp ?? disabledGroup + function onClick() { if (disabled) { return diff --git a/packages/core/src/radio/radio.tsx b/packages/core/src/radio/radio.tsx index bda58c979..53d97639c 100644 --- a/packages/core/src/radio/radio.tsx +++ b/packages/core/src/radio/radio.tsx @@ -39,7 +39,7 @@ export default function Radio(props: RadioProps) { const size = sizeProp ?? sizeGroup - const disabled = disabledProp || disabledGroup + const disabled = disabledProp ?? disabledGroup const checked = name === value From 2f4cdc66be4c3cb932c1e4cdddd09ed8a52bd6ba Mon Sep 17 00:00:00 2001 From: hbztd <38969912+hbztd@users.noreply.github.com> Date: Sat, 29 Jun 2024 17:12:37 +0800 Subject: [PATCH 3/4] feat(Form): add disabled property --- packages/core/src/form/README.md | 10 ++++++++++ .../form/control/form-control-handlers.tsx | 19 ++++++++++++------- packages/core/src/form/form-control.tsx | 4 ++++ packages/core/src/form/form-item.tsx | 9 +++++++-- packages/core/src/form/form.context.ts | 1 + packages/core/src/form/form.shared.ts | 1 + packages/core/src/form/form.tsx | 3 +++ packages/demo/src/pages/form/form/index.tsx | 7 +++++-- 8 files changed, 43 insertions(+), 11 deletions(-) diff --git a/packages/core/src/form/README.md b/packages/core/src/form/README.md index 51284ac9d..0c7af85de 100644 --- a/packages/core/src/form/README.md +++ b/packages/core/src/form/README.md @@ -147,6 +147,11 @@ function FormWithRules() { } ``` +### 禁用表单 +设置 `disabled` 后,会为 `Form` 内部的 `taroify` 组件 `Input`, `Textarea`, `Checkbox`, `Switch`, `Checkbox.Group`, `Radio.Group`, `Rate`, `Slider`, `Stepper`, `Uploader` 设置 `disabled`
+ +form设置disabled后,也可以单独为表单项和组件设置disabled={false}, 优先级:表单 < 表单项 < 组件 + ### 表单项类型 - 开关 在表单中使用 [Switch 组件](/components/switch)。 @@ -315,6 +320,7 @@ function DatetimePickerField() { {(controller) => ( setOpen(true)} @@ -360,6 +366,7 @@ function CalendarField() { {(controller) => ( setOpen(true)} @@ -560,10 +567,12 @@ function ShouldUpdateDemo() { | 参数 | 说明 | 类型 | 默认值 | |-----------------|------------------------------------------|------------|----------| +| defaultValues | 表单默认值 | _object_ | | | labelAlign | 表单项 label 对齐方式,可选值为 `center` `right` | _string_ | `left` | | controlAlign | 表单项 control 对齐方式,可选值为 `center` `right` | _string_ | `left` | | validateTrigger | 表单校验触发时机,可选值为 `onChange`、`onSubmit`,详见下表 | _string_ | `onBlur` | | colon | 是否在 label 后面添加冒号 | _boolean_ | `false` | +| disabled | 是否禁用表单 | _boolean_ | `false` | ### Form Events @@ -649,6 +658,7 @@ function ShouldUpdateDemo() { interface FormController { value?: V // 当前表单项值 validateStatus?: FormValidateStatus // 当前表单项验证状态 + disabled?: boolean // 当前表单项是否禁用 onChange?(value: V): void // 改变当前表单项值 diff --git a/packages/core/src/form/control/form-control-handlers.tsx b/packages/core/src/form/control/form-control-handlers.tsx index 49d97e48b..5e9864b96 100644 --- a/packages/core/src/form/control/form-control-handlers.tsx +++ b/packages/core/src/form/control/form-control-handlers.tsx @@ -24,15 +24,17 @@ registerFormControlHandler( name, value, validateStatus, + disabled: disabledProp, onBlur: onDelegatingBlur, onChange: onDelegatingChange, } = controller const { props: elementProps } = element - const { name: nameProp, value: valueProp, color, onBlur, onInput } = elementProps + const { name: nameProp, value: valueProp, color, onBlur, onInput, disabled } = elementProps return cloneElement(element, { name: nameProp ?? name, value: valueProp ?? value, color: color ?? (validateStatus === "invalid" ? "danger" : undefined), + disabled: disabled ?? disabledProp, onInput: (e) => { onInput?.(e) onDelegatingChange?.(e.detail.value) @@ -61,12 +63,13 @@ registerFormControlHandler( element: ReactElement, controller: FormController, ): ReactNode { - const { name, value, onChange: onDelegatingChange } = controller + const { name, value, onChange: onDelegatingChange, disabled: disabledProp } = controller const { props: elementProps } = element - const { name: nameProp, checked: checkedProp, onChange } = elementProps + const { name: nameProp, checked: checkedProp, onChange, disabled } = elementProps return cloneElement(element, { name: nameProp ?? name, checked: checkedProp ?? value, + disabled: disabled ?? disabledProp, onChange: (e) => { onChange?.(e) onDelegatingChange?.(e.detail.value) @@ -86,11 +89,12 @@ registerFormControlHandler( element: ReactElement, controller: FormController, ): ReactNode { - const { value, onChange: onDelegatingChange } = controller + const { value, onChange: onDelegatingChange, disabled: disabledProp } = controller const { props: elementProps } = element - const { checked: checkedProp, onChange } = elementProps + const { checked: checkedProp, onChange, disabled } = elementProps return cloneElement(element, { checked: checkedProp ?? value, + disabled: disabled ?? disabledProp, onChange: (checked) => { onChange?.(checked) onDelegatingChange?.(checked) @@ -126,9 +130,9 @@ registerFormControlHandler( >, controller: FormController, ): ReactNode { - const { value, onChange: onDelegatingChange } = controller + const { value, onChange: onDelegatingChange, disabled: disabledProp } = controller const { props: elementProps } = element - const { value: valueProp, onChange } = elementProps + const { value: valueProp, onChange, disabled } = elementProps return cloneElement< | CheckboxGroupProps | RadioGroupProps @@ -138,6 +142,7 @@ registerFormControlHandler( | UploaderProps >(element, { value: valueProp ?? value, + disabled: disabled ?? disabledProp, onChange: (nextValue: any) => { onChange?.(nextValue) onDelegatingChange?.(nextValue) diff --git a/packages/core/src/form/form-control.tsx b/packages/core/src/form/form-control.tsx index f4d55756e..605bccedc 100644 --- a/packages/core/src/form/form-control.tsx +++ b/packages/core/src/form/form-control.tsx @@ -21,6 +21,7 @@ function FormControl(props: FormControlProps) { className, name, value, + disabled, align: alignProp, children = , onChange: onDelegatingChange, @@ -38,6 +39,7 @@ function FormControl(props: FormControlProps) { name, value: formName ? value : undefined, validateStatus, + disabled, onChange: onDelegatingChange, onBlur: onDelegatingBlur, }) @@ -52,6 +54,7 @@ function FormControl(props: FormControlProps) { name, value, validateStatus, + disabled, onChange: onDelegatingChange, onBlur: onDelegatingBlur, }) @@ -63,6 +66,7 @@ function FormControl(props: FormControlProps) { onDelegatingBlur, onDelegatingChange, validateStatus, + disabled, value, ]) as JSX.Element diff --git a/packages/core/src/form/form-item.tsx b/packages/core/src/form/form-item.tsx index 3a583be6b..795750e20 100644 --- a/packages/core/src/form/form-item.tsx +++ b/packages/core/src/form/form-item.tsx @@ -83,6 +83,7 @@ export interface FormItemProps extends Omit { dependencies?: string[] shouldUpdate?: boolean | ((prev, next) => boolean) noStyle?: boolean + disabled?: boolean children?: (() => ReactNode) | ReactNode } @@ -108,6 +109,7 @@ const FormItem = forwardRef( dependencies, shouldUpdate, noStyle, + disabled: disabledProp, onClick, } = props const shouldUpdateSignal = useShouldUpdateSignal(shouldUpdate) @@ -127,7 +129,9 @@ const FormItem = forwardRef( const rulesRef = useToRef(rulesProp) - const { validateTrigger } = useContext(FormContext) + const { validateTrigger, disabled: disabledContext } = useContext(FormContext) + + const disabled = disabledProp ?? disabledContext const { validateStatus, error, setError, resetError } = useFormError(name) @@ -211,10 +215,11 @@ const FormItem = forwardRef( cloneElement(control, { name, value, + disabled, onBlur: () => validateWithTrigger("onBlur"), onChange: setValue, }), - [control, name, setValue, validateWithTrigger, value], + [control, name, setValue, validateWithTrigger, value, disabled], ) if (noStyle) { diff --git a/packages/core/src/form/form.context.ts b/packages/core/src/form/form.context.ts index d79a80242..c48f810e4 100644 --- a/packages/core/src/form/form.context.ts +++ b/packages/core/src/form/form.context.ts @@ -4,6 +4,7 @@ import { FormControlAlign, FormLabelAlign, FormValidateTrigger } from "./form.sh interface FormContextValue { name?: string colon?: boolean + disabled?: boolean labelAlign?: FormLabelAlign controlAlign?: FormControlAlign validateTrigger?: FormValidateTrigger diff --git a/packages/core/src/form/form.shared.ts b/packages/core/src/form/form.shared.ts index 8383a7b62..b44ad6efa 100644 --- a/packages/core/src/form/form.shared.ts +++ b/packages/core/src/form/form.shared.ts @@ -70,6 +70,7 @@ export interface FormController { name?: string value?: V validateStatus?: FormValidateStatus + disabled?: boolean onChange?(value: V): void diff --git a/packages/core/src/form/form.tsx b/packages/core/src/form/form.tsx index 7dfcf8881..2ae3fb0b2 100644 --- a/packages/core/src/form/form.tsx +++ b/packages/core/src/form/form.tsx @@ -32,6 +32,7 @@ export interface FormProps extends TaroFormProps { controlAlign?: FormControlAlign validateTrigger?: FormValidateTrigger colon?: boolean + disabled?: boolean children?: ReactNode @@ -50,6 +51,7 @@ const Form = forwardRef( controlAlign, validateTrigger = "onBlur", colon, + disabled, children: childrenProp, onValidate, onValuesChange, @@ -171,6 +173,7 @@ const Form = forwardRef( value={{ name, colon, + disabled, labelAlign, controlAlign, validateTrigger, diff --git a/packages/demo/src/pages/form/form/index.tsx b/packages/demo/src/pages/form/form/index.tsx index f171c6dd5..b3d915d28 100644 --- a/packages/demo/src/pages/form/form/index.tsx +++ b/packages/demo/src/pages/form/form/index.tsx @@ -18,7 +18,6 @@ import { Field, } from "@taroify/core" import { FormItemInstance, FormValidError, FormInstance } from "@taroify/core/form" -import { ArrowRight } from "@taroify/icons" import { View } from "@tarojs/components" import { BaseEventOrig } from "@tarojs/components/types/common" import { FormProps } from "@tarojs/components/types/Form" @@ -192,6 +191,7 @@ function DatetimePickerField() { {(controller) => ( setOpen(true)} @@ -231,6 +231,7 @@ function CalendarField() { {(controller) => ( setOpen(true)} @@ -252,8 +253,10 @@ function CalendarField() { } function FormWithFields() { + const [disabled, setDisabled] = useState(false) return ( -
Toast.open(JSON.stringify(e.detail.value, undefined, 2))}> + Toast.open(JSON.stringify(e.detail.value, undefined, 2))}> + setDisabled(e)}>禁用 From 064b64197746703b9df6beaae30a7068bc161447 Mon Sep 17 00:00:00 2001 From: hbztd <38969912+hbztd@users.noreply.github.com> Date: Sat, 29 Jun 2024 17:16:37 +0800 Subject: [PATCH 4/4] chore(Field): fix props type --- packages/core/src/field/field.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/field/field.tsx b/packages/core/src/field/field.tsx index 9b5283a71..daeaee57c 100644 --- a/packages/core/src/field/field.tsx +++ b/packages/core/src/field/field.tsx @@ -3,7 +3,7 @@ import { ReactNode, useRef, useImperativeHandle, forwardRef, ForwardRefExoticCom import Form, { FormController, FormFeedbackProps, FormItemInstance, FormItemProps, FormLabelProps } from "../form" import { createVariantElement } from "../utils/element" -export interface FieldProps extends Omit { +export interface FieldProps extends Omit { label?: ReactNode | FormLabelProps feedback?: ReactNode | FormFeedbackProps children?: ReactNode | ((controller: FormController) => ReactNode)