diff --git a/package.json b/package.json index 630207c64..3714c375b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sheinx", "private": true, - "version": "3.5.2-beta.6", + "version": "3.5.3-beta.1", "description": "A react library developed with sheinx", "module": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/base/src/button/button-group.tsx b/packages/base/src/button/button-group.tsx index 048723c5f..fba81e3d6 100644 --- a/packages/base/src/button/button-group.tsx +++ b/packages/base/src/button/button-group.tsx @@ -26,7 +26,7 @@ const Group = (props: ButtonGroupProps) => { const shapeSetted = shape === 'round' ? 'round' : undefined; return ( -
+
{Children.toArray(children).map((child) => { const Child = child as React.ReactElement; return cloneElement(Child, { diff --git a/packages/base/src/button/button.type.ts b/packages/base/src/button/button.type.ts index d17798ca8..351e1909e 100644 --- a/packages/base/src/button/button.type.ts +++ b/packages/base/src/button/button.type.ts @@ -135,6 +135,12 @@ export interface ButtonGroupProps extends Pick( props0: CascaderProps, ) => { const props = useWithFormConfig(props0); + const { fieldId } = useContext(FormFieldContext); const defaultHeight = 250; const { jssStyle, @@ -711,6 +713,7 @@ const Cascader = ( return (
d; const defaultRenderItem = (d: any) => d; @@ -13,6 +14,7 @@ const defaultRenderItem = (d: any) => d; const Group = (props0: CheckboxGroupProps) => { const {format = defaultFormat, renderItem = defaultRenderItem} = props0 const props = useWithFormConfig(props0); + const { fieldId } = useContext(FormFieldContext); const { children, className, block, keygen, jssStyle, size, style, disabled } = props; const checkboxStyle = jssStyle?.checkbox?.(); @@ -89,13 +91,13 @@ const Group = (props0: CheckboxGroupProps +
{children}
); } else { return ( -
+
{props.data.map((d, i) => ( { const { jssStyle, className, style, children, renderFooter, size, theme, ...rest } = props; + const { fieldId } = useContext(FormFieldContext); const checkboxStyle = jssStyle?.checkbox?.(); const { getRootProps, getIndicatorProps, getInputProps, disabled, checked } = useCheck({ ...rest, @@ -33,6 +35,7 @@ const Checkbox = (props: SimpleCheckboxProps) => { return (
{ } = props; const { locale } = useConfig(); + const { fieldId } = useContext(FormFieldContext); + const styles = jssStyle?.datePicker?.(); const { current: context } = useRef<{ inputRefs: Array; clickIndex: number }>({ inputRefs: [], @@ -162,6 +167,7 @@ const Result = (props: ResultProps) => { const placeholderArr = getPlaceHolderArr(); + const formFieldId = fieldId.split('__separator__'); const renderItem = (info: { inputable?: boolean; target: string | undefined; @@ -211,6 +217,7 @@ const Result = (props: ResultProps) => { props.onFocus?.(e); }} onClick={onClickProps} + id={formFieldId[info.index]} />
diff --git a/packages/base/src/editable-area/editable-area.tsx b/packages/base/src/editable-area/editable-area.tsx index a67a5c025..ccc0f0fe4 100644 --- a/packages/base/src/editable-area/editable-area.tsx +++ b/packages/base/src/editable-area/editable-area.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { Textarea } from '../textarea'; import { EditableAreaProps } from './editable-area.type'; import AbsoluteList from '../absolute-list'; @@ -6,6 +6,7 @@ import { useInputAble, usePersistFn } from '@sheinx/hooks'; import classNames from 'classnames'; import Icons from '../icons'; import useInnerTitle from '../common/use-inner-title'; +import { FormFieldContext } from '../form/form-field-context'; function formatShowValue(value: unknown) { if (!value && value !== 0) return ''; @@ -37,6 +38,8 @@ const EditableArea = (props: EditableAreaProps) => { bordered = false, } = props; + const { fieldId } = useContext(FormFieldContext); + const editableAreaStyle = jssStyle?.editableArea?.(); const status = error ? 'error' : props.status; @@ -166,6 +169,7 @@ const EditableArea = (props: EditableAreaProps) => { return (
({ + fieldId: '', + separator: '__separator__', +}); diff --git a/packages/base/src/form/form-field.tsx b/packages/base/src/form/form-field.tsx index 1c5302097..f7ee2acfc 100644 --- a/packages/base/src/form/form-field.tsx +++ b/packages/base/src/form/form-field.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import React, { useContext, useMemo } from 'react'; import { useFormControl, usePersistFn, util } from '@sheinx/hooks'; import { FieldControlProps, FormFieldProps } from './form-field.type'; +import { FormFieldContext } from './form-field-context'; const FormField = (props: FormFieldProps) => { const { children } = props; @@ -37,11 +38,21 @@ const FormField = (props: FormFieldProps) => { const status = childrenProps.status ?? (formControl.error ? 'error' : undefined); + const { separator } = useContext(FormFieldContext); + const formFieldId = useMemo(() => { + if(childrenProps.id) return childrenProps.id + + if(Array.isArray(formControl.name)) { + return formControl.name.map(name => util.getFieldId(name, props.formName)).join(separator) + } + + return util.getFieldId(formControl.name, props.formName) + }, [formControl.name, props.formName, childrenProps.id]) + const cloneProps: FieldControlProps = { onChange: handleChange, status, error, - id: childrenProps.id || util.getFieldId(formControl.name, props.formName), }; if (formControl.inForm) { @@ -51,12 +62,21 @@ const FormField = (props: FormFieldProps) => { if (formControl.disabled) { cloneProps.disabled = true; } + + let finalChildren if (util.isFunc(children)) { - return children(cloneProps); + finalChildren = children(cloneProps) + } else if (React.isValidElement(children)) { + finalChildren = React.cloneElement(children, cloneProps) + } else { + finalChildren = children } - if (React.isValidElement(children)) return React.cloneElement(children, cloneProps); - return children; + return ( + + {finalChildren} + + ); }; export default FormField; diff --git a/packages/base/src/form/form-field.type.ts b/packages/base/src/form/form-field.type.ts index d9ac3e93e..3dcf0befc 100644 --- a/packages/base/src/form/form-field.type.ts +++ b/packages/base/src/form/form-field.type.ts @@ -7,7 +7,6 @@ export interface FieldControlProps { status?: 'error'; disabled?: boolean; error?: { message?: string } | string; - id?: string; } export type FormFieldChildrenFunc = (props: FieldControlProps) => React.ReactElement; diff --git a/packages/base/src/form/form.type.ts b/packages/base/src/form/form.type.ts index 003b45077..c671d9de1 100644 --- a/packages/base/src/form/form.type.ts +++ b/packages/base/src/form/form.type.ts @@ -11,14 +11,14 @@ export interface FormClasses { export interface FormValidateFn< FormValue, - FieldKey extends KeyType = keyof FormValue, - FieldsType = FieldKey | FieldKey[] + // FieldKey extends KeyType = keyof FormValue, + // FieldsType = FieldKey | FieldKey[] > { /** * 验证所有表单的值,并且返回报错和表单数据 * @param fields 需要校验的表单字段 */ - (fields?: FieldsType): Promise>; + (fields?: string | string[]): Promise; } @@ -67,7 +67,7 @@ export interface FormRef { * @en Scroll to the position of the specified field * @cn 滚动到指定字段的位置 */ - scrollToField: (name: string) => void; + scrollToField: (name: string, scrollIntoViewOptions?: ScrollIntoViewOptions) => void; } export interface FormProps extends Partial>, diff --git a/packages/base/src/input/simple-input.tsx b/packages/base/src/input/simple-input.tsx index bec16bf41..79d91dacb 100644 --- a/packages/base/src/input/simple-input.tsx +++ b/packages/base/src/input/simple-input.tsx @@ -1,10 +1,10 @@ import { useInput, useKeyEvent, usePersistFn, util } from '@sheinx/hooks'; import classNames from 'classnames'; -import React, { KeyboardEvent } from 'react'; +import React, { KeyboardEvent, useContext } from 'react'; import { SimpleInputProps } from './input.type'; import Icons from '../icons'; import { useConfig } from '../config'; - +import { FormFieldContext } from '../form/form-field-context'; const Input = (props: SimpleInputProps) => { const { jssStyle, @@ -27,6 +27,7 @@ const Input = (props: SimpleInputProps) => { const inputStyle = jssStyle?.input?.(); const config = useConfig(); + const { fieldId } = useContext(FormFieldContext); const { getRootProps, getClearProps, getInputProps, showClear, focused, disabled } = useInput({ ...rest, onFocusedChange, @@ -69,6 +70,7 @@ const Input = (props: SimpleInputProps) => { return (
d; const defaultRenderItem = (d: any) => d; @@ -13,6 +14,7 @@ const defaultRenderItem = (d: any) => d; const Group = (props0: RadioGroupProps) => { const {format = defaultFormat, renderItem = defaultRenderItem} = props0 const props = useWithFormConfig(props0); + const { fieldId } = useContext(FormFieldContext); const { children, className, button, block, keygen, jssStyle, style, size, disabled } = props; const radioClasses = jssStyle?.radio?.(); @@ -125,13 +127,13 @@ const Group = (props0: RadioGroupProps) => { ); if (button) return ( - + {Radios} ); return ( -
+
{Radios}
); diff --git a/packages/base/src/radio/simple-radio.tsx b/packages/base/src/radio/simple-radio.tsx index 0b5f710d7..007e42c6d 100644 --- a/packages/base/src/radio/simple-radio.tsx +++ b/packages/base/src/radio/simple-radio.tsx @@ -1,10 +1,12 @@ import { useCheck } from '@sheinx/hooks'; import classNames from 'classnames'; -import React from 'react'; +import React, { useContext } from 'react'; import { SimpleRadioProps } from './radio.type'; +import { FormFieldContext } from '../form/form-field-context'; const Radio = (props: SimpleRadioProps) => { const { jssStyle, className, style, children, renderRadio, size, theme, ...rest } = props; + const { fieldId } = useContext(FormFieldContext); const radioClasses = jssStyle?.radio?.(); const { getRootProps, getIndicatorProps, getInputProps, disabled, checked } = useCheck({ ...rest, @@ -31,7 +33,7 @@ const Radio = (props: SimpleRadioProps) => { const indicatorProps = getIndicatorProps(); const simpleRadio = ( -
+
diff --git a/packages/base/src/rate/rate.tsx b/packages/base/src/rate/rate.tsx index 8d04b4d2b..4df16b1a8 100644 --- a/packages/base/src/rate/rate.tsx +++ b/packages/base/src/rate/rate.tsx @@ -1,14 +1,16 @@ import classNames from 'classnames'; -import React, { useState } from 'react'; +import React, { useContext, useState } from 'react'; import { RateProps } from './rate.type'; import Icons from '../icons'; import { useInputAble } from '@sheinx/hooks'; import useWithFormConfig from '../common/use-with-form-config'; import { useConfig } from '../config'; +import { FormFieldContext } from '../form/form-field-context'; const Rate = (props0: RateProps) => { const props = useWithFormConfig(props0); const config = useConfig(); + const { fieldId } = useContext(FormFieldContext); const { size } = props0; const { max = 5, repeat = true, clearable = false } = props; const [hoverValue, setHoverValue] = useState(null); @@ -115,6 +117,7 @@ const Rate = (props0: RateProps) => { const text = Array.isArray(props.text) && props.text[Math.ceil(value - 1)]; return (
{ diff --git a/packages/base/src/select/result.tsx b/packages/base/src/select/result.tsx index 0c9261b62..0a187fe31 100644 --- a/packages/base/src/select/result.tsx +++ b/packages/base/src/select/result.tsx @@ -60,7 +60,6 @@ const Result = (props: ResultProps) => { const [more, setMore] = useState(-1); const [shouldResetMore, setShouldResetMore] = useState(false); const render = useRender(); - const resultRef = useRef(null); const prevMore = useRef(more); const showInput = allowOnFilter; diff --git a/packages/base/src/select/select.tsx b/packages/base/src/select/select.tsx index 8d1e8bd1d..7ee219b45 100644 --- a/packages/base/src/select/select.tsx +++ b/packages/base/src/select/select.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode, useRef, useState } from 'react'; +import React, { ReactNode, useContext, useRef, useState } from 'react'; import classNames from 'classnames'; import { util, @@ -26,6 +26,7 @@ import ColumnsList from './list-columns'; import useWithFormConfig from '../common/use-with-form-config'; import useTip from '../common/use-tip'; import { getLocale, useConfig } from '../config'; +import { FormFieldContext } from '../form/form-field-context'; function Select(props0: SelectPropsBase) { const props = useWithFormConfig(props0); @@ -538,6 +539,7 @@ function Select(props0: SelectPropsBase) { ); }; + const { fieldId } = useContext(FormFieldContext); const renderResult = () => { const result = (
@@ -585,6 +587,7 @@ function Select(props0: SelectPropsBase) { return (
(props0: SliderProps) => { const props = useWithFormConfig(props0); const sliderClasses = props.jssStyle?.slider?.(); const config = useConfig() + const { fieldId } = useContext(FormFieldContext); const { scale = defaultScale, step = 1, height = 200, valueTipType: tipType = 'always' } = props; @@ -86,6 +88,7 @@ const Slider = (props0: SliderProps) => return (
{ const props = useWithFormConfig(props0); const { jssStyle, content, size, loading, className, style } = props; const config = useConfig(); + const { fieldId } = useContext(FormFieldContext); const switchClasses = jssStyle?.switch?.(); const disabled = props.disabled || props.loading; @@ -50,7 +52,7 @@ const Switch = (props0: SwitchProps) => { const inputProps = getInputProps(); return ( -
{ console.log('form submit', v); }} - onChange={setForm} + onChange={(v) => { + console.log('form change', v); + }} onReset={() => { console.log('form reset'); }} > + + + + + + + + + + + + + + + + + + + + + + + { + return data; + }} + /> + - i} columns={columns}>
+