@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/README.md +45 -16
- package/dist/{chunk-HP77TYTT.js → chunk-KUYYXBEN.js} +85 -103
- package/dist/chunk-KUYYXBEN.js.map +1 -0
- package/dist/index.d.ts +52 -200
- package/dist/index.js +35 -586
- package/dist/index.js.map +1 -1
- package/dist/rules.d.ts +500 -3
- package/dist/rules.js +1 -1
- package/package.json +6 -6
- package/dist/chunk-HP77TYTT.js.map +0 -1
- package/dist/rules-Bpy8zTON.d.ts +0 -494
package/dist/index.d.ts
CHANGED
|
@@ -1,207 +1,55 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
*
|
|
169
|
-
*
|
|
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
|
|
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
|
-
*
|
|
194
|
-
*
|
|
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
|
|
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 (
|
|
274
|
-
* reached it, how many stopped there, and that as a share, with the share as
|
|
275
|
-
* question most people left on in the warning colour). For a form that saves
|
|
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,
|
|
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 };
|