@marktiderman/genesis-forms-studio 0.3.0 → 0.5.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/index.d.ts CHANGED
@@ -1,207 +1,55 @@
1
- import { C as ChipTone, S as SaveState, R as Readiness, P as PrefillChoice, F as FiltersValue, Q as QuestionSummary, a as QuestionDropOff } from './rules-Bpy8zTON.js';
2
- export { A as AnswerColumn, b as AvailabilityInput, c as Cell, d as ChoiceSummary, D as DatePreset, e as FollowUp, f as FormAvailability, g as FormNavItem, h as FormTab, H as Headline, i as HeadlineNumber, j as HeadlineNumbers, N as NO_FILTERS, k as RESPONSE_STATUS_LABEL, l as ResponseFilter, m as ResponseStatus, n as SAVE_STATE_LABEL, o as SLUG_PATTERN, p as STATUS_FILTER_LABEL, q as ScaleSummary, r as StatusFilter, s as SummaryItem, T as TextSummary, t as answerCell, u as answerColumns, v as answersByKey, w as comparisonFilter, x as copyTitle, y as dayLabel, z as dropOffByQuestion, B as embedSnippet, E as filterResponses, G as followUpOf, I as formAvailability, J as formCounts, K as formNavItems, L as formStatusChip, M as freeSlug, O as hasLowRating, U as hasLowRatingExcept, V as headlineCards, W as headlineNumbers, X as highestRating, Y as isFiltered, Z as isFull, _ as lowRatingAtMost, $ as lowRatingLabel, a0 as lowScaleAtMost, a1 as lowThisWeek, a2 as lowestRating, a3 as matchesStatus, a4 as needsFollowUp, a5 as offersSubmitAnother, a6 as parseInstant, a7 as plainLabel, a8 as prefilledUrl, a9 as presetRange, aa as readinessChip, ab as readinessOf, ac as slugFromTitle, ad as summarizeResponses, ae as takesResponses, af as toCsv, ag as toResponseFilter, ah as validateSlug, ai as valuesByKey } from './rules-Bpy8zTON.js';
1
+ import { FiltersValue, QuestionSummary, QuestionDropOff } from './rules.js';
2
+ export { AnswerColumn, AvailabilityInput, Cell, ChipTone, ChoiceSummary, DatePreset, DropOffSummary, FORM_READINESS_LABELS, FORM_READINESS_OPTIONS, FollowUp, FormAvailability, FormNavItem, FormTab, Headline, NO_FILTERS, PrefillChoice, RESPONSE_STATUS_LABEL, Readiness, ResponseFilter, ResponseStatus, SAVE_STATE_LABEL, SLUG_PATTERN, STATUS_FILTER_LABEL, SaveState, ScaleSummary, StatusFilter, SummaryItem, TextSummary, answerCell, answerColumns, answersByKey, comparisonFilter, copyTitle, dayLabel, dropOffByQuestion, dropOffSummary, embedSnippet, filterResponses, followUpOf, formAvailability, formCounts, formNavItems, formStatusChip, freeSlug, hasLowRating, hasLowRatingExcept, headlineCards, headlineNumbers, highestRating, isFiltered, isFull, lowRatingAtMost, lowRatingLabel, lowScaleAtMost, lowThisWeek, lowestRating, matchesStatus, needsFollowUp, offersSubmitAnother, parseInstant, plainLabel, prefilledUrl, presetRange, readinessChip, readinessOf, slugFromTitle, summarizeResponses, takesResponses, toCsv, toResponseFilter, validateSlug, valuesByKey } from './rules.js';
3
3
  import * as react from 'react';
