@jamesodwyer/gds-figma-vite 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# InputField Component
|
|
2
|
+
|
|
3
|
+
Compound component for building accessible form inputs including text inputs, textareas, selects, checkboxes, and radio buttons.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { InputField } from '@jamesodwyer/gds-figma-vite';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Structure
|
|
12
|
+
|
|
13
|
+
InputField uses a compound component pattern with the following sub-components:
|
|
14
|
+
|
|
15
|
+
| Sub-component | Description |
|
|
16
|
+
|---------------|-------------|
|
|
17
|
+
| InputField | Container that provides context (requires `id` prop) |
|
|
18
|
+
| InputField.Label | Label element, auto-linked to input |
|
|
19
|
+
| InputField.Row | Layout wrapper with optional margin |
|
|
20
|
+
| InputField.Input | Text input field |
|
|
21
|
+
| InputField.Textarea | Multi-line text input |
|
|
22
|
+
| InputField.Select | Dropdown select |
|
|
23
|
+
| InputField.Checkbox | Checkbox input |
|
|
24
|
+
| InputField.Radio | Radio button input |
|
|
25
|
+
| InputField.StartIcon | Icon positioned at start of input |
|
|
26
|
+
| InputField.EndIcon | Icon positioned at end of input |
|
|
27
|
+
| InputField.Validation | Error or success message display |
|
|
28
|
+
|
|
29
|
+
## Basic Text Input
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
<InputField id="email">
|
|
33
|
+
<InputField.Label>Email Address</InputField.Label>
|
|
34
|
+
<InputField.Row marginTop="auditorium">
|
|
35
|
+
<InputField.Input type="email" placeholder="Enter email" />
|
|
36
|
+
</InputField.Row>
|
|
37
|
+
</InputField>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
### InputField (Container)
|
|
43
|
+
|
|
44
|
+
| Prop | Type | Required | Description |
|
|
45
|
+
|------|------|----------|-------------|
|
|
46
|
+
| id | string \| false | Yes | Unique ID for accessibility linking. Use `false` to disable auto-ID generation |
|
|
47
|
+
| as | ElementType | No | Render as different element (e.g., 'fieldset') |
|
|
48
|
+
|
|
49
|
+
### InputField.Label
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Default | Description |
|
|
52
|
+
|------|------|---------|-------------|
|
|
53
|
+
| disabled | boolean | false | Applies disabled styling |
|
|
54
|
+
| readOnly | boolean | false | Applies read-only styling |
|
|
55
|
+
| as | ElementType | 'label' | Render as different element |
|
|
56
|
+
|
|
57
|
+
### InputField.Row
|
|
58
|
+
|
|
59
|
+
| Prop | Type | Default | Description |
|
|
60
|
+
|------|------|---------|-------------|
|
|
61
|
+
| marginTop | SpacingToken | - | Top margin using spacing scale (lounge, club, auditorium, etc.) |
|
|
62
|
+
|
|
63
|
+
### InputField.Input
|
|
64
|
+
|
|
65
|
+
| Prop | Type | Default | Description |
|
|
66
|
+
|------|------|---------|-------------|
|
|
67
|
+
| isErrored | boolean | false | Shows error border styling |
|
|
68
|
+
| hasExtraPadding | boolean | false | Adds extra end padding (for icons) |
|
|
69
|
+
| isReadonlyDropdown | boolean | false | Special styling for readonly dropdowns |
|
|
70
|
+
| inputRef | Ref | - | Ref forwarding |
|
|
71
|
+
|
|
72
|
+
### InputField.Textarea
|
|
73
|
+
|
|
74
|
+
| Prop | Type | Default | Description |
|
|
75
|
+
|------|------|---------|-------------|
|
|
76
|
+
| isErrored | boolean | false | Shows error border styling |
|
|
77
|
+
|
|
78
|
+
### InputField.Select
|
|
79
|
+
|
|
80
|
+
| Prop | Type | Default | Description |
|
|
81
|
+
|------|------|---------|-------------|
|
|
82
|
+
| isErrored | boolean | false | Shows error border styling |
|
|
83
|
+
| isPillVariant | boolean | false | Applies pill-shaped border radius |
|
|
84
|
+
|
|
85
|
+
### InputField.Checkbox
|
|
86
|
+
|
|
87
|
+
| Prop | Type | Default | Description |
|
|
88
|
+
|------|------|---------|-------------|
|
|
89
|
+
| isErrored | boolean | false | Shows error border styling |
|
|
90
|
+
| isIndeterminate | boolean | false | Shows indeterminate state |
|
|
91
|
+
|
|
92
|
+
### InputField.Radio
|
|
93
|
+
|
|
94
|
+
| Prop | Type | Default | Description |
|
|
95
|
+
|------|------|---------|-------------|
|
|
96
|
+
| isErrored | boolean | false | Shows error border styling |
|
|
97
|
+
|
|
98
|
+
### InputField.Validation
|
|
99
|
+
|
|
100
|
+
| Prop | Type | Default | Description |
|
|
101
|
+
|------|------|---------|-------------|
|
|
102
|
+
| type | 'error' \| 'success' | 'error' | Message type |
|
|
103
|
+
| screenReaderErrorPrefix | string | Required | Prefix for screen readers (e.g., "Error:") |
|
|
104
|
+
|
|
105
|
+
## Input with Icons
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { InputField, MagnifyingGlassIcon } from '@jamesodwyer/gds-figma-vite';
|
|
109
|
+
|
|
110
|
+
<InputField id="search">
|
|
111
|
+
<InputField.Label>Search</InputField.Label>
|
|
112
|
+
<InputField.Row marginTop="auditorium">
|
|
113
|
+
<InputField.StartIcon>
|
|
114
|
+
<MagnifyingGlassIcon size="1.5rem" />
|
|
115
|
+
</InputField.StartIcon>
|
|
116
|
+
<InputField.Input placeholder="Search..." />
|
|
117
|
+
</InputField.Row>
|
|
118
|
+
</InputField>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Input with Validation
|
|
122
|
+
|
|
123
|
+
### Error State
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
<InputField id="password">
|
|
127
|
+
<InputField.Label>Password</InputField.Label>
|
|
128
|
+
<InputField.Row marginTop="auditorium">
|
|
129
|
+
<InputField.Input type="password" isErrored />
|
|
130
|
+
</InputField.Row>
|
|
131
|
+
<InputField.Validation
|
|
132
|
+
type="error"
|
|
133
|
+
screenReaderErrorPrefix="Error:"
|
|
134
|
+
>
|
|
135
|
+
Password must be at least 8 characters
|
|
136
|
+
</InputField.Validation>
|
|
137
|
+
</InputField>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Success State
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
<InputField id="username">
|
|
144
|
+
<InputField.Label>Username</InputField.Label>
|
|
145
|
+
<InputField.Row marginTop="auditorium">
|
|
146
|
+
<InputField.Input value="available_user" />
|
|
147
|
+
</InputField.Row>
|
|
148
|
+
<InputField.Validation type="success">
|
|
149
|
+
Username is available
|
|
150
|
+
</InputField.Validation>
|
|
151
|
+
</InputField>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Textarea
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<InputField id="message">
|
|
158
|
+
<InputField.Label>Message</InputField.Label>
|
|
159
|
+
<InputField.Row marginTop="auditorium">
|
|
160
|
+
<InputField.Textarea
|
|
161
|
+
rows={4}
|
|
162
|
+
placeholder="Enter your message..."
|
|
163
|
+
/>
|
|
164
|
+
</InputField.Row>
|
|
165
|
+
</InputField>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Select Dropdown
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<InputField id="country">
|
|
172
|
+
<InputField.Label>Country</InputField.Label>
|
|
173
|
+
<InputField.Row marginTop="auditorium">
|
|
174
|
+
<InputField.Select>
|
|
175
|
+
<option value="">Select a country</option>
|
|
176
|
+
<option value="us">United States</option>
|
|
177
|
+
<option value="uk">United Kingdom</option>
|
|
178
|
+
<option value="ca">Canada</option>
|
|
179
|
+
</InputField.Select>
|
|
180
|
+
</InputField.Row>
|
|
181
|
+
</InputField>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Pill Variant Select
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
<InputField.Select isPillVariant>
|
|
188
|
+
<option value="all">All Events</option>
|
|
189
|
+
<option value="music">Music</option>
|
|
190
|
+
<option value="sports">Sports</option>
|
|
191
|
+
</InputField.Select>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Checkbox
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
<InputField id="terms">
|
|
198
|
+
<InputField.Row>
|
|
199
|
+
<InputField.Checkbox />
|
|
200
|
+
<InputField.Label>I agree to the terms and conditions</InputField.Label>
|
|
201
|
+
</InputField.Row>
|
|
202
|
+
</InputField>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Indeterminate Checkbox
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
<InputField id="select-all">
|
|
209
|
+
<InputField.Row>
|
|
210
|
+
<InputField.Checkbox isIndeterminate />
|
|
211
|
+
<InputField.Label>Select All</InputField.Label>
|
|
212
|
+
</InputField.Row>
|
|
213
|
+
</InputField>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Radio Buttons
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
<fieldset>
|
|
220
|
+
<legend>Payment Method</legend>
|
|
221
|
+
|
|
222
|
+
<InputField id="credit-card">
|
|
223
|
+
<InputField.Row>
|
|
224
|
+
<InputField.Radio name="payment" value="credit" />
|
|
225
|
+
<InputField.Label>Credit Card</InputField.Label>
|
|
226
|
+
</InputField.Row>
|
|
227
|
+
</InputField>
|
|
228
|
+
|
|
229
|
+
<InputField id="paypal">
|
|
230
|
+
<InputField.Row>
|
|
231
|
+
<InputField.Radio name="payment" value="paypal" />
|
|
232
|
+
<InputField.Label>PayPal</InputField.Label>
|
|
233
|
+
</InputField.Row>
|
|
234
|
+
</InputField>
|
|
235
|
+
</fieldset>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Disabled State
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
<InputField id="disabled-input">
|
|
242
|
+
<InputField.Label disabled>Disabled Field</InputField.Label>
|
|
243
|
+
<InputField.Row marginTop="auditorium">
|
|
244
|
+
<InputField.Input disabled value="Cannot edit" />
|
|
245
|
+
</InputField.Row>
|
|
246
|
+
</InputField>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Read-Only State
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
<InputField id="readonly-input">
|
|
253
|
+
<InputField.Label readOnly>Read Only Field</InputField.Label>
|
|
254
|
+
<InputField.Row marginTop="auditorium">
|
|
255
|
+
<InputField.Input readOnly value="Read only value" />
|
|
256
|
+
</InputField.Row>
|
|
257
|
+
</InputField>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Styling Details
|
|
261
|
+
|
|
262
|
+
- **Border radius**: 2px (inputs), pill variant for select
|
|
263
|
+
- **Height**: 44px minimum (tap target compliance)
|
|
264
|
+
- **Padding**: Uses spacing.auditorium (12px)
|
|
265
|
+
- **Border**: 1px solid, 2px when errored
|
|
266
|
+
- **Focus**: Browser default focus with -2px offset
|
|
267
|
+
- **Disabled**: 50% opacity, light background
|
|
268
|
+
|
|
269
|
+
### Color Tokens Used
|
|
270
|
+
|
|
271
|
+
| State | Border | Background |
|
|
272
|
+
|-------|--------|------------|
|
|
273
|
+
| Default | theme.base.borderDark | theme.base.bg |
|
|
274
|
+
| Hover | theme.base.primary | theme.base.bg |
|
|
275
|
+
| Focus | theme.colors.highlight | theme.base.bg |
|
|
276
|
+
| Error | theme.status.danger | theme.base.bg |
|
|
277
|
+
| Disabled | theme.base.border | theme.base.borderLight |
|
|
278
|
+
|
|
279
|
+
## Accessibility
|
|
280
|
+
|
|
281
|
+
- **Auto-linked labels**: Label `htmlFor` automatically points to input
|
|
282
|
+
- **Error association**: Inputs use `aria-describedby` to link to validation messages
|
|
283
|
+
- **Invalid state**: `aria-invalid` set when `isErrored` is true
|
|
284
|
+
- **Screen reader support**: Validation messages include configurable prefix
|
|
285
|
+
- **Keyboard navigation**: Full keyboard support for all input types
|
|
286
|
+
- **Focus indicators**: Visible focus ring on all focusable elements
|
|
287
|
+
|
|
288
|
+
## Spacing Scale Reference
|
|
289
|
+
|
|
290
|
+
Use these tokens for `marginTop` on InputField.Row:
|
|
291
|
+
|
|
292
|
+
| Token | Value |
|
|
293
|
+
|-------|-------|
|
|
294
|
+
| lounge | 4px |
|
|
295
|
+
| club | 8px |
|
|
296
|
+
| auditorium | 12px |
|
|
297
|
+
| hall | 16px |
|
|
298
|
+
| arena | 20px |
|
|
299
|
+
| stadium | 24px |
|
|
300
|
+
| dome | 32px |
|
|
301
|
+
| field | 40px |
|
|
302
|
+
|
|
303
|
+
## Usage Guidelines
|
|
304
|
+
|
|
305
|
+
1. **Always provide an ID** - Required for accessibility linking
|
|
306
|
+
2. **Use labels** - Every input should have a visible label
|
|
307
|
+
3. **Show validation inline** - Display errors near the input
|
|
308
|
+
4. **Provide screen reader prefix** - Use meaningful prefixes like "Error:" or "Success:"
|
|
309
|
+
5. **Group related inputs** - Use fieldset/legend for radio groups
|
|
310
|
+
6. **Use appropriate input types** - email, tel, password, etc.
|
|
311
|
+
7. **Indicate required fields** - Mark required fields clearly
|
|
312
|
+
8. **Provide placeholder text sparingly** - Placeholders are not labels
|