@grampro/kit 2.6.3 → 2.7.1
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/.gbs/skills/gbs-components/SKILL.md +5 -4
- package/.gbs/skills/gbs-components/references/install.md +17 -14
- package/CHANGELOG.md +188 -0
- package/README.md +26 -7
- package/index.cjs +59 -59
- package/package.json +3 -3
- package/schema/passport-overlay-v1.schema.json +67 -0
- package/source/components/accordion/passport.json +45 -8
- package/source/components/accordion/passport.manual.json +46 -0
- package/source/components/alert/passport.json +41 -8
- package/source/components/alert/passport.manual.json +42 -0
- package/source/components/avatar/passport.json +40 -7
- package/source/components/avatar/passport.manual.json +43 -0
- package/source/components/badge/passport.json +43 -7
- package/source/components/badge/passport.manual.json +46 -0
- package/source/components/breadcrumb/passport.json +36 -7
- package/source/components/breadcrumb/passport.manual.json +39 -0
- package/source/components/button/passport.json +1 -1
- package/source/components/button/passport.manual.json +1 -1
- package/source/components/card/passport.json +45 -8
- package/source/components/card/passport.manual.json +47 -0
- package/source/components/checkbox/core/agent.ts +33 -0
- package/source/components/checkbox/core/index.ts +2 -0
- package/source/components/checkbox/passport.json +83 -10
- package/source/components/checkbox/passport.manual.json +82 -0
- package/source/components/combobox/core/agent.ts +38 -0
- package/source/components/combobox/core/index.ts +2 -0
- package/source/components/combobox/passport.json +103 -11
- package/source/components/combobox/passport.manual.json +101 -0
- package/source/components/combobox/react/props.ts +14 -0
- package/source/components/combobox/react/useCombobox.ts +7 -1
- package/source/components/data-grid/export/xlsx.ts +9 -2
- package/source/components/data-grid/passport.json +2 -2
- package/source/components/data-grid/passport.manual.json +1 -1
- package/source/components/date-picker/core/agent.ts +42 -0
- package/source/components/date-picker/core/index.ts +2 -0
- package/source/components/date-picker/passport.json +102 -11
- package/source/components/date-picker/passport.manual.json +100 -0
- package/source/components/date-picker/react/DatePicker.tsx +6 -0
- package/source/components/date-picker/react/DateRangePicker.tsx +4 -0
- package/source/components/date-picker/react/props.ts +17 -0
- package/source/components/dialog/passport.json +54 -9
- package/source/components/dialog/passport.manual.json +54 -0
- package/source/components/file-uploader/passport.json +65 -10
- package/source/components/file-uploader/passport.manual.json +64 -0
- package/source/components/input/core/agent.ts +36 -0
- package/source/components/input/core/index.ts +2 -0
- package/source/components/input/passport.json +89 -12
- package/source/components/input/passport.manual.json +86 -0
- package/source/components/menu/passport.json +64 -9
- package/source/components/menu/passport.manual.json +64 -0
- package/source/components/modal/passport.json +52 -9
- package/source/components/modal/passport.manual.json +52 -0
- package/source/components/number-input/core/agent.ts +38 -0
- package/source/components/number-input/core/index.ts +2 -0
- package/source/components/number-input/passport.json +92 -11
- package/source/components/number-input/passport.manual.json +90 -0
- package/source/components/popover/passport.json +47 -8
- package/source/components/popover/passport.manual.json +48 -0
- package/source/components/progress/passport.json +37 -8
- package/source/components/progress/passport.manual.json +39 -0
- package/source/components/radio-group/core/agent.ts +34 -0
- package/source/components/radio-group/core/index.ts +2 -0
- package/source/components/radio-group/passport.json +77 -10
- package/source/components/radio-group/passport.manual.json +76 -0
- package/source/components/shared/core/agent/field-agent.ts +101 -0
- package/source/components/shared/core/agent/field-executors.ts +137 -0
- package/source/components/shared/core/agent/field.ts +649 -0
- package/source/components/shared/core/agent/index.ts +30 -0
- package/source/components/shared/core/agent/write.ts +58 -0
- package/source/components/shared/react/useFieldAgent.ts +88 -0
- package/source/components/skeleton/passport.json +37 -6
- package/source/components/skeleton/passport.manual.json +39 -0
- package/source/components/spinner/passport.json +34 -7
- package/source/components/spinner/passport.manual.json +37 -0
- package/source/components/switch/core/agent.ts +31 -0
- package/source/components/switch/core/index.ts +2 -0
- package/source/components/switch/passport.json +68 -10
- package/source/components/switch/passport.manual.json +67 -0
- package/source/components/tabs/passport.json +50 -9
- package/source/components/tabs/passport.manual.json +50 -0
- package/source/components/textarea/core/agent.ts +34 -0
- package/source/components/textarea/core/index.ts +2 -0
- package/source/components/textarea/passport.json +83 -10
- package/source/components/textarea/passport.manual.json +82 -0
- package/source/components/toaster/passport.json +41 -8
- package/source/components/toaster/passport.manual.json +42 -0
- package/source/components/tooltip/passport.json +39 -6
- package/source/components/tooltip/passport.manual.json +41 -0
- package/tools/mcp/README.md +23 -0
- package/tools/mcp/design.cjs +6 -1
- package/tools/mcp/figma.cjs +49 -9
- package/tools/mcp/install.cjs +6 -1
- package/tools/mcp/server.cjs +30 -2
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"source": {
|
|
13
|
-
"libraryVersion": "2.
|
|
13
|
+
"libraryVersion": "2.7.1",
|
|
14
14
|
"files": [
|
|
15
|
+
"core/agent.ts",
|
|
15
16
|
"core/calendar.ts",
|
|
16
17
|
"core/format.ts",
|
|
17
18
|
"core/index.ts",
|
|
@@ -29,8 +30,9 @@
|
|
|
29
30
|
"react/props.ts",
|
|
30
31
|
"react/useDatePicker.ts"
|
|
31
32
|
],
|
|
32
|
-
"sourceHash": "sha256:
|
|
33
|
+
"sourceHash": "sha256:abe15583c9bca1d5cce8aa9a3cbbcfcfd29ad44b7e63a3b66956089dc2d18f72"
|
|
33
34
|
},
|
|
35
|
+
"purpose": "DatePicker and DateRangePicker: a text field people can type dates into, plus a calendar, both honouring the locale's order and separators.",
|
|
34
36
|
"props": [
|
|
35
37
|
{
|
|
36
38
|
"name": "allowInput",
|
|
@@ -126,7 +128,8 @@
|
|
|
126
128
|
"required": false,
|
|
127
129
|
"origin": "derived",
|
|
128
130
|
"description": "How the chosen date is displayed. `Intl.DateTimeFormatOptions` for the\nusual cases, or a function for a shape Intl cannot express. Left out,\nthe locale's own date format is used - which is the right default far\nmore often than a hand-written one.",
|
|
129
|
-
"descriptionOrigin": "jsdoc"
|
|
131
|
+
"descriptionOrigin": "jsdoc",
|
|
132
|
+
"note": "How a typed string is parsed as well as displayed. Changing it can turn a valid entry into a different day."
|
|
130
133
|
},
|
|
131
134
|
{
|
|
132
135
|
"name": "id",
|
|
@@ -238,7 +241,8 @@
|
|
|
238
241
|
"required": false,
|
|
239
242
|
"origin": "derived",
|
|
240
243
|
"description": "Shortcuts shown beside the calendar (\"Last 7 days\").",
|
|
241
|
-
"descriptionOrigin": "jsdoc"
|
|
244
|
+
"descriptionOrigin": "jsdoc",
|
|
245
|
+
"note": "Labelled shortcuts such as last quarter. They write the same value the calendar does."
|
|
242
246
|
},
|
|
243
247
|
{
|
|
244
248
|
"name": "readOnly",
|
|
@@ -404,20 +408,107 @@
|
|
|
404
408
|
}
|
|
405
409
|
],
|
|
406
410
|
"accessibility": {
|
|
407
|
-
"supplied": [
|
|
408
|
-
|
|
411
|
+
"supplied": [
|
|
412
|
+
"the calendar is a grid with arrow keys between days, PageUp/PageDown between months, Home and End within a week",
|
|
413
|
+
"the selected and focused days are distinguished for assistive technology, not only by colour",
|
|
414
|
+
"the field accepts typing, so the calendar is never the only way in",
|
|
415
|
+
"Escape closes the calendar and returns focus to the field"
|
|
416
|
+
],
|
|
417
|
+
"required": [
|
|
418
|
+
"a `label`, or `aria-label` when the field is visually unlabelled",
|
|
419
|
+
"a `locale` matching the user's, since 03/04 is two different days in two places"
|
|
420
|
+
]
|
|
421
|
+
},
|
|
422
|
+
"composition": {
|
|
423
|
+
"notes": "The calendar renders in the top layer. `presets` are shortcuts into the same value, not a separate control."
|
|
424
|
+
},
|
|
425
|
+
"operations": {
|
|
426
|
+
"setValue": {
|
|
427
|
+
"summary": "Write a value into the field, as though a person had entered it.",
|
|
428
|
+
"effects": [
|
|
429
|
+
"replaces the field's current value",
|
|
430
|
+
"fires the host's change handler"
|
|
431
|
+
],
|
|
432
|
+
"reversible": true
|
|
433
|
+
},
|
|
434
|
+
"clear": {
|
|
435
|
+
"summary": "Empty the field.",
|
|
436
|
+
"effects": [
|
|
437
|
+
"discards the field's current value",
|
|
438
|
+
"fires the host's change handler"
|
|
439
|
+
],
|
|
440
|
+
"reversible": true
|
|
441
|
+
},
|
|
442
|
+
"focus": {
|
|
443
|
+
"summary": "Move keyboard focus to the field.",
|
|
444
|
+
"effects": [
|
|
445
|
+
"moves focus"
|
|
446
|
+
],
|
|
447
|
+
"reversible": false
|
|
448
|
+
},
|
|
449
|
+
"open": {
|
|
450
|
+
"summary": "Open the field's calendar or option list.",
|
|
451
|
+
"effects": [
|
|
452
|
+
"shows the overlay"
|
|
453
|
+
],
|
|
454
|
+
"reversible": true
|
|
455
|
+
},
|
|
456
|
+
"close": {
|
|
457
|
+
"summary": "Close the field's calendar or option list.",
|
|
458
|
+
"effects": [
|
|
459
|
+
"hides the overlay"
|
|
460
|
+
],
|
|
461
|
+
"reversible": true
|
|
462
|
+
}
|
|
463
|
+
},
|
|
464
|
+
"intentDomains": [
|
|
465
|
+
"TemporalInterpretation",
|
|
466
|
+
"ActionIntent"
|
|
467
|
+
],
|
|
468
|
+
"safeMutations": {
|
|
469
|
+
"allowed": [
|
|
470
|
+
"size",
|
|
471
|
+
"placeholder",
|
|
472
|
+
"description",
|
|
473
|
+
"numberOfMonths",
|
|
474
|
+
"showToday",
|
|
475
|
+
"showWeekNumbers",
|
|
476
|
+
"fixedWeeks",
|
|
477
|
+
"presets",
|
|
478
|
+
"clearable",
|
|
479
|
+
"closeOnSelect",
|
|
480
|
+
"allowInput"
|
|
481
|
+
],
|
|
482
|
+
"forbidden": [
|
|
483
|
+
"value",
|
|
484
|
+
"defaultValue",
|
|
485
|
+
"name",
|
|
486
|
+
"min",
|
|
487
|
+
"max",
|
|
488
|
+
"isDateDisabled",
|
|
489
|
+
"format",
|
|
490
|
+
"locale",
|
|
491
|
+
"weekStartsOn",
|
|
492
|
+
"required",
|
|
493
|
+
"disabled",
|
|
494
|
+
"readOnly",
|
|
495
|
+
"onChange",
|
|
496
|
+
"error"
|
|
497
|
+
],
|
|
498
|
+
"rationale": "Calendar chrome is presentation. `min`, `max` and `isDateDisabled` are the rules about which dates are legal, and `format` and `locale` decide how a typed string is read — changing either can reinterpret a date the user already entered."
|
|
409
499
|
},
|
|
410
|
-
"composition": {},
|
|
411
|
-
"operations": {},
|
|
412
|
-
"intentDomains": [],
|
|
413
|
-
"safeMutations": {},
|
|
414
500
|
"examples": [],
|
|
415
501
|
"coverage": {
|
|
416
502
|
"propsTotal": 28,
|
|
417
503
|
"propsDescribed": 22,
|
|
418
504
|
"describedPct": 79,
|
|
419
505
|
"authoredSections": [
|
|
420
|
-
"accessibility"
|
|
506
|
+
"accessibility",
|
|
507
|
+
"composition",
|
|
508
|
+
"intentDomains",
|
|
509
|
+
"operations",
|
|
510
|
+
"purpose",
|
|
511
|
+
"safeMutations"
|
|
421
512
|
]
|
|
422
513
|
}
|
|
423
514
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schema/passport-overlay-v1.schema.json",
|
|
3
|
+
"component": "DatePicker",
|
|
4
|
+
"purpose": "DatePicker and DateRangePicker: a text field people can type dates into, plus a calendar, both honouring the locale's order and separators.",
|
|
5
|
+
"intentDomains": [
|
|
6
|
+
"TemporalInterpretation",
|
|
7
|
+
"ActionIntent"
|
|
8
|
+
],
|
|
9
|
+
"$operationsNote": "Mirrors shared/core/agent/field.ts, which is what the runtime dispatches on. source/components/shared/core/agent/__tests__/field-passport.test.ts fails if the two drift. No `apiMethod`: a field is written through its ref — the element for most of these, a handle for Combobox and DatePicker — and that is a normal case, not a gap.",
|
|
10
|
+
"operations": {
|
|
11
|
+
"setValue": {
|
|
12
|
+
"summary": "Write a value into the field, as though a person had entered it.",
|
|
13
|
+
"effects": [
|
|
14
|
+
"replaces the field's current value",
|
|
15
|
+
"fires the host's change handler"
|
|
16
|
+
],
|
|
17
|
+
"reversible": true
|
|
18
|
+
},
|
|
19
|
+
"clear": {
|
|
20
|
+
"summary": "Empty the field.",
|
|
21
|
+
"effects": [
|
|
22
|
+
"discards the field's current value",
|
|
23
|
+
"fires the host's change handler"
|
|
24
|
+
],
|
|
25
|
+
"reversible": true
|
|
26
|
+
},
|
|
27
|
+
"focus": {
|
|
28
|
+
"summary": "Move keyboard focus to the field.",
|
|
29
|
+
"effects": [
|
|
30
|
+
"moves focus"
|
|
31
|
+
],
|
|
32
|
+
"reversible": false
|
|
33
|
+
},
|
|
34
|
+
"open": {
|
|
35
|
+
"summary": "Open the field's calendar or option list.",
|
|
36
|
+
"effects": [
|
|
37
|
+
"shows the overlay"
|
|
38
|
+
],
|
|
39
|
+
"reversible": true
|
|
40
|
+
},
|
|
41
|
+
"close": {
|
|
42
|
+
"summary": "Close the field's calendar or option list.",
|
|
43
|
+
"effects": [
|
|
44
|
+
"hides the overlay"
|
|
45
|
+
],
|
|
46
|
+
"reversible": true
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"accessibility": {
|
|
50
|
+
"supplied": [
|
|
51
|
+
"the calendar is a grid with arrow keys between days, PageUp/PageDown between months, Home and End within a week",
|
|
52
|
+
"the selected and focused days are distinguished for assistive technology, not only by colour",
|
|
53
|
+
"the field accepts typing, so the calendar is never the only way in",
|
|
54
|
+
"Escape closes the calendar and returns focus to the field"
|
|
55
|
+
],
|
|
56
|
+
"required": [
|
|
57
|
+
"a `label`, or `aria-label` when the field is visually unlabelled",
|
|
58
|
+
"a `locale` matching the user's, since 03/04 is two different days in two places"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"composition": {
|
|
62
|
+
"notes": "The calendar renders in the top layer. `presets` are shortcuts into the same value, not a separate control."
|
|
63
|
+
},
|
|
64
|
+
"safeMutations": {
|
|
65
|
+
"allowed": [
|
|
66
|
+
"size",
|
|
67
|
+
"placeholder",
|
|
68
|
+
"description",
|
|
69
|
+
"numberOfMonths",
|
|
70
|
+
"showToday",
|
|
71
|
+
"showWeekNumbers",
|
|
72
|
+
"fixedWeeks",
|
|
73
|
+
"presets",
|
|
74
|
+
"clearable",
|
|
75
|
+
"closeOnSelect",
|
|
76
|
+
"allowInput"
|
|
77
|
+
],
|
|
78
|
+
"forbidden": [
|
|
79
|
+
"value",
|
|
80
|
+
"defaultValue",
|
|
81
|
+
"name",
|
|
82
|
+
"min",
|
|
83
|
+
"max",
|
|
84
|
+
"isDateDisabled",
|
|
85
|
+
"format",
|
|
86
|
+
"locale",
|
|
87
|
+
"weekStartsOn",
|
|
88
|
+
"required",
|
|
89
|
+
"disabled",
|
|
90
|
+
"readOnly",
|
|
91
|
+
"onChange",
|
|
92
|
+
"error"
|
|
93
|
+
],
|
|
94
|
+
"rationale": "Calendar chrome is presentation. `min`, `max` and `isDateDisabled` are the rules about which dates are legal, and `format` and `locale` decide how a typed string is read — changing either can reinterpret a date the user already entered."
|
|
95
|
+
},
|
|
96
|
+
"propNotes": {
|
|
97
|
+
"format": "How a typed string is parsed as well as displayed. Changing it can turn a valid entry into a different day.",
|
|
98
|
+
"presets": "Labelled shortcuts such as last quarter. They write the same value the calendar does."
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -124,6 +124,12 @@ export function DatePicker(props: DatePickerProps) {
|
|
|
124
124
|
toggle: () => picker.setOpen(!picker.open),
|
|
125
125
|
focus: () => inputRef.current?.focus({ preventScroll: true }),
|
|
126
126
|
clear: picker.clear,
|
|
127
|
+
// `applyRange` is what the presets already use; a single picker is a
|
|
128
|
+
// range whose two ends are the same day.
|
|
129
|
+
setValue: (next) => {
|
|
130
|
+
const date = toDate(next as DateInput);
|
|
131
|
+
picker.applyRange({ start: date, end: date }, true);
|
|
132
|
+
},
|
|
127
133
|
getValue: () => picker.selection.start,
|
|
128
134
|
}),
|
|
129
135
|
[picker],
|
|
@@ -136,6 +136,10 @@ export function DateRangePicker(props: DateRangePickerProps) {
|
|
|
136
136
|
toggle: () => picker.setOpen(!picker.open),
|
|
137
137
|
focus: () => startRef.current?.focus({ preventScroll: true }),
|
|
138
138
|
clear: picker.clear,
|
|
139
|
+
setValue: (next) => {
|
|
140
|
+
const range = (next ?? { start: null, end: null }) as { start?: DateInput; end?: DateInput };
|
|
141
|
+
picker.applyRange({ start: toDate(range.start ?? null), end: toDate(range.end ?? null) }, true);
|
|
142
|
+
},
|
|
139
143
|
getValue: () => picker.selection,
|
|
140
144
|
}),
|
|
141
145
|
[picker],
|
|
@@ -18,6 +18,23 @@ export interface DatePickerHandle<TValue> {
|
|
|
18
18
|
toggle(): void;
|
|
19
19
|
focus(): void;
|
|
20
20
|
clear(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Set the value, as picking from the calendar would: the change handler
|
|
23
|
+
* fires and an uncontrolled picker updates itself.
|
|
24
|
+
*
|
|
25
|
+
* Takes what the component's own `value` prop takes — a `Date`, an ISO
|
|
26
|
+
* `yyyy-mm-dd` string, or `null` for the single picker; a `{ start, end }`
|
|
27
|
+
* range for the range picker. A range given the wrong way round is
|
|
28
|
+
* normalised rather than refused, which is what choosing those two days in
|
|
29
|
+
* that order on the calendar already does.
|
|
30
|
+
*
|
|
31
|
+
* It respects `disabled` and `readOnly` and does nothing when either is set.
|
|
32
|
+
* It does *not* check `min`, `max` or `isDateDisabled`: those describe what
|
|
33
|
+
* a person may pick, and a host setting a value programmatically is not a
|
|
34
|
+
* person. The agent runtime's policy layer enforces them for anything that
|
|
35
|
+
* arrives from a model.
|
|
36
|
+
*/
|
|
37
|
+
setValue(next: TValue | string | null): void;
|
|
21
38
|
getValue(): TValue;
|
|
22
39
|
}
|
|
23
40
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
]
|
|
10
10
|
},
|
|
11
11
|
"source": {
|
|
12
|
-
"libraryVersion": "2.
|
|
12
|
+
"libraryVersion": "2.7.1",
|
|
13
13
|
"files": [
|
|
14
14
|
"core/api.ts",
|
|
15
15
|
"core/dialog.ts",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"sourceHash": "sha256:f0b7d7683418b4981af453e5bf4dc08034a6d854dbca6e192283a555e77fdd0d"
|
|
27
27
|
},
|
|
28
|
+
"purpose": "Alert, confirm and prompt dialogs you call from an event handler and await, so there is no open state to hold. For short questions; a form belongs in Modal.",
|
|
28
29
|
"props": [
|
|
29
30
|
{
|
|
30
31
|
"name": "cancelLabel",
|
|
@@ -158,7 +159,8 @@
|
|
|
158
159
|
"default": "confirm",
|
|
159
160
|
"origin": "derived",
|
|
160
161
|
"description": "`alert` has one button, `confirm` two, `prompt` adds a text field. Default `confirm`.",
|
|
161
|
-
"descriptionOrigin": "jsdoc"
|
|
162
|
+
"descriptionOrigin": "jsdoc",
|
|
163
|
+
"note": "alert, confirm or prompt. It decides the shape of what the promise resolves to."
|
|
162
164
|
},
|
|
163
165
|
{
|
|
164
166
|
"name": "localeText",
|
|
@@ -263,7 +265,8 @@
|
|
|
263
265
|
"required": false,
|
|
264
266
|
"origin": "derived",
|
|
265
267
|
"description": "Return a message to block confirming.",
|
|
266
|
-
"descriptionOrigin": "jsdoc"
|
|
268
|
+
"descriptionOrigin": "jsdoc",
|
|
269
|
+
"note": "Prompt only. Returning a string keeps the dialog open and shows it as the error."
|
|
267
270
|
}
|
|
268
271
|
],
|
|
269
272
|
"inherits": [
|
|
@@ -339,20 +342,62 @@
|
|
|
339
342
|
}
|
|
340
343
|
],
|
|
341
344
|
"accessibility": {
|
|
342
|
-
"supplied": [
|
|
343
|
-
|
|
345
|
+
"supplied": [
|
|
346
|
+
"built on the same native <dialog> as Modal: top layer, inert page, focus trapped and returned",
|
|
347
|
+
"the confirm button takes initial focus, and Enter resolves it",
|
|
348
|
+
"Escape resolves as a cancel rather than leaving the promise hanging",
|
|
349
|
+
"the intent is conveyed in text, not only by the icon's colour"
|
|
350
|
+
],
|
|
351
|
+
"required": [
|
|
352
|
+
"a question that reads as a question, and button labels that name the action rather than saying Yes and No",
|
|
353
|
+
"`intent: \"danger\"` on anything destructive, so the styling matches the stakes"
|
|
354
|
+
]
|
|
355
|
+
},
|
|
356
|
+
"composition": {
|
|
357
|
+
"mustNotContain": [
|
|
358
|
+
"Dialog",
|
|
359
|
+
"Modal",
|
|
360
|
+
"dialog"
|
|
361
|
+
],
|
|
362
|
+
"notes": "Called as a function, not composed as a tree. Mount the host once; do not nest it inside another dialog."
|
|
344
363
|
},
|
|
345
|
-
"composition": {},
|
|
346
364
|
"operations": {},
|
|
347
|
-
"intentDomains": [
|
|
348
|
-
|
|
365
|
+
"intentDomains": [
|
|
366
|
+
"ActionIntent"
|
|
367
|
+
],
|
|
368
|
+
"safeMutations": {
|
|
369
|
+
"allowed": [
|
|
370
|
+
"size",
|
|
371
|
+
"icon",
|
|
372
|
+
"confirmLabel",
|
|
373
|
+
"cancelLabel"
|
|
374
|
+
],
|
|
375
|
+
"forbidden": [
|
|
376
|
+
"open",
|
|
377
|
+
"kind",
|
|
378
|
+
"intent",
|
|
379
|
+
"onConfirm",
|
|
380
|
+
"onClose",
|
|
381
|
+
"validate",
|
|
382
|
+
"store",
|
|
383
|
+
"defaultValue",
|
|
384
|
+
"required",
|
|
385
|
+
"inputType",
|
|
386
|
+
"dismissible"
|
|
387
|
+
],
|
|
388
|
+
"rationale": "Labels and the icon are presentation, provided the labels still name the same action. `kind` changes whether it returns a boolean or a string, `intent` is the warning, and `validate` decides what a prompt will accept."
|
|
389
|
+
},
|
|
349
390
|
"examples": [],
|
|
350
391
|
"coverage": {
|
|
351
392
|
"propsTotal": 21,
|
|
352
393
|
"propsDescribed": 16,
|
|
353
394
|
"describedPct": 76,
|
|
354
395
|
"authoredSections": [
|
|
355
|
-
"accessibility"
|
|
396
|
+
"accessibility",
|
|
397
|
+
"composition",
|
|
398
|
+
"intentDomains",
|
|
399
|
+
"purpose",
|
|
400
|
+
"safeMutations"
|
|
356
401
|
]
|
|
357
402
|
}
|
|
358
403
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schema/passport-overlay-v1.schema.json",
|
|
3
|
+
"component": "Dialog",
|
|
4
|
+
"purpose": "Alert, confirm and prompt dialogs you call from an event handler and await, so there is no open state to hold. For short questions; a form belongs in Modal.",
|
|
5
|
+
"intentDomains": [
|
|
6
|
+
"ActionIntent"
|
|
7
|
+
],
|
|
8
|
+
"accessibility": {
|
|
9
|
+
"supplied": [
|
|
10
|
+
"built on the same native <dialog> as Modal: top layer, inert page, focus trapped and returned",
|
|
11
|
+
"the confirm button takes initial focus, and Enter resolves it",
|
|
12
|
+
"Escape resolves as a cancel rather than leaving the promise hanging",
|
|
13
|
+
"the intent is conveyed in text, not only by the icon's colour"
|
|
14
|
+
],
|
|
15
|
+
"required": [
|
|
16
|
+
"a question that reads as a question, and button labels that name the action rather than saying Yes and No",
|
|
17
|
+
"`intent: \"danger\"` on anything destructive, so the styling matches the stakes"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"composition": {
|
|
21
|
+
"mustNotContain": [
|
|
22
|
+
"Dialog",
|
|
23
|
+
"Modal",
|
|
24
|
+
"dialog"
|
|
25
|
+
],
|
|
26
|
+
"notes": "Called as a function, not composed as a tree. Mount the host once; do not nest it inside another dialog."
|
|
27
|
+
},
|
|
28
|
+
"safeMutations": {
|
|
29
|
+
"allowed": [
|
|
30
|
+
"size",
|
|
31
|
+
"icon",
|
|
32
|
+
"confirmLabel",
|
|
33
|
+
"cancelLabel"
|
|
34
|
+
],
|
|
35
|
+
"forbidden": [
|
|
36
|
+
"open",
|
|
37
|
+
"kind",
|
|
38
|
+
"intent",
|
|
39
|
+
"onConfirm",
|
|
40
|
+
"onClose",
|
|
41
|
+
"validate",
|
|
42
|
+
"store",
|
|
43
|
+
"defaultValue",
|
|
44
|
+
"required",
|
|
45
|
+
"inputType",
|
|
46
|
+
"dismissible"
|
|
47
|
+
],
|
|
48
|
+
"rationale": "Labels and the icon are presentation, provided the labels still name the same action. `kind` changes whether it returns a boolean or a string, `intent` is the warning, and `validate` decides what a prompt will accept."
|
|
49
|
+
},
|
|
50
|
+
"propNotes": {
|
|
51
|
+
"kind": "alert, confirm or prompt. It decides the shape of what the promise resolves to.",
|
|
52
|
+
"validate": "Prompt only. Returning a string keeps the dialog open and shows it as the error."
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
]
|
|
14
14
|
},
|
|
15
15
|
"source": {
|
|
16
|
-
"libraryVersion": "2.
|
|
16
|
+
"libraryVersion": "2.7.1",
|
|
17
17
|
"files": [
|
|
18
18
|
"core/format.ts",
|
|
19
19
|
"core/index.ts",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
],
|
|
32
32
|
"sourceHash": "sha256:f77a12b14c2d24bc55a922a38f2f85dca85eafe89f63ffb28932e0dc4639d965"
|
|
33
33
|
},
|
|
34
|
+
"purpose": "Drop, browse or paste files, validate them against size and type, and upload in chunks that can pause, resume and retry.",
|
|
34
35
|
"props": [
|
|
35
36
|
{
|
|
36
37
|
"name": "accept",
|
|
@@ -58,7 +59,8 @@
|
|
|
58
59
|
"default": false,
|
|
59
60
|
"origin": "derived",
|
|
60
61
|
"description": "Upload as soon as files are added. Default false.",
|
|
61
|
-
"descriptionOrigin": "jsdoc"
|
|
62
|
+
"descriptionOrigin": "jsdoc",
|
|
63
|
+
"note": "Off means the host triggers the upload; on means dropping a file starts a network request immediately."
|
|
62
64
|
},
|
|
63
65
|
{
|
|
64
66
|
"name": "chunkSize",
|
|
@@ -116,7 +118,8 @@
|
|
|
116
118
|
"required": false,
|
|
117
119
|
"origin": "derived",
|
|
118
120
|
"description": "Where chunks are POSTed. Without `endpoint` or `transport`, files are only selected.",
|
|
119
|
-
"descriptionOrigin": "jsdoc"
|
|
121
|
+
"descriptionOrigin": "jsdoc",
|
|
122
|
+
"note": "Where files are sent. Never an agent's to set."
|
|
120
123
|
},
|
|
121
124
|
{
|
|
122
125
|
"name": "error",
|
|
@@ -409,7 +412,8 @@
|
|
|
409
412
|
"required": false,
|
|
410
413
|
"origin": "derived",
|
|
411
414
|
"description": "Replaces the built-in HTTP transport, e.g. for presigned URLs or an SDK.",
|
|
412
|
-
"descriptionOrigin": "jsdoc"
|
|
415
|
+
"descriptionOrigin": "jsdoc",
|
|
416
|
+
"note": "Replaces the whole upload mechanism. Treat as code, not configuration."
|
|
413
417
|
},
|
|
414
418
|
{
|
|
415
419
|
"name": "validate",
|
|
@@ -525,20 +529,71 @@
|
|
|
525
529
|
}
|
|
526
530
|
],
|
|
527
531
|
"accessibility": {
|
|
528
|
-
"supplied": [
|
|
529
|
-
|
|
532
|
+
"supplied": [
|
|
533
|
+
"the drop zone is a real button, so it is reachable and operable from the keyboard",
|
|
534
|
+
"upload progress is announced through a live region rather than only drawn",
|
|
535
|
+
"each file row names its own state and its own remove control",
|
|
536
|
+
"rejection reasons are text, not just a red border"
|
|
537
|
+
],
|
|
538
|
+
"required": [
|
|
539
|
+
"a `label` on the drop zone saying what should be uploaded",
|
|
540
|
+
"`accept` and `maxSize` matching what the server enforces, so a file is refused before it is sent rather than after"
|
|
541
|
+
]
|
|
542
|
+
},
|
|
543
|
+
"composition": {
|
|
544
|
+
"notes": "The uploader owns the file list it renders. `existingFiles` describes files already on the server and is a different thing from the queue."
|
|
530
545
|
},
|
|
531
|
-
"composition": {},
|
|
532
546
|
"operations": {},
|
|
533
|
-
"intentDomains": [
|
|
534
|
-
|
|
547
|
+
"intentDomains": [
|
|
548
|
+
"Extraction",
|
|
549
|
+
"Classification"
|
|
550
|
+
],
|
|
551
|
+
"safeMutations": {
|
|
552
|
+
"allowed": [
|
|
553
|
+
"size",
|
|
554
|
+
"description",
|
|
555
|
+
"preview",
|
|
556
|
+
"removable",
|
|
557
|
+
"label"
|
|
558
|
+
],
|
|
559
|
+
"forbidden": [
|
|
560
|
+
"endpoint",
|
|
561
|
+
"method",
|
|
562
|
+
"headers",
|
|
563
|
+
"params",
|
|
564
|
+
"transport",
|
|
565
|
+
"chunkSize",
|
|
566
|
+
"concurrency",
|
|
567
|
+
"retries",
|
|
568
|
+
"retryDelay",
|
|
569
|
+
"withCredentials",
|
|
570
|
+
"accept",
|
|
571
|
+
"maxSize",
|
|
572
|
+
"minSize",
|
|
573
|
+
"maxFiles",
|
|
574
|
+
"multiple",
|
|
575
|
+
"validate",
|
|
576
|
+
"autoUpload",
|
|
577
|
+
"name",
|
|
578
|
+
"required",
|
|
579
|
+
"disabled",
|
|
580
|
+
"onChange",
|
|
581
|
+
"onUploadComplete",
|
|
582
|
+
"parseResponse"
|
|
583
|
+
],
|
|
584
|
+
"rationale": "This is the one component where a wrong prop sends data somewhere. Everything describing the destination, the credentials sent with it, or what is allowed through is off-limits to an agent; only how the queue looks is safe."
|
|
585
|
+
},
|
|
535
586
|
"examples": [],
|
|
536
587
|
"coverage": {
|
|
537
588
|
"propsTotal": 39,
|
|
538
589
|
"propsDescribed": 36,
|
|
539
590
|
"describedPct": 92,
|
|
540
591
|
"authoredSections": [
|
|
541
|
-
"accessibility"
|
|
592
|
+
"accessibility",
|
|
593
|
+
"composition",
|
|
594
|
+
"intentDomains",
|
|
595
|
+
"purpose",
|
|
596
|
+
"safeMutations"
|
|
542
597
|
]
|
|
543
598
|
}
|
|
544
599
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schema/passport-overlay-v1.schema.json",
|
|
3
|
+
"component": "FileUploader",
|
|
4
|
+
"purpose": "Drop, browse or paste files, validate them against size and type, and upload in chunks that can pause, resume and retry.",
|
|
5
|
+
"intentDomains": [
|
|
6
|
+
"Extraction",
|
|
7
|
+
"Classification"
|
|
8
|
+
],
|
|
9
|
+
"accessibility": {
|
|
10
|
+
"supplied": [
|
|
11
|
+
"the drop zone is a real button, so it is reachable and operable from the keyboard",
|
|
12
|
+
"upload progress is announced through a live region rather than only drawn",
|
|
13
|
+
"each file row names its own state and its own remove control",
|
|
14
|
+
"rejection reasons are text, not just a red border"
|
|
15
|
+
],
|
|
16
|
+
"required": [
|
|
17
|
+
"a `label` on the drop zone saying what should be uploaded",
|
|
18
|
+
"`accept` and `maxSize` matching what the server enforces, so a file is refused before it is sent rather than after"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"composition": {
|
|
22
|
+
"notes": "The uploader owns the file list it renders. `existingFiles` describes files already on the server and is a different thing from the queue."
|
|
23
|
+
},
|
|
24
|
+
"safeMutations": {
|
|
25
|
+
"allowed": [
|
|
26
|
+
"size",
|
|
27
|
+
"description",
|
|
28
|
+
"preview",
|
|
29
|
+
"removable",
|
|
30
|
+
"label"
|
|
31
|
+
],
|
|
32
|
+
"forbidden": [
|
|
33
|
+
"endpoint",
|
|
34
|
+
"method",
|
|
35
|
+
"headers",
|
|
36
|
+
"params",
|
|
37
|
+
"transport",
|
|
38
|
+
"chunkSize",
|
|
39
|
+
"concurrency",
|
|
40
|
+
"retries",
|
|
41
|
+
"retryDelay",
|
|
42
|
+
"withCredentials",
|
|
43
|
+
"accept",
|
|
44
|
+
"maxSize",
|
|
45
|
+
"minSize",
|
|
46
|
+
"maxFiles",
|
|
47
|
+
"multiple",
|
|
48
|
+
"validate",
|
|
49
|
+
"autoUpload",
|
|
50
|
+
"name",
|
|
51
|
+
"required",
|
|
52
|
+
"disabled",
|
|
53
|
+
"onChange",
|
|
54
|
+
"onUploadComplete",
|
|
55
|
+
"parseResponse"
|
|
56
|
+
],
|
|
57
|
+
"rationale": "This is the one component where a wrong prop sends data somewhere. Everything describing the destination, the credentials sent with it, or what is allowed through is off-limits to an agent; only how the queue looks is safe."
|
|
58
|
+
},
|
|
59
|
+
"propNotes": {
|
|
60
|
+
"endpoint": "Where files are sent. Never an agent's to set.",
|
|
61
|
+
"transport": "Replaces the whole upload mechanism. Treat as code, not configuration.",
|
|
62
|
+
"autoUpload": "Off means the host triggers the upload; on means dropping a file starts a network request immediately."
|
|
63
|
+
}
|
|
64
|
+
}
|