|
2 | 2 | title: Basic Configuration |
3 | 3 | description: Basic configuration of a field |
4 | 4 | --- |
5 | | - |
6 | | -## id、name |
7 | | - |
8 | | -- `id` is the unique identifier of the field in the form, must be a string. In the model, `name` is used by default for data entry and field path calculation, with the default value of name being id |
9 | | -- Why do we need name when we have id? Because some fields have the same name and need to be distinguished, for example, both teacher information and student information have a "name" field |
10 | | - |
11 | | -```ts |
12 | | -const teachername = defineField({ |
13 | | - id: "teachername", |
14 | | - name: "username" |
15 | | -}) |
16 | | - |
17 | | -const studentname = defineField({ |
18 | | - id: "studentname", |
19 | | - name: "username" |
20 | | -}) |
21 | | -``` |
22 | | - |
23 | | -## component |
24 | | -`component` is the component that the field renders in the page. It must be a controlled component and must have `value` and `onChange` properties. `value` is the value of the field, and `onChange` is the callback function when the field value changes. |
25 | | - |
26 | | -```ts |
27 | | -const username = defineField({ |
28 | | - id: "username", |
29 | | - component: Input |
30 | | - }) |
31 | | -``` |
32 | | - |
33 | | -### Controlled Component |
34 | | -A controlled component means its value is controlled externally, and the value is passed to the component via `props`. When the value changes, the `onChange` callback is called to pass the new value to the outside. |
35 | | - |
36 | | -```tsx |
37 | | -export default function Input(props: { |
38 | | - label: string |
39 | | - value: string |
40 | | - onChange: (value: string) => void |
41 | | -}) { |
42 | | - return <div> |
43 | | - <label>{props.label}: </label> |
44 | | - <input |
45 | | - type="text" |
46 | | - value={props.value} |
47 | | - onChange={(e) => props.onChange(e.target.value)} |
48 | | - /> |
49 | | - </div> |
50 | | -} |
51 | | -``` |
52 | | - |
53 | | -## Initial Value |
54 | | - |
55 | | -`initialValue` is the initial value of the field and can be of any type. `initialValue` can be a function or a Promise. |
56 | | - |
57 | | -```ts |
58 | | -const username = defineField({ |
59 | | - id: "username", |
60 | | - component: Input, |
61 | | - initialValue: "admin" |
62 | | - }) |
63 | | -``` |
64 | | - |
65 | | -## props |
66 | | - |
67 | | -`props` are the properties of the field and must be an object. The properties in `props` will be passed to the component. Properties in `props` can be of any type. |
68 | | - |
69 | | -```ts |
70 | | -const username = defineField({ |
71 | | - id: "username", |
72 | | - component: Input, |
73 | | - props: { |
74 | | - label: "Username" |
75 | | - } |
76 | | - }) |
77 | | -``` |
78 | | - |
79 | | -## properties |
80 | | -`properties` is the collection of child fields and must be an array. Each element in `properties` is a field object. |
81 | | - |
82 | | -```ts |
83 | | -const username = defineField().basicConfig({ |
84 | | - id: "username", |
85 | | - component: Input |
86 | | -}) |
87 | | - |
88 | | -const password = defineField().basicConfig({ |
89 | | - id: "password", |
90 | | - component: Input |
91 | | -}) |
92 | | - |
93 | | -const account = defineField({ |
94 | | - id: "account", |
95 | | - component: Form, |
96 | | - properties: [ |
97 | | - username, |
98 | | - password |
99 | | - ] |
100 | | -}) |
101 | | -``` |
102 | | - |
103 | | - |
104 | | -## slotMode |
105 | | -- slot mode refers to the way a subfield of a field is rendered in a component by default subfields are rendered in the component as child elements of the component when the `slotMode` of a field is `true` the subfields representing the field are passed to the component as the component's `props` allowing the component to decide how to render the subfields themselves. |
106 | | -- `slotName`: the name of the slot used to identify the slot in the form default is field `id`. |
107 | | -- `slotMode`: slot mode used to control the rendering method of slots. |
108 | | - |
109 | | -```ts |
110 | | -const firstName = defineField({ |
111 | | - id: "firstName", |
112 | | - component: Input, |
113 | | - props: { |
114 | | - label: "firstName", |
115 | | - prefix: "👤", |
116 | | - required: true, |
117 | | - }, |
118 | | -}); |
119 | | - |
120 | | -const lastName = defineField({ |
121 | | - id: "lastName", |
122 | | - component: Input, |
123 | | - props: { |
124 | | - label: "lastName", |
125 | | - prefix: "👤", |
126 | | - required: true, |
127 | | - }, |
128 | | -}); |
129 | | - |
130 | | -const usernameLayout = defineVoidField({ |
131 | | - id: "usernameLayout", |
132 | | - component: Flex, |
133 | | - slotMode: true, |
134 | | - hidden: (handler) => { |
135 | | - return handler.queryState(age)?.value > 18; |
136 | | - }, |
137 | | - properties: [firstName, lastName], |
138 | | - props: { |
139 | | - vertical: false, |
140 | | - } |
141 | | -}); |
142 | | - |
143 | | -function Flex(props: { |
144 | | - firstName?: RectNode; |
145 | | - lastName?: RectNode; |
146 | | - vertical?: boolean; |
147 | | -}) { |
148 | | - return ( |
149 | | - <div |
150 | | - style={{ |
151 | | - display: "flex", |
152 | | - flexDirection: props.vertical ? "column" : "row", |
153 | | - alignItems: "center", |
154 | | - gap: 8, |
155 | | - }} |
156 | | - > |
157 | | - {props.firstName} |
158 | | - {props.lastName} |
159 | | - </div> |
160 | | - ); |
161 | | -} |
162 | | -``` |
163 | | - |
164 | | -## hidden |
165 | | - |
166 | | -- `hidden` is a `Decision` object that indicates whether the field is hidden. `hidden` can also be a function. The function's parameters are a `handler` with read-only operations, and the return value is a boolean. The default value is false. |
167 | | - |
168 | | -- **Note**: This option has reactive capabilities and doesn't require manually setting whether the field is hidden or not |
169 | | - |
170 | | -```ts |
171 | | -import { defineField, D } from "@signals-form/core" |
172 | | -const username = defineField({ |
173 | | - id: "username", |
174 | | - component: Input, |
175 | | - hidden: D.use('isHidden') |
176 | | -}) |
177 | | -``` |
178 | | - |
179 | | -### hidden behavior |
180 | | - |
181 | | -- `hidden` can be a configuration object that can be used to configure whether field values are deleted and restored when hidden, whether child components are kept alive, and whether hidden fields should also be submitted when the form is submitted. |
182 | | -- `when` is a `Decision` object that indicates whether the field is hidden. `hidden` can also be a function. The function's parameters are the `value` of the `Field` and the form model `model`, and the return value is a boolean. The default value of `hidden` is `false`. |
183 | | -- When `activityOnHidden` is `true`, it means that when the field is hidden, combined with the `Activity` component, the field component is kept alive, so the component won't be unmounted, only hidden. Default is `false`. |
184 | | -- When `removeValueOnHidden` is `true`, it means that when the field is hidden, the field's `value` will be deleted, that is, set to `undefined`. Default is `true`. |
185 | | -- When `recoverValueOnShown` is `true`, it means that when the field changes from hidden to shown, the field's `value` will be backfilled with the value when it was hidden. Default is `false`. |
186 | | -- When `submitOnHidden` is `true`, it means that when the field is hidden, it will also be submitted when the form is submitted. |
187 | | - |
188 | | -```ts |
189 | | -{ |
190 | | - when: D.and("isJerry", "is18"), |
191 | | - behavior: { |
192 | | - activityOnHidden: true, |
193 | | - removeValueOnHidden: true, |
194 | | - recoverValueOnShown: true, |
195 | | - submitOnHidden: false |
196 | | - }, |
197 | | -} |
198 | | -``` |
199 | | - |
200 | | -## disabled |
201 | | -- `disabled` is a `Decision` object that indicates whether the field is disabled. `disabled` can also be a function. The function's parameters are a `handler` with read-only operations, and the return value is a boolean. The default value is false. |
202 | | -- **Note**: This option has reactive capabilities and doesn't require manually setting whether the field is disabled or not |
203 | | - |
204 | | -```ts |
205 | | -import { defineField, D } from "@signals-form/core" |
206 | | -const username = defineField({ |
207 | | - id: "username", |
208 | | - component: Input, |
209 | | - disabled: D.use('isDisabled') |
210 | | - }) |
211 | | -``` |
212 | | - |
213 | | -## Event Handling |
214 | | -- `events` is an object that represents the event handling functions of the field. Each property in `events` is an event handling function. |
215 | | -- The `this` in event handling functions points to the current field's `handler` object, and you can update the field's state through `this.setState` or `this.setAsyncState`. Other states and methods will be introduced in later chapters. |
216 | | -- **Note**: Event handling functions cannot be arrow functions, because the `this` of arrow functions points to the context when defined, not the context when the event is triggered. |
217 | | - |
218 | | -```ts |
219 | | -import { defineField } from "@signals-form/core" |
220 | | -const username = defineField({ |
221 | | - id: "username", |
222 | | - component: Input, |
223 | | - events: { |
224 | | - onChange(value) { |
225 | | - this.setState('value', value) |
226 | | - } |
227 | | - } |
228 | | -}) |
229 | | -``` |
230 | | - |
231 | | - |
0 commit comments