@nanisoft/prism-ui 0.16.1 → 1.1.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/.tsbuildinfo +1 -1
- package/dist/blocks/activity-feed-01/activity-feed-01.d.ts +120 -190
- package/dist/blocks/activity-feed-01/activity-feed-01.d.ts.map +1 -1
- package/dist/blocks/activity-feed-01/activity-feed-01.js +107 -97
- package/dist/blocks/activity-feed-01/index.d.ts +1 -1
- package/dist/blocks/activity-feed-01/index.d.ts.map +1 -1
- package/dist/blocks/auth-form-01/auth-form.d.ts +86 -53
- package/dist/blocks/auth-form-01/auth-form.d.ts.map +1 -1
- package/dist/blocks/auth-form-01/auth-form.js +95 -31
- package/dist/blocks/auth-form-01/index.d.ts +1 -1
- package/dist/blocks/auth-form-01/index.d.ts.map +1 -1
- package/dist/blocks/calendar-01/calendar.d.ts +28 -0
- package/dist/blocks/calendar-01/calendar.d.ts.map +1 -1
- package/dist/blocks/calendar-01/calendar.js +15 -1
- package/dist/blocks/card-index-01/card-index.d.ts +225 -0
- package/dist/blocks/card-index-01/card-index.d.ts.map +1 -0
- package/dist/blocks/card-index-01/card-index.js +154 -0
- package/dist/blocks/card-index-01/index.d.ts +3 -0
- package/dist/blocks/card-index-01/index.d.ts.map +1 -0
- package/dist/blocks/card-index-01/index.js +1 -0
- package/dist/blocks/chart-card-01/chart-card-01.d.ts +23 -21
- package/dist/blocks/chart-card-01/chart-card-01.d.ts.map +1 -1
- package/dist/blocks/chart-card-01/chart-card-01.js +46 -1
- package/dist/blocks/chart-card-01/index.d.ts +1 -1
- package/dist/blocks/chart-card-01/index.d.ts.map +1 -1
- package/dist/blocks/chart-group-01/chart-group-01.d.ts +3 -3
- package/dist/blocks/chart-group-01/chart-group-01.d.ts.map +1 -1
- package/dist/blocks/contact-01/contact.d.ts +30 -82
- package/dist/blocks/contact-01/contact.d.ts.map +1 -1
- package/dist/blocks/contact-01/contact.js +59 -30
- package/dist/blocks/contact-01/index.d.ts +1 -1
- package/dist/blocks/contact-01/index.d.ts.map +1 -1
- package/dist/blocks/dashboard-01/dashboard-01.d.ts +26 -71
- package/dist/blocks/dashboard-01/dashboard-01.d.ts.map +1 -1
- package/dist/blocks/dashboard-01/dashboard-01.js +34 -23
- package/dist/blocks/dashboard-01/index.d.ts +1 -1
- package/dist/blocks/dashboard-01/index.d.ts.map +1 -1
- package/dist/blocks/data-table-01/data-table.d.ts +276 -59
- package/dist/blocks/data-table-01/data-table.d.ts.map +1 -1
- package/dist/blocks/data-table-01/data-table.js +217 -35
- package/dist/blocks/data-table-01/index.d.ts +1 -1
- package/dist/blocks/data-table-01/index.d.ts.map +1 -1
- package/dist/blocks/directory-01/directory-01.d.ts +23 -2
- package/dist/blocks/directory-01/directory-01.d.ts.map +1 -1
- package/dist/blocks/directory-01/directory-01.js +3 -3
- package/dist/blocks/empty-state-01/empty-state.d.ts +60 -21
- package/dist/blocks/empty-state-01/empty-state.d.ts.map +1 -1
- package/dist/blocks/empty-state-01/empty-state.js +52 -17
- package/dist/blocks/index-detail-01/index-detail.d.ts +85 -0
- package/dist/blocks/index-detail-01/index-detail.d.ts.map +1 -0
- package/dist/blocks/index-detail-01/index-detail.js +58 -0
- package/dist/blocks/index-detail-01/index.d.ts +3 -0
- package/dist/blocks/index-detail-01/index.d.ts.map +1 -0
- package/dist/blocks/index-detail-01/index.js +1 -0
- package/dist/blocks/index.d.ts +20 -8
- package/dist/blocks/index.d.ts.map +1 -1
- package/dist/blocks/index.js +7 -0
- package/dist/blocks/issue-detail-01/issue-detail.d.ts +18 -0
- package/dist/blocks/issue-detail-01/issue-detail.d.ts.map +1 -1
- package/dist/blocks/issue-detail-01/issue-detail.js +18 -0
- package/dist/blocks/nothing-chosen-01/index.d.ts +3 -0
- package/dist/blocks/nothing-chosen-01/index.d.ts.map +1 -0
- package/dist/blocks/nothing-chosen-01/index.js +1 -0
- package/dist/blocks/nothing-chosen-01/nothing-chosen.d.ts +119 -0
- package/dist/blocks/nothing-chosen-01/nothing-chosen.d.ts.map +1 -0
- package/dist/blocks/nothing-chosen-01/nothing-chosen.js +79 -0
- package/dist/blocks/project-dashboard-01/index.d.ts +1 -1
- package/dist/blocks/project-dashboard-01/index.d.ts.map +1 -1
- package/dist/blocks/project-dashboard-01/project-dashboard.d.ts +21 -27
- package/dist/blocks/project-dashboard-01/project-dashboard.d.ts.map +1 -1
- package/dist/blocks/project-dashboard-01/project-dashboard.js +45 -5
- package/dist/blocks/provisioning-01/index.d.ts +1 -1
- package/dist/blocks/provisioning-01/index.d.ts.map +1 -1
- package/dist/blocks/provisioning-01/provisioning.d.ts +9 -97
- package/dist/blocks/provisioning-01/provisioning.d.ts.map +1 -1
- package/dist/blocks/provisioning-01/provisioning.js +26 -13
- package/dist/blocks/record-detail-01/index.d.ts +3 -0
- package/dist/blocks/record-detail-01/index.d.ts.map +1 -0
- package/dist/blocks/record-detail-01/index.js +1 -0
- package/dist/blocks/record-detail-01/record-detail.d.ts +239 -0
- package/dist/blocks/record-detail-01/record-detail.d.ts.map +1 -0
- package/dist/blocks/record-detail-01/record-detail.js +150 -0
- package/dist/blocks/record-form-01/index.d.ts +3 -0
- package/dist/blocks/record-form-01/index.d.ts.map +1 -0
- package/dist/blocks/record-form-01/index.js +1 -0
- package/dist/blocks/record-form-01/record-form.d.ts +148 -0
- package/dist/blocks/record-form-01/record-form.d.ts.map +1 -0
- package/dist/blocks/record-form-01/record-form.js +107 -0
- package/dist/blocks/record-grid-01/index.d.ts +3 -0
- package/dist/blocks/record-grid-01/index.d.ts.map +1 -0
- package/dist/blocks/record-grid-01/index.js +1 -0
- package/dist/blocks/record-grid-01/record-grid.d.ts +145 -0
- package/dist/blocks/record-grid-01/record-grid.d.ts.map +1 -0
- package/dist/blocks/record-grid-01/record-grid.js +114 -0
- package/dist/blocks/record-wizard-01/index.d.ts +3 -0
- package/dist/blocks/record-wizard-01/index.d.ts.map +1 -0
- package/dist/blocks/record-wizard-01/index.js +1 -0
- package/dist/blocks/record-wizard-01/record-wizard.d.ts +152 -0
- package/dist/blocks/record-wizard-01/record-wizard.d.ts.map +1 -0
- package/dist/blocks/record-wizard-01/record-wizard.js +144 -0
- package/dist/blocks/settings-members-01/settings-members.d.ts +2 -1
- package/dist/blocks/settings-members-01/settings-members.d.ts.map +1 -1
- package/dist/blocks/settings-panel-01/index.d.ts +1 -1
- package/dist/blocks/settings-panel-01/index.d.ts.map +1 -1
- package/dist/blocks/settings-panel-01/settings-panel.d.ts +165 -67
- package/dist/blocks/settings-panel-01/settings-panel.d.ts.map +1 -1
- package/dist/blocks/settings-panel-01/settings-panel.js +92 -33
- package/dist/blocks/signup-01/index.d.ts +1 -1
- package/dist/blocks/signup-01/index.d.ts.map +1 -1
- package/dist/blocks/signup-01/signup-01.d.ts +10 -84
- package/dist/blocks/signup-01/signup-01.d.ts.map +1 -1
- package/dist/blocks/signup-01/signup-01.js +41 -23
- package/dist/blocks/stats-01/index.d.ts +5 -5
- package/dist/blocks/stats-01/index.d.ts.map +1 -1
- package/dist/blocks/stats-01/index.js +4 -4
- package/dist/blocks/stats-01/stats.d.ts +49 -14
- package/dist/blocks/stats-01/stats.d.ts.map +1 -1
- package/dist/blocks/stats-01/stats.js +65 -15
- package/dist/blocks/trend-01/index.d.ts +1 -1
- package/dist/blocks/trend-01/index.d.ts.map +1 -1
- package/dist/blocks/trend-01/trend.d.ts +26 -73
- package/dist/blocks/trend-01/trend.d.ts.map +1 -1
- package/dist/blocks/trend-01/trend.js +47 -30
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +93 -3
- package/dist/components/ui/metric.d.ts +4 -2
- package/dist/components/ui/metric.d.ts.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/lib/field-render.d.ts +107 -0
- package/dist/lib/field-render.d.ts.map +1 -0
- package/dist/lib/field-render.js +251 -0
- package/dist/lib/spec.d.ts +609 -0
- package/dist/lib/spec.d.ts.map +1 -0
- package/dist/lib/spec.js +1 -0
- package/dist/live/index.d.ts +2 -0
- package/dist/live/index.d.ts.map +1 -1
- package/dist/live/index.js +6 -0
- package/dist/live/message-thread-01/index.d.ts +3 -0
- package/dist/live/message-thread-01/index.d.ts.map +1 -0
- package/dist/live/message-thread-01/index.js +1 -0
- package/dist/live/message-thread-01/message-thread.d.ts +282 -0
- package/dist/live/message-thread-01/message-thread.d.ts.map +1 -0
- package/dist/live/message-thread-01/message-thread.js +221 -0
- package/dist/live/run-stream-01/run-stream.d.ts +2 -1
- package/dist/live/run-stream-01/run-stream.d.ts.map +1 -1
- package/dist/live/run-stream-01/run-stream.js +1 -7
- package/dist/live/status.d.ts +27 -0
- package/dist/live/status.d.ts.map +1 -0
- package/dist/live/status.js +15 -0
- package/dist/live/tool-call-row.d.ts +26 -0
- package/dist/live/tool-call-row.d.ts.map +1 -0
- package/dist/live/tool-call-row.js +60 -0
- package/dist/live/tool-ledger-01/tool-ledger.d.ts.map +1 -1
- package/dist/live/tool-ledger-01/tool-ledger.js +2 -42
- package/dist/pages/contact-page/index.d.ts +7 -7
- package/dist/pages/contact-page/index.d.ts.map +1 -1
- package/dist/pages/contact-page/index.js +17 -5
- package/dist/pages/document-page/document-page.d.ts +146 -0
- package/dist/pages/document-page/document-page.d.ts.map +1 -0
- package/dist/pages/document-page/document-page.js +80 -0
- package/dist/pages/document-page/index.d.ts +3 -0
- package/dist/pages/document-page/index.d.ts.map +1 -0
- package/dist/pages/document-page/index.js +1 -0
- package/dist/pages/index.d.ts +2 -0
- package/dist/pages/index.d.ts.map +1 -1
- package/dist/pages/index.js +6 -0
- package/dist/styles.css +35 -3
- package/package.json +7 -2
|
@@ -5,140 +5,151 @@ import { Section, SectionHeading, childLevel, } from '../../components/ui/sectio
|
|
|
5
5
|
import { Status } from '../../components/ui/status.js';
|
|
6
6
|
import { dayKey } from '../../lib/utils.js';
|
|
7
7
|
/**
|
|
8
|
-
* The refusals, as checks, so a row that would render a link nobody can name,
|
|
9
|
-
*
|
|
10
|
-
* control.
|
|
8
|
+
* The refusals, as checks, so a row that would render a link nobody can name, a
|
|
9
|
+
* tone with no words beside it, or a moment with no machine value, is a
|
|
10
|
+
* diagnostic in a console rather than a rendered control.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* `
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* **Two of these four pairs are already held by the type and the checks exist for
|
|
13
|
+
* the caller the type never saw.** `EventSpec` names both pairs as unions, but
|
|
14
|
+
* `tone` and `href` are each optional and their labels are optional beside them,
|
|
15
|
+
* so a typed caller can reach neither diagnostic and a JavaScript caller can. The
|
|
16
|
+
* moment rule is `RelativeTime`'s: a value the platform cannot read has nothing to
|
|
17
|
+
* put in a `dateTime`, and a `time` element with no value in it claims to be a
|
|
18
|
+
* moment and is not one. Every diagnostic names the field so a caller knows which
|
|
19
|
+
* of their own values to fix.
|
|
17
20
|
*/
|
|
18
21
|
function assertEvent(event) {
|
|
22
|
+
if ((event.tone === undefined) !== (event.toneLabel === undefined)) {
|
|
23
|
+
throw new Error(`ActivityFeed01: the event "${event.key}" declares one of tone and toneLabel without the other, so the row ` +
|
|
24
|
+
'would carry a colour with no words beside it, or words with no colour. A tone is a colour and the words ' +
|
|
25
|
+
'are the information, so on a record a reader may be checking a claim against, a colour alone is worse ' +
|
|
26
|
+
'than anywhere else. Pass the words the tone means, or omit the tone.');
|
|
27
|
+
}
|
|
19
28
|
if ((event.href === undefined) !== (event.hrefLabel === undefined)) {
|
|
20
|
-
throw new Error(`ActivityFeed01: the event "${event.
|
|
21
|
-
'
|
|
22
|
-
'
|
|
29
|
+
throw new Error(`ActivityFeed01: the event "${event.key}" declares one of href and hrefLabel without the other, so the row ` +
|
|
30
|
+
'would carry a link with no words on it, or a name with no link beside it. Pass the words that say what ' +
|
|
31
|
+
'following it does, or omit the href.');
|
|
23
32
|
}
|
|
24
33
|
if (!Number.isFinite(new Date(event.at).getTime())) {
|
|
25
|
-
throw new Error(`ActivityFeed01: the event "${event.
|
|
26
|
-
'
|
|
27
|
-
'
|
|
34
|
+
throw new Error(`ActivityFeed01: the event "${event.key}" passes an at the platform cannot read, so there is no value to ` +
|
|
35
|
+
'put in the time element and the row would claim to be a moment it cannot name. Pass epoch milliseconds, ' +
|
|
36
|
+
'or a string the platform parses.');
|
|
28
37
|
}
|
|
29
38
|
}
|
|
30
39
|
/**
|
|
31
40
|
* The class list every row shares, so the selectable and the plain row are the same
|
|
32
41
|
* row with a different element and cannot drift apart.
|
|
33
|
-
*
|
|
34
|
-
* One constant rather than two, and the alternative was a function returning a
|
|
35
|
-
* `ReactNode` per element shape. There are two shapes, so a constant is the cheaper
|
|
36
|
-
* way to be sure they are identical, and a third shape would be the moment to reach
|
|
37
|
-
* for the function.
|
|
38
42
|
*/
|
|
39
43
|
const ROW = 'flex w-full flex-col gap-1 border-b py-4 first:border-t last:border-b-0';
|
|
40
44
|
/**
|
|
41
|
-
* One record: the
|
|
45
|
+
* One record: the shared event's fields, drawn as one run of words, with the
|
|
46
|
+
* moment under it and the destination beside it.
|
|
42
47
|
*
|
|
43
48
|
* **The element is a decision about what a reader can do with the row, and the body
|
|
44
49
|
* is built once and placed in one of two so the two cannot disagree.** A row with an
|
|
45
50
|
* `onSelect` and no destination is a `button`; a row with neither is a `li`. The
|
|
46
51
|
* destination is never the whole row, and that is the second decision here: a link
|
|
47
|
-
* whose only words are the record's own
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
+
* whose only words are the record's own fields tells a reader nothing about what
|
|
53
|
+
* following it does, so the destination is a control with the caller's words and it
|
|
54
|
+
* sits under the record. Putting it inside the row's own control was the alternative
|
|
55
|
+
* and it is invalid markup, since an anchor inside a button is neither focusable in
|
|
56
|
+
* the way a reader expects nor announced as two things.
|
|
52
57
|
*
|
|
53
58
|
* **The body is phrasing content only, so a button can hold it.** A `button` may
|
|
54
59
|
* contain phrasing content and nothing else, so the record, the moment and the
|
|
55
60
|
* detail line are spans and the column arrangement is a flex `span` rather than the
|
|
56
|
-
* list item's own layout.
|
|
57
|
-
*
|
|
58
|
-
*
|
|
61
|
+
* list item's own layout.
|
|
62
|
+
*
|
|
63
|
+
* **The tone is drawn with its words and never without them.** The `tone` is a
|
|
64
|
+
* `Status` and the `toneLabel` is the text beside it, and the type pairs them; a
|
|
65
|
+
* caller who sets one without the other reaches `assertEvent` rather than a row
|
|
66
|
+
* with a coloured dot no screen reader can read.
|
|
59
67
|
*/
|
|
60
68
|
function EventRow({ event, onSelect, }) {
|
|
61
|
-
const record = (_jsxs(_Fragment, { children: [_jsxs("span", { "data-slot": "activity-feed-01-record", className: "flex flex-wrap items-baseline gap-x-2 text-sm", children: [event.tone === undefined ? null : (_jsx(Status, { "data-slot": "activity-feed-01-tone", tone: event.tone, label: event.
|
|
62
|
-
return (_jsxs("li", { "data-slot": "activity-feed-01-event", "data-event": event.
|
|
69
|
+
const record = (_jsxs(_Fragment, { children: [_jsxs("span", { "data-slot": "activity-feed-01-record", className: "flex flex-wrap items-baseline gap-x-2 text-sm", children: [event.tone === undefined ? null : (_jsx(Status, { "data-slot": "activity-feed-01-tone", tone: event.tone, label: event.toneLabel, size: "sm" })), _jsx("span", { className: "font-medium", children: event.actor }), _jsx("span", { className: "text-muted-foreground", children: event.action }), event.target === undefined ? null : (_jsx("span", { className: "font-medium", children: event.target }))] }), _jsx("span", { "data-slot": "activity-feed-01-at", className: "text-muted-foreground font-mono text-xs", children: _jsx("time", { dateTime: new Date(event.at).toISOString(), children: event.at }) }), event.detail === undefined ? null : (_jsx("span", { "data-slot": "activity-feed-01-detail", className: "text-muted-foreground text-sm", children: event.detail }))] }));
|
|
70
|
+
return (_jsxs("li", { "data-slot": "activity-feed-01-event", "data-event": event.key, className: ROW, children: [onSelect === undefined ? (record) : (_jsx("button", { type: "button", "data-slot": "activity-feed-01-select", onClick: () => onSelect(event.key), className: "w-full rounded-sm text-left focus-visible:ring-ring focus-visible:ring-[3px] focus-visible:outline-none", children: _jsx("span", { className: "flex flex-col gap-1", children: record }) })), event.href === undefined ? null : (_jsx(CtaLink, { "data-slot": "activity-feed-01-link", href: event.href, variant: "ghost", size: "sm", className: "self-start", children: event.hrefLabel }))] }));
|
|
63
71
|
}
|
|
64
72
|
/**
|
|
65
|
-
* A chronological list of what happened:
|
|
66
|
-
*
|
|
73
|
+
* A chronological list of what happened: the shared event specification, one record
|
|
74
|
+
* per entry, with an optional line under each.
|
|
67
75
|
*
|
|
68
|
-
* **The
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
76
|
+
* **The trail's entry declaration is `EventSpec`, and this Block mints no second
|
|
77
|
+
* event shape beside it.** `@nanisoft/prism-ui/spec` is the one declaration of a
|
|
78
|
+
* dated attributed occurrence in this package, so a shipment scan, a sign in and a
|
|
79
|
+
* permission change are one type and the vocabulary a consumer learns on this Block
|
|
80
|
+
* is the vocabulary everywhere an occurrence is drawn. An event carries a stable
|
|
81
|
+
* `key` that is never the words of a label, a moment printed exactly as the caller
|
|
82
|
+
* passed it with the machine value on the element, a required `actor` and `action`,
|
|
83
|
+
* an optional `target`, an optional `detail` node for the diff, the payload or the
|
|
84
|
+
* composed reading that four fields cannot hold, a `tone` whose label is required
|
|
85
|
+
* wherever the tone is set, and a destination whose words are required wherever it
|
|
86
|
+
* is set.
|
|
77
87
|
*
|
|
78
|
-
* **
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
88
|
+
* **It names no vocabulary of what happened, and there is no `kind` member.** An
|
|
89
|
+
* event's kind would name what somebody's product calls a thing that happened, and
|
|
90
|
+
* no enumeration of those is this package's to publish: a member on a Prism type
|
|
91
|
+
* would be promising that every consumer's world is this one. A caller needing one
|
|
92
|
+
* puts the word in `action` or composes a `Status` into `detail`. It carries no
|
|
93
|
+
* `progress`, no `severity`, no `duration` and no `role`, each refused for a reason
|
|
94
|
+
* rather than left out, and the specification module's own JSDoc is the whole of
|
|
95
|
+
* that argument.
|
|
96
|
+
*
|
|
97
|
+
* **The words are the caller's and the shape is Prism's.** A feed that composed the
|
|
98
|
+
* sentence would ship English into every consumer's product: "Ada published a
|
|
99
|
+
* release four hours ago" is a word order, an article, an inflected verb and a
|
|
100
|
+
* relative phrase, and a Block that assembled it would have assembled the English
|
|
101
|
+
* one and given the consumer no way to translate it, inflect it or reorder it. So
|
|
102
|
+
* this Block takes the parts as the caller's own nodes and draws them as one run of
|
|
103
|
+
* words, which is the most a design system can do without writing a sentence.
|
|
85
104
|
*
|
|
86
105
|
* **`at` is printed exactly as passed, and the Block formats no moment.** A Block
|
|
87
106
|
* that formatted one would have to pick a locale, a calendar and a granularity, and
|
|
88
|
-
* `relative-time` already holds that decision
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
107
|
+
* `relative-time` already holds that decision: it formats the absolute reading with
|
|
108
|
+
* the platform and hands the sentence back. So this Block prints the caller's value,
|
|
109
|
+
* puts the ISO form on the `time` element's `dateTime` so a crawler and a screen
|
|
110
|
+
* reader get a timestamp whatever the visible reading says, and a caller who wants a
|
|
111
|
+
* relative phrase composes the node beside the record in `detail`.
|
|
112
|
+
*
|
|
113
|
+
* **A vertical arrangement's only spatial claim is order, and this Block draws no
|
|
114
|
+
* length.** There is no scale, no range, no bar and no axis: a bar's length is a
|
|
115
|
+
* claim about a difference between two caller moments, and time as an axis belongs
|
|
116
|
+
* to a screen that composes `Gantt01` or `Calendar01` instead. Append only is a
|
|
117
|
+
* rendering fact and nothing more: what is rendered is the entries it was handed, in
|
|
118
|
+
* the order it was handed, with no control that edits one, removes one or reorders
|
|
119
|
+
* one, and that absence is what append only means. What the Block cannot render is
|
|
120
|
+
* that the record is immutable, tamper evident, signed, sealed or retained, because
|
|
121
|
+
* a Block has no authority over the store behind it: so there is no `immutable`
|
|
122
|
+
* prop, no seal glyph and no verification mark, and no retention window, archive,
|
|
123
|
+
* purge, legal hold, export, freshness or as-of clock. A consumer whose domain
|
|
124
|
+
* requires one enforces it in its own store and shows what the store says.
|
|
97
125
|
*
|
|
98
|
-
* **A row is a control only when there is something for it to do.** An event with
|
|
99
|
-
* handler renders as a `li`, which is a record a reader reads and not a thing
|
|
100
|
-
* act on. The destination is a separate control carrying the caller's own
|
|
101
|
-
* row can be selectable and linked at once, which is the arrangement a
|
|
102
|
-
* wants: a reader activates the row to open the thing, and the caller
|
|
103
|
-
* the way past.
|
|
104
|
-
* links is a page where the tab order runs down the whole feed before it reaches
|
|
105
|
-
* anything after it.
|
|
126
|
+
* **A row is a control only when there is something for it to do.** An event with
|
|
127
|
+
* no handler renders as a `li`, which is a record a reader reads and not a thing
|
|
128
|
+
* they act on. The destination is a separate control carrying the caller's own
|
|
129
|
+
* words, so a row can be selectable and linked at once, which is the arrangement a
|
|
130
|
+
* feed actually wants: a reader activates the row to open the thing, and the caller
|
|
131
|
+
* marks it read on the way past.
|
|
106
132
|
*
|
|
107
133
|
* **A day group is a list item holding a heading and a nested list, and not a merged
|
|
108
134
|
* row.** The structure is an `ol` of `li` and each `li` is a heading plus its own
|
|
109
135
|
* `ol`, because a reader moving by list item should hear how many days there are and
|
|
110
|
-
* then how many records are in the day they are reading. The
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* outline with it, and the day groups themselves are not headings at the same level,
|
|
115
|
-
* which is what makes a list of days a list rather than a flat run of headings.
|
|
116
|
-
*
|
|
117
|
-
* **The order is the caller's and the Block never sorts.** A feed is the surface
|
|
118
|
-
* where the exceptions live: a pinned event, a run that arrived late, a record the
|
|
119
|
-
* caller wants beside its own retry. A Block that sorted by moment would move the
|
|
120
|
-
* pin, and the caller would have to add a flag and this Block would have to know what
|
|
121
|
-
* the flag meant. The groups follow the order the days first appear, so a pinned
|
|
122
|
-
* event from yesterday puts yesterday first, which is the only arrangement that
|
|
123
|
-
* survives a pin.
|
|
136
|
+
* then how many records are in the day they are reading. The day heading is at
|
|
137
|
+
* `childLevel(headingLevel)`, so a feed embedded one level deeper carries its outline
|
|
138
|
+
* with it, and the groups follow the order the days first appear, so a pinned event
|
|
139
|
+
* from yesterday keeps yesterday where the caller put it.
|
|
124
140
|
*
|
|
125
|
-
* **The
|
|
126
|
-
* feed is
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* differently composes its own mark into `detail` and leaves `tone` unset. That is
|
|
134
|
-
* the cost of the split, stated rather than hidden.
|
|
141
|
+
* **The order is the caller's and the Block never sorts, groups or aggregates.** A
|
|
142
|
+
* feed is the surface where the exceptions live: a pinned event, a run that arrived
|
|
143
|
+
* late, a record the caller wants beside its own retry. The day grouping is content
|
|
144
|
+
* rather than structure, a caller-supplied key with a caller-supplied label, and the
|
|
145
|
+
* Block owns no count, no rate and no elapsed figure. It owns no navigation and no
|
|
146
|
+
* address, so the only route out of an entry is the caller's `href`, and it holds no
|
|
147
|
+
* selection state, because a trail is read and the index holds the set a batch action
|
|
148
|
+
* acts on.
|
|
135
149
|
*
|
|
136
150
|
* It is a client Component, and the reason is the handler rather than the state, as
|
|
137
151
|
* in `data-table-01`: `onSelect` is a function, a function is a piece of state, and
|
|
138
|
-
* state is a client module.
|
|
139
|
-
* `onSelect` is a static list that ships this file's client runtime for nothing, and
|
|
140
|
-
* the fix for a consumer who needs that surface to be static is a `ReactNode` slot of
|
|
141
|
-
* their own rather than a Block that attaches a handler to every row.
|
|
152
|
+
* state is a client module.
|
|
142
153
|
*/
|
|
143
154
|
export function ActivityFeed01({ eyebrow, title, description, events, onSelect, limit, empty, groupBy = 'none', dayLabel, headingLevel = 'h2', className, }) {
|
|
144
155
|
// A day's heading is one step below the section that introduces the feed, so a
|
|
@@ -153,8 +164,7 @@ export function ActivityFeed01({ eyebrow, title, description, events, onSelect,
|
|
|
153
164
|
The test is on `dayLabel` and not on `groupBy` alone, because destructuring the
|
|
154
165
|
props loses the discriminant the union carries: a caller who wrote
|
|
155
166
|
`groupBy="day"` without the label has a type error rather than a runtime one, and
|
|
156
|
-
this is the guard for a JavaScript caller who did not get that far.
|
|
157
|
-
branch is built once and the two arms below are the two renderings of it.
|
|
167
|
+
this is the guard for a JavaScript caller who did not get that far.
|
|
158
168
|
*/
|
|
159
169
|
const grouped = groupBy === 'day' && dayLabel !== undefined;
|
|
160
170
|
const heading = title === undefined ? null : (_jsx(SectionHeading, { as: headingLevel, align: "left", eyebrow: eyebrow, title: title, description: description, className: "mb-10" }));
|
|
@@ -178,8 +188,8 @@ export function ActivityFeed01({ eyebrow, title, description, events, onSelect,
|
|
|
178
188
|
else
|
|
179
189
|
found.push(event);
|
|
180
190
|
}
|
|
181
|
-
return (_jsxs(Section, { "data-slot": "activity-feed-01", className: className, children: [heading, _jsx("ol", { "data-slot": "activity-feed-01-days", className: "flex flex-col", children: [...days].map(([key, inDay]) => (_jsxs("li", { "data-slot": "activity-feed-01-day", "data-day": key, className: "flex flex-col gap-3 py-2 first:pt-0", children: [_jsx(GroupHeading, { "data-slot": "activity-feed-01-day-label", className: "text-muted-foreground text-sm font-medium", children: dayLabel(key) }), _jsx("ol", { "data-slot": "activity-feed-01-events", className: "flex flex-col", children: inDay.map((event) => (_jsx(EventRow, { event: event, onSelect: onSelect }, event.
|
|
191
|
+
return (_jsxs(Section, { "data-slot": "activity-feed-01", className: className, children: [heading, _jsx("ol", { "data-slot": "activity-feed-01-days", className: "flex flex-col", children: [...days].map(([key, inDay]) => (_jsxs("li", { "data-slot": "activity-feed-01-day", "data-day": key, className: "flex flex-col gap-3 py-2 first:pt-0", children: [_jsx(GroupHeading, { "data-slot": "activity-feed-01-day-label", className: "text-muted-foreground text-sm font-medium", children: dayLabel(key) }), _jsx("ol", { "data-slot": "activity-feed-01-events", className: "flex flex-col", children: inDay.map((event) => (_jsx(EventRow, { event: event, onSelect: onSelect }, event.key))) })] }, key))) })] }));
|
|
182
192
|
}
|
|
183
|
-
return (_jsxs(Section, { "data-slot": "activity-feed-01", className: className, children: [heading, _jsx("ol", { "data-slot": "activity-feed-01-events", className: "flex flex-col", children: shown.map((event) => (_jsx(EventRow, { event: event, onSelect: onSelect }, event.
|
|
193
|
+
return (_jsxs(Section, { "data-slot": "activity-feed-01", className: className, children: [heading, _jsx("ol", { "data-slot": "activity-feed-01-events", className: "flex flex-col", children: shown.map((event) => (_jsx(EventRow, { event: event, onSelect: onSelect }, event.key))) })] }));
|
|
184
194
|
}
|
|
185
195
|
export default ActivityFeed01;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/activity-feed-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAK5D,YAAY,EAAE,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/activity-feed-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAK5D,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -1,37 +1,29 @@
|
|
|
1
1
|
import type { FormEvent, ReactNode } from 'react';
|
|
2
2
|
import type { HeadingLevel } from '../../components/ui/section.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
*
|
|
18
|
-
* A form-level message with no field named is a statement about the submission:
|
|
19
|
-
* "those credentials do not match" is not a claim about the password field any
|
|
20
|
-
* more than it is a claim about the email field, and marking both of them
|
|
21
|
-
* `aria-invalid` tells a reader that two correctly filled fields are wrong. So the
|
|
22
|
-
* Block marks the field the caller names and no other, and a caller with nothing
|
|
23
|
-
* to name leaves every field unmarked, which is the honest state: the message
|
|
24
|
-
* still sits above the fields in an `Alert`, so it is still announced and still
|
|
25
|
-
* identified, and WCAG 3.3.1 is answered by the message rather than by a mark on a
|
|
26
|
-
* control that is not the problem.
|
|
27
|
-
*
|
|
28
|
-
* Omit it rather than setting it on every field. That was the arrangement this
|
|
29
|
-
* replaces and it is the arrangement a reader pays for, because the first thing a
|
|
30
|
-
* screen reader says about each field is "invalid" and a reader who is told two
|
|
31
|
-
* correct answers are wrong stops trusting the rest of the form.
|
|
32
|
-
*/
|
|
33
|
-
errorId?: string;
|
|
3
|
+
import type { FieldSpecGroup } from '../../lib/spec.js';
|
|
4
|
+
/**
|
|
5
|
+
* One thing wrong with the form, in the caller's own words.
|
|
6
|
+
*
|
|
7
|
+
* `field` is the `key` of the field the message belongs to, and the key rather
|
|
8
|
+
* than the label because it is what the caller's values and the form's own
|
|
9
|
+
* `FormData` are keyed by. The shape is the one the write form, the dialog and
|
|
10
|
+
* the wizard already publish, so this Block mints no fifth spelling of an issue.
|
|
11
|
+
*/
|
|
12
|
+
export type AuthForm01Issue = {
|
|
13
|
+
/** The `key` of the field this message belongs to. */
|
|
14
|
+
field: string;
|
|
15
|
+
/** The message, in the product's own words. */
|
|
16
|
+
message: string;
|
|
34
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* The remember-me row.
|
|
20
|
+
*
|
|
21
|
+
* It is not a field of the shared specification, and the reason is that it is a
|
|
22
|
+
* control this Block owns rather than one the caller declares: a sign-in screen
|
|
23
|
+
* has a remember row and the row is one control with a sentence and a starting
|
|
24
|
+
* state, so a caller who wants a second one draws it in the footer rather than
|
|
25
|
+
* widening the field vocabulary for a shape one screen has.
|
|
26
|
+
*/
|
|
35
27
|
export type AuthFormRemember = {
|
|
36
28
|
id: string;
|
|
37
29
|
label: string;
|
|
@@ -52,17 +44,31 @@ export type AuthForm01Props = {
|
|
|
52
44
|
*/
|
|
53
45
|
headingLevel?: HeadingLevel;
|
|
54
46
|
description?: string;
|
|
55
|
-
/**
|
|
56
|
-
|
|
47
|
+
/**
|
|
48
|
+
* The credential fields, grouped and ordered, as the shared field specification.
|
|
49
|
+
*
|
|
50
|
+
* A field carries a stable `key`, a required `label`, a required `kind` drawn
|
|
51
|
+
* from Prism's own input vocabulary, and optional help, hint, placeholder,
|
|
52
|
+
* autofill hint, disabled flag and starting value. A control this package does
|
|
53
|
+
* not ship is the `slot` arm, and the Block still draws the label, the help and
|
|
54
|
+
* the error around the caller's node. Asking for an email is an `Input` and
|
|
55
|
+
* asking for a password is the `PasswordField` this package ships, so the
|
|
56
|
+
* vocabulary is the same one a record write form takes.
|
|
57
|
+
*/
|
|
58
|
+
groups: readonly FieldSpecGroup[];
|
|
59
|
+
/** The issues to draw, keyed by field. Drawn under the control that owns them. */
|
|
60
|
+
issues?: readonly AuthForm01Issue[];
|
|
57
61
|
/**
|
|
58
62
|
* An error message shown above the fields.
|
|
59
63
|
*
|
|
60
64
|
* A sentence about the submission rather than about a control, which is why
|
|
61
|
-
* naming
|
|
62
|
-
* field
|
|
63
|
-
*
|
|
65
|
+
* naming a field it concerns is a separate decision: an entry in `issues` marks
|
|
66
|
+
* its own field, and a message here marks none. Telling a reader that two
|
|
67
|
+
* correctly filled fields are wrong is how they learn to stop trusting the rest
|
|
68
|
+
* of the form, so a submission sentence never marks more than the issue list
|
|
69
|
+
* already did.
|
|
64
70
|
*/
|
|
65
|
-
|
|
71
|
+
submitError?: ReactNode;
|
|
66
72
|
/** A remember-me row under the fields. */
|
|
67
73
|
remember?: AuthFormRemember;
|
|
68
74
|
/** The submit button label. */
|
|
@@ -71,31 +77,58 @@ export type AuthForm01Props = {
|
|
|
71
77
|
pendingLabel?: string;
|
|
72
78
|
/** Disables the submit control while a request is in flight. */
|
|
73
79
|
pending?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Called when the reader submits, with the form's own element.
|
|
82
|
+
*
|
|
83
|
+
* The Block is uncontrolled where a Prism control can be, so the caller reads
|
|
84
|
+
* the values out of the form element: the field keys are on the controls and a
|
|
85
|
+
* control the platform will not submit carries a hidden input under its key.
|
|
86
|
+
*/
|
|
74
87
|
onSubmit?: (event: FormEvent<HTMLFormElement>) => void;
|
|
75
88
|
/** A row under the submit button, e.g. a link to another screen. */
|
|
76
89
|
footer?: ReactNode;
|
|
77
90
|
};
|
|
78
91
|
/**
|
|
79
|
-
* A sign-in card
|
|
92
|
+
* A sign-in card, or a registration or a recovery, rendered from the shared field
|
|
93
|
+
* specification.
|
|
80
94
|
*
|
|
81
95
|
* The block renders the card, the labelled fields, the remember row and the
|
|
82
|
-
* submit control. It owns no credentials and no request: every field value
|
|
83
|
-
* the
|
|
84
|
-
* the consumer's validation decides when it
|
|
96
|
+
* submit control. It owns no credentials and no request: every field value comes
|
|
97
|
+
* from the controls the Block draws, the submit handler comes from the consumer,
|
|
98
|
+
* and a submission message is a prop so the consumer's validation decides when it
|
|
99
|
+
* appears. Every string is a prop.
|
|
100
|
+
*
|
|
101
|
+
* **It takes the shared field specification.** `groups` is an ordered list of
|
|
102
|
+
* `FieldSpecGroup`, each an optional heading and an ordered list of `FieldSpec`,
|
|
103
|
+
* and a field carries a stable `key`, a required `label` and a required `kind`
|
|
104
|
+
* drawn from Prism's own input vocabulary. A login, a registration and a password
|
|
105
|
+
* recovery are one Block and nothing forks here: asking for an email draws the
|
|
106
|
+
* `Input` this package ships and asking for a password draws its `PasswordField`,
|
|
107
|
+
* and a control this package does not ship is the `slot` arm rather than a second
|
|
108
|
+
* Block. The vocabulary a consumer learns on a record write form is the
|
|
109
|
+
* vocabulary here, and there is no second field declaration beside it.
|
|
110
|
+
*
|
|
111
|
+
* **An error is one message about the submission, and it marks no field.** A
|
|
112
|
+
* form-level sentence is usually not about a control at all: bad credentials, a
|
|
113
|
+
* locked account and a rate limit are all things no field is wrong about. The
|
|
114
|
+
* message is drawn in an `Alert`, which announces itself, and a message that
|
|
115
|
+
* belongs to one field is an entry in `issues`, drawn under that control and
|
|
116
|
+
* marking only it. A submission sentence never marks two fields, because a reader
|
|
117
|
+
* who is told two correctly filled fields are wrong stops trusting the rest of the
|
|
118
|
+
* form.
|
|
85
119
|
*
|
|
86
|
-
* **
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* announces itself, and the field the caller names in `errorId` carries
|
|
91
|
-
* `aria-invalid`, and every other field carries nothing. Marking them all was the
|
|
92
|
-
* arrangement before, and it told a reader that two fields they had filled in
|
|
93
|
-
* correctly were wrong.
|
|
120
|
+
* **A field's help is drawn under it and referred to by it.** The id is derived
|
|
121
|
+
* from the control's own `id`, which is stable for the life of the form, so the
|
|
122
|
+
* reference cannot collide and a screen reader hears what the field is for as it
|
|
123
|
+
* reaches it.
|
|
94
124
|
*
|
|
95
|
-
* **
|
|
96
|
-
*
|
|
97
|
-
*
|
|
125
|
+
* **It is uncontrolled where a Prism control can be.** The platform submits an
|
|
126
|
+
* `Input`, a `Textarea`, a `NativeSelect` and the controls that render their own
|
|
127
|
+
* input, so the caller reads the values out of the form element in `onSubmit`.
|
|
128
|
+
* The handful of Prism controls the platform will not submit on their own hold
|
|
129
|
+
* their value and carry a hidden input under the field's key, so the payload is
|
|
130
|
+
* complete either way.
|
|
98
131
|
*/
|
|
99
|
-
export declare function AuthForm01({ title, description,
|
|
132
|
+
export declare function AuthForm01({ title, description, groups, issues, submitError, remember, submitLabel, pendingLabel, pending, onSubmit, footer, headingLevel, }: AuthForm01Props): import("react").JSX.Element;
|
|
100
133
|
export default AuthForm01;
|
|
101
134
|
//# sourceMappingURL=auth-form.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-form.d.ts","sourceRoot":"","sources":["../../../src/blocks/auth-form-01/auth-form.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"auth-form.d.ts","sourceRoot":"","sources":["../../../src/blocks/auth-form-01/auth-form.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAgBjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAU/D,OAAO,KAAK,EAAa,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/D;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;;;;;OAUG;IACH,MAAM,EAAE,SAAS,cAAc,EAAE,CAAA;IACjC,kFAAkF;IAClF,MAAM,CAAC,EAAE,SAAS,eAAe,EAAE,CAAA;IACnC;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IAC3B,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAA;IACtD,oEAAoE;IACpE,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,CAAA;AAqCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,MAAM,EACN,MAAM,EACN,WAAW,EACX,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,OAAe,EACf,QAAQ,EACR,MAAM,EACN,YAAmB,GACpB,EAAE,eAAe,+BAkIjB;AAED,eAAe,UAAU,CAAA"}
|