4
- import { ReactNode } from 'react';
4
+ import { ComponentProps, ReactNode } from 'react';
5
+ import { Chip as Chip$1, FollowUpEntry as FollowUpEntry$1, FollowUpList as FollowUpList$1, HeadlineNumber as HeadlineNumber$1, HeadlineNumbers as HeadlineNumbers$1, ReadinessChip as ReadinessChip$1, ResourceHeader as ResourceHeader$1, ResourceHeaderProps as ResourceHeaderProps$1, ResourceSettingsPage as ResourceSettingsPage$1, ResponsesToolbar as ResponsesToolbar$1, ResponsesView as ResponsesView$1, ResourceSettingsSection, SettingsSection as SettingsSection$1, ShareDialog as ShareDialog$1, SummaryCard as SummaryCard$1 } from '@marktiderman/genesis-ui/resource';
5
6
  import * as lucide_react from 'lucide-react';
6
7
  import { PhotoRef } from '@marktiderman/genesis-forms';
7
8
  export { carryAnswers } from '@marktiderman/genesis-forms';
8
9
  import '@marktiderman/genesis-ui/layout';
10
+ import '@marktiderman/genesis-ui/resource/rules';
9
11
 
10
- interface ResourceHeaderProps {
11
- /** The title, shown once: as the heading and the breadcrumb's last part. */
12
- title: string;
13
- /** Shown when the title is empty. Default "Untitled". */
14
- untitled?: string | undefined;
15
- /**
16
- * The breadcrumb's parent link, e.g. `<Link to="/forms">Forms</Link>`: one element, so
17
- * the host's router renders it.
18
- */
19
- parent?: ReactNode;
20
- /** The status chip, e.g. formStatusChip's "Live · version 3" or "Draft". */
21
- status?: {
22
- label: string;
23
- tone: ChipTone;
24
- } | undefined;
25
- /** Where saving the draft stands; no chip when absent. */
26
- saveState?: SaveState | undefined;
27
- /** Undo and redo buttons, shown when given (for example the builder's history). */
28
- onUndo?: (() => void) | undefined;
29
- onRedo?: (() => void) | undefined;
30
- canUndo?: boolean | undefined;
31
- canRedo?: boolean | undefined;
32
- /** A Preview button. */
33
- onPreview?: (() => void) | undefined;
34
- /** A Share button (open a share dialog). */
35
- onShare?: (() => void) | undefined;
36
- /** The primary button: "Publish", or "Publish changes" once it is live. */
37
- publish?: {
38
- onClick: () => void;
39
- label?: string | undefined;
40
- loading?: boolean | undefined;
41
- disabled?: boolean | undefined;
42
- } | undefined;
43
- /** Anything else for the right-hand side, before Preview (a Reload button, a menu). */
44
- actions?: ReactNode;
45
- className?: string | undefined;
46
- }
47
- /**
48
- * The header of a page that edits one publishable thing (a form, a course, a lesson, a
49
- * worksheet): the breadcrumb ("Forms › name"), the title once, its status and save-state
50
- * chips, and on the right undo and redo, Preview, Share and Publish. Every action is the
51
- * host's; a button shows only when its handler is given.
52
- */
53
- declare function ResourceHeader({ title, untitled, parent, status, saveState, onUndo, onRedo, canUndo, canRedo, onPreview, onShare, publish, actions, className, }: ResourceHeaderProps): react.JSX.Element;
54
-
55
- /**
56
- * "Ready to publish", or how many problems to fix: for the trailing slot of a resource
57
- * page's row of tabs (genesis-ui's `<AppShellSubNavEnd>`). With `onClick` it is a button (open the checks).
58
- */
59
- declare function ReadinessChip({ readiness, onClick, className, }: {
60
- readiness: Readiness;
61
- onClick?: (() => void) | undefined;
62
- className?: string | undefined;
63
- }): react.JSX.Element;
64
-
65
- /** A small status chip in one of the studio's tones (tinted, AA-safe Genesis badges). */
66
- declare function Chip({ tone, icon, children, className, testID, }: {
67
- tone: ChipTone;
68
- icon?: ReactNode;
69
- children: ReactNode;
70
- className?: string | undefined;
71
- testID?: string | undefined;
72
- }): react.JSX.Element;
73
-
74
- type ResponsesView = "summary" | "each";
75
- /**
76
- * The Responses tab's toolbar: a Summary / Each response switch, the host's filters
77
- * (ResponsesFilters, or its own) and, on the right, its export actions (open a Sheet,
78
- * Download CSV).
79
- */
80
- declare function ResponsesToolbar({ view, onViewChange, filters, actions, className, }: {
81
- view: ResponsesView;
82
- onViewChange: (view: ResponsesView) => void;
83
- filters?: ReactNode;
84
- actions?: ReactNode;
85
- className?: string | undefined;
86
- }): react.JSX.Element;
87
-
88
- /**
89
- * One card of a summary column: an icon and a title, a short line on the right ("24
90
- * answers · average 4.1"), then whatever summarises it (bars, quotes, a split bar).
91
- */
92
- declare function SummaryCard({ icon, title, meta, children, className, testID, }: {
93
- icon?: ReactNode;
94
- title: string;
95
- meta?: ReactNode;
96
- children?: ReactNode;
97
- className?: string | undefined;
98
- testID?: string | undefined;
99
- }): react.JSX.Element;
100
-
101
- /** One response in the follow-up list, as the host describes it. */
102
- interface FollowUpEntry {
103
- id: string;
104
- /** Who answered: a name, or "Anonymous". */
105
- name: string;
106
- /** A tag beside the name, e.g. "Member" or "New lead". */
107
- tag?: {
108
- label: string;
109
- tone?: ChipTone | undefined;
110
- } | undefined;
111
- /** One line under the name: "Today · 6:00 WOD · Leo". */
112
- meta?: ReactNode;
113
- /** What they wrote; null shows "No comment". */
114
- comment?: string | null | undefined;
115
- /** The low score, on its scale. */
116
- rating?: {
117
- value: number;
118
- max: number;
119
- } | null | undefined;
120
- }
121
- /**
122
- * Responses that need a follow-up (needsFollowUp), each with who answered, a tag, the day
123
- * and context, their comment, its low score and the host's actions (Reply, Mark handled).
124
- * Handled items are the host's to leave out.
125
- */
126
- declare function FollowUpList({ entries, actions, title, isLoading, empty, className, }: {
127
- entries: readonly FollowUpEntry[];
128
- /** Buttons for one entry. */
129
- actions?: ((entry: FollowUpEntry) => ReactNode) | undefined;
130
- title?: string | undefined;
131
- isLoading?: boolean | undefined;
132
- /** Said when the list is empty. */
133
- empty?: ReactNode;
134
- className?: string | undefined;
135
- }): react.JSX.Element;
136
-
137
- /**
138
- * Sharing one published page (a form, a course), as Google Forms' Send step: its link with Copy, a QR code
139
- * (and a printable poster when the host has one), an `<iframe>` to embed it on a website,
140
- * and a builder for prefilled links (`?class=…&coach=…`, or whatever the host offers).
141
- * Generic: the host passes the link, how to draw a QR code, and the prefill choices.
142
- * Moved up from Breakthrough's src/components/forms/ShareDialog.tsx.
143
- */
144
- declare function ShareDialog({ open, onOpenChange, noun, title, description, url, posterUrl, renderQr, name, prefill, prefillNote, defaultTab, }: {
145
- open: boolean;
146
- onOpenChange: (open: boolean) => void;
147
- title?: string | undefined;
148
- description?: ReactNode;
149
- /** The public link; null while it is still loading. */
150
- url: string | null;
151
- /** A printable poster for a link (the base link, or a prefilled one), when the host has one. */
152
- posterUrl?: ((url: string, prefill: Record<string, string>) => string | null) | undefined;
153
- /** Draws a QR code for a link. */
154
- renderQr?: ((url: string) => ReactNode) | undefined;
155
- /** Its name, for the embed's accessible title. */
156
- name: string;
157
- /** What it is, in the default title and buttons: "form" (default), "course". */
158
- noun?: string | undefined;
159
- /** The search params a prefilled link may set, each with its choices. None hides the builder. */
160
- prefill?: readonly PrefillChoice[] | undefined;
161
- /** Said under the prefilled-link builder (what a prefilled link does). */
162
- prefillNote?: ReactNode;
163
- /** The tab it opens on (each time it opens). Default "link". */
164
- defaultTab?: "link" | "qr" | "embed" | undefined;
165
- }): react.JSX.Element;
166
-
12
+ /** A form's Share dialog words: "Share your form", "Anyone with the link can answer." */
13
+ declare const FORM_SHARE_LABELS: {
14
+ readonly noun: "form";
15
+ readonly description: "Anyone with the link can answer.";
16
+ };
17
+ /** @deprecated import from @marktiderman/genesis-ui */
18
+ type ResourceHeaderProps = ResourceHeaderProps$1;
19
+ /** @deprecated import from @marktiderman/genesis-ui */
20
+ type ResponsesView = ResponsesView$1;
21
+ /** @deprecated import from @marktiderman/genesis-ui */
22
+ type HeadlineNumber = HeadlineNumber$1;
23
+ /** @deprecated import from @marktiderman/genesis-ui */
24
+ type FollowUpEntry = FollowUpEntry$1;
25
+ /** @deprecated import `ResourceSettingsSection` from @marktiderman/genesis-ui */
26
+ type SettingsPageSection = ResourceSettingsSection;
27
+ /** @deprecated import from @marktiderman/genesis-ui */
28
+ declare const ResourceHeader: typeof ResourceHeader$1;
29
+ /** @deprecated import from @marktiderman/genesis-ui */
30
+ declare const Chip: typeof Chip$1;
31
+ /** @deprecated import from @marktiderman/genesis-ui */
32
+ declare const ResponsesToolbar: typeof ResponsesToolbar$1;
33
+ /** @deprecated import from @marktiderman/genesis-ui */
34
+ declare const HeadlineNumbers: typeof HeadlineNumbers$1;
35
+ /** @deprecated import from @marktiderman/genesis-ui */
36
+ declare const SummaryCard: typeof SummaryCard$1;
37
+ /** @deprecated import from @marktiderman/genesis-ui */
38
+ declare const FollowUpList: typeof FollowUpList$1;
39
+ /** @deprecated import from @marktiderman/genesis-ui */
40
+ declare const SettingsSection: typeof SettingsSection$1;
41
+ /** @deprecated import from @marktiderman/genesis-ui */
42
+ declare const ResourceSettingsPage: typeof ResourceSettingsPage$1;
167
43
  /**
168
- * One group of settings as a card: an icon, a title and a sentence, then its rows
169
- * (genesis-ui `SettingsRow` and `ToggleRow`: a label, a one-sentence description and the
170
- * control), divided by lines. On a phone a row whose control isn't a switch puts the
171
- * control under its label, so wide controls (a link, a list of people) still fit.
44
+ * "Ready to publish", or how many problems to fix, in a form's words ("Add a question").
45
+ * @deprecated import from @marktiderman/genesis-ui and pass `labels={FORM_READINESS_LABELS}`
172
46
  */
