Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/form #767

Merged
merged 4 commits into from
Jun 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/src/checkbox/checkbox-group.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CheckboxGroupDirection } from "./checkbox-group.shared"
interface CheckboxGroupContextValue {
value?: any[]
max?: number

disabled?: boolean
direction?: CheckboxGroupDirection

onChange?(value: any[]): void
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/checkbox/checkbox-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CheckboxGroupDirection } from "./checkbox-group.shared"
export interface CheckboxGroupProps<T = any> extends ViewProps {
defaultValue?: T[]
value?: T[]
disabled?: boolean
max?: number
direction?: CheckboxGroupDirection
children?: ReactNode
Expand All @@ -22,6 +23,7 @@ function CheckboxGroup<T = any>(props: CheckboxGroupProps<T>) {
const {
defaultValue,
value: valueProp,
disabled,
max,
direction = "vertical",
children,
Expand All @@ -40,6 +42,7 @@ function CheckboxGroup<T = any>(props: CheckboxGroupProps<T>) {
value={{
value,
max,
disabled,
direction,
onChange: setValue,
}}
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function Checkbox(props: CheckboxProps) {
name,
defaultChecked,
checked: checkedProp,
disabled,
disabled: disabledProp,
shape = "round",
icon = <Success />,
size,
Expand All @@ -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,
)

Expand All @@ -49,6 +49,8 @@ export default function Checkbox(props: CheckboxProps) {
onChange: onChangeProp,
})

const disabled = disabledProp ?? disabledGroup

function onClick() {
if (disabled) {
return
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/field/field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<FormItemProps, "children"> {
export interface FieldProps extends Omit<FormItemProps, "children" | "noStyle" | "shouldUpdate"> {
label?: ReactNode | FormLabelProps
feedback?: ReactNode | FormFeedbackProps
children?: ReactNode | ((controller: FormController<any>) => ReactNode)
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/form/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ function FormWithRules() {
}
```

### 禁用表单
设置 `disabled` 后,会为 `Form` 内部的 `taroify` 组件 `Input`, `Textarea`, `Checkbox`, `Switch`, `Checkbox.Group`, `Radio.Group`, `Rate`, `Slider`, `Stepper`, `Uploader` 设置 `disabled` <br>

form设置disabled后,也可以单独为表单项和组件设置disabled={false}, 优先级:表单 < 表单项 < 组件

### 表单项类型 - 开关

在表单中使用 [Switch 组件](/components/switch)。
Expand Down Expand Up @@ -315,6 +320,7 @@ function DatetimePickerField() {
{(controller) => (
<Input
value={formatDate(controller.value)}
disabled={controller.disabled}
readonly
placeholder="点击选择时间"
onClick={() => setOpen(true)}
Expand Down Expand Up @@ -360,6 +366,7 @@ function CalendarField() {
{(controller) => (
<Input
value={formatDate(controller.value)}
disabled={controller.disabled}
readonly
placeholder="点击选择日期"
onClick={() => setOpen(true)}
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -649,6 +658,7 @@ function ShouldUpdateDemo() {
interface FormController<V> {
value?: V // 当前表单项值
validateStatus?: FormValidateStatus // 当前表单项验证状态
disabled?: boolean // 当前表单项是否禁用

onChange?(value: V): void // 改变当前表单项值

Expand Down
19 changes: 12 additions & 7 deletions packages/core/src/form/control/form-control-handlers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<InputProps>(element, {
name: nameProp ?? name,
value: valueProp ?? value,
color: color ?? (validateStatus === "invalid" ? "danger" : undefined),
disabled: disabled ?? disabledProp,
onInput: (e) => {
onInput?.(e)
onDelegatingChange?.(e.detail.value)
Expand Down Expand Up @@ -61,12 +63,13 @@ registerFormControlHandler(
element: ReactElement<TaroSwitchProps>,
controller: FormController<any>,
): 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<TaroSwitchProps>(element, {
name: nameProp ?? name,
checked: checkedProp ?? value,
disabled: disabled ?? disabledProp,
onChange: (e) => {
onChange?.(e)
onDelegatingChange?.(e.detail.value)
Expand All @@ -86,11 +89,12 @@ registerFormControlHandler(
element: ReactElement<CheckboxProps | SwitchProps>,
controller: FormController<any>,
): 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<CheckboxProps | SwitchProps>(element, {
checked: checkedProp ?? value,
disabled: disabled ?? disabledProp,
onChange: (checked) => {
onChange?.(checked)
onDelegatingChange?.(checked)
Expand Down Expand Up @@ -126,9 +130,9 @@ registerFormControlHandler(
>,
controller: FormController<any>,
): 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
Expand All @@ -138,6 +142,7 @@ registerFormControlHandler(
| UploaderProps
>(element, {
value: valueProp ?? value,
disabled: disabled ?? disabledProp,
onChange: (nextValue: any) => {
onChange?.(nextValue)
onDelegatingChange?.(nextValue)
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/form/form-control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function FormControl<V = any>(props: FormControlProps<V>) {
className,
name,
value,
disabled,
align: alignProp,
children = <Input />,
onChange: onDelegatingChange,
Expand All @@ -38,6 +39,7 @@ function FormControl<V = any>(props: FormControlProps<V>) {
name,
value: formName ? value : undefined,
validateStatus,
disabled,
onChange: onDelegatingChange,
onBlur: onDelegatingBlur,
})
Expand All @@ -52,6 +54,7 @@ function FormControl<V = any>(props: FormControlProps<V>) {
name,
value,
validateStatus,
disabled,
onChange: onDelegatingChange,
onBlur: onDelegatingBlur,
})
Expand All @@ -63,6 +66,7 @@ function FormControl<V = any>(props: FormControlProps<V>) {
onDelegatingBlur,
onDelegatingChange,
validateStatus,
disabled,
value,
]) as JSX.Element

Expand Down
9 changes: 7 additions & 2 deletions packages/core/src/form/form-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export interface FormItemProps extends Omit<CellProps, "children"> {
dependencies?: string[]
shouldUpdate?: boolean | ((prev, next) => boolean)
noStyle?: boolean
disabled?: boolean

children?: (() => ReactNode) | ReactNode
}
Expand All @@ -108,6 +109,7 @@ const FormItem = forwardRef<FormItemInstance, FormItemProps>(
dependencies,
shouldUpdate,
noStyle,
disabled: disabledProp,
onClick,
} = props
const shouldUpdateSignal = useShouldUpdateSignal(shouldUpdate)
Expand All @@ -127,7 +129,9 @@ const FormItem = forwardRef<FormItemInstance, FormItemProps>(

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)

Expand Down Expand Up @@ -211,10 +215,11 @@ const FormItem = forwardRef<FormItemInstance, FormItemProps>(
cloneElement(control, {
name,
value,
disabled,
onBlur: () => validateWithTrigger("onBlur"),
onChange: setValue,
}),
[control, name, setValue, validateWithTrigger, value],
[control, name, setValue, validateWithTrigger, value, disabled],
)

if (noStyle) {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/form/form.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/form/form.shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export interface FormInstance {
*/
getFieldsValue<V>(): V

submit(): void

getErrors(name?: string | string[]): FormValidError[]

setErrors(errors: FormValidError[]): void
Expand Down Expand Up @@ -68,6 +70,7 @@ export interface FormController<V> {
name?: string
value?: V
validateStatus?: FormValidateStatus
disabled?: boolean

onChange?(value: V): void

Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/form/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface FormProps extends TaroFormProps {
controlAlign?: FormControlAlign
validateTrigger?: FormValidateTrigger
colon?: boolean
disabled?: boolean

children?: ReactNode

Expand All @@ -50,6 +51,7 @@ const Form = forwardRef<FormInstance, FormProps>(
controlAlign,
validateTrigger = "onBlur",
colon,
disabled,
children: childrenProp,
onValidate,
onValuesChange,
Expand Down Expand Up @@ -116,6 +118,7 @@ const Form = forwardRef<FormInstance, FormProps>(
useImperativeHandle(
ref,
() => ({
submit: () => handleSubmit({} as any),
getErrors,
setErrors,
getValues,
Expand All @@ -136,6 +139,7 @@ const Form = forwardRef<FormInstance, FormProps>(
validateFields,
}),
[
handleSubmit,
delegatingReset,
getErrors,
getFieldsValue,
Expand Down Expand Up @@ -169,6 +173,7 @@ const Form = forwardRef<FormInstance, FormProps>(
value={{
name,
colon,
disabled,
labelAlign,
controlAlign,
validateTrigger,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/radio/radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 5 additions & 2 deletions packages/demo/src/pages/form/form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -192,6 +191,7 @@ function DatetimePickerField() {
{(controller) => (
<Input
value={formatDate(controller.value)}
disabled={controller.disabled}
readonly
placeholder="点击选择时间"
onClick={() => setOpen(true)}
Expand Down Expand Up @@ -231,6 +231,7 @@ function CalendarField() {
{(controller) => (
<Input
value={formatDate(controller.value)}
disabled={controller.disabled}
readonly
placeholder="点击选择日期"
onClick={() => setOpen(true)}
Expand All @@ -252,8 +253,10 @@ function CalendarField() {
}

function FormWithFields() {
const [disabled, setDisabled] = useState(false)
return (
<Form onSubmit={(e) => Toast.open(JSON.stringify(e.detail.value, undefined, 2))}>
<Form disabled={disabled} onSubmit={(e) => Toast.open(JSON.stringify(e.detail.value, undefined, 2))}>
<Checkbox shape="square" style={{ marginLeft: "1rem" }} onChange={(e) => setDisabled(e)}>禁用</Checkbox>
<Cell.Group inset>
<Field label="开关" name="switch">
<Switch size={20} />
Expand Down