@marktiderman/genesis-forms-web 0.1.1 → 0.2.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 +25 -5
- package/dist/index.d.ts +29 -3
- package/dist/index.js +642 -6
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@ The web renderer for [Genesis Forms](../forms/README.md), built on Genesis UI co
|
|
|
6
6
|
import { Form } from "@marktiderman/genesis-forms-web";
|
|
7
7
|
|
|
8
8
|
<Form
|
|
9
|
-
form={
|
|
9
|
+
form={eventFeedback} // a defineForm result or a canonical definition
|
|
10
10
|
layout="focus" // one question at a time; or "classic"
|
|
11
|
-
options={{ hidden: {
|
|
11
|
+
options={{ hidden: { owner: "Sam" } }}
|
|
12
12
|
onChange={(state) => saveDraft(state)}
|
|
13
13
|
onSubmit={(engine) => submit(engine.getState().events)}
|
|
14
14
|
/>
|
|
@@ -41,13 +41,13 @@ import { Form } from "@marktiderman/genesis-forms-web";
|
|
|
41
41
|
`prefers-reduced-motion`). The ending is centred and large. In classic layout, page mode is one
|
|
42
42
|
scrolling page, Google Forms style: a header card with the title and description, each question
|
|
43
43
|
in its own card (red-edged while invalid), Submit at the end.
|
|
44
|
-
`brand={{ name: "
|
|
44
|
+
`brand={{ name: "Acme", logo }}` shows an organisation's or business's logo (an image URL or an
|
|
45
45
|
element; its initials without one) and name small at the top of every step and on the ending.
|
|
46
46
|
Custom slots and renderers can match with `useFormPresentation()`, which returns
|
|
47
47
|
`{ presentation, layout }`.
|
|
48
48
|
|
|
49
49
|
```tsx
|
|
50
|
-
<Form form={
|
|
50
|
+
<Form form={eventFeedback} presentation="page" brand={{ name: "Acme" }} onSubmit={send} />
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
- **Accessible by default:** group questions are a `fieldset` with a `legend`, and rating, NPS and
|
|
@@ -74,7 +74,27 @@ import { Form } from "@marktiderman/genesis-forms-web";
|
|
|
74
74
|
`defaultRegistry.register(entry)` mutates the shared registry in place, for every form in the app.
|
|
75
75
|
|
|
76
76
|
Renderers: short and long text, email, phone (`type="tel"`), rating, NPS, single choice, multiple
|
|
77
|
-
choice, yes/no
|
|
77
|
+
choice, yes/no, and the structured types:
|
|
78
|
+
|
|
79
|
+
- **`list`** (goals, action items, three wins) and **`table`** (an action plan with What / Who /
|
|
80
|
+
By when, pros and cons) add, remove and reorder entries (SortableList: drag, keyboard and a Move
|
|
81
|
+
menu).
|
|
82
|
+
- **`media-notes`** (lecture notes, reviewing a recorded call) takes a typed time (`m:ss`,
|
|
83
|
+
`h:mm:ss` or seconds). Wrap the form in `MediaTimeContext` to link it to your video or audio
|
|
84
|
+
player: `currentTime` prefills "Add note at 1:23" and `seek` plays from a note.
|
|
85
|
+
- **`text-highlights`** (annotating an article, a policy or a contract) takes highlights by
|
|
86
|
+
selecting words in the passage or typing them. The passage is the field's `text` prop, or the
|
|
87
|
+
value of `SourceTextContext` around the form.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<MediaTimeContext.Provider value={{ currentTime: () => player.currentTime, seek: (s) => player.seek(s) }}>
|
|
91
|
+
<SourceTextContext.Provider value={article.body}>
|
|
92
|
+
<Form form={videoNotes} onSubmit={send} />
|
|
93
|
+
</SourceTextContext.Provider>
|
|
94
|
+
</MediaTimeContext.Provider>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`useMediaTime()` and `useSourceText()` read them in a custom renderer.
|
|
78
98
|
|
|
79
99
|
## License
|
|
80
100
|
|
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ interface HeaderSlotProps {
|
|
|
28
28
|
className?: string;
|
|
29
29
|
}
|
|
30
30
|
interface BrandSlotProps {
|
|
31
|
-
/** The
|
|
31
|
+
/** The organisation or business name, shown beside the logo. */
|
|
32
32
|
name: string;
|
|
33
33
|
/** An image URL or your own element. Without one, the name's initials are shown. */
|
|
34
34
|
logo?: ReactNode;
|
|
@@ -110,7 +110,7 @@ interface FormProps {
|
|
|
110
110
|
* layout the questions are sections on one scrolling page.
|
|
111
111
|
*/
|
|
112
112
|
presentation?: FormPresentation | undefined;
|
|
113
|
-
/**
|
|
113
|
+
/** An organisation's or business's name and logo, shown small at the top of every step and on the ending. */
|
|
114
114
|
brand?: FormBrand | undefined;
|
|
115
115
|
registry?: RendererRegistry | undefined;
|
|
116
116
|
/**
|
|
@@ -164,6 +164,7 @@ interface FieldChromeProps {
|
|
|
164
164
|
*/
|
|
165
165
|
declare function FieldChrome({ props, children, className }: FieldChromeProps): react.JSX.Element;
|
|
166
166
|
declare function describedBy(props: FieldRendererProps): string | undefined;
|
|
167
|
+
|
|
167
168
|
declare const builtInRenderers: RendererEntry[];
|
|
168
169
|
/**
|
|
169
170
|
* The built-in web renderers, shared by every `<Form>` that gets no
|
|
@@ -172,4 +173,29 @@ declare const builtInRenderers: RendererEntry[];
|
|
|
172
173
|
*/
|
|
173
174
|
declare const defaultRegistry: _marktiderman_genesis_forms_react.RendererRegistry;
|
|
174
175
|
|
|
175
|
-
|
|
176
|
+
/**
|
|
177
|
+
* The video or audio a form is about, as the host app plays it. `media-notes`
|
|
178
|
+
* fields read it: with `currentTime` the add row starts at the current moment
|
|
179
|
+
* ("Add note at 1:23"), with `seek` a note's time plays the media from there.
|
|
180
|
+
* Both are in seconds from the start of the full recording.
|
|
181
|
+
*/
|
|
182
|
+
interface MediaTime {
|
|
183
|
+
/** The playhead now, or undefined when it isn't known yet. */
|
|
184
|
+
currentTime?: (() => number | undefined) | undefined;
|
|
185
|
+
/** Move the playhead. */
|
|
186
|
+
seek?: ((seconds: number) => void) | undefined;
|
|
187
|
+
}
|
|
188
|
+
/** Provide it around `<Form>` to link `media-notes` fields to a media player. */
|
|
189
|
+
declare const MediaTimeContext: react.Context<MediaTime | null>;
|
|
190
|
+
/** The enclosing `MediaTimeContext` value, or null. */
|
|
191
|
+
declare function useMediaTime(): MediaTime | null;
|
|
192
|
+
/**
|
|
193
|
+
* The text a form is about (an article, a policy, a contract). `text-highlights`
|
|
194
|
+
* fields highlight passages of it; a field's own `props.text` is used when no
|
|
195
|
+
* host provides one. Offsets are UTF-16 indices into this exact string.
|
|
196
|
+
*/
|
|
197
|
+
declare const SourceTextContext: react.Context<string | null>;
|
|
198
|
+
/** The enclosing `SourceTextContext` value, or null. */
|
|
199
|
+
declare function useSourceText(): string | null;
|
|
200
|
+
|
|
201
|
+
export { type BrandSlotProps, type EndingSlotProps, type ErrorSummaryItem, type ErrorSummarySlotProps, FieldChrome, type FieldChromeProps, Form, type FormBrand, type FormPresentation, type FormPresentationValue, type FormProps, type FormSlotMap, type HeaderSlotProps, type MediaTime, MediaTimeContext, type NavigationSlotProps, type ProgressSlotProps, SourceTextContext, builtInRenderers, defaultRegistry, describedBy, useFormPresentation, useMediaTime, useSourceText };
|