173
- declare function SettingsSection({ id, icon, title, description, children, className, }: {
174
- /** The jump link's target. */
175
- id?: string | undefined;
176
- icon?: ReactNode;
177
- title: ReactNode;
178
- description?: ReactNode;
179
- children?: ReactNode;
180
- className?: string | undefined;
181
- }): react.JSX.Element;
182
- interface SettingsPageSection {
183
- id: string;
184
- title: string;
185
- icon?: ReactNode;
186
- description?: ReactNode;
187
- /** The rows. Absent: a jump link only, to `#id` elsewhere on the page (or `onSelect`). */
188
- content?: ReactNode;
189
- /** For a link-only section whose target has no id: scroll to it yourself. */
190
- onSelect?: (() => void) | undefined;
191
- }
47
+ declare function ReadinessChip({ labels, ...props }: ComponentProps<typeof ReadinessChip$1>): react.JSX.Element;
192
48
  /**
193
- * Every setting of one thing (a form, a course) on one page: jump links on the left ("On this page", the one in
194
- * view marked), the sections as cards on the right. On a phone the links sit above the
195
- * sections as a row that scrolls sideways.
196
- *
197
- * Not genesis-ui's `SettingsPage`: that one is a whole page with its own title, and plain
198
- * sections; these settings sit under the resource's header, as cards with icons.
49
+ * Sharing a published form: "Share your form", "Anyone with the link can answer."
50
+ * @deprecated import from @marktiderman/genesis-ui and pass `{...FORM_SHARE_LABELS}`
199
51
  */
