@dfosco/storyboard 0.5.0-beta.44 → 0.5.0-beta.45
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/package.json
CHANGED
|
@@ -164,6 +164,8 @@ export default function ArtifactForm({
|
|
|
164
164
|
setErrors({})
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
const [showAdvanced, setShowAdvanced] = useState(false)
|
|
168
|
+
|
|
167
169
|
const visibleFields = useMemo(() => {
|
|
168
170
|
if (!schema) return []
|
|
169
171
|
if (compact) return schema.fields.filter(f => f.required)
|
|
@@ -182,6 +184,18 @@ export default function ArtifactForm({
|
|
|
182
184
|
return fields
|
|
183
185
|
}, [schema, compact, values])
|
|
184
186
|
|
|
187
|
+
// Split into basic/advanced. A field with no `tier` defaults to 'basic'
|
|
188
|
+
// (matches the old behaviour for any schema not yet annotated).
|
|
189
|
+
const { basicFields, advancedFields } = useMemo(() => {
|
|
190
|
+
const basic = []
|
|
191
|
+
const advanced = []
|
|
192
|
+
for (const f of visibleFields) {
|
|
193
|
+
if (f.tier === 'advanced') advanced.push(f)
|
|
194
|
+
else basic.push(f)
|
|
195
|
+
}
|
|
196
|
+
return { basicFields: basic, advancedFields: advanced }
|
|
197
|
+
}, [visibleFields])
|
|
198
|
+
|
|
185
199
|
if (!schema) {
|
|
186
200
|
return (
|
|
187
201
|
<Flash variant="warning">
|
|
@@ -234,7 +248,7 @@ export default function ArtifactForm({
|
|
|
234
248
|
)}
|
|
235
249
|
|
|
236
250
|
<div className={styles.fields}>
|
|
237
|
-
{
|
|
251
|
+
{basicFields.map(field => {
|
|
238
252
|
const options = field.dynamic ? dynamicOptions[field.dynamic] : field.options
|
|
239
253
|
return (
|
|
240
254
|
<FormControl key={field.name} required={field.required}>
|
|
@@ -257,6 +271,43 @@ export default function ArtifactForm({
|
|
|
257
271
|
</FormControl>
|
|
258
272
|
)
|
|
259
273
|
})}
|
|
274
|
+
|
|
275
|
+
{advancedFields.length > 0 && (
|
|
276
|
+
<>
|
|
277
|
+
<Button
|
|
278
|
+
type="button"
|
|
279
|
+
variant="invisible"
|
|
280
|
+
size="small"
|
|
281
|
+
onClick={() => setShowAdvanced(s => !s)}
|
|
282
|
+
className={styles.advancedToggle}
|
|
283
|
+
>
|
|
284
|
+
{showAdvanced ? '− Hide advanced fields' : '+ Advanced fields'}
|
|
285
|
+
</Button>
|
|
286
|
+
{showAdvanced && advancedFields.map(field => {
|
|
287
|
+
const options = field.dynamic ? dynamicOptions[field.dynamic] : field.options
|
|
288
|
+
return (
|
|
289
|
+
<FormControl key={field.name} required={field.required}>
|
|
290
|
+
<FormControl.Label>{field.label}</FormControl.Label>
|
|
291
|
+
<FieldRenderer
|
|
292
|
+
field={field}
|
|
293
|
+
value={values[field.name]}
|
|
294
|
+
error={errors[field.name]}
|
|
295
|
+
onChange={val => handleChange(field.name, val)}
|
|
296
|
+
options={options}
|
|
297
|
+
/>
|
|
298
|
+
{errors[field.name] && (
|
|
299
|
+
<FormControl.Validation variant="error">
|
|
300
|
+
{errors[field.name]}
|
|
301
|
+
</FormControl.Validation>
|
|
302
|
+
)}
|
|
303
|
+
{field.patternHint && !errors[field.name] && (
|
|
304
|
+
<FormControl.Caption>{field.patternHint}</FormControl.Caption>
|
|
305
|
+
)}
|
|
306
|
+
</FormControl>
|
|
307
|
+
)
|
|
308
|
+
})}
|
|
309
|
+
</>
|
|
310
|
+
)}
|
|
260
311
|
</div>
|
|
261
312
|
|
|
262
313
|
{errors._form && (
|
|
@@ -14,17 +14,17 @@ export const ARTIFACT_SCHEMAS = {
|
|
|
14
14
|
icon: '📐',
|
|
15
15
|
description: 'Interactive prototype with pages and flows. Add a URL to make it external.',
|
|
16
16
|
fields: [
|
|
17
|
-
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'my-app', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64 },
|
|
18
|
-
{ name: 'title', label: 'Title', type: 'text', placeholder: 'My App' },
|
|
19
|
-
{ name: 'description', label: 'Description', type: 'textarea', placeholder: 'What this prototype demonstrates…' },
|
|
20
|
-
{ name: '
|
|
21
|
-
{ name: '
|
|
22
|
-
{ name: '
|
|
23
|
-
{ name: '
|
|
24
|
-
{ name: '
|
|
25
|
-
{ name: '
|
|
26
|
-
{ name: '
|
|
27
|
-
{ name: 'flow', label: 'Create default flow', type: 'checkbox', checkboxLabel: 'Generate a default.flow.json' },
|
|
17
|
+
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'my-app', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64, tier: 'basic' },
|
|
18
|
+
{ name: 'title', label: 'Title', type: 'text', placeholder: 'My App', tier: 'basic' },
|
|
19
|
+
{ name: 'description', label: 'Description', type: 'textarea', placeholder: 'What this prototype demonstrates…', tier: 'basic' },
|
|
20
|
+
{ name: 'url', label: 'External URL', type: 'url', placeholder: 'https://figma.com/… (makes it external)', tier: 'basic' },
|
|
21
|
+
{ name: 'partial', label: 'Template / Recipe', type: 'select', placeholder: 'Blank prototype', dynamic: 'partials', tier: 'basic' },
|
|
22
|
+
{ name: 'author', label: 'Author', type: 'text', placeholder: 'dfosco (or comma-separated)', tier: 'advanced' },
|
|
23
|
+
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'main (optional .folder grouping)', tier: 'advanced' },
|
|
24
|
+
{ name: 'icon', label: 'Icon', type: 'text', placeholder: 'rocket', tier: 'advanced' },
|
|
25
|
+
{ name: 'tags', label: 'Tags', type: 'text', placeholder: 'design, exploration (comma-separated)', tier: 'advanced' },
|
|
26
|
+
{ name: 'team', label: 'Team', type: 'text', placeholder: 'design-systems', tier: 'advanced' },
|
|
27
|
+
{ name: 'flow', label: 'Create default flow', type: 'checkbox', checkboxLabel: 'Generate a default.flow.json', tier: 'advanced' },
|
|
28
28
|
],
|
|
29
29
|
operations: ['create', 'edit', 'delete', 'duplicate'],
|
|
30
30
|
mutuallyExclusive: [['url', 'flow'], ['url', 'partial']],
|
|
@@ -35,10 +35,10 @@ export const ARTIFACT_SCHEMAS = {
|
|
|
35
35
|
icon: '🎨',
|
|
36
36
|
description: 'Freeform spatial canvas for exploration and planning',
|
|
37
37
|
fields: [
|
|
38
|
-
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'design-system', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64 },
|
|
39
|
-
{ name: 'title', label: 'Title', type: 'text', placeholder: 'Design Exploration' },
|
|
40
|
-
{ name: 'description', label: 'Description', type: 'textarea', placeholder: 'Purpose of this canvas…' },
|
|
41
|
-
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'storyboarding (optional grouping)' },
|
|
38
|
+
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'design-system', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64, tier: 'basic' },
|
|
39
|
+
{ name: 'title', label: 'Title', type: 'text', placeholder: 'Design Exploration', tier: 'basic' },
|
|
40
|
+
{ name: 'description', label: 'Description', type: 'textarea', placeholder: 'Purpose of this canvas…', tier: 'basic' },
|
|
41
|
+
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'storyboarding (optional grouping)', tier: 'advanced' },
|
|
42
42
|
],
|
|
43
43
|
operations: ['create', 'edit', 'delete', 'duplicate'],
|
|
44
44
|
},
|
|
@@ -48,8 +48,8 @@ export const ARTIFACT_SCHEMAS = {
|
|
|
48
48
|
icon: '🧩',
|
|
49
49
|
description: 'Reusable UI component with story file',
|
|
50
50
|
fields: [
|
|
51
|
-
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'LoginForm', pattern: '^[A-Z][A-Za-z0-9]+$', patternHint: 'PascalCase (e.g. LoginForm)', maxLength: 64 },
|
|
52
|
-
{ name: 'directory', label: 'Directory', type: 'text', placeholder: 'src/components (default)' },
|
|
51
|
+
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'LoginForm', pattern: '^[A-Z][A-Za-z0-9]+$', patternHint: 'PascalCase (e.g. LoginForm)', maxLength: 64, tier: 'basic' },
|
|
52
|
+
{ name: 'directory', label: 'Directory', type: 'text', placeholder: 'src/components (default)', tier: 'advanced' },
|
|
53
53
|
],
|
|
54
54
|
operations: ['create', 'delete'],
|
|
55
55
|
},
|
|
@@ -59,14 +59,14 @@ export const ARTIFACT_SCHEMAS = {
|
|
|
59
59
|
icon: '🔀',
|
|
60
60
|
description: 'Page data context — composes objects via $ref and $global',
|
|
61
61
|
fields: [
|
|
62
|
-
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'default', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64 },
|
|
63
|
-
{ name: 'prototype', label: 'Prototype', type: 'select', required: true, options: [], dynamic: 'prototypes' },
|
|
64
|
-
{ name: 'title', label: 'Title', type: 'text', placeholder: 'Settings Flow' },
|
|
65
|
-
{ name: 'description', label: 'Description', type: 'textarea', placeholder: 'Data context for…' },
|
|
66
|
-
{ name: 'globals', label: '$global objects', type: 'text', placeholder: 'navigation, sidebar (comma-separated)' },
|
|
67
|
-
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'Optional subfolder' },
|
|
68
|
-
{ name: 'copyFrom', label: 'Copy from', type: 'text', placeholder: 'Existing flow name to duplicate' },
|
|
69
|
-
{ name: 'startingPage', label: 'Starting page', type: 'text', placeholder: 'Route to open with this flow' },
|
|
62
|
+
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'default', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64, tier: 'basic' },
|
|
63
|
+
{ name: 'prototype', label: 'Prototype', type: 'select', required: true, options: [], dynamic: 'prototypes', tier: 'basic' },
|
|
64
|
+
{ name: 'title', label: 'Title', type: 'text', placeholder: 'Settings Flow', tier: 'basic' },
|
|
65
|
+
{ name: 'description', label: 'Description', type: 'textarea', placeholder: 'Data context for…', tier: 'basic' },
|
|
66
|
+
{ name: 'globals', label: '$global objects', type: 'text', placeholder: 'navigation, sidebar (comma-separated)', tier: 'advanced' },
|
|
67
|
+
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'Optional subfolder', tier: 'advanced' },
|
|
68
|
+
{ name: 'copyFrom', label: 'Copy from', type: 'text', placeholder: 'Existing flow name to duplicate', tier: 'advanced' },
|
|
69
|
+
{ name: 'startingPage', label: 'Starting page', type: 'text', placeholder: 'Route to open with this flow', tier: 'advanced' },
|
|
70
70
|
],
|
|
71
71
|
operations: ['create', 'edit', 'delete', 'duplicate'],
|
|
72
72
|
},
|
|
@@ -76,9 +76,9 @@ export const ARTIFACT_SCHEMAS = {
|
|
|
76
76
|
icon: '📦',
|
|
77
77
|
description: 'Reusable data fragment — freeform JSON',
|
|
78
78
|
fields: [
|
|
79
|
-
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'jane-doe', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64 },
|
|
80
|
-
{ name: '
|
|
81
|
-
{ name: '
|
|
79
|
+
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'jane-doe', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64, tier: 'basic' },
|
|
80
|
+
{ name: 'body', label: 'JSON Body', type: 'code', placeholder: '{\n "name": "Jane Doe",\n "role": "admin"\n}', language: 'json', tier: 'basic' },
|
|
81
|
+
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'Optional folder (or inside prototype for scoping)', tier: 'advanced' },
|
|
82
82
|
],
|
|
83
83
|
operations: ['create', 'edit', 'delete', 'duplicate'],
|
|
84
84
|
},
|
|
@@ -88,9 +88,9 @@ export const ARTIFACT_SCHEMAS = {
|
|
|
88
88
|
icon: '📋',
|
|
89
89
|
description: 'Collection of entries — array of objects with unique id',
|
|
90
90
|
fields: [
|
|
91
|
-
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'posts', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64 },
|
|
92
|
-
{ name: '
|
|
93
|
-
{ name: '
|
|
91
|
+
{ name: 'name', label: 'Name', type: 'text', required: true, placeholder: 'posts', pattern: NAME_PATTERN, patternHint: NAME_HINT, maxLength: 64, tier: 'basic' },
|
|
92
|
+
{ name: 'body', label: 'Entries (JSON array)', type: 'code', placeholder: '[\n { "id": "first", "title": "First Entry" }\n]', language: 'json', tier: 'basic' },
|
|
93
|
+
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'Optional folder', tier: 'advanced' },
|
|
94
94
|
],
|
|
95
95
|
operations: ['create', 'edit', 'delete'],
|
|
96
96
|
},
|
|
@@ -100,10 +100,10 @@ export const ARTIFACT_SCHEMAS = {
|
|
|
100
100
|
icon: '📄',
|
|
101
101
|
description: 'A page inside an existing prototype',
|
|
102
102
|
fields: [
|
|
103
|
-
{ name: 'prototype', label: 'Prototype', type: 'select', required: true, options: [], dynamic: 'prototypes' },
|
|
104
|
-
{ name: 'path', label: 'Path', type: 'text', required: true, placeholder: 'settings/general', pattern: '^[a-z0-9][a-z0-9-/]*$', patternHint: 'Lowercase path with slashes (e.g. settings/general)' },
|
|
105
|
-
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'Optional subfolder within prototype' },
|
|
106
|
-
{ name: 'template', label: 'Template', type: 'text', placeholder: 'Template page to copy from' },
|
|
103
|
+
{ name: 'prototype', label: 'Prototype', type: 'select', required: true, options: [], dynamic: 'prototypes', tier: 'basic' },
|
|
104
|
+
{ name: 'path', label: 'Path', type: 'text', required: true, placeholder: 'settings/general', pattern: '^[a-z0-9][a-z0-9-/]*$', patternHint: 'Lowercase path with slashes (e.g. settings/general)', tier: 'basic' },
|
|
105
|
+
{ name: 'folder', label: 'Folder', type: 'text', placeholder: 'Optional subfolder within prototype', tier: 'advanced' },
|
|
106
|
+
{ name: 'template', label: 'Template', type: 'text', placeholder: 'Template page to copy from', tier: 'advanced' },
|
|
107
107
|
],
|
|
108
108
|
operations: ['create', 'delete'],
|
|
109
109
|
},
|