@clickless/react 0.0.0-stage → 0.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/LICENSE +21 -0
- package/README.md +1095 -2
- package/dist/actions/actionCalls.d.ts +50 -0
- package/dist/actions/actionRegistry.d.ts +78 -0
- package/dist/components/Adaptive.d.ts +116 -0
- package/dist/components/AdaptiveAction.d.ts +4 -0
- package/dist/components/AdaptiveProvider.d.ts +38 -0
- package/dist/components/AdaptiveRegion.d.ts +60 -0
- package/dist/components/ClicklessUiErrorBoundary.d.ts +24 -0
- package/dist/components/OriginalToolbar.d.ts +21 -0
- package/dist/components/PromptBar.d.ts +21 -0
- package/dist/components/PromptPanel.d.ts +103 -0
- package/dist/components/WorkingDots.d.ts +4 -0
- package/dist/components/focusAfterPromptAction.d.ts +15 -0
- package/dist/components/hostColorScheme.d.ts +35 -0
- package/dist/components/promptPanelStyles.d.ts +14 -0
- package/dist/core/applyOperations.d.ts +21 -0
- package/dist/core/colorContrast.d.ts +22 -0
- package/dist/core/defaultLayout.d.ts +12 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/ownProperties.d.ts +11 -0
- package/dist/core/propValues.d.ts +8 -0
- package/dist/core/reconcileLayout.d.ts +59 -0
- package/dist/core/schemas.gen.d.ts +427 -0
- package/dist/core/validateActionCalls.d.ts +28 -0
- package/dist/core/validateManifest.d.ts +11 -0
- package/dist/core/validateOperations.d.ts +15 -0
- package/dist/engine/engineClient.d.ts +231 -0
- package/dist/engine/engineErrorMessages.d.ts +13 -0
- package/dist/engine/engineResponses.d.ts +201 -0
- package/dist/engine/plainReplies.d.ts +2 -0
- package/dist/hooks/useActionRunHistory.d.ts +12 -0
- package/dist/hooks/useAdaptiveAction.d.ts +11 -0
- package/dist/hooks/useAdaptiveRegion.d.ts +34 -0
- package/dist/hooks/useChangeHistory.d.ts +32 -0
- package/dist/hooks/useDictation.d.ts +50 -0
- package/dist/hooks/useEngineReachable.d.ts +5 -0
- package/dist/hooks/usePromptBar.d.ts +163 -0
- package/dist/hooks/useRegionGroup.d.ts +15 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +6600 -0
- package/dist/presets/mergePresets.d.ts +20 -0
- package/dist/presets/propPresets.d.ts +305 -0
- package/dist/region/changedComponentIds.d.ts +13 -0
- package/dist/region/firstPaintOrder.d.ts +19 -0
- package/dist/region/previewRequests.d.ts +21 -0
- package/dist/region/regionContext.d.ts +96 -0
- package/dist/region/regionGroup.d.ts +189 -0
- package/dist/region/regionSnapshot.d.ts +52 -0
- package/dist/region/regionStore.d.ts +361 -0
- package/dist/region/responsiveColumns.d.ts +35 -0
- package/dist/region/retrier.d.ts +22 -0
- package/dist/region/savedLayoutParsing.d.ts +7 -0
- package/dist/region/settleIntoSavedLayout.d.ts +14 -0
- package/dist/region/textDirection.d.ts +12 -0
- package/dist/region/unsavedChangeSaver.d.ts +45 -0
- package/dist/region/unsavedChanges.d.ts +78 -0
- package/dist/region/userFacingTitle.d.ts +7 -0
- package/package.json +59 -3
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Capabilities, LayoutItem } from "../core/index.js";
|
|
2
|
+
import type { PropPreset } from "./propPresets.js";
|
|
3
|
+
type OwnDeclaration = {
|
|
4
|
+
description: string | undefined;
|
|
5
|
+
capabilities: Partial<Omit<Capabilities, "props">> | undefined;
|
|
6
|
+
defaults: Partial<Pick<LayoutItem, "w" | "h" | "hidden">>;
|
|
7
|
+
};
|
|
8
|
+
type Declaration = {
|
|
9
|
+
description: string | undefined;
|
|
10
|
+
capabilities: Partial<Capabilities> | undefined;
|
|
11
|
+
defaults: Partial<Pick<LayoutItem, "w" | "h" | "hidden" | "props">>;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* A component's declaration with its presets folded in: their props make up
|
|
15
|
+
* `capabilities.props`, their starting values `defaults.props`, and their
|
|
16
|
+
* sentences follow `description` in order. A prop declared by two presets is
|
|
17
|
+
* refused, since its two meanings would contradict.
|
|
18
|
+
*/
|
|
19
|
+
export declare function mergePresets(componentId: string, declaration: OwnDeclaration, presets: readonly PropPreset[]): Declaration;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import { type PropCapabilities, type PropValue } from "../core/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* A setting users may change, or a few that belong together, with its values
|
|
5
|
+
* and the sentence that tells the model what it means. Pass it in `<Adaptive presets>`:
|
|
6
|
+
* its props and starting values become part of the component's declaration, and
|
|
7
|
+
* its sentence follows `description`, which is where the model learns what each
|
|
8
|
+
* prop means.
|
|
9
|
+
*/
|
|
10
|
+
export interface PropPreset<Reading = unknown> {
|
|
11
|
+
/** Which preset this is, such as "stripes". */
|
|
12
|
+
readonly preset: string;
|
|
13
|
+
readonly capabilities: Readonly<Record<string, PropCapabilities>>;
|
|
14
|
+
readonly defaults: Readonly<Record<string, PropValue>>;
|
|
15
|
+
/** One or two sentences naming each of its props, added to the component's description. */
|
|
16
|
+
readonly description: string;
|
|
17
|
+
/**
|
|
18
|
+
* The preset's current value, from the props a render-function child receives.
|
|
19
|
+
* A missing or unexpected value reads as the preset's default.
|
|
20
|
+
*/
|
|
21
|
+
read(adaptiveProps: Readonly<Record<string, PropValue>>): Reading;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A custom setting: one whose values the application gives, such as a choice of
|
|
25
|
+
* the application's own views. Its prop takes the name it is given in
|
|
26
|
+
* `<Adaptive presets>`, so `{ order: propPresets.choice(...) }` declares a prop
|
|
27
|
+
* called `order`.
|
|
28
|
+
*/
|
|
29
|
+
export interface CustomPreset<Reading = unknown> {
|
|
30
|
+
/** Which preset this is, such as "choice". */
|
|
31
|
+
readonly preset: string;
|
|
32
|
+
/** The preset with its prop given this name. */
|
|
33
|
+
named(propName: string): PropPreset<Reading>;
|
|
34
|
+
}
|
|
35
|
+
/** The presets of one component, each under a name of the integrator's choosing. */
|
|
36
|
+
export type PresetSet = Readonly<Record<string, PropPreset | CustomPreset>>;
|
|
37
|
+
/** The current value of each preset in a set, under the same name. */
|
|
38
|
+
export type PresetValues<Presets extends PresetSet> = {
|
|
39
|
+
[PresetName in keyof Presets]: Presets[PresetName] extends PropPreset<infer Reading> ? Reading : Presets[PresetName] extends CustomPreset<infer Reading> ? Reading : never;
|
|
40
|
+
};
|
|
41
|
+
/** Each preset of a set as a `PropPreset`, a custom one taking its key as its prop's name. */
|
|
42
|
+
export declare function presetsByName(presets: PresetSet): Record<string, PropPreset>;
|
|
43
|
+
/**
|
|
44
|
+
* A chosen colour and the text colour to draw on it: black or white, whichever
|
|
45
|
+
* reads better on that colour.
|
|
46
|
+
*/
|
|
47
|
+
export type ColourReading = {
|
|
48
|
+
colour: string;
|
|
49
|
+
/** Black or white, whichever is readable on `colour`. */
|
|
50
|
+
textColour: string;
|
|
51
|
+
};
|
|
52
|
+
/** The options `accent`, `colour` and `stripes` share on what is drawn on the colour and behind it. */
|
|
53
|
+
type ReadabilityOptions = {
|
|
54
|
+
/**
|
|
55
|
+
* Text is drawn on the colour in its reading's `textColour`, as on a button
|
|
56
|
+
* or a selected entry. The planner is then told, and its reply says when a
|
|
57
|
+
* chosen colour turns that text from white to black or back.
|
|
58
|
+
*/
|
|
59
|
+
textOn?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The colour behind it, written as #rrggbb, such as the page's `#ffffff`. The
|
|
62
|
+
* planner's reply then says when a chosen colour would be hard to see on it:
|
|
63
|
+
* under 3:1 for a colour with no text on it, such as a link or a line, and
|
|
64
|
+
* all but the same as what is behind it, such as white on white, with `textOn`.
|
|
65
|
+
*/
|
|
66
|
+
against?: string;
|
|
67
|
+
};
|
|
68
|
+
type Density = "comfortable" | "compact";
|
|
69
|
+
/** `density`: how much room each row or entry takes. Reads as "comfortable" or "compact". */
|
|
70
|
+
declare function density({ initial }?: {
|
|
71
|
+
initial?: Density;
|
|
72
|
+
}): PropPreset<Density>;
|
|
73
|
+
/**
|
|
74
|
+
* `stripes`: colouring every other row. Reads as the stripe colour and the text
|
|
75
|
+
* colour readable on it, or null when off.
|
|
76
|
+
*
|
|
77
|
+
* With `palette`, users choose among the named colours given, such as
|
|
78
|
+
* `{ grey: "#f3f2ee", red: "#b91c1c" }`. Without it, they may choose any colour,
|
|
79
|
+
* held in a second prop, `stripeColour`.
|
|
80
|
+
*/
|
|
81
|
+
declare function stripes(options?: ({
|
|
82
|
+
initial?: "off" | "on";
|
|
83
|
+
colour?: string;
|
|
84
|
+
suggested?: readonly string[];
|
|
85
|
+
} & ReadabilityOptions) | {
|
|
86
|
+
palette: Readonly<Record<string, string>>;
|
|
87
|
+
initial?: string;
|
|
88
|
+
}): PropPreset<ColourReading | null>;
|
|
89
|
+
/**
|
|
90
|
+
* `background` and `textColour`. Reads as both colours, with `textColour` turned
|
|
91
|
+
* black or white where the chosen one would be hard to read on the background,
|
|
92
|
+
* as the description promises the model; `chosenTextColour` is the user's choice as is.
|
|
93
|
+
*/
|
|
94
|
+
declare function colours({ background, textColour, suggested, }?: {
|
|
95
|
+
background?: string;
|
|
96
|
+
textColour?: string;
|
|
97
|
+
suggested?: readonly string[];
|
|
98
|
+
}): PropPreset<{
|
|
99
|
+
background: string;
|
|
100
|
+
textColour: string;
|
|
101
|
+
chosenTextColour: string;
|
|
102
|
+
/** Both colours as a style, ready to spread onto the component's outer element. */
|
|
103
|
+
style: CSSProperties;
|
|
104
|
+
}>;
|
|
105
|
+
/** `textSize`: the size of the text in pixels, a whole number from `min` to `max`. */
|
|
106
|
+
declare function textSize({ initial, min, max, }?: {
|
|
107
|
+
initial?: number;
|
|
108
|
+
min?: number;
|
|
109
|
+
max?: number;
|
|
110
|
+
}): PropPreset<number>;
|
|
111
|
+
/**
|
|
112
|
+
* Showing or hiding one part of the component, such as
|
|
113
|
+
* `{ trend: propPresets.toggle({ shows: "the line comparing it with last month" }) }`.
|
|
114
|
+
* The prop takes its name from the key and holds "on" or "off"; it reads as true while shown.
|
|
115
|
+
*/
|
|
116
|
+
declare function toggle({ shows, initial }: {
|
|
117
|
+
shows: string;
|
|
118
|
+
initial?: boolean;
|
|
119
|
+
}): CustomPreset<boolean>;
|
|
120
|
+
/**
|
|
121
|
+
* One of a list of the application's own values, such as the view of a calendar:
|
|
122
|
+
* `{ view: propPresets.choice({ values: ["day", "week", "month"], initial: "week", means: "how much of the calendar shows at once" }) }`.
|
|
123
|
+
* `means` says what the prop is, in plain words, for the model: "view is …".
|
|
124
|
+
*/
|
|
125
|
+
declare function choice<const Value extends string>({ values, initial, means, }: {
|
|
126
|
+
values: readonly Value[];
|
|
127
|
+
initial: NoInfer<Value>;
|
|
128
|
+
means: string;
|
|
129
|
+
}): CustomPreset<Value>;
|
|
130
|
+
/**
|
|
131
|
+
* A number from `min` to `max`, whole unless `whole` is false, such as the corner
|
|
132
|
+
* radius of a button. `means` says what it is, with its unit: "the corner radius in pixels".
|
|
133
|
+
*/
|
|
134
|
+
declare function number({ min, max, initial, whole, means, }: {
|
|
135
|
+
min: number;
|
|
136
|
+
max: number;
|
|
137
|
+
initial: number;
|
|
138
|
+
whole?: boolean;
|
|
139
|
+
means: string;
|
|
140
|
+
}): CustomPreset<number>;
|
|
141
|
+
/**
|
|
142
|
+
* Any colour, such as the colour of a chart's bars. `means` says what it colours:
|
|
143
|
+
* "the colour of the bars". `suggested` lists colours to prefer, such as the brand's.
|
|
144
|
+
* Reads as the colour and the text colour readable on it; give `textOn` where
|
|
145
|
+
* text is drawn on it in that text colour, and `against` for the colour behind it.
|
|
146
|
+
*/
|
|
147
|
+
declare function colour({ initial, suggested, means, ...readabilityOptions }: {
|
|
148
|
+
initial: string;
|
|
149
|
+
suggested?: readonly string[];
|
|
150
|
+
means: string;
|
|
151
|
+
} & ReadabilityOptions): CustomPreset<ColourReading>;
|
|
152
|
+
/**
|
|
153
|
+
* Which of the application's own entries show, and in what order, such as the
|
|
154
|
+
* columns of a table. `means` says what the list holds: "the columns that show,
|
|
155
|
+
* left to right". All of `values` show to begin with unless `initial` is given;
|
|
156
|
+
* `min` is the fewest the list may hold, and `required` lists entries it must
|
|
157
|
+
* always hold, such as the tab of the page that is open. They can still be moved.
|
|
158
|
+
*/
|
|
159
|
+
declare function visibleList<const Value extends string>({ values, initial, min, required, means, }: {
|
|
160
|
+
values: readonly Value[];
|
|
161
|
+
initial?: readonly NoInfer<Value>[];
|
|
162
|
+
min?: number;
|
|
163
|
+
required?: readonly NoInfer<Value>[];
|
|
164
|
+
means: string;
|
|
165
|
+
}): CustomPreset<Value[]>;
|
|
166
|
+
/**
|
|
167
|
+
* `count`: how many entries show, such as rows of a table or bars of a chart.
|
|
168
|
+
* `of` names the entries, in the plural, where the component's title does not
|
|
169
|
+
* make them plain: "months" on a chart titled "Revenue".
|
|
170
|
+
*/
|
|
171
|
+
declare function count({ of, min, max, initial, }: {
|
|
172
|
+
of?: string;
|
|
173
|
+
min?: number;
|
|
174
|
+
max: number;
|
|
175
|
+
initial: number;
|
|
176
|
+
}): PropPreset<number>;
|
|
177
|
+
type HighlightReading = {
|
|
178
|
+
/** The highlight colour. */
|
|
179
|
+
colour: string;
|
|
180
|
+
/** Black or white, whichever is readable on the highlight colour. */
|
|
181
|
+
textColour: string;
|
|
182
|
+
/**
|
|
183
|
+
* Whether an entry is highlighted. `position` counts from 0 at the top. `entry`
|
|
184
|
+
* is the entry's value of the measure given to `above` or `below`, or, where
|
|
185
|
+
* `kinds` is given too, `{ measure, kind }`, with `kind` the entry's value of it.
|
|
186
|
+
*/
|
|
187
|
+
isHighlighted(position: number, entry?: HighlightedEntry): boolean;
|
|
188
|
+
/**
|
|
189
|
+
* The style for an entry: the highlight colour and readable text where it is
|
|
190
|
+
* highlighted, and nothing where it is not. Pass it to the entry's own `style`,
|
|
191
|
+
* such as `<tr style={highlight.styleFor(rowIndex, row.amount)}>` or
|
|
192
|
+
* `<tr style={highlight.styleFor(rowIndex, { kind: row.status })}>`.
|
|
193
|
+
*/
|
|
194
|
+
styleFor(position: number, entry?: HighlightedEntry): CSSProperties | undefined;
|
|
195
|
+
};
|
|
196
|
+
/** An entry's value of the measure, or that and its kind. */
|
|
197
|
+
type HighlightedEntry = number | {
|
|
198
|
+
measure?: number;
|
|
199
|
+
kind?: string;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Colouring the entries that stand out in a list or table: the top few, such as
|
|
203
|
+
* the top 3 (`top`), those whose value of a measure is more than an amount
|
|
204
|
+
* (`above`) or less than one (`below`), or any of these. `entries` names them, in
|
|
205
|
+
* the plural, where the component's title does not make them plain. `measure`
|
|
206
|
+
* says what is compared, with its unit and without "the": "amount invoiced in
|
|
207
|
+
* pounds", or "start time in hours from midnight, such as 13.5 for 1:30 pm".
|
|
208
|
+
* `above` and `below` compare the same value, so given together they name the
|
|
209
|
+
* same measure.
|
|
210
|
+
* `kinds` colours the entries of chosen kinds, from a fixed set the application
|
|
211
|
+
* names in `values`, such as `{ of: "statuses", values: ["booked", "arrived",
|
|
212
|
+
* "cancelled"] }`. The values are kinds an entry falls into, never the entries
|
|
213
|
+
* themselves, so a person's or customer's name is never one.
|
|
214
|
+
* Adds `highlightTop`, `highlightAbove`, `highlightBelow`, `highlightKinds`
|
|
215
|
+
* (whichever are given) and `highlightColour`. 0, or no kinds, turns any of them
|
|
216
|
+
* off, and all start off.
|
|
217
|
+
*
|
|
218
|
+
* None has a largest value unless you give `max`: the amount is compared
|
|
219
|
+
* with the entries shown at the time, so it suits a list whose contents change.
|
|
220
|
+
*/
|
|
221
|
+
declare function highlight({ entries, top, above, below, kinds, colour, suggested, }: {
|
|
222
|
+
entries?: string;
|
|
223
|
+
top?: true | {
|
|
224
|
+
max: number;
|
|
225
|
+
};
|
|
226
|
+
above?: {
|
|
227
|
+
measure: string;
|
|
228
|
+
max?: number;
|
|
229
|
+
};
|
|
230
|
+
below?: {
|
|
231
|
+
measure: string;
|
|
232
|
+
max?: number;
|
|
233
|
+
};
|
|
234
|
+
kinds?: {
|
|
235
|
+
of: string;
|
|
236
|
+
values: readonly string[];
|
|
237
|
+
};
|
|
238
|
+
colour?: string;
|
|
239
|
+
suggested?: readonly string[];
|
|
240
|
+
}): PropPreset<HighlightReading>;
|
|
241
|
+
type TextStyle = "regular" | "italic" | "bold" | "bold italic";
|
|
242
|
+
/**
|
|
243
|
+
* `textStyle`: whether the text is bold, italic, both or neither. It leaves
|
|
244
|
+
* letter case alone, so a prop of your own for capitals combines with it.
|
|
245
|
+
* Reads as `{ bold, italic }`; what bold looks like is up to you.
|
|
246
|
+
*/
|
|
247
|
+
declare function textStyle({ initial }?: {
|
|
248
|
+
initial?: TextStyle;
|
|
249
|
+
}): PropPreset<{
|
|
250
|
+
bold: boolean;
|
|
251
|
+
italic: boolean;
|
|
252
|
+
}>;
|
|
253
|
+
/**
|
|
254
|
+
* `accent`: the one colour that marks what stands out, such as the selected
|
|
255
|
+
* entry of a menu or today in a calendar. Name what it marks in `marks`.
|
|
256
|
+
* Reads as the colour and the text colour readable on it; give `textOn` where
|
|
257
|
+
* text is drawn on it in that text colour, such as a button's label, and
|
|
258
|
+
* `against` for the colour behind it.
|
|
259
|
+
*/
|
|
260
|
+
declare function accent({ marks, colour, suggested, ...readabilityOptions }: {
|
|
261
|
+
marks: string;
|
|
262
|
+
colour?: string;
|
|
263
|
+
suggested?: readonly string[];
|
|
264
|
+
} & ReadabilityOptions): PropPreset<ColourReading>;
|
|
265
|
+
/**
|
|
266
|
+
* The settings users may change, for `<Adaptive presets>`, each under a name of
|
|
267
|
+
* your choosing. Built-in settings (`count`, `highlight`, `density`, `stripes`,
|
|
268
|
+
* `colours`, `textSize`, `textStyle`, `accent`) come with their names, values and
|
|
269
|
+
* wording, shared across applications; use one when it fits. Custom settings
|
|
270
|
+
* (`toggle`, `choice`, `number`, `colour`, `visibleList`) take the application's
|
|
271
|
+
* own values and a few words saying what they mean, and their prop takes the name
|
|
272
|
+
* it is given.
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* <Adaptive id="invoices" kind="table" title="Invoices" defaults={{ w: 12, h: 5 }}
|
|
276
|
+
* presets={{
|
|
277
|
+
* columns: propPresets.visibleList({ values: COLUMN_IDS, min: 1, means: "the columns that show, left to right" }),
|
|
278
|
+
* stripes: propPresets.stripes({ suggested: BRAND_COLOURS }),
|
|
279
|
+
* rows: propPresets.density(),
|
|
280
|
+
* }}>
|
|
281
|
+
* {(props, adaptiveControls, presetValues) => (
|
|
282
|
+
* <InvoiceTable
|
|
283
|
+
* columns={presetValues.columns}
|
|
284
|
+
* stripeColour={presetValues.stripes}
|
|
285
|
+
* compact={presetValues.rows === "compact"}
|
|
286
|
+
* />
|
|
287
|
+
* )}
|
|
288
|
+
* </Adaptive>
|
|
289
|
+
*/
|
|
290
|
+
export declare const propPresets: {
|
|
291
|
+
count: typeof count;
|
|
292
|
+
highlight: typeof highlight;
|
|
293
|
+
density: typeof density;
|
|
294
|
+
stripes: typeof stripes;
|
|
295
|
+
colours: typeof colours;
|
|
296
|
+
textSize: typeof textSize;
|
|
297
|
+
textStyle: typeof textStyle;
|
|
298
|
+
accent: typeof accent;
|
|
299
|
+
toggle: typeof toggle;
|
|
300
|
+
choice: typeof choice;
|
|
301
|
+
number: typeof number;
|
|
302
|
+
colour: typeof colour;
|
|
303
|
+
visibleList: typeof visibleList;
|
|
304
|
+
};
|
|
305
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Layout } from "../core/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Components whose own settings differ, plus the smallest set that had to move
|
|
4
|
+
* to turn one order into the other. Components that merely shifted because
|
|
5
|
+
* something else moved past them are left out.
|
|
6
|
+
*/
|
|
7
|
+
export declare function findChangedComponentIds(previousLayout: Layout, nextLayout: Layout): ReadonlySet<string>;
|
|
8
|
+
/**
|
|
9
|
+
* The entries of `nextOrder` that are new, or had to move to turn
|
|
10
|
+
* `previousOrder` into it. Entries that merely shifted because something else
|
|
11
|
+
* moved past them are left out.
|
|
12
|
+
*/
|
|
13
|
+
export declare function entriesOutOfOrder(previousOrder: readonly string[], nextOrder: readonly string[]): Set<string>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where each item is drawn before the region has mounted: on the server and
|
|
3
|
+
* on the first paint. There is no manifest yet, only the saved layout and the
|
|
4
|
+
* items as they render, one after another in the order they are written.
|
|
5
|
+
*
|
|
6
|
+
* A saved item keeps its saved place. One added since the layout was saved
|
|
7
|
+
* goes straight after the item written before it, or first if it is written
|
|
8
|
+
* first, which is where reconciling puts it once the region mounts.
|
|
9
|
+
*
|
|
10
|
+
* "Written before" is taken to be "rendered before". That holds unless part
|
|
11
|
+
* of the region is inside a Suspense boundary that is still waiting while the
|
|
12
|
+
* server sends the rest: items after it then render first, and an added item
|
|
13
|
+
* may be drawn out of place until the region mounts.
|
|
14
|
+
*/
|
|
15
|
+
export declare class FirstPaintOrder {
|
|
16
|
+
private placedItems;
|
|
17
|
+
/** `savedIndex` is the item's position in the saved order, or -1 if it is not in it. */
|
|
18
|
+
placeItem(itemId: string, savedIndex: number): number;
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A request whose answer is part of the preview on the screen. A follow-up
|
|
3
|
+
* typed during a preview adds its change to the preview, so one preview can
|
|
4
|
+
* hold several, and is kept or discarded as one change.
|
|
5
|
+
*/
|
|
6
|
+
export interface PreviewRequest {
|
|
7
|
+
prompt: string;
|
|
8
|
+
/** What the planner answered: what this request changed from the screen it was typed on. */
|
|
9
|
+
message: string;
|
|
10
|
+
viaVoice: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* How the change the requests made together is told, as it is saved or
|
|
14
|
+
* reported: their prompts one to a line, and their answers one after another.
|
|
15
|
+
* The oldest requests are left out where all of them would be too long to store.
|
|
16
|
+
*/
|
|
17
|
+
export declare function describePreviewRequests(previewRequests: readonly PreviewRequest[]): {
|
|
18
|
+
prompt: string;
|
|
19
|
+
message: string;
|
|
20
|
+
viaVoice: boolean;
|
|
21
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useLayoutEffect } from "react";
|
|
2
|
+
import type { Layout } from "../core/index.js";
|
|
3
|
+
import { ActionRegistry } from "../actions/actionRegistry.js";
|
|
4
|
+
import { EngineClient, type EngineOptions } from "../engine/engineClient.js";
|
|
5
|
+
import type { FirstPaintOrder } from "./firstPaintOrder.js";
|
|
6
|
+
import { RegionGroup } from "./regionGroup.js";
|
|
7
|
+
import { RegionStore } from "./regionStore.js";
|
|
8
|
+
export declare class RegionStoreRegistry {
|
|
9
|
+
private storesByRegionId;
|
|
10
|
+
private groupsByRegionIds;
|
|
11
|
+
/** Null when the provider was given no engine. */
|
|
12
|
+
readonly engine: EngineClient | null;
|
|
13
|
+
/** The actions offered on the page right now. */
|
|
14
|
+
readonly actions: ActionRegistry;
|
|
15
|
+
private dictationOffered;
|
|
16
|
+
private promptDrafts;
|
|
17
|
+
private draftListeners;
|
|
18
|
+
constructor(engineOptions: EngineOptions | undefined, userId?: string);
|
|
19
|
+
/**
|
|
20
|
+
* Whether the engine can turn speech into text. Asked once for all the
|
|
21
|
+
* regions on a page. A failed request is not remembered, so it is asked again.
|
|
22
|
+
*/
|
|
23
|
+
isDictationOffered(): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* The prompt typed for a set of regions and not sent yet, so it is still
|
|
26
|
+
* there when the user comes back to them, as on returning to a page.
|
|
27
|
+
*/
|
|
28
|
+
draftFor: (regionIdsKey: string) => string;
|
|
29
|
+
keepDraft: (regionIdsKey: string, draftText: string) => void;
|
|
30
|
+
/** Two bars for the same regions show the same draft, so each hears when it changes. */
|
|
31
|
+
subscribeToDrafts: (draftListener: () => void) => (() => void);
|
|
32
|
+
private latestChangeSequence;
|
|
33
|
+
/** Numbers the changes made in any of these regions, so the newest among several can be told. */
|
|
34
|
+
private nextChangeSequence;
|
|
35
|
+
/**
|
|
36
|
+
* Where the latest action run falls among the changes, in the same
|
|
37
|
+
* numbering, or 0 when none has run since the page was loaded.
|
|
38
|
+
*/
|
|
39
|
+
private actionRunSequence;
|
|
40
|
+
private actionRunListeners;
|
|
41
|
+
latestActionRunSequence: () => number;
|
|
42
|
+
/** Notes that an action has just run, after every change made so far. */
|
|
43
|
+
noteActionRun: () => void;
|
|
44
|
+
subscribeToActionRuns: (actionRunListener: () => void) => (() => void);
|
|
45
|
+
/**
|
|
46
|
+
* Stops every store trying the engine again in the background, to save
|
|
47
|
+
* changes or read saved layouts, for when the provider unmounts.
|
|
48
|
+
*/
|
|
49
|
+
dispose: () => void;
|
|
50
|
+
/** Lets the stores try the engine again in the background, as when React mounts the provider once more. */
|
|
51
|
+
resume: () => void;
|
|
52
|
+
storeFor(regionId: string): RegionStore;
|
|
53
|
+
/** The regions one prompt bar speaks for. The same ids in the same order give the same group. */
|
|
54
|
+
groupFor(regionIds: readonly string[]): RegionGroup;
|
|
55
|
+
}
|
|
56
|
+
export declare const RegionStoreRegistryContext: import("react").Context<RegionStoreRegistry | null>;
|
|
57
|
+
/**
|
|
58
|
+
* The id an item's element carries in the page, so the region can name its
|
|
59
|
+
* items to assistive technology in the order they are shown. `regionTag` is
|
|
60
|
+
* the region's own `useId`, which keeps the id from matching one the host
|
|
61
|
+
* application uses, or one in another region. Ids in a list of references are
|
|
62
|
+
* separated by spaces, so anything but letters, digits and `-` is written as
|
|
63
|
+
* its character code between two `_`.
|
|
64
|
+
*/
|
|
65
|
+
export declare function itemElementId(regionTag: string, itemId: string): string;
|
|
66
|
+
export interface RegionContextValue {
|
|
67
|
+
/** Unique to this region on the page, and the same on the server and in the browser. */
|
|
68
|
+
regionTag: string;
|
|
69
|
+
regionStore: RegionStore;
|
|
70
|
+
/** False when the region draws nothing of its own and the page's containers place its items. */
|
|
71
|
+
regionDrawsGrid: boolean;
|
|
72
|
+
/** The columns the layout is kept in. */
|
|
73
|
+
layoutColumns: number;
|
|
74
|
+
/** The columns drawn on this screen, which may be fewer. */
|
|
75
|
+
drawnColumns: number;
|
|
76
|
+
/** Each item's span on this screen when it has fewer columns than the layout, else null. */
|
|
77
|
+
drawnSpans: ReadonlyMap<string, number> | null;
|
|
78
|
+
/** Lets items render the saved layout on the server and on first paint. */
|
|
79
|
+
initialLayout: Layout | undefined;
|
|
80
|
+
/** The order the saved layout gives every component it knows, on screen or off. */
|
|
81
|
+
initialOrder: readonly string[];
|
|
82
|
+
firstPaintOrder: FirstPaintOrder;
|
|
83
|
+
}
|
|
84
|
+
export declare const RegionContext: import("react").Context<RegionContextValue | null>;
|
|
85
|
+
export declare function useRegionStore(regionId: string): RegionStore;
|
|
86
|
+
/** For ClickLess's own prompt UI, which has nothing to show without the provider. */
|
|
87
|
+
export declare function useRegionStoreRegistry(): RegionStoreRegistry;
|
|
88
|
+
/**
|
|
89
|
+
* For what wraps or runs in the application's own components. Outside a
|
|
90
|
+
* provider, as in the application's tests or stories, each caller gets a
|
|
91
|
+
* registry of its own with no engine: a region shows its defaults and keeps
|
|
92
|
+
* changes in memory, `useAdaptiveRegion` reads the region it sits in (or an
|
|
93
|
+
* empty one of its own outside any region), and an action is offered to no one.
|
|
94
|
+
*/
|
|
95
|
+
export declare function useRegionStoreRegistryOrStandIn(): RegionStoreRegistry;
|
|
96
|
+
export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type { Action, ActionCall } from "../core/index.js";
|
|
2
|
+
import { type ConversationTurn, type EngineClient } from "../engine/engineClient.js";
|
|
3
|
+
import type { HistoryPage } from "../engine/engineResponses.js";
|
|
4
|
+
import type { RegionSnapshot } from "./regionSnapshot.js";
|
|
5
|
+
import { type PlannedPreviewOutcome, type RegionStore, type UndoResult } from "./regionStore.js";
|
|
6
|
+
/** What a prompt bar shows of the regions it speaks for. */
|
|
7
|
+
export interface RegionGroupSnapshot {
|
|
8
|
+
/**
|
|
9
|
+
* Each region, in the order they were named. One that is not on the screen
|
|
10
|
+
* has a null manifest, and takes no part in anything until it is.
|
|
11
|
+
*/
|
|
12
|
+
regions: readonly {
|
|
13
|
+
regionId: string;
|
|
14
|
+
snapshot: RegionSnapshot;
|
|
15
|
+
}[];
|
|
16
|
+
/** True while a proposed change is on the screen, waiting to be kept or discarded. */
|
|
17
|
+
previewing: boolean;
|
|
18
|
+
canUndo: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The order of the newest change on the screen an undo would take back,
|
|
21
|
+
* among the changes and action runs since the page was loaded, or 0 when it
|
|
22
|
+
* was made before then. See `RegionStoreRegistry.latestActionRunSequence`.
|
|
23
|
+
*/
|
|
24
|
+
newestChangeSequence: number;
|
|
25
|
+
/** True while the regions show how they first looked, in place of their layouts. */
|
|
26
|
+
showingOriginal: boolean;
|
|
27
|
+
/** True when any region on the screen differs from how it first looked. */
|
|
28
|
+
differsFromOriginal: boolean;
|
|
29
|
+
/** True while any region's saved layout is being fetched. */
|
|
30
|
+
loading: boolean;
|
|
31
|
+
/** True when any region's saved layout could not be fetched. */
|
|
32
|
+
loadFailed: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Which point in the history the screen is at, in the same numbering as
|
|
35
|
+
* `HistoryEntry.revision`: for one region, that region's revision; for
|
|
36
|
+
* several, the latest change's own number (its `changeId`), which the
|
|
37
|
+
* engine counts across regions.
|
|
38
|
+
*/
|
|
39
|
+
revision: number;
|
|
40
|
+
hasHistory: boolean;
|
|
41
|
+
/** True while any region shows a change of the application's own that is not saved yet. */
|
|
42
|
+
hasUnsavedChanges: boolean;
|
|
43
|
+
}
|
|
44
|
+
/** What a prompt is planned with besides the regions: what the screen can do, and what was said before. */
|
|
45
|
+
export interface PlanContext {
|
|
46
|
+
actions: readonly Action[];
|
|
47
|
+
conversation: readonly ConversationTurn[];
|
|
48
|
+
/** Files the user attached: their names and types only. */
|
|
49
|
+
attachedFiles: readonly {
|
|
50
|
+
name: string;
|
|
51
|
+
type: string;
|
|
52
|
+
}[];
|
|
53
|
+
/** What a missed request is recorded under when no region is on the screen. */
|
|
54
|
+
screenId: string;
|
|
55
|
+
}
|
|
56
|
+
/** What a prompt bar's request came to: the answer for the user, the actions to run, and what became of the preview. */
|
|
57
|
+
export interface PlannedRequest {
|
|
58
|
+
message: string;
|
|
59
|
+
actionCalls: ActionCall[];
|
|
60
|
+
previewOutcome: PlannedPreviewOutcome;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The regions one prompt bar speaks for, such as a page and the sidebar beside
|
|
64
|
+
* it. A prompt is planned for all of them in one request, and what it changes
|
|
65
|
+
* is previewed, kept, discarded and undone in all of them together, while each
|
|
66
|
+
* region's layout is still stored on its own.
|
|
67
|
+
*
|
|
68
|
+
* A group of one is that region and nothing more: everything is passed
|
|
69
|
+
* straight to its store.
|
|
70
|
+
*/
|
|
71
|
+
export declare class RegionGroup {
|
|
72
|
+
private readonly regionStores;
|
|
73
|
+
private readonly engine;
|
|
74
|
+
private readonly singleRegionStore;
|
|
75
|
+
private pendingPreview;
|
|
76
|
+
/** The last preview saved, so an answer planned from it is shown on the layouts it became. */
|
|
77
|
+
private lastSavedPreview;
|
|
78
|
+
private commitInProgress;
|
|
79
|
+
private snapshotListeners;
|
|
80
|
+
private stopListeningToStores;
|
|
81
|
+
private cachedSnapshot;
|
|
82
|
+
private cachedSnapshotInputs;
|
|
83
|
+
private serverSnapshot;
|
|
84
|
+
constructor(regionStores: readonly RegionStore[], engine: EngineClient | null);
|
|
85
|
+
subscribe: (snapshotListener: () => void) => (() => void);
|
|
86
|
+
/**
|
|
87
|
+
* Stops listening to the regions once nothing listens here. While a preview
|
|
88
|
+
* waits it goes on listening, though the prompt bar may be gone, as one in a
|
|
89
|
+
* closed sheet is: if a region then drops its part, as on leaving the page,
|
|
90
|
+
* the preview is still reported as abandoned.
|
|
91
|
+
*/
|
|
92
|
+
private stopListeningIfUnwatched;
|
|
93
|
+
getSnapshot: () => RegionGroupSnapshot;
|
|
94
|
+
getServerSnapshot: () => RegionGroupSnapshot;
|
|
95
|
+
/**
|
|
96
|
+
* Asks the engine to turn a request into operations and previews them, in
|
|
97
|
+
* every region they are for. As for one region, a request made while a
|
|
98
|
+
* preview is showing is planned from it, region by region, and its answer
|
|
99
|
+
* is added to it; one made with none showing replaces any that appears
|
|
100
|
+
* meanwhile, as if discarded.
|
|
101
|
+
*/
|
|
102
|
+
planFromPrompt: (prompt: string, viaVoice?: boolean, planContext?: PlanContext) => Promise<PlannedRequest>;
|
|
103
|
+
/** Previews the operations, in every region they are for, or none of them if any no longer fits. */
|
|
104
|
+
private showNewPreview;
|
|
105
|
+
/**
|
|
106
|
+
* Adds a follow-up's operations to the preview it was planned from: each
|
|
107
|
+
* region's after its part of the preview, in a region the preview had not
|
|
108
|
+
* changed as its first part. Nothing changes if any region no longer fits.
|
|
109
|
+
* A follow-up that takes the whole preview back leaves nothing to keep, so
|
|
110
|
+
* the preview counts as discarded.
|
|
111
|
+
*/
|
|
112
|
+
private addToPreview;
|
|
113
|
+
/**
|
|
114
|
+
* Sends a plan request made from `preview`. When the engine says the preview
|
|
115
|
+
* no longer applies to the saved layouts it was made on, it can never be
|
|
116
|
+
* saved, so it is taken off, as one that left the screen.
|
|
117
|
+
*/
|
|
118
|
+
private answeringForPreview;
|
|
119
|
+
/**
|
|
120
|
+
* Saves the preview: every region's part, or none. Resolves to null when
|
|
121
|
+
* there is no preview. One that no longer fits is taken off the screen.
|
|
122
|
+
*/
|
|
123
|
+
commitPreview: () => Promise<{
|
|
124
|
+
applied: boolean;
|
|
125
|
+
} | null>;
|
|
126
|
+
/** Takes the preview off the screen, in every region, without saving it. */
|
|
127
|
+
cancelPreview: () => void;
|
|
128
|
+
/** `cancelPreview`, for when the user chose not to keep it. The engine is told, once. */
|
|
129
|
+
discardPreview: () => void;
|
|
130
|
+
/**
|
|
131
|
+
* `cancelPreview`, for when the preview leaves the screen before the user
|
|
132
|
+
* chose, because a region it changed dropped its part. The engine is told, once.
|
|
133
|
+
*/
|
|
134
|
+
private abandonPreview;
|
|
135
|
+
/** Record-keeping only: the user is never made to wait on it or told it failed. One being saved is not reported. */
|
|
136
|
+
private reportPreviewNotKept;
|
|
137
|
+
/**
|
|
138
|
+
* Takes back the latest change among the regions on the screen, in each of
|
|
139
|
+
* them it reached, on the screen or not: a prompt that changed two is undone
|
|
140
|
+
* in both. The result says when part of it stays in place elsewhere.
|
|
141
|
+
*/
|
|
142
|
+
undoLastChange: () => Promise<UndoResult>;
|
|
143
|
+
/**
|
|
144
|
+
* Shows every region as it first looked, before any change, without saving
|
|
145
|
+
* anything, or goes back to their layouts. A preview, or any change, ends it.
|
|
146
|
+
*/
|
|
147
|
+
showOriginal: (shown: boolean) => void;
|
|
148
|
+
/**
|
|
149
|
+
* Returns the screen to how it was after the given saved change; 0 is as it
|
|
150
|
+
* was before any. Resolves to the number of the latest saved change afterwards.
|
|
151
|
+
*/
|
|
152
|
+
restoreRevision: (revision: number) => Promise<number>;
|
|
153
|
+
/** Saved changes, newest first. For several regions each entry is one change, whichever regions it reached. */
|
|
154
|
+
readHistory: (options: {
|
|
155
|
+
limit: number;
|
|
156
|
+
before?: number;
|
|
157
|
+
promptedOnly?: boolean;
|
|
158
|
+
}) => Promise<HistoryPage>;
|
|
159
|
+
private savePreview;
|
|
160
|
+
/**
|
|
161
|
+
* Shows what the engine answered, in each of `regionStores` whose layout it
|
|
162
|
+
* changed, with the operations that changed it. Every other region, one off
|
|
163
|
+
* the screen as well, gives way to it, unless it is an undo, which is no new
|
|
164
|
+
* change. A preview no longer describes the screen.
|
|
165
|
+
*/
|
|
166
|
+
private acceptAnswer;
|
|
167
|
+
/** `regionStores` and every other region of the group holding changes not saved yet, which go first. */
|
|
168
|
+
private withUnsavedChanges;
|
|
169
|
+
/**
|
|
170
|
+
* When the engine says a region changed elsewhere, nothing was saved in any
|
|
171
|
+
* of them. The ones it names are fetched again before failing, which takes
|
|
172
|
+
* the preview off the screen.
|
|
173
|
+
*/
|
|
174
|
+
private reloadingOnConflict;
|
|
175
|
+
/**
|
|
176
|
+
* Waits its turn in every one of the regions, so a change to several does
|
|
177
|
+
* not cross one made to any of them alone. Turns are always taken in the
|
|
178
|
+
* same order, so two groups that share regions cannot wait on each other.
|
|
179
|
+
* `writeChange` is given the change's `sequence`, taken once the first turn has
|
|
180
|
+
* begun: a change made in any of the regions while it waits for the others
|
|
181
|
+
* is newer than it.
|
|
182
|
+
*/
|
|
183
|
+
private oneWriteAtATime;
|
|
184
|
+
private storesOnScreen;
|
|
185
|
+
private onStoreChange;
|
|
186
|
+
private isStillShowing;
|
|
187
|
+
private notifyListeners;
|
|
188
|
+
private computeSnapshot;
|
|
189
|
+
}
|