200
- declare function ResourceSettingsPage({ sections, navLabel, className, }: {
201
- sections: readonly SettingsPageSection[];
202
- navLabel?: string | undefined;
203
- className?: string | undefined;
204
- }): react.JSX.Element;
52
+ declare function ShareDialog({ noun, description, ...props }: ComponentProps<typeof ShareDialog$1>): react.JSX.Element;
205
53
 
206
54
  /** The form page's four places' icons, for `formNavItems(path, counts, FORM_NAV_ICONS)`. */
207
55
  declare const FORM_NAV_ICONS: {
@@ -270,13 +118,17 @@ declare function QuestionSummaryCards({ summaries, responses, isLoading, emptyTi
270
118
  }): react.JSX.Element;
271
119
 
272
120
  /**
273
- * Drop-off by question (dropOffByQuestion): for each question in order, how many people
274
- * reached it, how many stopped there, and that as a share, with the share as a bar (the
275
- * question most people left on in the warning colour). For a form that saves answers as
276
- * they go.
121
+ * Drop-off by question (`dropOffSummary`): how many people started, then for each question in
122
+ * order how many reached it, how many stopped there, and that as a share, with the share as
123
+ * a bar (the question most people left on in the warning colour). For a form that saves
124
+ * answers as they go. Spread `dropOffSummary(...)` into it; without `started` it falls back
125
+ * to the first question's views, which leaves out responses in progress and anyone logic
126
+ * hid the first question from.
277
127
  */
278
- declare function DropOffByQuestion({ dropOffs, isLoading, title, className, }: {
128
+ declare function DropOffByQuestion({ dropOffs, started: startedCount, isLoading, title, className, }: {
279
129
  dropOffs: readonly QuestionDropOff[];
130
+ /** How many people started (`dropOffSummary`'s `started`). */
131
+ started?: number | undefined;
280
132
  isLoading?: boolean | undefined;
281
133
  title?: string | undefined;
282
134
  className?: string | undefined;
@@ -295,4 +147,4 @@ declare function PhotoAnswer({ photos, resolveUrl, className, testID, }: {
295
147
  testID?: string | undefined;
296
148
  }): react.JSX.Element | null;
297
149
 
298
- export { Chip, ChipTone, type ChoiceFilter, DropOffByQuestion, FORM_NAV_ICONS, FiltersValue, type FollowUpEntry, FollowUpList, PhotoAnswer, PrefillChoice, QuestionDropOff, QuestionSummary, QuestionSummaryCard, QuestionSummaryCards, Readiness, ReadinessChip, ResourceHeader, type ResourceHeaderProps, ResourceSettingsPage, ResponsesFilters, ResponsesToolbar, type ResponsesView, SaveState, type SettingsPageSection, SettingsSection, ShareDialog, SummaryCard };
150
+ export { Chip, type ChoiceFilter, DropOffByQuestion, FORM_NAV_ICONS, FORM_SHARE_LABELS, FiltersValue, type FollowUpEntry, FollowUpList, type HeadlineNumber, HeadlineNumbers, PhotoAnswer, QuestionDropOff, QuestionSummary, QuestionSummaryCard, QuestionSummaryCards, ReadinessChip, ResourceHeader, type ResourceHeaderProps, ResourceSettingsPage, ResponsesFilters, ResponsesToolbar, type ResponsesView, type SettingsPageSection, SettingsSection, ShareDialog, SummaryCard };