@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
|
@@ -1,49 +1,113 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { CircleAlert } from 'lucide-react';
|
|
4
|
+
import { useId, useState } from 'react';
|
|
4
5
|
import { Alert, AlertDescription } from '../../components/ui/alert.js';
|
|
5
6
|
import { Button } from '../../components/ui/button.js';
|
|
6
7
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from '../../components/ui/card.js';
|
|
7
8
|
import { Checkbox } from '../../components/ui/checkbox.js';
|
|
8
|
-
import { Field, FieldDescription,
|
|
9
|
-
import {
|
|
9
|
+
import { Field, FieldDescription, FieldError, FieldGroup } from '../../components/ui/field.js';
|
|
10
|
+
import { Label } from '../../components/ui/label.js';
|
|
11
|
+
import { CHOICE_KINDS, fieldText, NEEDS_HIDDEN, renderControl, serialize, SELF_LABELLED, } from '../../lib/field-render.js';
|
|
10
12
|
/**
|
|
11
|
-
*
|
|
13
|
+
* The two ways a caller's field declaration can be a form that cannot be filled,
|
|
14
|
+
* checked before anything is drawn so the run fails once with the name of the
|
|
15
|
+
* field rather than once per field with a nameless control on the page.
|
|
16
|
+
*
|
|
17
|
+
* Both reach a developer in a console rather than a reader, which is what makes
|
|
18
|
+
* them refusals rather than copy. The type catches both for a TypeScript caller,
|
|
19
|
+
* and the check is here for the JavaScript caller and for the value that came out
|
|
20
|
+
* of a database with the type's guarantee already gone.
|
|
21
|
+
*/
|
|
22
|
+
function assertGroups(groups) {
|
|
23
|
+
for (const group of groups) {
|
|
24
|
+
for (const field of group.fields) {
|
|
25
|
+
if (field.label === undefined || (typeof field.label === 'string' && field.label.trim() === '')) {
|
|
26
|
+
throw new Error(`AuthForm01: the field "${field.key}" declares no label, so its control would be announced with no name ` +
|
|
27
|
+
'and two fields on this page would be announced identically. Every control this Block draws is named ' +
|
|
28
|
+
'by its label, so there is no fallback to fall back to.');
|
|
29
|
+
}
|
|
30
|
+
if (CHOICE_KINDS.has(field.kind) &&
|
|
31
|
+
(field.options?.length ?? 0) === 0) {
|
|
32
|
+
throw new Error(`AuthForm01: the field "${field.key}" is a choice and passes no options, so it would render a control ` +
|
|
33
|
+
'with nothing in it, which is a question no reader can answer and looks answered only because the ' +
|
|
34
|
+
'control is there and focusable. Pass the choices, or declare the field as a text field and check the ' +
|
|
35
|
+
'answer in your own handler.');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A sign-in card, or a registration or a recovery, rendered from the shared field
|
|
42
|
+
* specification.
|
|
12
43
|
*
|
|
13
44
|
* The block renders the card, the labelled fields, the remember row and the
|
|
14
|
-
* submit control. It owns no credentials and no request: every field value
|
|
15
|
-
* the
|
|
16
|
-
* the consumer's validation decides when it
|
|
45
|
+
* submit control. It owns no credentials and no request: every field value comes
|
|
46
|
+
* from the controls the Block draws, the submit handler comes from the consumer,
|
|
47
|
+
* and a submission message is a prop so the consumer's validation decides when it
|
|
48
|
+
* appears. Every string is a prop.
|
|
49
|
+
*
|
|
50
|
+
* **It takes the shared field specification.** `groups` is an ordered list of
|
|
51
|
+
* `FieldSpecGroup`, each an optional heading and an ordered list of `FieldSpec`,
|
|
52
|
+
* and a field carries a stable `key`, a required `label` and a required `kind`
|
|
53
|
+
* drawn from Prism's own input vocabulary. A login, a registration and a password
|
|
54
|
+
* recovery are one Block and nothing forks here: asking for an email draws the
|
|
55
|
+
* `Input` this package ships and asking for a password draws its `PasswordField`,
|
|
56
|
+
* and a control this package does not ship is the `slot` arm rather than a second
|
|
57
|
+
* Block. The vocabulary a consumer learns on a record write form is the
|
|
58
|
+
* vocabulary here, and there is no second field declaration beside it.
|
|
59
|
+
*
|
|
60
|
+
* **An error is one message about the submission, and it marks no field.** A
|
|
61
|
+
* form-level sentence is usually not about a control at all: bad credentials, a
|
|
62
|
+
* locked account and a rate limit are all things no field is wrong about. The
|
|
63
|
+
* message is drawn in an `Alert`, which announces itself, and a message that
|
|
64
|
+
* belongs to one field is an entry in `issues`, drawn under that control and
|
|
65
|
+
* marking only it. A submission sentence never marks two fields, because a reader
|
|
66
|
+
* who is told two correctly filled fields are wrong stops trusting the rest of the
|
|
67
|
+
* form.
|
|
17
68
|
*
|
|
18
|
-
* **
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* announces itself, and the field the caller names in `errorId` carries
|
|
23
|
-
* `aria-invalid`, and every other field carries nothing. Marking them all was the
|
|
24
|
-
* arrangement before, and it told a reader that two fields they had filled in
|
|
25
|
-
* correctly were wrong.
|
|
69
|
+
* **A field's help is drawn under it and referred to by it.** The id is derived
|
|
70
|
+
* from the control's own `id`, which is stable for the life of the form, so the
|
|
71
|
+
* reference cannot collide and a screen reader hears what the field is for as it
|
|
72
|
+
* reaches it.
|
|
26
73
|
*
|
|
27
|
-
* **
|
|
28
|
-
*
|
|
29
|
-
*
|
|
74
|
+
* **It is uncontrolled where a Prism control can be.** The platform submits an
|
|
75
|
+
* `Input`, a `Textarea`, a `NativeSelect` and the controls that render their own
|
|
76
|
+
* input, so the caller reads the values out of the form element in `onSubmit`.
|
|
77
|
+
* The handful of Prism controls the platform will not submit on their own hold
|
|
78
|
+
* their value and carry a hidden input under the field's key, so the payload is
|
|
79
|
+
* complete either way.
|
|
30
80
|
*/
|
|
31
|
-
export function AuthForm01({ title, description,
|
|
81
|
+
export function AuthForm01({ title, description, groups, issues, submitError, remember, submitLabel, pendingLabel, pending = false, onSubmit, footer, headingLevel = 'h2', }) {
|
|
82
|
+
const generated = useId();
|
|
83
|
+
const [values, setValues] = useState({});
|
|
84
|
+
const setValue = (key, value) => setValues((previous) => ({ ...previous, [key]: value }));
|
|
85
|
+
assertGroups(groups);
|
|
32
86
|
// This Block draws no section heading, so the card title is the one heading it
|
|
33
87
|
// renders and takes the level directly rather than a step below one.
|
|
34
88
|
const Title = headingLevel;
|
|
35
|
-
return (_jsx("form", { onSubmit: onSubmit, className: "w-full", children: _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: _jsx(Title, { children: title }) }), description ? _jsx(CardDescription, { children: description }) : null] }), _jsxs(CardContent, { className: "flex flex-col gap-4", children: [
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
89
|
+
return (_jsx("form", { onSubmit: onSubmit, className: "w-full", children: _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: _jsx(Title, { children: title }) }), description ? _jsx(CardDescription, { children: description }) : null] }), _jsxs(CardContent, { className: "flex flex-col gap-4", children: [submitError ? (_jsxs(Alert, { variant: "destructive", children: [_jsx(CircleAlert, {}), _jsx(AlertDescription, { children: submitError })] })) : null, groups.map((group, groupIndex) => (_jsxs(FieldGroup, { "data-slot": "auth-form-01-group", className: "flex flex-col gap-4", children: [group.label === undefined ? null : (_jsx("p", { "data-slot": "auth-form-01-group-label", className: "text-foreground text-sm font-medium", children: group.label })), group.description === undefined ? null : (_jsx("p", { "data-slot": "auth-form-01-group-description", className: "text-muted-foreground text-sm", children: group.description })), group.fields.map((field, fieldIndex) => {
|
|
90
|
+
const id = `${generated}-${groupIndex}-${fieldIndex}`;
|
|
91
|
+
const labelId = `${id}-label`;
|
|
92
|
+
const helpId = field.help === undefined ? undefined : `${id}-help`;
|
|
93
|
+
const fieldIssues = (issues ?? []).filter((issue) => issue.field === field.key);
|
|
94
|
+
const errorId = fieldIssues.length > 0 ? `${id}-error` : undefined;
|
|
95
|
+
const describedBy = helpId === undefined
|
|
96
|
+
? errorId
|
|
97
|
+
: errorId === undefined
|
|
98
|
+
? helpId
|
|
99
|
+
: `${helpId} ${errorId}`;
|
|
100
|
+
const kind = field.kind.toLowerCase();
|
|
101
|
+
const ctx = {
|
|
102
|
+
id,
|
|
103
|
+
labelId,
|
|
104
|
+
describedBy,
|
|
105
|
+
invalid: fieldIssues.length > 0,
|
|
106
|
+
text: fieldText(field),
|
|
107
|
+
values,
|
|
108
|
+
setValue,
|
|
109
|
+
};
|
|
110
|
+
return (_jsxs(Field, { "data-slot": "auth-form-01-field", "data-field": field.kind, children: [SELF_LABELLED.has(kind) ? null : (_jsx(Label, { id: labelId, htmlFor: id, required: field.required, disabled: field.disabled, children: field.label })), renderControl(field, ctx), NEEDS_HIDDEN.has(kind) ? (_jsx("input", { type: "hidden", name: field.key, value: serialize(values[field.key] ?? field.defaultValue) })) : null, field.help === undefined ? null : (_jsx(FieldDescription, { id: helpId, children: field.help })), fieldIssues.length === 0 ? null : (_jsx(FieldError, { id: errorId, children: fieldIssues.map((issue, issueIndex) => (_jsx("span", { "data-slot": "auth-form-01-issue", children: issue.message }, issueIndex))) }))] }, field.key));
|
|
111
|
+
})] }, group.id ?? groupIndex))), remember ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: remember.id, checked: remember.checked, defaultChecked: remember.defaultChecked, onCheckedChange: remember.onCheckedChange, disabled: remember.disabled }), _jsx(Label, { htmlFor: remember.id, children: remember.label })] })) : null] }), _jsxs(CardFooter, { className: "flex-col gap-3", children: [_jsx(Button, { type: "submit", className: "w-full", disabled: pending, children: pending ? (pendingLabel ?? submitLabel) : submitLabel }), footer] })] }) }));
|
|
48
112
|
}
|
|
49
113
|
export default AuthForm01;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/auth-form-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/auth-form-01/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAMjD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -47,6 +47,20 @@ export type CalendarItem = {
|
|
|
47
47
|
* what activating it does, which is the same defect `Download01` refuses.
|
|
48
48
|
*/
|
|
49
49
|
hrefLabel?: string;
|
|
50
|
+
/**
|
|
51
|
+
* The caller's own control for one item, drawn at the leading edge of its row.
|
|
52
|
+
*
|
|
53
|
+
* It exists for the one interaction a date view has that this Block does not
|
|
54
|
+
* own: a move. Rescheduling an item onto another day is a drag with a drop
|
|
55
|
+
* target, a new order, a write and a conflict, and all four are the consumer's,
|
|
56
|
+
* exactly as `Kanban01` leaves a board's drag to a control the caller writes into
|
|
57
|
+
* a card slot. So the Block places this node and the caller wires it to whatever
|
|
58
|
+
* owns their schedule: it draws no drag, reports no move and holds no order,
|
|
59
|
+
* because a drag is behaviour a Block does not hold and a move is a write to a
|
|
60
|
+
* store this package never sees. A handle a reader can hear carries its own
|
|
61
|
+
* words, and the Block adds none.
|
|
62
|
+
*/
|
|
63
|
+
handle?: ReactNode;
|
|
50
64
|
};
|
|
51
65
|
/**
|
|
52
66
|
* The props a Calendar01 takes.
|
|
@@ -230,6 +244,20 @@ export type CalendarBlock01Props = {
|
|
|
230
244
|
* rejected alternative was to print the tone's name as a fallback, and that is the
|
|
231
245
|
* defect `check-block-copy.mjs` exists to end.
|
|
232
246
|
*
|
|
247
|
+
* **A move is the caller's, and the Block exposes a per-item node rather than a
|
|
248
|
+
* move callback.** Rescheduling an item onto another day is the one interaction a
|
|
249
|
+
* date view has that this Block does not own: a drag with a drop target, a new
|
|
250
|
+
* order, a write and a conflict, and every one of the four is the consumer's,
|
|
251
|
+
* exactly as `Kanban01` leaves a board's drag to a control the caller writes into
|
|
252
|
+
* a card. So a `CalendarItem` carries a `handle`, a node the caller fills with
|
|
253
|
+
* their own control and wires to whatever owns their schedule, and the Block
|
|
254
|
+
* places it and nothing more. The rejected alternative is an `onMove` the Block
|
|
255
|
+
* wires to a drop target, and it is refused for the reason the kanban refuses a
|
|
256
|
+
* drag: it would make the Block own an order, a target and a write, and the
|
|
257
|
+
* conflict two reschedules create is a case this package has no answer for. The
|
|
258
|
+
* cost is named: a caller who wants a move writes the drag itself, and the Block
|
|
259
|
+
* gives it a place to attach rather than a model to adopt.
|
|
260
|
+
*
|
|
233
261
|
* **A day is a heading one level below the section, and the items are not
|
|
234
262
|
* headings at all.** A month is a set of days and the days are the things a reader
|
|
235
263
|
* navigates to, so they are headings at `childLevel(headingLevel)` and moving this
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../src/blocks/calendar-01/calendar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAU,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAGpE;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAA;IACV;;;;;;;;;;OAUG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mFAAmF;IACnF,KAAK,EAAE,SAAS,CAAA;IAChB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,kEAAkE;IAClE,YAAY,CAAC,EAAE,IAAI,CAAA;IACnB,oEAAoE;IACpE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAA;IACrC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACpB,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;OAQG;IACH,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;;OASG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACxC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAsCD
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../src/blocks/calendar-01/calendar.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAU,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAGpE;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAA;IACV;;;;;;;;;;OAUG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mFAAmF;IACnF,KAAK,EAAE,SAAS,CAAA;IAChB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,kEAAkE;IAClE,YAAY,CAAC,EAAE,IAAI,CAAA;IACnB,oEAAoE;IACpE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,IAAI,CAAA;IACrC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACpB,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;OAQG;IACH,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;;OASG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACxC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAsCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,WAAW,EACX,KAAK,EACL,YAAY,EACZ,aAAa,EACb,MAAM,EACN,YAAY,EACZ,aAAa,EACb,SAAS,EACT,KAAK,EACL,KAAK,EACL,QAAQ,EACR,SAAa,EACb,aAAa,EACb,KAAK,EACL,YAAmB,EACnB,SAAS,GACV,EAAE,oBAAoB,+BAgKtB;AA4CD,eAAe,UAAU,CAAA"}
|
|
@@ -97,6 +97,20 @@ function parseDay(value) {
|
|
|
97
97
|
* rejected alternative was to print the tone's name as a fallback, and that is the
|
|
98
98
|
* defect `check-block-copy.mjs` exists to end.
|
|
99
99
|
*
|
|
100
|
+
* **A move is the caller's, and the Block exposes a per-item node rather than a
|
|
101
|
+
* move callback.** Rescheduling an item onto another day is the one interaction a
|
|
102
|
+
* date view has that this Block does not own: a drag with a drop target, a new
|
|
103
|
+
* order, a write and a conflict, and every one of the four is the consumer's,
|
|
104
|
+
* exactly as `Kanban01` leaves a board's drag to a control the caller writes into
|
|
105
|
+
* a card. So a `CalendarItem` carries a `handle`, a node the caller fills with
|
|
106
|
+
* their own control and wires to whatever owns their schedule, and the Block
|
|
107
|
+
* places it and nothing more. The rejected alternative is an `onMove` the Block
|
|
108
|
+
* wires to a drop target, and it is refused for the reason the kanban refuses a
|
|
109
|
+
* drag: it would make the Block own an order, a target and a write, and the
|
|
110
|
+
* conflict two reschedules create is a case this package has no answer for. The
|
|
111
|
+
* cost is named: a caller who wants a move writes the drag itself, and the Block
|
|
112
|
+
* gives it a place to attach rather than a model to adopt.
|
|
113
|
+
*
|
|
100
114
|
* **A day is a heading one level below the section, and the items are not
|
|
101
115
|
* headings at all.** A month is a set of days and the days are the things a reader
|
|
102
116
|
* navigates to, so they are headings at `childLevel(headingLevel)` and moving this
|
|
@@ -165,7 +179,7 @@ export function Calendar01({ eyebrow, title, description, month, defaultMonth, o
|
|
|
165
179
|
return (_jsxs(Section, { "data-slot": "calendar-01", className: cn(className), children: [_jsx(SectionHeading, { as: headingLevel, align: "left", eyebrow: eyebrow, title: title, description: description, className: "mb-10" }), _jsxs("div", { "data-slot": "calendar-01-body", className: "flex flex-col gap-8 lg:flex-row lg:items-start", children: [_jsx(MiniCalendar, { month: shown, onMonthChange: changeMonth, locale: locale, weekStartsOn: weekStartsOn, previousLabel: previousLabel, nextLabel: nextLabel, label: label, className: "w-full shrink-0 lg:w-64" }), _jsx("div", { "data-slot": "calendar-01-days", className: "min-w-0 flex-1", children: days.length === 0 ? (empty === undefined ? null : (_jsx("p", { "data-slot": "calendar-01-empty", className: "text-muted-foreground text-pretty text-sm", children: empty }))) : (_jsx("ul", { className: "flex flex-col gap-6", children: days.map((day) => {
|
|
166
180
|
const visible = day.items.slice(0, maxPerDay);
|
|
167
181
|
const held = day.items.length - visible.length;
|
|
168
|
-
return (_jsxs("li", { "data-slot": "calendar-01-day", className: "flex flex-col gap-2", children: [_jsx(DayTitle, { className: "text-sm font-semibold", children: dayHeading.format(day.at) }), _jsx("ul", { className: "flex flex-col gap-1.5", children: visible.map((item) => (_jsxs("li", { "data-slot": "calendar-01-item", "data-state": item.state, className: "flex min-w-0 flex-wrap items-baseline gap-x-2 gap-y-1", children: [activatorOf(item, onSelect), item.state === undefined || item.stateLabel === undefined ? null : (_jsx(Status, { size: "sm", tone: item.state, label: item.stateLabel })), item.href === undefined || item.hrefLabel === undefined ? null : (_jsx(CtaLink, { href: item.href, variant: "ghost", size: "sm", children: item.hrefLabel }))] }, item.id))) }), held > 0 ? (_jsx("p", { "data-slot": "calendar-01-overflow", className: "text-muted-foreground text-xs", children: overflowLabel(held) })) : null] }, dayKey(day.at)));
|
|
182
|
+
return (_jsxs("li", { "data-slot": "calendar-01-day", className: "flex flex-col gap-2", children: [_jsx(DayTitle, { className: "text-sm font-semibold", children: dayHeading.format(day.at) }), _jsx("ul", { className: "flex flex-col gap-1.5", children: visible.map((item) => (_jsxs("li", { "data-slot": "calendar-01-item", "data-state": item.state, className: "flex min-w-0 flex-wrap items-baseline gap-x-2 gap-y-1", children: [item.handle === undefined ? null : (_jsx("span", { "data-slot": "calendar-01-handle", className: "shrink-0", children: item.handle })), activatorOf(item, onSelect), item.state === undefined || item.stateLabel === undefined ? null : (_jsx(Status, { size: "sm", tone: item.state, label: item.stateLabel })), item.href === undefined || item.hrefLabel === undefined ? null : (_jsx(CtaLink, { href: item.href, variant: "ghost", size: "sm", children: item.hrefLabel }))] }, item.id))) }), held > 0 ? (_jsx("p", { "data-slot": "calendar-01-overflow", className: "text-muted-foreground text-xs", children: overflowLabel(held) })) : null] }, dayKey(day.at)));
|
|
169
183
|
}) })) })] })] }));
|
|
170
184
|
}
|
|
171
185
|
/**
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type HeadingLevel } from '../../components/ui/section.js';
|
|
3
|
+
/** One row of data. Identity comes from `getRowId`, not from the shape. */
|
|
4
|
+
export type CardIndex01Row = Record<string, unknown>;
|
|
5
|
+
/**
|
|
6
|
+
* Every string the block renders. Required because the block ships no copy of
|
|
7
|
+
* its own: a selection summary, a per card name and an empty-state line are the
|
|
8
|
+
* consumer's to write.
|
|
9
|
+
*/
|
|
10
|
+
export type CardIndex01Labels = {
|
|
11
|
+
/** The header's selection control, naming the page it covers. */
|
|
12
|
+
selectAll: string;
|
|
13
|
+
/**
|
|
14
|
+
* The name of one card's selection control, in the caller's words.
|
|
15
|
+
*
|
|
16
|
+
* A function of the row rather than a string, because a checkbox announced as
|
|
17
|
+
* "Select" on all forty cards is a checkbox no reader can tell from the one
|
|
18
|
+
* below it. The name must name the record this checkbox ticks.
|
|
19
|
+
*/
|
|
20
|
+
selectCard: (row: CardIndex01Row) => string;
|
|
21
|
+
/** The name of the region a card's own controls sit in, when they are supplied. */
|
|
22
|
+
cardActions: string;
|
|
23
|
+
/**
|
|
24
|
+
* The selection summary and the announced number for the page scope.
|
|
25
|
+
*
|
|
26
|
+
* It should say the page, in the caller's words, because "24 selected" over a
|
|
27
|
+
* grid of twenty four cards is true and says nothing about whether there are
|
|
28
|
+
* more: the page is the one population this Block can count for itself.
|
|
29
|
+
*/
|
|
30
|
+
selectedCount: (count: number) => string;
|
|
31
|
+
/**
|
|
32
|
+
* The selection summary and the announced number for the filter scope.
|
|
33
|
+
*
|
|
34
|
+
* Used when the caller reports that the whole matching population is selected
|
|
35
|
+
* through `selectionScope`, and it takes the caller's own `count` rather than
|
|
36
|
+
* the number of cards on screen.
|
|
37
|
+
*/
|
|
38
|
+
selectedAllMatching: (count: number) => string;
|
|
39
|
+
/**
|
|
40
|
+
* The sentence spoken when the selection empties.
|
|
41
|
+
*
|
|
42
|
+
* Not a count of zero: "0 selected" is a number the reader already heard and
|
|
43
|
+
* says nothing about why the batch bar has gone. The emptying is its own
|
|
44
|
+
* sentence.
|
|
45
|
+
*/
|
|
46
|
+
clearedSelection: string;
|
|
47
|
+
/** The accessible name of the batch bar's dismiss control. */
|
|
48
|
+
dismissSelection: string;
|
|
49
|
+
previous: string;
|
|
50
|
+
next: string;
|
|
51
|
+
/** Accessible name for one page control. */
|
|
52
|
+
page: (page: number) => string;
|
|
53
|
+
/** Shown in the body when `rows` is empty and `emptyMessage` is not set. */
|
|
54
|
+
empty: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Which population the current selection covers, because the two are announced
|
|
58
|
+
* differently.
|
|
59
|
+
*
|
|
60
|
+
* A selection of everything on the page is one the block can count, so the page
|
|
61
|
+
* arm needs nothing beyond the selection set and the block announces
|
|
62
|
+
* `labels.selectedCount`. A selection of everything matching the current filter
|
|
63
|
+
* is a population the block never fetched, so the filter arm carries the number
|
|
64
|
+
* from the caller and the block announces `labels.selectedAllMatching` instead
|
|
65
|
+
* of printing the page as if it were the total.
|
|
66
|
+
*
|
|
67
|
+
* It is the same union and the same rule `DataTable01` uses, because ticket 166
|
|
68
|
+
* made one selection and announcement contract the record index family's, and
|
|
69
|
+
* this Block is the index's second arrangement rather than a second index.
|
|
70
|
+
*/
|
|
71
|
+
export type CardIndex01SelectionScope = {
|
|
72
|
+
scope: 'page';
|
|
73
|
+
} | {
|
|
74
|
+
scope: 'filter';
|
|
75
|
+
/**
|
|
76
|
+
* How many records match the current filter, in the caller's own count.
|
|
77
|
+
*
|
|
78
|
+
* Required, and never derived from the cards: the block holds one page and
|
|
79
|
+
* a count over that page says nothing about the population the reader
|
|
80
|
+
* asked for.
|
|
81
|
+
*/
|
|
82
|
+
count: number;
|
|
83
|
+
};
|
|
84
|
+
/** The props every arm of the block shares, selection aside. */
|
|
85
|
+
type CardIndex01SharedProps = {
|
|
86
|
+
title?: ReactNode;
|
|
87
|
+
description?: ReactNode;
|
|
88
|
+
/** Heading level for the block's own heading. @defaultValue 'h2' */
|
|
89
|
+
headingLevel?: HeadingLevel;
|
|
90
|
+
/** The cards for the current page, in the caller's own order. */
|
|
91
|
+
rows: readonly CardIndex01Row[];
|
|
92
|
+
/**
|
|
93
|
+
* Returns a stable identity for a row.
|
|
94
|
+
*
|
|
95
|
+
* Required rather than optional, because paging moves a row's index, so an
|
|
96
|
+
* index-keyed selection silently changes which records a batch action acts on.
|
|
97
|
+
*/
|
|
98
|
+
getRowId: (row: CardIndex01Row) => string;
|
|
99
|
+
/**
|
|
100
|
+
* The caller's own node for one card's body: the picture, the name and the
|
|
101
|
+
* price.
|
|
102
|
+
*
|
|
103
|
+
* A node per card rather than a declared field list, because a picture, a name
|
|
104
|
+
* and a price are three different value shapes and the read vocabulary this
|
|
105
|
+
* package publishes (`ColumnKind`) describes a row of a table rather than the
|
|
106
|
+
* anatomy of a card. The caller composes the card and the block owns the
|
|
107
|
+
* arrangement, the selection and the announcement.
|
|
108
|
+
*/
|
|
109
|
+
renderCard: (row: CardIndex01Row) => ReactNode;
|
|
110
|
+
/**
|
|
111
|
+
* The caller's own controls for one card, drawn in a trailing region.
|
|
112
|
+
*
|
|
113
|
+
* A node per card rather than a declared action list, because a block ships no
|
|
114
|
+
* behaviour and a control that looks like a command but carries none is a
|
|
115
|
+
* control a reader can focus and cannot act on.
|
|
116
|
+
*/
|
|
117
|
+
renderCardActions?: (row: CardIndex01Row) => ReactNode;
|
|
118
|
+
/**
|
|
119
|
+
* How many cards sit in one row at the widest width.
|
|
120
|
+
*
|
|
121
|
+
* Layout, and the only density knob the block owns. The grid always falls to
|
|
122
|
+
* one column at the narrowest width and to two at the small breakpoint, so a
|
|
123
|
+
* card is never squeezed below the width its own picture needs.
|
|
124
|
+
*
|
|
125
|
+
* @defaultValue 3
|
|
126
|
+
*/
|
|
127
|
+
columnsPerRow?: 2 | 3 | 4;
|
|
128
|
+
/** The current page, 1-based. */
|
|
129
|
+
page?: number;
|
|
130
|
+
defaultPage?: number;
|
|
131
|
+
/** How many pages exist. At least 1. */
|
|
132
|
+
pageCount: number;
|
|
133
|
+
onPageChange?: (page: number) => void;
|
|
134
|
+
/** Replaces the fallback empty line. */
|
|
135
|
+
emptyMessage?: ReactNode;
|
|
136
|
+
labels: CardIndex01Labels;
|
|
137
|
+
/** Layout only. Changing a Prism-owned visual property from here is prohibited. */
|
|
138
|
+
className?: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* The record index as pictures, which owns a set of row keys and reports every
|
|
142
|
+
* change.
|
|
143
|
+
*
|
|
144
|
+
* The two arms make the contract the type's: a selectable index must be handed
|
|
145
|
+
* the callback that reports a change and the node the batch bar holds, and a
|
|
146
|
+
* plain grid may be handed neither, because a tick with nowhere to report is a
|
|
147
|
+
* checkbox that changes nothing a caller can hear. It is the same union
|
|
148
|
+
* `DataTable01` declares, because ticket 166 made one selection contract the
|
|
149
|
+
* record index family's.
|
|
150
|
+
*/
|
|
151
|
+
export type CardIndex01Props = (CardIndex01SharedProps & {
|
|
152
|
+
selectable?: false;
|
|
153
|
+
selectedIds?: never;
|
|
154
|
+
defaultSelectedIds?: never;
|
|
155
|
+
onSelectedIdsChange?: never;
|
|
156
|
+
batchActions?: never;
|
|
157
|
+
selectionScope?: never;
|
|
158
|
+
}) | (CardIndex01SharedProps & {
|
|
159
|
+
selectable: true;
|
|
160
|
+
/** The selected keys, controlled. Omit it and the block holds the set. */
|
|
161
|
+
selectedIds?: readonly string[];
|
|
162
|
+
/** The selected keys the in-heart set starts from. */
|
|
163
|
+
defaultSelectedIds?: readonly string[];
|
|
164
|
+
/**
|
|
165
|
+
* Called with the whole set after every change, whether or not the caller
|
|
166
|
+
* is listening, so mirroring it costs one line and ignoring it costs zero.
|
|
167
|
+
*/
|
|
168
|
+
onSelectedIdsChange: (ids: string[]) => void;
|
|
169
|
+
/**
|
|
170
|
+
* The caller's own controls for the batch bar, mounted only while a
|
|
171
|
+
* selection exists. The block draws the frame, the count and the dismiss
|
|
172
|
+
* and places this node; it never draws a command of its own.
|
|
173
|
+
*/
|
|
174
|
+
batchActions: ReactNode;
|
|
175
|
+
/**
|
|
176
|
+
* Which population the selection covers. Absent means the page.
|
|
177
|
+
*
|
|
178
|
+
* The caller reports it when its own selection is the whole matching
|
|
179
|
+
* population rather than the rows on screen, and passes that population's
|
|
180
|
+
* count on the filter arm.
|
|
181
|
+
*/
|
|
182
|
+
selectionScope?: CardIndex01SelectionScope;
|
|
183
|
+
});
|
|
184
|
+
/**
|
|
185
|
+
* The record index as a grid of picture cards a reader compares and acts on.
|
|
186
|
+
*
|
|
187
|
+
* **It is the record index's second arrangement, and the job-identity test is
|
|
188
|
+
* what settles it.** A reader here is doing the index's job, deciding which
|
|
189
|
+
* record to act on, and the difference from `DataTable01` is the arrangement
|
|
190
|
+
* rather than the content: records are compared as pictures rather than
|
|
191
|
+
* across columns, so a screen that wants this has not found the index with one
|
|
192
|
+
* more prop, it has found the picture arrangement. `DESIGN.md` names it as an
|
|
193
|
+
* arrangement that forces a second Item, and this is that Item. A card carries
|
|
194
|
+
* the caller's own picture, name and price through `renderCard`, and per card
|
|
195
|
+
* actions through `renderCardActions`.
|
|
196
|
+
*
|
|
197
|
+
* **It shares the record index's selection and announcement contract.** The
|
|
198
|
+
* same `selectable` union, the same held set, the same three-state header
|
|
199
|
+
* control, the same polite `LiveRegion` carrying a count, the same batch bar
|
|
200
|
+
* that mounts only while the set is non-empty, and the same `selectionScope`
|
|
201
|
+
* that distinguishes a page-wide selection from a filter-wide one, all because
|
|
202
|
+
* ticket 166 made one contract the law for the index family. The count is
|
|
203
|
+
* announced once, politely, and never assertively; when the set empties the
|
|
204
|
+
* region speaks its own sentence rather than a count of zero; and the visible
|
|
205
|
+
* summary and the announced count are the same string.
|
|
206
|
+
*
|
|
207
|
+
* **It draws the page of cards it was handed, and it fetches nothing.** It sorts
|
|
208
|
+
* nothing, filters nothing and slices nothing, and every control in the footer
|
|
209
|
+
* is a report. It owns no action, batch or per card, so it owns no confirmation
|
|
210
|
+
* dialog, no toast and no undo; the batch bar is the Block's region and the
|
|
211
|
+
* caller's controls, and the dismiss is the Block's one control because its
|
|
212
|
+
* whole body is a call on the set the Block already holds.
|
|
213
|
+
*
|
|
214
|
+
* **The card is the caller's composition, and the arrangement is the Block's.**
|
|
215
|
+
* A picture, a name and a price are three different value shapes, and the read
|
|
216
|
+
* vocabulary this package publishes (`ColumnSpec` and `ColumnKind`) describes a
|
|
217
|
+
* value a reader reads in a table rather than the anatomy of a card. So the card
|
|
218
|
+
* body is one node per record and the picture, the name and the price are the
|
|
219
|
+
* caller's own composition, exactly as a per card action is. The Block owns the
|
|
220
|
+
* grid, the selection set, the count, the batch bar and the page boundary, which
|
|
221
|
+
* is the whole of what makes this an index rather than a list of pictures.
|
|
222
|
+
*/
|
|
223
|
+
export declare function CardIndex01(props: CardIndex01Props): import("react").JSX.Element;
|
|
224
|
+
export default CardIndex01;
|
|
225
|
+
//# sourceMappingURL=card-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-index.d.ts","sourceRoot":"","sources":["../../../src/blocks/card-index-01/card-index.tsx"],"names":[],"mappings":"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"}
|