@marktiderman/genesis-ui 2.12.2 → 2.14.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.
@@ -0,0 +1,92 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+ import { VariantProps } from 'class-variance-authority';
4
+
5
+ /**
6
+ * The surfaces a band can sit on. Each pairs a background with the
7
+ * foreground made for it, so text on a band always uses the colour designed
8
+ * against that background:
9
+ *
10
+ * - `base`: the page (`background` / `foreground`).
11
+ * - `muted`: a quiet alternate band (`muted` / `foreground`), for rhythm.
12
+ * - `accent`: the brand's primary (`primary` / `primary-foreground`), for a call to action.
13
+ * - `inverse`: the page's colours swapped (`foreground` / `background`), for a footer or a dark band.
14
+ */
15
+ declare const bandVariants: (props?: ({
16
+ surface?: "muted" | "base" | "accent" | "inverse" | null | undefined;
17
+ spacing?: "sm" | "lg" | "none" | "md" | null | undefined;
18
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
19
+ interface BandProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof bandVariants> {
20
+ /**
21
+ * The element to render. `section` (default) for a region of the page,
22
+ * `header` / `footer` for the site's banner and footer, `div` for a band
23
+ * that is not a region of its own.
24
+ */
25
+ as?: "section" | "header" | "footer" | "div" | "aside";
26
+ /** The inner column's width (Container's named widths). Default `lg`. */
27
+ width?: "sm" | "md" | "lg" | "full" | "prose";
28
+ /** Classes for the inner column, after the width and gutter. */
29
+ innerClassName?: string;
30
+ /** Stable test/automation selector (emitted as `data-testid`). */
31
+ testID?: string;
32
+ }
33
+ /**
34
+ * Band: a full-bleed, full-width marketing section. The background runs
35
+ * edge to edge; the content sits in a centered column with the page gutter.
36
+ * It is what a landing page is made of: a hero, a features band, a call to
37
+ * action, a footer.
38
+ *
39
+ * ```tsx
40
+ * <Band surface="accent" spacing="lg" aria-labelledby="cta-title">
41
+ * <Display as="h2" id="cta-title" size="lg">Start today</Display>
42
+ * </Band>
43
+ * ```
44
+ *
45
+ * Unlike `Section` (a titled region inside an app page), a band carries no
46
+ * heading of its own: a marketing page decides its heading levels per page
47
+ * (one `h1`, then `h2`s), so the caller places a `Display` and names the
48
+ * region with `aria-labelledby`. Server-safe: no state, no effects.
49
+ *
50
+ * @stability Beta
51
+ */
52
+ declare const Band: React.ForwardRefExoticComponent<BandProps & React.RefAttributes<HTMLElement>>;
53
+ /**
54
+ * The marketing (display) type scale: larger than the app scale and
55
+ * responsive, mobile first, so a headline fits a phone and fills a desktop.
56
+ * Size is independent of the heading level: a page has one `h1` whatever
57
+ * size it is drawn at.
58
+ */
59
+ declare const displayVariants: (props?: ({
60
+ size?: "sm" | "lg" | "md" | "xl" | null | undefined;
61
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
62
+ interface DisplayProps extends React.HTMLAttributes<HTMLHeadingElement>, VariantProps<typeof displayVariants> {
63
+ /** The heading level: document structure, not a size. Default `h2`. */
64
+ as?: "h1" | "h2" | "h3" | "h4" | "p";
65
+ /** Stable test/automation selector (emitted as `data-testid`). */
66
+ testID?: string;
67
+ }
68
+ /**
69
+ * Display: a heading in the marketing type scale (`displayVariants`).
70
+ *
71
+ * ```tsx
72
+ * <Display as="h1" size="xl">Train with people who know your name</Display>
73
+ * ```
74
+ *
75
+ * @stability Beta
76
+ */
77
+ declare const Display: React.ForwardRefExoticComponent<DisplayProps & React.RefAttributes<HTMLHeadingElement>>;
78
+ /**
79
+ * Lead copy under a display heading: one size up from body text, in the
80
+ * muted foreground on the page (`tone="muted"`), or the band's own
81
+ * foreground on an accent or inverse band (`tone="inherit"`).
82
+ */
83
+ declare const leadVariants: (props?: ({
84
+ tone?: "inherit" | "muted" | null | undefined;
85
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
86
+ interface BandLeadProps extends React.HTMLAttributes<HTMLParagraphElement>, VariantProps<typeof leadVariants> {
87
+ testID?: string;
88
+ }
89
+ /** @stability Beta */
90
+ declare const BandLead: React.ForwardRefExoticComponent<BandLeadProps & React.RefAttributes<HTMLParagraphElement>>;
91
+
92
+ export { Band, BandLead, type BandLeadProps, type BandProps, Display, type DisplayProps, bandVariants, displayVariants, leadVariants };
@@ -0,0 +1,5 @@
1
+ export { Band, BandLead, Display, bandVariants, displayVariants, leadVariants } from '../../chunk-ZHCP2RZP.js';
2
+ import '../../chunk-NZ5WBA4R.js';
3
+ import '../../chunk-424PT5DM.js';
4
+ //# sourceMappingURL=band.js.map
5
+ //# sourceMappingURL=band.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"band.js"}
@@ -7,6 +7,7 @@ export { D as DashboardPage, a as DashboardPageProps, G as Grid, b as GridProps,
7
7
  export { SettingsPage, SettingsPageProps, SettingsPageSection } from './settings-page.js';
8
8
  export { C as Container, a as ContainerProps, G as GAP_CLASSES, S as Section, b as SectionProps, c as SpaceToken, d as Stack, e as StackProps, f as containerVariants, s as sectionHeadingVariants, g as spaceScale, h as stackVariants } from '../../spacing-BS6qECD4.js';
9
9
  export { S as Split, a as SplitBreakpoint, b as SplitProps, c as SplitRatio, s as splitVariants } from '../../split-Dk9f4Mi0.js';
10
+ export { Band, BandLead, BandLeadProps, BandProps, Display, DisplayProps, bandVariants, displayVariants, leadVariants } from './band.js';
10
11
  export { NavigationNode, ResolvedNavigation, resolveNavigation } from '@marktiderman/genesis-core/navigation';
11
12
  import 'react';
12
13
  import 'lucide-react';
@@ -1,13 +1,15 @@
1
- export { AppShell, AppShellPageHeader, AppShellSubNavEnd, PageHeader, SubNavTabs, useAppShellSubNav } from '../../chunk-MLZEKXV2.js';
1
+ export { AppShell, AppShellPageHeader, AppShellSubNavEnd, PageHeader, SubNavTabs, useAppShellSubNav } from '../../chunk-5OFA2CQR.js';
2
2
  import '../../chunk-46TZGMFW.js';
3
- export { Container, Stack, containerVariants, stackVariants } from '../../chunk-4CQHPWJD.js';
3
+ export { Stack, stackVariants } from '../../chunk-ORCI5SVM.js';
4
4
  import '../../chunk-B2GIBUQD.js';
5
5
  import '../../chunk-NPNADZHM.js';
6
+ import '../../chunk-G5YKBPBF.js';
6
7
  import '../../chunk-FK42ZGGV.js';
8
+ import '../../chunk-22XB3Q6H.js';
7
9
  import '../../chunk-QJ6P2DW6.js';
8
10
  import '../../chunk-27ELYTGE.js';
9
- import '../../chunk-G5YKBPBF.js';
10
- import '../../chunk-22XB3Q6H.js';
11
+ import '../../chunk-F47U5KNW.js';
12
+ export { Band, BandLead, Container, Display, bandVariants, containerVariants, displayVariants, leadVariants } from '../../chunk-ZHCP2RZP.js';
11
13
  export { DashboardPage, Grid, gridVariants } from '../../chunk-ARJI2JUV.js';
12
14
  export { DetailPage } from '../../chunk-AFZ76Q26.js';
13
15
  export { FormPage } from '../../chunk-MPI33I4K.js';
@@ -16,7 +18,6 @@ export { Section, SettingsPage, sectionHeadingVariants } from '../../chunk-P64MF
16
18
  export { Split, splitVariants } from '../../chunk-D2LIXA2Y.js';
17
19
  export { GAP_CLASSES, spaceScale } from '../../chunk-AVFZ4P4B.js';
18
20
  import '../../chunk-NWSCYLPT.js';
19
- import '../../chunk-F47U5KNW.js';
20
21
  import '../../chunk-NZ5WBA4R.js';
21
22
  export { resolveNavigation } from '../../chunk-J45FHL7D.js';
22
23
  import '../../chunk-424PT5DM.js';
@@ -8,14 +8,14 @@ import '../../chunk-LNFF2RBD.js';
8
8
  export { PageLoading, pageLoadingVariants } from '../../chunk-YRYQXU3G.js';
9
9
  import '../../chunk-OVU3Z2MT.js';
10
10
  import '../../chunk-I4NBE2KL.js';
11
+ export { FormDescription, FormError, FormField, FormLabel } from '../../chunk-R7QFP6EL.js';
11
12
  import '../../chunk-FK42ZGGV.js';
13
+ import '../../chunk-22XB3Q6H.js';
12
14
  import '../../chunk-QJ6P2DW6.js';
13
15
  import '../../chunk-27ELYTGE.js';
14
- import '../../chunk-22XB3Q6H.js';
16
+ import '../../chunk-F47U5KNW.js';
15
17
  export { EmptyState, NoFeaturesFound, NoFeedbackFound, NoSearchResults } from '../../chunk-65SPT7EA.js';
16
18
  import '../../chunk-NWSCYLPT.js';
17
- export { FormDescription, FormError, FormField, FormLabel } from '../../chunk-R7QFP6EL.js';
18
- import '../../chunk-F47U5KNW.js';
19
19
  import '../../chunk-NZ5WBA4R.js';
20
20
  import '../../chunk-424PT5DM.js';
21
21
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  export { ToggleRow } from '../../chunk-6M4NHHKG.js';
2
2
  import '../../chunk-A7AHVDG7.js';
3
- import '../../chunk-27ELYTGE.js';
4
3
  import '../../chunk-R7QFP6EL.js';
4
+ import '../../chunk-27ELYTGE.js';
5
5
  import '../../chunk-F47U5KNW.js';
6
6
  import '../../chunk-NZ5WBA4R.js';
7
7
  import '../../chunk-424PT5DM.js';
@@ -0,0 +1,234 @@
1
+ import { ChipTone, SaveState, Readiness, ReadinessLabels, PrefillChoice } from './rules.js';
2
+ export { ReadinessFinding, ReadinessOptions, SAVE_STATE_LABEL, dayLabel, embedSnippet, prefilledUrl, readinessChip, readinessOf } from './rules.js';
3
+ import * as React from 'react';
4
+ import { ReactNode } from 'react';
5
+
6
+ /** A small status chip in one of the resource workspace's tones (tinted, AA-safe Genesis badges). */
7
+ declare function Chip({ tone, icon, children, className, testID, }: {
8
+ tone: ChipTone;
9
+ icon?: ReactNode;
10
+ children: ReactNode;
11
+ className?: string | undefined;
12
+ testID?: string | undefined;
13
+ }): React.JSX.Element;
14
+
15
+ interface ResourceHeaderProps {
16
+ /** The title, shown once: as the heading and the breadcrumb's last part. */
17
+ title: string;
18
+ /** Shown when the title is empty. Default "Untitled". */
19
+ untitled?: string | undefined;
20
+ /**
21
+ * The breadcrumb's parent link, e.g. `<Link to="/courses">Courses</Link>`: one element, so
22
+ * the host's router renders it.
23
+ */
24
+ parent?: ReactNode;
25
+ /** The status chip, e.g. "Live · version 3" or "Draft" (forms-studio's formStatusChip makes a form's). */
26
+ status?: {
27
+ label: string;
28
+ tone: ChipTone;
29
+ } | undefined;
30
+ /** Where saving the draft stands; no chip when absent. */
31
+ saveState?: SaveState | undefined;
32
+ /** Undo and redo buttons, shown when given (for example the builder's history). */
33
+ onUndo?: (() => void) | undefined;
34
+ onRedo?: (() => void) | undefined;
35
+ canUndo?: boolean | undefined;
36
+ canRedo?: boolean | undefined;
37
+ /** A Preview button. */
38
+ onPreview?: (() => void) | undefined;
39
+ /** A Share button (open a share dialog). */
40
+ onShare?: (() => void) | undefined;
41
+ /** The primary button: "Publish", or "Publish changes" once it is live. */
42
+ publish?: {
43
+ onClick: () => void;
44
+ label?: string | undefined;
45
+ loading?: boolean | undefined;
46
+ disabled?: boolean | undefined;
47
+ } | undefined;
48
+ /** Anything else for the right-hand side, before Preview (a Reload button, a menu). */
49
+ actions?: ReactNode;
50
+ className?: string | undefined;
51
+ }
52
+ /**
53
+ * The header of a page that edits one publishable thing (a form, a course, a lesson, a
54
+ * worksheet): the breadcrumb ("Courses › name"), the title once, its status and save-state
55
+ * chips, and on the right undo and redo, Preview, Share and Publish. Every action is the
56
+ * host's; a button shows only when its handler is given.
57
+ */
58
+ declare function ResourceHeader({ title, untitled, parent, status, saveState, onUndo, onRedo, canUndo, canRedo, onPreview, onShare, publish, actions, className, }: ResourceHeaderProps): React.JSX.Element;
59
+
60
+ /**
61
+ * "Ready to publish", or how many problems to fix: for the trailing slot of a resource
62
+ * page's row of tabs (genesis-ui's `<AppShellSubNavEnd>`). With `onClick` it is a button (open the checks).
63
+ */
64
+ declare function ReadinessChip({ readiness, onClick, labels, className, }: {
65
+ readiness: Readiness;
66
+ /** The chip's words; the defaults are neutral ("Nothing to publish yet" when empty). */
67
+ labels?: ReadinessLabels | undefined;
68
+ onClick?: (() => void) | undefined;
69
+ className?: string | undefined;
70
+ }): React.JSX.Element;
71
+
72
+ type ResponsesView = "summary" | "each";
73
+ /**
74
+ * The Responses tab's toolbar: a Summary / Each response switch, the host's filters
75
+ * (forms-studio's ResponsesFilters, or its own) and, on the right, its export actions
76
+ * (open a Sheet, Download CSV). `labels` renames the switch, e.g. "Each submission".
77
+ */
78
+ declare function ResponsesToolbar({ view, onViewChange, filters, actions, labels, className, }: {
79
+ view: ResponsesView;
80
+ onViewChange: (view: ResponsesView) => void;
81
+ filters?: ReactNode;
82
+ actions?: ReactNode;
83
+ /** The switch's words. Defaults "Summary", "Each response" and "Show responses as". */
84
+ labels?: {
85
+ summary?: string | undefined;
86
+ each?: string | undefined;
87
+ group?: string | undefined;
88
+ } | undefined;
89
+ className?: string | undefined;
90
+ }): React.JSX.Element;
91
+
92
+ /** One headline number: a label, the number, and a short line under it. */
93
+ interface HeadlineNumber {
94
+ key: string;
95
+ label: string;
96
+ value: ReactNode;
97
+ detail?: ReactNode;
98
+ /** The detail's colour: good news, bad news, a warning, or plain. Default plain. */
99
+ tone?: "positive" | "negative" | "warning" | "muted" | undefined;
100
+ }
101
+ /** A row of headline numbers (KPI cards): two across on a phone, up to four on a wide screen. */
102
+ declare function HeadlineNumbers({ numbers, isLoading, className, }: {
103
+ numbers: readonly HeadlineNumber[];
104
+ isLoading?: boolean | undefined;
105
+ className?: string | undefined;
106
+ }): React.JSX.Element | null;
107
+
108
+ /**
109
+ * One card of a summary column: an icon and a title, a short line on the right ("24
110
+ * responses · average 4.1"), then whatever summarises it (bars, quotes, a split bar).
111
+ */
112
+ declare function SummaryCard({ icon, title, meta, children, className, testID, }: {
113
+ icon?: ReactNode;
114
+ title: string;
115
+ meta?: ReactNode;
116
+ children?: ReactNode;
117
+ className?: string | undefined;
118
+ testID?: string | undefined;
119
+ }): React.JSX.Element;
120
+
121
+ /** One item in the follow-up list (a response, a submission), as the host describes it. */
122
+ interface FollowUpEntry {
123
+ id: string;
124
+ /** Who answered: a name, or "Anonymous". */
125
+ name: string;
126
+ /** A tag beside the name, e.g. "Member" or "New lead". */
127
+ tag?: {
128
+ label: string;
129
+ tone?: ChipTone | undefined;
130
+ } | undefined;
131
+ /** One line under the name: "Today · 6:00 WOD · Leo". */
132
+ meta?: ReactNode;
133
+ /** What they wrote; null shows `noComment`. */
134
+ comment?: string | null | undefined;
135
+ /** The low score, on its scale. */
136
+ rating?: {
137
+ value: number;
138
+ max: number;
139
+ } | null | undefined;
140
+ }
141
+ /**
142
+ * Responses that need a follow-up (the host decides which; forms-studio's needsFollowUp is
143
+ * one rule), each with who answered, a tag, the day and context, their comment, its low
144
+ * score and the host's actions (Reply, Mark handled). Handled items are the host's to leave out.
145
+ */
146
+ declare function FollowUpList({ entries, actions, title, isLoading, empty, noComment, className, }: {
147
+ entries: readonly FollowUpEntry[];
148
+ /** Buttons for one entry. */
149
+ actions?: ((entry: FollowUpEntry) => ReactNode) | undefined;
150
+ title?: string | undefined;
151
+ isLoading?: boolean | undefined;
152
+ /** Said when the list is empty. */
153
+ empty?: ReactNode;
154
+ /** Said for an entry without a comment. Default "No comment". */
155
+ noComment?: string | undefined;
156
+ className?: string | undefined;
157
+ }): React.JSX.Element;
158
+
159
+ /**
160
+ * One group of settings as a card: an icon, a title and a sentence, then its rows
161
+ * (genesis-ui `SettingsRow` and `ToggleRow`: a label, a one-sentence description and the
162
+ * control), divided by lines. On a phone a row whose control isn't a switch puts the
163
+ * control under its label, so wide controls (a link, a list of people) still fit.
164
+ */
165
+ declare function SettingsSection({ id, icon, title, description, children, className, }: {
166
+ /** The jump link's target. */
167
+ id?: string | undefined;
168
+ icon?: ReactNode;
169
+ title: ReactNode;
170
+ description?: ReactNode;
171
+ children?: ReactNode;
172
+ className?: string | undefined;
173
+ }): React.JSX.Element;
174
+ /**
175
+ * One section of a ResourceSettingsPage. (Named apart from the layout tier's
176
+ * `SettingsPageSection`, which belongs to the whole-page `SettingsPage`.)
177
+ */
178
+ interface ResourceSettingsSection {
179
+ id: string;
180
+ title: string;
181
+ icon?: ReactNode;
182
+ description?: ReactNode;
183
+ /** The rows. Absent: a jump link only, to `#id` elsewhere on the page (or `onSelect`). */
184
+ content?: ReactNode;
185
+ /** For a link-only section whose target has no id: scroll to it yourself. */
186
+ onSelect?: (() => void) | undefined;
187
+ }
188
+ /**
189
+ * Every setting of one thing (a form, a course, a worksheet) on one page: jump links on the left ("On this page", the one in
190
+ * view marked), the sections as cards on the right. On a phone the links sit above the
191
+ * sections as a row that scrolls sideways.
192
+ *
193
+ * Not genesis-ui's `SettingsPage`: that one is a whole page with its own title, and plain
194
+ * sections; these settings sit under the resource's header, as cards with icons.
195
+ */
196
+ declare function ResourceSettingsPage({ sections, navLabel, className, }: {
197
+ sections: readonly ResourceSettingsSection[];
198
+ navLabel?: string | undefined;
199
+ className?: string | undefined;
200
+ }): React.JSX.Element;
201
+
202
+ /**
203
+ * Sharing one published page (a form, a course, a worksheet), as Google Forms' Send step:
204
+ * its link with Copy, a QR code (and a printable poster when the host has one), an
205
+ * `<iframe>` to embed it on a website, and a builder for prefilled links
206
+ * (`?location=…&staff=…`, or whatever the host offers).
207
+ * Generic: the host passes the link, how to draw a QR code, and the prefill choices.
208
+ */
209
+ declare function ShareDialog({ open, onOpenChange, noun, title, description, url, posterUrl, renderQr, name, prefill, prefillNote, defaultTab, }: {
210
+ open: boolean;
211
+ onOpenChange: (open: boolean) => void;
212
+ /** Default "Share your {noun}". */
213
+ title?: string | undefined;
214
+ /** Default "Anyone with the link can open it." */
215
+ description?: ReactNode;
216
+ /** The public link; null while it is still loading. */
217
+ url: string | null;
218
+ /** A printable poster for a link (the base link, or a prefilled one), when the host has one. */
219
+ posterUrl?: ((url: string, prefill: Record<string, string>) => string | null) | undefined;
220
+ /** Draws a QR code for a link. */
221
+ renderQr?: ((url: string) => ReactNode) | undefined;
222
+ /** Its name, for the embed's accessible title. */
223
+ name: string;
224
+ /** What it is, in the default title and buttons: "page" (default), "form", "course". */
225
+ noun?: string | undefined;
226
+ /** The search params a prefilled link may set, each with its choices. None hides the builder. */
227
+ prefill?: readonly PrefillChoice[] | undefined;
228
+ /** Said under the prefilled-link builder (what a prefilled link does). */
229
+ prefillNote?: ReactNode;
230
+ /** The tab it opens on (each time it opens). Default "link". */
231
+ defaultTab?: "link" | "qr" | "embed" | undefined;
232
+ }): React.JSX.Element;
233
+
234
+ export { Chip, ChipTone, type FollowUpEntry, FollowUpList, type HeadlineNumber, HeadlineNumbers, PrefillChoice, Readiness, ReadinessChip, ReadinessLabels, ResourceHeader, type ResourceHeaderProps, ResourceSettingsPage, type ResourceSettingsSection, ResponsesToolbar, type ResponsesView, SaveState, SettingsSection, ShareDialog, SummaryCard };
@@ -0,0 +1,21 @@
1
+ export { Chip, FollowUpList, HeadlineNumbers, ReadinessChip, ResourceHeader, ResourceSettingsPage, ResponsesToolbar, SettingsSection, ShareDialog, SummaryCard } from '../../chunk-D3U5SBLW.js';
2
+ import '../../chunk-VXFYETRK.js';
3
+ import '../../chunk-NUXW6NPP.js';
4
+ import '../../chunk-2MQKBZBJ.js';
5
+ export { SAVE_STATE_LABEL, dayLabel, embedSnippet, prefilledUrl, readinessChip, readinessOf } from '../../chunk-SURORBV7.js';
6
+ import '../../chunk-C46ITXE4.js';
7
+ import '../../chunk-XMK3T4TA.js';
8
+ import '../../chunk-YETMISCE.js';
9
+ import '../../chunk-SXSCHWZU.js';
10
+ import '../../chunk-QFM4Z2SS.js';
11
+ import '../../chunk-QSXVL5UB.js';
12
+ import '../../chunk-NPNADZHM.js';
13
+ import '../../chunk-FK42ZGGV.js';
14
+ import '../../chunk-F47U5KNW.js';
15
+ import '../../chunk-NWSCYLPT.js';
16
+ import '../../chunk-4RAZJ6LL.js';
17
+ import '../../chunk-7XMZVISM.js';
18
+ import '../../chunk-NZ5WBA4R.js';
19
+ import '../../chunk-424PT5DM.js';
20
+ //# sourceMappingURL=index.js.map
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,74 @@
1
+ /** Where the host's draft saving stands. */
2
+ type SaveState = "saved" | "saving" | "unsaved" | "failed" | "stopped" | "conflict";
3
+ declare const SAVE_STATE_LABEL: Record<SaveState, string>;
4
+ /** A chip's colour: the tinted, AA-safe Genesis badge tones. */
5
+ type ChipTone = "success" | "warning" | "danger" | "info" | "muted";
6
+ /** Whether something can be published, from an editor's checks. */
7
+ interface Readiness {
8
+ state: "ready" | "problems" | "warnings" | "empty" | "pending";
9
+ /** Problems or warnings to look at (0 when ready, empty or pending). */
10
+ count: number;
11
+ }
12
+ /** One of an editor's findings, as readinessOf reads it. */
13
+ interface ReadinessFinding {
14
+ level: "error" | "warning" | "info";
15
+ code?: string | undefined;
16
+ }
17
+ interface ReadinessOptions {
18
+ /** Errors are held back while something new is being written: "pending", not "problems". */
19
+ pending?: boolean | undefined;
20
+ /**
21
+ * The finding code that means "nothing to publish yet" (for example a form builder's
22
+ * `no-questions`): it makes the result "empty", not broken. None by default.
23
+ */
24
+ emptyCode?: string | undefined;
25
+ }
26
+ /**
27
+ * Readiness from an editor's findings (any list of `{ level, code? }`): errors block
28
+ * publishing, warnings ask for a look. One pass over the findings.
29
+ */
30
+ declare function readinessOf(findings: readonly ReadinessFinding[], options?: ReadinessOptions): Readiness;
31
+ /** The readiness chip's words, each optional; the defaults are resource-neutral. */
32
+ interface ReadinessLabels {
33
+ /** Default "Ready to publish". */
34
+ ready?: string | undefined;
35
+ /** When there is nothing yet. Default "Nothing to publish yet"; a form says "Add a question". */
36
+ empty?: string | undefined;
37
+ /** Default "In progress". */
38
+ pending?: string | undefined;
39
+ /** Default "1 problem to fix" / "3 problems to fix". */
40
+ problems?: ((count: number) => string) | undefined;
41
+ /** Default "2 to check". */
42
+ warnings?: ((count: number) => string) | undefined;
43
+ }
44
+ /** The readiness chip's label and tone. */
45
+ declare function readinessChip(readiness: Readiness, labels?: ReadinessLabels): {
46
+ label: string;
47
+ tone: ChipTone;
48
+ };
49
+
50
+ /** A day (YYYY-MM-DD) in words, given today on the same clock: "Today", "Yesterday", "Oct 21", "Oct 21, 2025". */
51
+ declare function dayLabel(day: string, today?: string): string;
52
+
53
+ /** One search param a prefilled link may set, and the values staff pick from. */
54
+ interface PrefillChoice {
55
+ key: string;
56
+ /** The picker's accessible name, e.g. "Location". */
57
+ label: string;
58
+ /** The picker's "leave it out" choice, e.g. "Any location". */
59
+ anyLabel: string;
60
+ options: readonly {
61
+ value: string;
62
+ label: string;
63
+ }[];
64
+ }
65
+ /**
66
+ * `url` with `values` set as search params (empty values left out), keeping what it has.
67
+ * An absolute link stays absolute; a relative one (`/f/a?x=1`) stays relative, so it never
68
+ * throws while a page is still working out its origin.
69
+ */
70
+ declare function prefilledUrl(url: string, values: Record<string, string | undefined>): string;
71
+ /** An `<iframe>` that shows the page on another website, full width. */
72
+ declare function embedSnippet(url: string, title: string): string;
73
+
74
+ export { type ChipTone, type PrefillChoice, type Readiness, type ReadinessFinding, type ReadinessLabels, type ReadinessOptions, SAVE_STATE_LABEL, type SaveState, dayLabel, embedSnippet, prefilledUrl, readinessChip, readinessOf };
@@ -0,0 +1,4 @@
1
+ export { SAVE_STATE_LABEL, dayLabel, embedSnippet, prefilledUrl, readinessChip, readinessOf } from '../../chunk-SURORBV7.js';
2
+ import '../../chunk-424PT5DM.js';
3
+ //# sourceMappingURL=rules.js.map
4
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"rules.js"}
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import { parseVideoUrl, sanitizeVideoEmbedAttrs, videoEmbedTitle, VIDEO_IFRAME_ATTRS, videoEmbedSrc, isRichTextDoc, isSafeUrl, sanitizeRichTextDoc, richTextClassName, richTextToHtml, RichText, normalizeLinkUrl, isRichTextEmpty, richTextToPlainText } from '../../chunk-ZDHWNQTR.js';
3
3
  import { ToolbarButton, Toolbar, ToolbarSeparator, ToolbarToggleGroup, ToolbarToggleItem } from '../../chunk-YYEGAFUE.js';
4
- import '../../chunk-C46ITXE4.js';
5
4
  import { Kbd } from '../../chunk-FFSDFQQN.js';
5
+ import '../../chunk-C46ITXE4.js';
6
6
  import { Input } from '../../chunk-QSXVL5UB.js';
7
7
  import { Tooltip } from '../../chunk-G5YKBPBF.js';
8
8
  import { Popover, PopoverTrigger, PopoverContent } from '../../chunk-22XB3Q6H.js';
9
- import { Button } from '../../chunk-NWSCYLPT.js';
10
9
  import { Label } from '../../chunk-F47U5KNW.js';
10
+ import { Button } from '../../chunk-NWSCYLPT.js';
11
11
  import { cn } from '../../chunk-NZ5WBA4R.js';
12
12
  import '../../chunk-424PT5DM.js';
13
13
  import * as React from 'react';
@@ -4,9 +4,9 @@ export { useResourceUrlState } from '../chunk-DIV4BYXX.js';
4
4
  export { useSavedViews } from '../chunk-GCQFVMPI.js';
5
5
  export { useViewPreference } from '../chunk-PKFDGGZV.js';
6
6
  export { useViewSettings } from '../chunk-OZ7ZAYCS.js';
7
- import '../chunk-4RAZJ6LL.js';
8
7
  export { CommandPalette, useCommandPaletteHotkey } from '../chunk-CNTWQSUT.js';
9
8
  import '../chunk-SEFK4NZV.js';
9
+ import '../chunk-4RAZJ6LL.js';
10
10
  import '../chunk-7XMZVISM.js';
11
11
  import '../chunk-NZ5WBA4R.js';
12
12
  export { useDataFilters } from '../chunk-PMCUHSZS.js';
package/dist/index.d.ts CHANGED
@@ -64,9 +64,12 @@ export { PasswordToggleField, PasswordToggleFieldIcon, PasswordToggleFieldIconPr
64
64
  export { C as Container, a as ContainerProps, G as GAP_CLASSES, S as Section, b as SectionProps, c as SpaceToken, d as Stack, e as StackProps, f as containerVariants, s as sectionHeadingVariants, g as spaceScale, h as stackVariants } from './spacing-BS6qECD4.js';
65
65
  export { D as DashboardPage, a as DashboardPageProps, G as Grid, b as GridProps, g as gridVariants } from './dashboard-page-C0TihRl5.js';
66
66
  export { S as Split, a as SplitBreakpoint, b as SplitProps, c as SplitRatio, s as splitVariants } from './split-Dk9f4Mi0.js';
67
+ export { Band, BandLead, BandLeadProps, BandProps, Display, DisplayProps, bandVariants, displayVariants, leadVariants } from './components/layout/band.js';
67
68
  export { DetailPage, DetailPageProps } from './components/layout/detail-page.js';
68
69
  export { FormPage, FormPageProps } from './components/layout/form-page.js';
69
70
  export { SettingsPage, SettingsPageProps, SettingsPageSection } from './components/layout/settings-page.js';
71
+ export { ChipTone, PrefillChoice, Readiness, ReadinessFinding, ReadinessLabels, ReadinessOptions, SAVE_STATE_LABEL, SaveState, dayLabel, embedSnippet, prefilledUrl, readinessChip, readinessOf } from './components/resource/rules.js';
72
+ export { Chip, FollowUpEntry, FollowUpList, HeadlineNumber, HeadlineNumbers, ReadinessChip, ResourceHeader, ResourceHeaderProps, ResourceSettingsPage, ResourceSettingsSection, ResponsesToolbar, ResponsesView, SettingsSection, ShareDialog, SummaryCard } from './components/resource/index.js';
70
73
  export { cn } from './utils.js';
71
74
  export { D as DefaultLink, G as GenesisLinkProps, L as LinkComponent, N as NavigateFn, S as SearchParamsAdapter, d as defaultNavigate, u as useBrowserSearchParams } from './navigation-vmFJ6r1m.js';
72
75
  export * from '@marktiderman/genesis-core/slots';