@object-ui/fields 0.3.0 → 0.5.0
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.
- package/dist/fields/src/complex-widgets.test.d.ts +1 -0
- package/dist/fields/src/datetime-widgets.test.d.ts +1 -0
- package/dist/fields/src/fields.stories.d.ts +56 -0
- package/dist/fields/src/index.d.ts +48 -0
- package/dist/fields/src/new-widgets.test.d.ts +8 -0
- package/dist/fields/src/remaining-widgets.test.d.ts +1 -0
- package/dist/fields/src/standard-widgets.test.d.ts +0 -0
- package/dist/fields/src/text-rich-widgets.test.d.ts +1 -0
- package/dist/fields/src/visual-widgets.test.d.ts +1 -0
- package/dist/fields/src/widgets/AddressField.d.ts +16 -0
- package/dist/fields/src/widgets/AutoNumberField.d.ts +6 -0
- package/dist/fields/src/widgets/AvatarField.d.ts +6 -0
- package/dist/fields/src/widgets/CodeField.d.ts +7 -0
- package/dist/fields/src/widgets/ColorField.d.ts +6 -0
- package/dist/fields/src/widgets/CurrencyField.d.ts +1 -1
- package/dist/fields/src/widgets/DateTimeField.d.ts +2 -0
- package/dist/fields/src/widgets/FileField.d.ts +2 -0
- package/dist/fields/src/widgets/FormulaField.d.ts +6 -0
- package/dist/fields/src/widgets/GeolocationField.d.ts +14 -0
- package/dist/fields/src/widgets/GridField.d.ts +7 -0
- package/dist/fields/src/widgets/ImageField.d.ts +2 -0
- package/dist/fields/src/widgets/LocationField.d.ts +2 -0
- package/dist/fields/src/widgets/LookupField.d.ts +1 -1
- package/dist/fields/src/widgets/MasterDetailField.d.ts +14 -0
- package/dist/fields/src/widgets/ObjectField.d.ts +6 -0
- package/dist/fields/src/widgets/PasswordField.d.ts +2 -0
- package/dist/fields/src/widgets/PercentField.d.ts +2 -0
- package/dist/fields/src/widgets/QRCodeField.d.ts +6 -0
- package/dist/fields/src/widgets/RatingField.d.ts +6 -0
- package/dist/fields/src/widgets/SignatureField.d.ts +6 -0
- package/dist/fields/src/widgets/SliderField.d.ts +6 -0
- package/dist/fields/src/widgets/SummaryField.d.ts +6 -0
- package/dist/fields/src/widgets/TimeField.d.ts +2 -0
- package/dist/fields/src/widgets/UserField.d.ts +6 -0
- package/dist/fields/src/widgets/VectorField.d.ts +6 -0
- package/dist/fields/src/widgets/types.d.ts +2 -0
- package/dist/index.cjs +4 -2
- package/dist/index.js +2003 -618
- package/package.json +10 -8
- package/src/complex-widgets.test.tsx +146 -0
- package/src/datetime-widgets.test.tsx +93 -0
- package/src/fields.stories.tsx +566 -0
- package/src/index.tsx +303 -68
- package/src/new-widgets.test.tsx +302 -0
- package/src/remaining-widgets.test.tsx +172 -0
- package/src/standard-widgets.test.tsx +278 -0
- package/src/text-rich-widgets.test.tsx +104 -0
- package/src/visual-widgets.test.tsx +97 -0
- package/src/widgets/AddressField.tsx +112 -0
- package/src/widgets/AutoNumberField.tsx +16 -0
- package/src/widgets/AvatarField.tsx +110 -0
- package/src/widgets/BooleanField.tsx +19 -11
- package/src/widgets/CodeField.tsx +34 -0
- package/src/widgets/ColorField.tsx +44 -0
- package/src/widgets/CurrencyField.tsx +8 -7
- package/src/widgets/DateField.tsx +5 -2
- package/src/widgets/DateTimeField.tsx +28 -0
- package/src/widgets/EmailField.tsx +7 -3
- package/src/widgets/FileField.tsx +114 -0
- package/src/widgets/FormulaField.tsx +31 -0
- package/src/widgets/GeolocationField.tsx +151 -0
- package/src/widgets/GridField.tsx +63 -0
- package/src/widgets/ImageField.tsx +108 -0
- package/src/widgets/LocationField.tsx +46 -0
- package/src/widgets/LookupField.tsx +5 -5
- package/src/widgets/MasterDetailField.tsx +131 -0
- package/src/widgets/NumberField.tsx +8 -4
- package/src/widgets/ObjectField.tsx +85 -0
- package/src/widgets/PasswordField.tsx +45 -0
- package/src/widgets/PercentField.tsx +49 -0
- package/src/widgets/PhoneField.tsx +7 -3
- package/src/widgets/QRCodeField.tsx +96 -0
- package/src/widgets/RatingField.tsx +66 -0
- package/src/widgets/RichTextField.tsx +5 -5
- package/src/widgets/SelectField.tsx +7 -5
- package/src/widgets/SignatureField.tsx +140 -0
- package/src/widgets/SliderField.tsx +39 -0
- package/src/widgets/SummaryField.tsx +29 -0
- package/src/widgets/TextAreaField.tsx +9 -6
- package/src/widgets/TextField.tsx +13 -8
- package/src/widgets/TimeField.tsx +22 -0
- package/src/widgets/UrlField.tsx +7 -3
- package/src/widgets/UserField.tsx +88 -0
- package/src/widgets/VectorField.tsx +28 -0
- package/src/widgets/types.ts +2 -0
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
TextField,
|
|
5
|
+
CurrencyField,
|
|
6
|
+
SelectField,
|
|
7
|
+
DateField,
|
|
8
|
+
DateTimeField,
|
|
9
|
+
TimeField,
|
|
10
|
+
BooleanField,
|
|
11
|
+
NumberField,
|
|
12
|
+
PercentField,
|
|
13
|
+
UrlField,
|
|
14
|
+
PhoneField,
|
|
15
|
+
EmailField,
|
|
16
|
+
PasswordField,
|
|
17
|
+
TextAreaField,
|
|
18
|
+
AutoNumberField,
|
|
19
|
+
LookupField,
|
|
20
|
+
UserField,
|
|
21
|
+
FileField,
|
|
22
|
+
LocationField,
|
|
23
|
+
FormulaField,
|
|
24
|
+
SummaryField,
|
|
25
|
+
RichTextField,
|
|
26
|
+
ImageField,
|
|
27
|
+
ObjectField,
|
|
28
|
+
VectorField,
|
|
29
|
+
GridField,
|
|
30
|
+
ColorField,
|
|
31
|
+
SliderField,
|
|
32
|
+
RatingField,
|
|
33
|
+
CodeField,
|
|
34
|
+
AvatarField,
|
|
35
|
+
AddressField,
|
|
36
|
+
GeolocationField,
|
|
37
|
+
SignatureField,
|
|
38
|
+
QRCodeField,
|
|
39
|
+
MasterDetailField
|
|
40
|
+
} from './index';
|
|
41
|
+
import { FieldMetadata } from '@object-ui/types';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* **Field Widgets** from `@object-ui/fields`.
|
|
45
|
+
*
|
|
46
|
+
* These components handle data formatting, validation, and display logic for specific data types.
|
|
47
|
+
* They are typically used within `ObjectForm` or `ObjectGrid` but can be used standalone.
|
|
48
|
+
*
|
|
49
|
+
* Note: These widgets implement the `FieldWidgetProps` interface.
|
|
50
|
+
*/
|
|
51
|
+
const meta = {
|
|
52
|
+
title: 'Fields/Gallery',
|
|
53
|
+
parameters: {
|
|
54
|
+
layout: 'centered',
|
|
55
|
+
},
|
|
56
|
+
tags: ['autodocs'],
|
|
57
|
+
} satisfies Meta;
|
|
58
|
+
|
|
59
|
+
export default meta;
|
|
60
|
+
type Story = StoryObj<any>;
|
|
61
|
+
|
|
62
|
+
// Wrapper to handle state since these are controlled components
|
|
63
|
+
const FieldWrapper = ({
|
|
64
|
+
Component,
|
|
65
|
+
field,
|
|
66
|
+
initialValue,
|
|
67
|
+
readonly = false
|
|
68
|
+
}: {
|
|
69
|
+
Component: any,
|
|
70
|
+
field: Partial<FieldMetadata>,
|
|
71
|
+
initialValue?: any,
|
|
72
|
+
readonly?: boolean
|
|
73
|
+
}) => {
|
|
74
|
+
const [value, setValue] = useState(initialValue);
|
|
75
|
+
|
|
76
|
+
// Ensure field has minimal required props
|
|
77
|
+
const fullField = {
|
|
78
|
+
name: 'test_field',
|
|
79
|
+
label: 'Test Field',
|
|
80
|
+
type: 'text',
|
|
81
|
+
...field
|
|
82
|
+
} as FieldMetadata;
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div className="w-[350px] space-y-2 p-4 border rounded-lg shadow-sm bg-white">
|
|
86
|
+
<div className="flex justify-between items-center mb-2">
|
|
87
|
+
<label className="text-sm font-semibold text-gray-700">{fullField.label}</label>
|
|
88
|
+
{readonly && <span className="text-[10px] bg-slate-100 px-2 py-0.5 rounded text-slate-500 font-medium">Read Only</span>}
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<Component
|
|
92
|
+
value={value}
|
|
93
|
+
onChange={(val: any) => {
|
|
94
|
+
console.log('onChange', val);
|
|
95
|
+
setValue(val);
|
|
96
|
+
}}
|
|
97
|
+
field={fullField}
|
|
98
|
+
readonly={readonly}
|
|
99
|
+
/>
|
|
100
|
+
|
|
101
|
+
{!readonly && (
|
|
102
|
+
<div className="text-xs text-muted-foreground mt-4 pt-2 border-t font-mono overflow-hidden text-ellipsis">
|
|
103
|
+
Value: {JSON.stringify(value)}
|
|
104
|
+
</div>
|
|
105
|
+
)}
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// --- Text Based ---
|
|
111
|
+
|
|
112
|
+
export const Text: Story = {
|
|
113
|
+
render: () => (
|
|
114
|
+
<FieldWrapper
|
|
115
|
+
Component={TextField}
|
|
116
|
+
field={{ label: 'Deal Name', type: 'text', placeholder: 'Enter deal name...' }}
|
|
117
|
+
initialValue="Big Enterprise Deal"
|
|
118
|
+
/>
|
|
119
|
+
)
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const TextArea: Story = {
|
|
123
|
+
render: () => (
|
|
124
|
+
<FieldWrapper
|
|
125
|
+
Component={TextAreaField}
|
|
126
|
+
field={{ label: 'Description', type: 'textarea', rows: 4 }}
|
|
127
|
+
initialValue="This is a multi-line description text area."
|
|
128
|
+
/>
|
|
129
|
+
)
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const Email: Story = {
|
|
133
|
+
render: () => (
|
|
134
|
+
<FieldWrapper
|
|
135
|
+
Component={EmailField}
|
|
136
|
+
field={{ label: 'Email', type: 'email' }}
|
|
137
|
+
initialValue="contact@example.com"
|
|
138
|
+
/>
|
|
139
|
+
)
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export const Phone: Story = {
|
|
143
|
+
render: () => (
|
|
144
|
+
<FieldWrapper
|
|
145
|
+
Component={PhoneField}
|
|
146
|
+
field={{ label: 'Phone', type: 'phone' }}
|
|
147
|
+
initialValue="+1 (555) 123-4567"
|
|
148
|
+
/>
|
|
149
|
+
)
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export const Url: Story = {
|
|
153
|
+
render: () => (
|
|
154
|
+
<FieldWrapper
|
|
155
|
+
Component={UrlField}
|
|
156
|
+
field={{ label: 'Website', type: 'url' }}
|
|
157
|
+
initialValue="https://objectui.org"
|
|
158
|
+
/>
|
|
159
|
+
)
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const Password: Story = {
|
|
163
|
+
render: () => (
|
|
164
|
+
<FieldWrapper
|
|
165
|
+
Component={PasswordField}
|
|
166
|
+
field={{ label: 'Secret Key', type: 'password' }}
|
|
167
|
+
initialValue="supersecret"
|
|
168
|
+
/>
|
|
169
|
+
)
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export const AutoNumber: Story = {
|
|
173
|
+
render: () => (
|
|
174
|
+
<FieldWrapper
|
|
175
|
+
Component={AutoNumberField}
|
|
176
|
+
field={{ label: 'Order Number', type: 'auto_number' }}
|
|
177
|
+
initialValue="ORD-2024-001"
|
|
178
|
+
readonly={true}
|
|
179
|
+
/>
|
|
180
|
+
)
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// --- Numbers ---
|
|
184
|
+
|
|
185
|
+
export const Number: Story = {
|
|
186
|
+
render: () => (
|
|
187
|
+
<FieldWrapper
|
|
188
|
+
Component={NumberField}
|
|
189
|
+
field={{ label: 'Quantity', type: 'number', precision: 0 }}
|
|
190
|
+
initialValue={42}
|
|
191
|
+
/>
|
|
192
|
+
)
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const Currency: Story = {
|
|
196
|
+
render: () => (
|
|
197
|
+
<FieldWrapper
|
|
198
|
+
Component={CurrencyField}
|
|
199
|
+
field={{ label: 'Amount', type: 'currency', currency: 'USD', precision: 2 }}
|
|
200
|
+
initialValue={1234567.89}
|
|
201
|
+
/>
|
|
202
|
+
)
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export const Percent: Story = {
|
|
206
|
+
render: () => (
|
|
207
|
+
<FieldWrapper
|
|
208
|
+
Component={PercentField}
|
|
209
|
+
field={{ label: 'Probability', type: 'percent', precision: 2 }}
|
|
210
|
+
initialValue={0.75}
|
|
211
|
+
/>
|
|
212
|
+
)
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// --- Date & Time ---
|
|
216
|
+
|
|
217
|
+
export const Date: Story = {
|
|
218
|
+
render: () => (
|
|
219
|
+
<FieldWrapper
|
|
220
|
+
Component={DateField}
|
|
221
|
+
field={{ label: 'Close Date', type: 'date' }}
|
|
222
|
+
initialValue={new globalThis.Date().toISOString()}
|
|
223
|
+
/>
|
|
224
|
+
)
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export const DateTime: Story = {
|
|
228
|
+
render: () => (
|
|
229
|
+
<FieldWrapper
|
|
230
|
+
Component={DateTimeField}
|
|
231
|
+
field={{ label: 'Meeting Time', type: 'datetime' }}
|
|
232
|
+
initialValue={new globalThis.Date().toISOString()}
|
|
233
|
+
/>
|
|
234
|
+
)
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
export const Time: Story = {
|
|
238
|
+
render: () => (
|
|
239
|
+
<FieldWrapper
|
|
240
|
+
Component={TimeField}
|
|
241
|
+
field={{ label: 'Start Time', type: 'time' }}
|
|
242
|
+
initialValue="14:30"
|
|
243
|
+
/>
|
|
244
|
+
)
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// --- Selection ---
|
|
248
|
+
|
|
249
|
+
export const Boolean: Story = {
|
|
250
|
+
render: () => (
|
|
251
|
+
<FieldWrapper
|
|
252
|
+
Component={BooleanField}
|
|
253
|
+
field={{ label: 'Is Active?', type: 'boolean' }}
|
|
254
|
+
initialValue={true}
|
|
255
|
+
/>
|
|
256
|
+
)
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export const Select: Story = {
|
|
260
|
+
render: () => (
|
|
261
|
+
<FieldWrapper
|
|
262
|
+
Component={SelectField}
|
|
263
|
+
field={{
|
|
264
|
+
label: 'Stage',
|
|
265
|
+
type: 'select',
|
|
266
|
+
options: [
|
|
267
|
+
{ label: 'Prospecting', value: 'prospecting' },
|
|
268
|
+
{ label: 'Qualification', value: 'qualification' },
|
|
269
|
+
{ label: 'Proposal', value: 'proposal' },
|
|
270
|
+
{ label: 'Closed Won', value: 'closed_won' },
|
|
271
|
+
{ label: 'Closed Lost', value: 'closed_lost' },
|
|
272
|
+
]
|
|
273
|
+
}}
|
|
274
|
+
initialValue="proposal"
|
|
275
|
+
/>
|
|
276
|
+
)
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export const Lookup: Story = {
|
|
280
|
+
render: () => (
|
|
281
|
+
<FieldWrapper
|
|
282
|
+
Component={LookupField}
|
|
283
|
+
field={{
|
|
284
|
+
label: 'Account',
|
|
285
|
+
type: 'lookup',
|
|
286
|
+
options: [
|
|
287
|
+
{ label: 'Acme Corp', value: 'acme' },
|
|
288
|
+
{ label: 'Globex', value: 'globex' },
|
|
289
|
+
{ label: 'Soylent Corp', value: 'soylent' },
|
|
290
|
+
] as any
|
|
291
|
+
}}
|
|
292
|
+
initialValue="acme"
|
|
293
|
+
/>
|
|
294
|
+
)
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
export const MultiSelectLookup: Story = {
|
|
298
|
+
render: () => (
|
|
299
|
+
<FieldWrapper
|
|
300
|
+
Component={LookupField}
|
|
301
|
+
field={{
|
|
302
|
+
label: 'Related Accounts',
|
|
303
|
+
type: 'lookup',
|
|
304
|
+
multiple: true,
|
|
305
|
+
options: [
|
|
306
|
+
{ label: 'Acme Corp', value: 'acme' },
|
|
307
|
+
{ label: 'Globex', value: 'globex' },
|
|
308
|
+
{ label: 'Soylent Corp', value: 'soylent' },
|
|
309
|
+
] as any
|
|
310
|
+
}}
|
|
311
|
+
initialValue={['acme', 'soylent']}
|
|
312
|
+
/>
|
|
313
|
+
)
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// --- Special ---
|
|
317
|
+
|
|
318
|
+
export const User: Story = {
|
|
319
|
+
render: () => (
|
|
320
|
+
<FieldWrapper
|
|
321
|
+
Component={UserField}
|
|
322
|
+
field={{ label: 'Assigned To', type: 'user' }}
|
|
323
|
+
initialValue={{ name: 'John Doe', username: 'jdoe' }}
|
|
324
|
+
/>
|
|
325
|
+
)
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
export const File: Story = {
|
|
329
|
+
render: () => (
|
|
330
|
+
<FieldWrapper
|
|
331
|
+
Component={FileField}
|
|
332
|
+
field={{ label: 'Attachment', type: 'file' }}
|
|
333
|
+
initialValue={{ name: 'report.pdf', size: 1024000 }}
|
|
334
|
+
/>
|
|
335
|
+
)
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
export const Location: Story = {
|
|
339
|
+
render: () => (
|
|
340
|
+
<FieldWrapper
|
|
341
|
+
Component={LocationField}
|
|
342
|
+
field={{ label: 'Coordinates', type: 'location' }}
|
|
343
|
+
initialValue={{ latitude: 37.7749, longitude: -122.4194 }}
|
|
344
|
+
/>
|
|
345
|
+
)
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
export const Formula: Story = {
|
|
349
|
+
render: () => (
|
|
350
|
+
<FieldWrapper
|
|
351
|
+
Component={FormulaField}
|
|
352
|
+
field={{ label: 'Net Profit', type: 'formula' }}
|
|
353
|
+
initialValue={5000}
|
|
354
|
+
readonly
|
|
355
|
+
/>
|
|
356
|
+
)
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
export const Summary: Story = {
|
|
360
|
+
render: () => (
|
|
361
|
+
<FieldWrapper
|
|
362
|
+
Component={SummaryField}
|
|
363
|
+
field={{ label: 'Total Sales', type: 'summary' }}
|
|
364
|
+
initialValue={100000}
|
|
365
|
+
readonly
|
|
366
|
+
/>
|
|
367
|
+
)
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export const ReadOnly: Story = {
|
|
371
|
+
render: () => (
|
|
372
|
+
<div className="flex flex-col gap-4">
|
|
373
|
+
<FieldWrapper
|
|
374
|
+
Component={TextField}
|
|
375
|
+
field={{ label: 'Read Only Text', type: 'text' }}
|
|
376
|
+
initialValue="You cannot edit this"
|
|
377
|
+
readonly={true}
|
|
378
|
+
/>
|
|
379
|
+
<FieldWrapper
|
|
380
|
+
Component={CurrencyField}
|
|
381
|
+
field={{ label: 'Read Only Currency', type: 'currency' }}
|
|
382
|
+
initialValue={9999.99}
|
|
383
|
+
readonly={true}
|
|
384
|
+
/>
|
|
385
|
+
<FieldWrapper
|
|
386
|
+
Component={UserField}
|
|
387
|
+
field={{ label: 'Read Only User', type: 'user' }}
|
|
388
|
+
initialValue={{ name: 'Jane Smith' }}
|
|
389
|
+
readonly={true}
|
|
390
|
+
/>
|
|
391
|
+
</div>
|
|
392
|
+
)
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// --- New Widgets ---
|
|
396
|
+
|
|
397
|
+
export const RichText: Story = {
|
|
398
|
+
render: () => (
|
|
399
|
+
<FieldWrapper
|
|
400
|
+
Component={RichTextField}
|
|
401
|
+
field={{ label: 'Description', type: 'html' }}
|
|
402
|
+
initialValue="<p><b>Rich</b> text content...</p>"
|
|
403
|
+
/>
|
|
404
|
+
)
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
export const Image: Story = {
|
|
408
|
+
render: () => (
|
|
409
|
+
<FieldWrapper
|
|
410
|
+
Component={ImageField}
|
|
411
|
+
field={{ label: 'Banner', type: 'image' }}
|
|
412
|
+
initialValue="https://placehold.co/600x400"
|
|
413
|
+
/>
|
|
414
|
+
)
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
export const Color: Story = {
|
|
418
|
+
render: () => (
|
|
419
|
+
<FieldWrapper
|
|
420
|
+
Component={ColorField}
|
|
421
|
+
field={{ label: 'Theme Color', type: 'color' }}
|
|
422
|
+
initialValue="#3b82f6"
|
|
423
|
+
/>
|
|
424
|
+
)
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
export const Slider: Story = {
|
|
428
|
+
render: () => (
|
|
429
|
+
<FieldWrapper
|
|
430
|
+
Component={SliderField}
|
|
431
|
+
field={{ label: 'Opacity', type: 'slider', min: 0, max: 100 } as any}
|
|
432
|
+
initialValue={75}
|
|
433
|
+
/>
|
|
434
|
+
)
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
export const Rating: Story = {
|
|
438
|
+
render: () => (
|
|
439
|
+
<FieldWrapper
|
|
440
|
+
Component={RatingField}
|
|
441
|
+
field={{ label: 'Score', type: 'rating', max: 5 } as any}
|
|
442
|
+
initialValue={4}
|
|
443
|
+
/>
|
|
444
|
+
)
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
export const Code: Story = {
|
|
448
|
+
render: () => (
|
|
449
|
+
<FieldWrapper
|
|
450
|
+
Component={CodeField}
|
|
451
|
+
field={{ label: 'Config JSON', type: 'code' }}
|
|
452
|
+
initialValue='{ "debug": true }'
|
|
453
|
+
/>
|
|
454
|
+
)
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
export const Avatar: Story = {
|
|
458
|
+
render: () => (
|
|
459
|
+
<FieldWrapper
|
|
460
|
+
Component={AvatarField}
|
|
461
|
+
field={{ label: 'Profile', type: 'avatar' }}
|
|
462
|
+
initialValue="https://github.com/shadcn.png"
|
|
463
|
+
/>
|
|
464
|
+
)
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
export const Signature: Story = {
|
|
468
|
+
render: () => (
|
|
469
|
+
<FieldWrapper
|
|
470
|
+
Component={SignatureField}
|
|
471
|
+
field={{ label: 'Sign Here', type: 'signature' }}
|
|
472
|
+
initialValue=""
|
|
473
|
+
/>
|
|
474
|
+
)
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
export const QRCode: Story = {
|
|
478
|
+
render: () => (
|
|
479
|
+
<FieldWrapper
|
|
480
|
+
Component={QRCodeField}
|
|
481
|
+
field={{ label: 'Scan Me', type: 'qrcode' }}
|
|
482
|
+
initialValue="https://objectui.org"
|
|
483
|
+
/>
|
|
484
|
+
)
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
export const Address: Story = {
|
|
488
|
+
render: () => (
|
|
489
|
+
<FieldWrapper
|
|
490
|
+
Component={AddressField}
|
|
491
|
+
field={{ label: 'Shipping Address', type: 'address' }}
|
|
492
|
+
initialValue={{ street: '123 Main St', city: 'Anytown', country: 'USA' }}
|
|
493
|
+
/>
|
|
494
|
+
)
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
export const Geolocation: Story = {
|
|
498
|
+
render: () => (
|
|
499
|
+
<FieldWrapper
|
|
500
|
+
Component={GeolocationField}
|
|
501
|
+
field={{ label: 'Location', type: 'geolocation' }}
|
|
502
|
+
initialValue={{ lat: 37.7749, lng: -122.4194 }}
|
|
503
|
+
/>
|
|
504
|
+
)
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
export const Object: Story = {
|
|
508
|
+
render: () => (
|
|
509
|
+
<FieldWrapper
|
|
510
|
+
Component={ObjectField}
|
|
511
|
+
field={{
|
|
512
|
+
label: 'Metadata',
|
|
513
|
+
type: 'object',
|
|
514
|
+
fields: [
|
|
515
|
+
{ name: 'key', type: 'text', label: 'Key' },
|
|
516
|
+
{ name: 'value', type: 'text', label: 'Value' }
|
|
517
|
+
]
|
|
518
|
+
} as any}
|
|
519
|
+
initialValue={{ key: 'theme', value: 'dark' }}
|
|
520
|
+
/>
|
|
521
|
+
)
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
export const Grid: Story = {
|
|
525
|
+
render: () => (
|
|
526
|
+
<FieldWrapper
|
|
527
|
+
Component={GridField}
|
|
528
|
+
field={{
|
|
529
|
+
label: 'Order Items',
|
|
530
|
+
type: 'grid',
|
|
531
|
+
columns: [
|
|
532
|
+
{ field: 'item', label: 'Item' },
|
|
533
|
+
{ field: 'qty', label: 'Qty' }
|
|
534
|
+
]
|
|
535
|
+
} as any}
|
|
536
|
+
initialValue={[
|
|
537
|
+
{ item: 'Apple', qty: 2 },
|
|
538
|
+
{ item: 'Banana', qty: 5 }
|
|
539
|
+
]}
|
|
540
|
+
/>
|
|
541
|
+
)
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
export const MasterDetail: Story = {
|
|
545
|
+
render: () => (
|
|
546
|
+
<FieldWrapper
|
|
547
|
+
Component={MasterDetailField}
|
|
548
|
+
field={{
|
|
549
|
+
label: 'Line Items',
|
|
550
|
+
type: 'master_detail',
|
|
551
|
+
reference_to: 'products'
|
|
552
|
+
} as any}
|
|
553
|
+
initialValue={[]}
|
|
554
|
+
/>
|
|
555
|
+
)
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
export const Vector: Story = {
|
|
559
|
+
render: () => (
|
|
560
|
+
<FieldWrapper
|
|
561
|
+
Component={VectorField}
|
|
562
|
+
field={{ label: 'Embedding', type: 'vector' }}
|
|
563
|
+
initialValue={[0.1, 0.2, 0.3, 0.4]}
|
|
564
|
+
/>
|
|
565
|
+
)
|
|
566
|
+
};
|