diff --git a/docs/demo/value-form-event.md b/docs/demo/value-form-event.md new file mode 100644 index 00000000..d8b00535 --- /dev/null +++ b/docs/demo/value-form-event.md @@ -0,0 +1,4 @@ +## ValueFromEvent + + + diff --git a/docs/examples/value-form-event.tsx b/docs/examples/value-form-event.tsx new file mode 100644 index 00000000..7635ee67 --- /dev/null +++ b/docs/examples/value-form-event.tsx @@ -0,0 +1,259 @@ +import Form, { Field as OriginField } from 'rc-field-form'; +import React from 'react'; +import Input from './components/Input'; +import type { FieldProps } from '../../src/Field'; + +const Divider = (props: React.PropsWithChildren) => ( +
+ 🔽🔽🔽 + {props.children} + 🔽🔽🔽 +
+) + +interface CustomValue { + timestamp: number, + date: Date, + formatted: string, +} + +type FormData = { + // Input + text?: string; // default + + // ========== 🔽 event.target.checked + checkbox?: boolean; + radio?: boolean; + // ========== 🔽 event.target.valueAsNumber + number?: number; + range?: number; + // ========== 🔽 event.target.files + file?: FileList; + + // ========== 🔽 event.target.value(default)!!! + password?: string; + search?: string; + email?: string; + url?: string; + tel?: string; + date?: number; + time?: string; + dateTimeLocal?: string; + week?: string; + month?: string; + color?: string; + + // Select + select?: string; + // Textarea + textarea?: string; + + // Custom + custom?: CustomValue; +}; + +function commonGetValueFromEvent(...args: any[]) { + const event = args[0]; + + /** + * `target` is the element that triggered the event (e.g., the user clicked on) + * `currentTarget` is the element that the event listener is attached to. + */ + const nodeName = (event?.target?.nodeName ?? '').toLowerCase(); + + if (nodeName === 'input') { + const type = (event.target.type ?? 'text').toLowerCase(); + + if (['checkbox', 'radio'].includes(type)) { + return event.target.checked; + } + + // `datetime` Obsolete + if (['number', 'range'].includes(type)) { + // https://caniuse.com/?search=valueAsNumber, support IE11+ + return event.target.valueAsNumber ?? event.target.value; + } + + /** + * Problems with backfilling the data collected, so it is not processed here + * @see https://devlog.willcodefor.beer/pages/use-valueasnumber-and-valueasdate-on-inputs/ + * `datetime` Obsolete + */ + // if (['date', 'datetime-local'].includes(type)) { + // const _value = { + // timestamp: event.target.valueAsNumber, + // date: event.target.valueAsDate, + // formatted: event.target.value, + // } + // } + + // if (type === 'file') { + // return event.target.files; + // } + + /** + * text password search email url week month tel color time + * [submit, reset, button, image, hidden] ?? i dont care :) + */ + return event.target.value; // valuePropName default is 'value' + } + + if (['textarea', 'select'].includes(nodeName)) { + return event.target.value; + } + + return event; +} + +function Field(props: FieldProps) { + return ( + + getValueFromEvent={commonGetValueFromEvent} + {...props} + /> + ) +} + + +function App() { + const [form] = Form.useForm(); + + const initialValues: FormData = { + url: 'https://github.com/react-component/field-form', + email: 'wxh16144@users.noreply.github.com', + } + + return ( +
{ + console.log('Finish:', values); + }} + onFieldsChange={fields => { + console.error('fields:', fields); + }} + > + name="text"> + + + + event.target.checked + + name="checkbox"> + + + + name="radio"> + + + + event.target.valueAsNumber + + name="number"> + + + + name="range"> + + + + event.target.files + + name="file"> + + + + event.target.value + + name="password"> + + + + name="search"> + + + + name="email"> + + + + name="url"> + + + + name="tel"> + + + + name="date"> + + + + name="dateTimeLocal"> + + + + name="time"> + + + + name="week"> + + + + name="month"> + + + + name="color"> + + + + {/* Select */} + name="select"> + + + +
+ + {/* Textarea */} + name="textarea"> +