@embedpdf/core-ui 3.0.0-next.14 → 3.0.0-next.16

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,19 +1,21 @@
1
1
  //#region src/schema.d.ts
2
2
  /**
3
- * @embedpdf/core-ui — the structure-only schema vocabulary.
3
+ * @embedpdf/core-ui — the structure-only bar vocabulary.
4
4
  *
5
- * The schema contains ONLY what a designer decides and the runtime cannot
5
+ * A bar contains only what a designer decides and the runtime cannot
6
6
  * compute: order, grouping, importance, and each item's degradation ladder.
7
- * Everything the runtime CAN compute is banned from it by construction:
7
+ * Everything the runtime can compute is banned from it by construction:
8
8
  * no breakpoints, no show/hide lists, no locale overrides, no dividers, no
9
9
  * spacers, no hand-written overflow menus. Fit is measured and solved at
10
10
  * runtime (see solver.ts); the overflow menu is derived (see projection.ts).
11
+ * Where bars go, and the menus and panels around them, is the viewer's
12
+ * layout (see layout.ts).
11
13
  */
12
14
  /** Presentation ladder for a command button, richest first. */
13
15
  type Variant = 'icon+label' | 'icon' | 'label';
14
16
  /**
15
17
  * Who yields space first. 1 = first to degrade/overflow · 3 = default ·
16
- * 5 = pinned: may still degrade variants, but NEVER leaves the bar.
18
+ * 5 = pinned: may still degrade variants, but never leaves the bar.
17
19
  */
18
20
  type Importance = 1 | 2 | 3 | 4 | 5;
19
21
  declare const PINNED: Importance;
@@ -26,16 +28,17 @@ interface BarItem {
26
28
  }
27
29
  /**
28
30
  * An app-rendered slot (e.g. the inline zoom strip). Each named variant is
29
- * measured like any command button. The ladder MUST terminate in a command
30
- * (`terminal`) so the item always has a menu form when it overflows — this
31
- * is what makes the overflow projection total.
31
+ * measured like any command button. Its `terminal` command is its menu form,
32
+ * what it becomes when it overflows; an item without one never leaves the bar
33
+ * (it is pinned, and so is its group), which keeps the overflow projection
34
+ * total.
32
35
  */
33
36
  interface CustomItem {
34
37
  readonly slot: string;
35
38
  /** Named presentation variants, richest first. Default: ['default']. */
36
39
  readonly variants?: readonly string[];
37
40
  /** The command that stands in for this slot in menus (its last resort). */
38
- readonly terminal: string;
41
+ readonly terminal?: string;
39
42
  readonly importance?: Importance;
40
43
  }
41
44
  type BarChild = BarItem | CustomItem | string;
@@ -46,22 +49,27 @@ interface BarGroup {
46
49
  /** Presentation hint: 'tabs' renders as a tab strip and projects as radio rows. */
47
50
  readonly role?: 'buttons' | 'tabs';
48
51
  /**
49
- * Stage 1 of the GROUP degradation ladder: under pressure, move trailing
50
- * children (rightmost first, at the CHILD's importance) into a derived
52
+ * Stage 1 of the group degradation ladder: under pressure, move trailing
53
+ * children (rightmost first, at the child's importance) into a derived
51
54
  * group-local disclosure — a trigger rendered inside the group opening a
52
55
  * menu of the hidden children. Never sheds the last visible child: below
53
- * that floor the group `collapse`s (stage 2) or overflows whole. This is
54
- * v2's `overflow-tabs-button`, computed instead of authored.
56
+ * that floor the group `collapse`s (stage 2) or overflows whole. The
57
+ * disclosure is computed, never authored.
55
58
  */
56
59
  readonly shed?: boolean;
57
60
  /**
58
- * Stage 2: what the WHOLE group degrades to once its children have
61
+ * Stage 2: what the whole group degrades to once its children have
59
62
  * exhausted their ladders (and shedding, if enabled, has hit its floor): a
60
63
  * single menu button or a select-style picker. Groups with neither `shed`
61
64
  * nor `collapse` send children to the global overflow menu one by one.
62
65
  */
63
66
  readonly collapse?: 'menu' | 'select';
64
67
  readonly importance?: Importance;
68
+ /**
69
+ * Shows only while something that isn't dependent shows in the same bar, like undo and redo
70
+ * beside a mode's tools: a bar with only dependent groups left shows nothing.
71
+ */
72
+ readonly dependent?: boolean;
65
73
  readonly items: readonly BarChild[];
66
74
  }
67
75
  /**
@@ -69,11 +77,11 @@ interface BarGroup {
69
77
  * within a section — never across sections, never from schema data.
70
78
  *
71
79
  * The names are direction-aware (RTL flips start/end) and `center` is a
72
- * SOFT contract: "balance this segment in the space left over by start and
80
+ * soft contract: "balance this segment in the space left over by start and
73
81
  * end". With symmetric flanks that coincides with true centering; with a
74
82
  * heavy flank the segment drifts rather than fights — segments never
75
- * overlap, matching how every toolbar convention (including v2's
76
- * spacer-flanked tabs) treats its middle region. Strict geometric centering
83
+ * overlap, matching how every toolbar convention (including spacer-flanked
84
+ * tabs) treats its middle region. Strict geometric centering
77
85
  * would be a solver concern (a tighter budget: 2×max(start,end)+center),
78
86
  * deliberately not offered until a product needs it.
79
87
  */
@@ -86,57 +94,16 @@ interface BarSchema {
86
94
  readonly id: string;
87
95
  readonly sections: BarSections;
88
96
  }
89
- /** A run of command rows; separators derive between sections. */
90
- interface MenuSection {
91
- /** Optional section heading (i18n key). */
92
- readonly labelKey?: string;
93
- readonly items: readonly string[];
94
- }
95
- interface MenuSchema {
96
- readonly id: string;
97
- readonly sections: readonly MenuSection[];
98
- }
99
- /**
100
- * The shell FRAME — region arrangement and visibility. Regions are a FIXED
101
- * vocabulary (each carries semantics the shell must own: the toolbar's
102
- * measurement physics, the document gate, aria landmarks); what's YOURS is
103
- * where they sit, whether they show, and — through the region slots — what
104
- * fills them. Part of the chrome value because it is structure: owned, never
105
- * merged. Free-form layout is deliberately not offered — wanting a different
106
- * frame architecture is what headless is for.
107
- */
108
- interface FrameSchema {
109
- /** Where the main bar lives. Its mode band rides the CONTENT side (below a
110
- * top bar, above a bottom bar). Default: 'top'. */
111
- readonly toolbar?: 'top' | 'bottom';
112
- /** Document tab strip: 'multiple' shows it only with >1 tab. A hidden
113
- * region hides its SLOT too — visibility outranks slotted content.
114
- * Default: 'always'. */
115
- readonly tabs?: 'always' | 'multiple' | 'never';
116
- /** The header row — a socket only: the chrome ships no header of its own,
117
- * so it renders nothing until a `slot="header"` child fills it. `false`
118
- * removes the socket, keeping a slotted header out. Default: true. */
119
- readonly header?: boolean;
120
- }
121
- interface ChromeSchema {
122
- /** Standalone bars (e.g. the main toolbar). */
123
- readonly bars: Readonly<Record<string, BarSchema>>;
124
- /** Secondary bars keyed by tool mode — WHICH one shows is derived from the
125
- * interaction hub's active tool, never stored. */
126
- readonly modeBars?: Readonly<Record<string, BarSchema>>;
127
- /** Named dropdown menus referenced by commands' `menu:` targets. */
128
- readonly menus?: Readonly<Record<string, MenuSchema>>;
129
- /** Contextual strips (selection menus) — same BarSchema, same fit engine. */
130
- readonly strips?: Readonly<Record<string, BarSchema>>;
131
- /** Region arrangement & visibility. Omitted = the default frame. */
132
- readonly frame?: FrameSchema;
133
- }
134
- declare function item(command: string, opts?: Omit<BarItem, 'command'>): BarItem;
135
- declare function custom(slot: string, opts: Omit<CustomItem, 'slot'>): CustomItem;
136
- declare function group(id: string, items: readonly BarChild[]): BarGroup;
137
- declare function group(id: string, opts: Omit<BarGroup, 'id' | 'items'> & {
138
- items?: readonly BarChild[];
139
- }, items?: readonly BarChild[]): BarGroup;
97
+ /** A command button: `item('zoom:in', { variants: ['icon+label', 'icon'] })`. */
98
+ declare function item(command: string, options?: Omit<BarItem, 'command'>): BarItem;
99
+ /**
100
+ * An item you draw yourself, by its slot name, and the command it becomes in the "More" menu:
101
+ * `custom('page-number', 'page:go-to', { variants: ['full', 'compact'] })`. Without a command,
102
+ * the item never leaves the bar.
103
+ */
104
+ declare function custom(slot: string, terminal?: string, options?: Omit<CustomItem, 'slot' | 'terminal'>): CustomItem;
105
+ /** A group of items, with a separator between groups: `group('zoom', ['zoom:out', 'zoom:in'])`. */
106
+ declare function group(id: string, items: readonly BarChild[], options?: Omit<BarGroup, 'id' | 'items'>): BarGroup;
140
107
  type NormalizedUnit = {
141
108
  readonly kind: 'command';
142
109
  /** Unique within the bar: `${groupId}:${command}`. Measurement + assignment key. */
@@ -149,7 +116,11 @@ type NormalizedUnit = {
149
116
  readonly key: string;
150
117
  readonly slot: string;
151
118
  readonly variants: readonly string[];
152
- readonly terminal: string;
119
+ /**
120
+ * The command it becomes in menus, or null for an item without one, which
121
+ * {@link filterBar} keeps, pinned.
122
+ */
123
+ readonly terminal: string | null;
153
124
  readonly importance: Importance;
154
125
  };
155
126
  interface NormalizedGroup {
@@ -159,6 +130,8 @@ interface NormalizedGroup {
159
130
  readonly shed: boolean;
160
131
  readonly collapse?: 'menu' | 'select';
161
132
  readonly importance: Importance;
133
+ /** See {@link BarGroup.dependent}; the rule is {@link hasVisibleUnits}. */
134
+ readonly dependent: boolean;
162
135
  readonly units: readonly NormalizedUnit[];
163
136
  }
164
137
  interface NormalizedSection {
@@ -170,76 +143,396 @@ interface NormalizedBar {
170
143
  readonly sections: readonly NormalizedSection[];
171
144
  }
172
145
  declare const DEFAULT_IMPORTANCE: Importance;
173
- /** Resolve shorthands + defaults; validate uniqueness. Solver/projection input. */
146
+ /** Whether a unit is a custom item with no command to become in menus: it never leaves the bar. */
147
+ declare const isStandaloneUnit: (unit: NormalizedUnit) => boolean;
148
+ /** The command a unit runs: its own, or a custom item's `terminal`; null for a standalone item. */
149
+ declare const commandOfUnit: (unit: NormalizedUnit) => string | null;
150
+ /**
151
+ * Resolve shorthands + defaults; validate uniqueness. Solver/projection input.
152
+ * A group holding a custom item without a command is pinned with it: it never
153
+ * collapses or overflows whole, so the item stays in the bar.
154
+ */
174
155
  declare function normalizeBar(bar: BarSchema): NormalizedBar;
175
156
  /**
176
157
  * Drop units whose command is currently invisible (permissions, disabled
177
- * categories, contextual visibility) BEFORE solving — an invisible unit must
158
+ * categories, contextual visibility) before solving — an invisible unit must
178
159
  * not consume budget or appear in the overflow. Groups that empty out vanish
179
- * naturally in the solver's separator math and in the projection.
160
+ * naturally in the solver's separator math and in the projection. A custom
161
+ * item without a command has nothing to ask `keep` about, and stays. A bar
162
+ * that shows nothing ({@link hasVisibleUnits}) keeps no unit at all, so its
163
+ * dependent groups go too.
180
164
  */
181
165
  declare function filterBar(bar: NormalizedBar, keep: (unit: NormalizedUnit) => boolean): NormalizedBar;
182
166
  /**
183
- * Identity + validation. Checks what is checkable without a command registry:
184
- * bars normalize cleanly, and every `menu` a strip/bar could reference exists
185
- * is left to `validateChrome` (which also takes the known command ids).
167
+ * Whether the bar shows anything once `keep` (as for {@link filterBar}) has had its say: a unit
168
+ * left in a group that isn't dependent. Dependent groups show only beside one, so a bar with
169
+ * only dependent groups left shows nothing.
186
170
  */
187
- declare function defineChrome<T extends ChromeSchema>(chrome: T): T;
188
- /** Dev-time cross-check: every command referenced by the chrome exists. */
189
- declare function validateChrome(chrome: ChromeSchema, knownCommands: ReadonlySet<string>): string[];
171
+ declare function hasVisibleUnits(bar: NormalizedBar, keep: (unit: NormalizedUnit) => boolean): boolean;
190
172
  //#endregion
191
- //#region src/transforms.d.ts
192
- interface AddItemSpec {
193
- /** Bar id ('main', 'annotate', …) or a modeBars surface key ('mode:annotate'). */
194
- readonly bar: string;
195
- readonly section: keyof BarSections;
196
- /** Target group id. Unknown in the bar → a new group is created at the end
197
- * of `section`; known but in a DIFFERENT section → error (group ids are
198
- * bar-unique, so that is a contradiction, not a request). */
199
- readonly group: string;
200
- readonly item: BarChild;
201
- /** Insert position within the group. Default: append. */
202
- readonly at?: number;
203
- }
204
- /** Insert `spec.item` into a group of one bar. See AddItemSpec for semantics. */
205
- declare function addItem(schema: ChromeSchema, spec: AddItemSpec): ChromeSchema;
206
- /**
207
- * Purge commands (or custom slots, by slot name) from every bar, mode bar,
208
- * strip, and menu. Groups and menu sections that empty out are dropped;
209
- * emptied menus keep their key (commands may still target them) with no rows.
210
- */
211
- declare function removeItems(schema: ChromeSchema, ids: readonly string[]): ChromeSchema;
212
- /**
213
- * Swap a command in place everywhere it appears — bars, mode bars, strips,
214
- * and (when the replacement is itself a plain command) menu rows.
215
- */
216
- declare function replaceItem(schema: ChromeSchema, id: string, item: BarChild): ChromeSchema;
217
- //#endregion
218
- //#region src/helpers.d.ts
219
- declare const chromeHelpers: {
220
- readonly addItem: typeof addItem;
221
- readonly removeItems: typeof removeItems;
222
- readonly replaceItem: typeof replaceItem;
223
- readonly item: typeof item;
224
- readonly group: typeof group;
225
- readonly custom: typeof custom;
226
- readonly defineChrome: typeof defineChrome;
173
+ //#region src/layout.d.ts
174
+ /** An edge of the viewer. `start` and `end` follow the language: left and right, swapped in a right-to-left one. */
175
+ type BarEdge = 'top' | 'bottom' | 'start' | 'end';
176
+ /** Where a floating bar sits over the pages. */
177
+ type FloatPosition = 'top-start' | 'top' | 'top-end' | 'start' | 'end' | 'bottom-start' | 'bottom' | 'bottom-end';
178
+ /** What a bar over a selection follows: selected text, or selected annotations. */
179
+ type SelectionTarget = 'selection' | 'annotation';
180
+ /**
181
+ * Where a bar goes: along an edge, floating over the pages, along another bar on the side of the
182
+ * pages, or over what's selected. Bars on one edge stack from the outside in, in the order they
183
+ * were added; `before` and `after` put a bar next to another bar on that edge.
184
+ */
185
+ type BarPlace = BarEdge | {
186
+ readonly edge: BarEdge;
187
+ readonly before?: string;
188
+ readonly after?: string;
189
+ } | {
190
+ readonly float: FloatPosition;
191
+ } | {
192
+ readonly with: string;
193
+ } | {
194
+ readonly at: SelectionTarget;
227
195
  };
228
- type ChromeHelpers = typeof chromeHelpers;
196
+ /** A command with options. */
197
+ interface LayoutCommandItem {
198
+ readonly command: string;
199
+ /** How it may show, richest first. Default `['icon']`. */
200
+ readonly variants?: readonly Variant[];
201
+ /** Who makes room first: `1` to `5` (never leaves the bar). Default `3`. */
202
+ readonly importance?: Importance;
203
+ }
204
+ /** Your own component, by its id. `command` is what it becomes in the "More" menu; without one, it never leaves the bar. */
205
+ interface LayoutCustomItem {
206
+ readonly custom: string;
207
+ readonly command?: string;
208
+ /** Your component's forms, largest first. Default `['default']`. */
209
+ readonly variants?: readonly string[];
210
+ readonly importance?: Importance;
211
+ }
212
+ /** A command id, a command with options, or your own component. */
213
+ type LayoutItem = string | LayoutCommandItem | LayoutCustomItem;
214
+ /** A group that needs a name or options. */
215
+ interface LayoutGroupObject {
216
+ /** Its name, so `add(item, { group })` can find it. */
217
+ readonly id?: string;
218
+ readonly items: readonly LayoutItem[];
219
+ /** Fold into one button with a menu (`'menu'`) or a dropdown (`'select'`) when there's no room. */
220
+ readonly collapse?: 'menu' | 'select';
221
+ /** Move items behind a button inside the group before the group folds or leaves the bar. */
222
+ readonly shed?: boolean;
223
+ /** Who makes room first: `1` to `5`. Default `3`. */
224
+ readonly importance?: Importance;
225
+ /** Its title in the "More" menu, as a translation key. */
226
+ readonly titleKey?: string;
227
+ /**
228
+ * Show only while something in the bar that isn't dependent shows, like undo and redo beside a
229
+ * mode's tools. A bar with only dependent groups left is empty, and a mode's tab goes with it.
230
+ */
231
+ readonly dependent?: boolean;
232
+ }
233
+ /** A group of items, with a line between groups: an array, or an object when it needs a name or options. */
234
+ type LayoutGroup = readonly LayoutItem[] | LayoutGroupObject;
235
+ /** A section of a bar: its groups in order. A lone item is a group of one. */
236
+ type LayoutSection = readonly (LayoutGroup | LayoutItem)[];
237
+ /** A bar's sections: `start` (left), `center` and `end` (right); `start` and `end` swap in a right-to-left language. */
238
+ type SectionName = 'start' | 'center' | 'end';
239
+ interface LayoutBar {
240
+ readonly place: BarPlace;
241
+ /** Shown in this mode only. The mode gets a tab, titled by the bar's title, and a `mode:<mode>` command. */
242
+ readonly mode?: string;
243
+ readonly title?: string;
244
+ /** The title as a translation key. */
245
+ readonly titleKey?: string;
246
+ readonly start?: LayoutSection;
247
+ readonly center?: LayoutSection;
248
+ readonly end?: LayoutSection;
249
+ }
250
+ /** A section of a menu: an array of command ids, or an object when it has a title. */
251
+ type LayoutMenuSection = readonly string[] | {
252
+ readonly title?: string;
253
+ /** The title as a translation key. */
254
+ readonly titleKey?: string;
255
+ readonly items: readonly string[];
256
+ };
257
+ /** A menu: its sections, with a line between them. */
258
+ type LayoutMenu = readonly LayoutMenuSection[];
259
+ /** How a panel opens: beside the pages, over them, or up from the bottom. */
260
+ type PanelPresentation = 'dock' | 'overlay' | 'sheet';
261
+ /** How a panel opens at each of the viewer's sizes. A size left out opens the default way. */
262
+ interface PanelPresentationBySize {
263
+ readonly compact?: PanelPresentation;
264
+ readonly medium?: PanelPresentation;
265
+ readonly expanded?: PanelPresentation;
266
+ }
267
+ /** A panel's width: the one it starts at, and the narrowest and widest it can be dragged to. */
268
+ interface PanelWidth {
269
+ /** In px. Default `288`. */
270
+ readonly initial?: number;
271
+ /** In px. Default `200`. */
272
+ readonly min?: number;
273
+ /** In px. Default `640`. A docked panel never takes more than half the viewer. */
274
+ readonly max?: number;
275
+ }
276
+ interface LayoutPanel {
277
+ /** Default `'end'`. */
278
+ readonly side?: 'start' | 'end';
279
+ readonly title?: string;
280
+ /** The title as a translation key. */
281
+ readonly titleKey?: string;
282
+ /** Its button's icon. */
283
+ readonly icon?: string;
284
+ /**
285
+ * How it opens: the same way at every size, or per size. Default
286
+ * `{ compact: 'sheet', medium: 'overlay', expanded: 'dock' }`.
287
+ */
288
+ readonly present?: PanelPresentation | PanelPresentationBySize;
289
+ /** Its width in px (where it starts), or where it starts and how far it drags. Default `288`. */
290
+ readonly width?: number | PanelWidth;
291
+ /** Whether people can drag its edge to change its width. Default `true`. */
292
+ readonly resizable?: boolean;
293
+ }
294
+ /**
295
+ * Changes to a panel: the fields to set. `present` and `width` change only what they name: a
296
+ * map of sizes keeps the other sizes, and a number or `{ initial }` keeps `min` and `max`.
297
+ */
298
+ type LayoutPanelPatch = Partial<LayoutPanel>;
299
+ /** When the document tabs show: always, while more than one document is open, or never. */
300
+ type TabsVisibility = 'always' | 'multiple' | 'never';
301
+ /** A layout as plain data: bars, menus and panels, each by id. */
302
+ interface LayoutData {
303
+ readonly bars?: Readonly<Record<string, LayoutBar>>;
304
+ readonly menus?: Readonly<Record<string, LayoutMenu>>;
305
+ readonly panels?: Readonly<Record<string, LayoutPanel>>;
306
+ readonly tabs?: TabsVisibility;
307
+ }
308
+ /** Where {@link Layout.add} puts an item. */
309
+ interface AddItemOptions {
310
+ /** The bar or menu. A bar wins over a menu with the same id. */
311
+ readonly to: string;
312
+ /** The bar's section for a new group. Default `'end'`. */
313
+ readonly section?: SectionName;
314
+ /** The group to join, by id; a new id starts a new group at the end of the section. */
315
+ readonly group?: string;
316
+ /** An item to put it before, in that item's group. */
317
+ readonly before?: string;
318
+ /** An item to put it after, in that item's group. */
319
+ readonly after?: string;
320
+ }
321
+ /** Where {@link Layout.remove} takes items from. */
322
+ interface RemoveItemOptions {
323
+ /** The bar or menu: always one place. To leave something out everywhere, turn it off instead. */
324
+ readonly from: string;
325
+ }
326
+ /**
327
+ * A layout: its data and the edits. Every edit returns a new layout and leaves this one as it
328
+ * was; an edit that names an id the layout doesn't have changes nothing and records a warning.
329
+ */
330
+ interface Layout {
331
+ /** Move a bar. */
332
+ place(bar: string, place: BarPlace): Layout;
333
+ /** Add a bar, or replace the bar with that id. */
334
+ addBar(id: string, bar: LayoutBar): Layout;
335
+ /** Remove a bar. Removing a mode's bar removes its tab. */
336
+ removeBar(id: string): Layout;
337
+ /** Put an item in a bar or a menu: at the end of a section, in a group, or next to an item. */
338
+ add(item: LayoutItem, options: AddItemOptions): Layout;
339
+ /** Take items out of one bar or menu; a group or section with nothing left goes with them. */
340
+ remove(ids: string | readonly string[], options: RemoveItemOptions): Layout;
341
+ /** Put another item in an item's place, in every bar and menu. */
342
+ replace(id: string, item: LayoutItem): Layout;
343
+ /** Add a menu, or replace the menu with that id. */
344
+ addMenu(id: string, sections: LayoutMenu): Layout;
345
+ /** Add a panel, or replace the panel with that id. */
346
+ addPanel(id: string, panel: LayoutPanel): Layout;
347
+ /** Change a panel's fields. */
348
+ panel(id: string, changes: LayoutPanelPatch): Layout;
349
+ /**
350
+ * Change every panel's fields, as `panel(id, changes)` changes one: every panel the layout has
351
+ * so far, so a panel added after it keeps its own.
352
+ */
353
+ panels(changes: LayoutPanelPatch): Layout;
354
+ /** Remove a panel, and its `panel:<id>` button from every bar and menu. */
355
+ removePanel(id: string): Layout;
356
+ /** When the document tabs show. */
357
+ tabs(visibility: TabsVisibility): Layout;
358
+ /** The layout as plain data. */
359
+ toJSON(): LayoutData;
360
+ }
361
+ /** A layout of `data`, which it never changes. */
362
+ declare function createLayout(data?: LayoutData): Layout;
363
+ /** Whether `value` is a layout made by {@link createLayout} or one of its edits. */
364
+ declare function isLayout(value: unknown): value is Layout;
365
+ /** What an item is called in edits: its command id, your component's id, or `''` for a non-item. */
366
+ declare function itemIdOf(item: LayoutItem): string;
367
+ /** The command an item runs or stands for in menus, or `null` for your component without one. */
368
+ declare function itemCommandOf(item: LayoutItem): string | null;
369
+ /** A panel's `present` as a map of sizes: one way at every size, or the sizes it names. */
370
+ declare const panelPresentationsOf: (present: PanelPresentation | PanelPresentationBySize) => PanelPresentationBySize;
371
+ /** A panel's `width` as its fields: a number is where it starts. */
372
+ declare const panelWidthFieldsOf: (width: number | PanelWidth) => PanelWidth;
373
+ /** The viewer's size class, from its own width. */
374
+ type ViewerSize = 'compact' | 'medium' | 'expanded';
375
+ /** What the layout function knows about the viewer, measured on the viewer itself. */
376
+ interface LayoutEnv {
377
+ /** `'compact'` under 600 px, `'medium'` to 1023 px, `'expanded'` from 1024 px. */
378
+ readonly size: ViewerSize;
379
+ /** The viewer's width, in px. */
380
+ readonly width: number;
381
+ /** Whether the main way of pointing is a finger. */
382
+ readonly touch: boolean;
383
+ /** How the user's language reads. */
384
+ readonly dir: 'ltr' | 'rtl';
385
+ }
386
+ /** The narrowest a medium viewer is, in px. */
387
+ declare const MEDIUM_MIN_WIDTH_PX = 600;
388
+ /** The narrowest an expanded viewer is, in px. */
389
+ declare const EXPANDED_MIN_WIDTH_PX = 1024;
390
+ /** The size class of a viewer this wide. */
391
+ declare function sizeOf(widthPx: number): ViewerSize;
392
+ /** Whether two envs are the same: the layout function runs again only when one of the fields changes. */
393
+ declare const sameLayoutEnv: (left: LayoutEnv, right: LayoutEnv) => boolean;
394
+ /** Gets the default layout and the viewer's env, and returns your layout. */
395
+ type LayoutFunction = (layout: Layout, env: LayoutEnv) => Layout | LayoutData;
396
+ /** What the `layout` config takes: a layout, plain layout data, or a function of the default. */
397
+ type LayoutOption = Layout | LayoutData | LayoutFunction;
398
+ /**
399
+ * The layout an option gives at this env: the default without one, the function's result, or
400
+ * the option itself. A function that throws or returns no layout gives the default, with a
401
+ * warning saying so.
402
+ */
403
+ declare function resolveLayout(option: LayoutOption | null | undefined, defaults: Layout, env: LayoutEnv): Layout;
404
+ //#endregion
405
+ //#region src/layout-compile.d.ts
406
+ /** The id of the group that holds the mode tabs. */
407
+ declare const MODES_GROUP = "modes";
408
+ /** The command of the mode with no bar of its own: viewing. */
409
+ declare const VIEW_MODE_COMMAND = "mode:view";
410
+ /** The command that opens a mode, and its tab. */
411
+ declare const modeCommandOf: (mode: string) => string;
412
+ /** The command that opens and closes a panel, and its button. */
413
+ declare const panelCommandOf: (panel: string) => string;
414
+ /** Every place a bar can float over the pages: each corner, and the middle of each side. */
415
+ declare const FLOAT_POSITIONS: readonly FloatPosition[];
416
+ /** The edge a place is on, or `null` for a place that isn't an edge. */
417
+ declare function edgeOf(place: BarPlace | undefined): BarEdge | null;
418
+ /** The bar a place rides along, or `null`. */
419
+ declare function hostOf(place: BarPlace | undefined): string | null;
420
+ /** What a place follows when it is over a selection, or `null`. */
421
+ declare function selectionOf(place: BarPlace | undefined): SelectionTarget | null;
422
+ /** Where a place floats over the pages, or `null` for a place that doesn't float. */
423
+ declare function floatOf(place: BarPlace | undefined): FloatPosition | null;
424
+ /**
425
+ * The bars along an edge, from the outside in: in the order they were added, then each bar
426
+ * with `before` or `after` put next to the bar it names. A bar that names a bar not on this
427
+ * edge goes innermost.
428
+ */
429
+ declare function barsOnEdge(data: LayoutData, edge: BarEdge): string[];
430
+ /** The bars that ride along `host`, in the order they were added, nearest first. */
431
+ declare function barsWith(data: LayoutData, host: string): string[];
432
+ /**
433
+ * Every bar drawn along an edge, from the outside in: each bar on the edge, followed by the bars
434
+ * that ride along it (nearest first) and the bars that ride along those.
435
+ */
436
+ declare function edgeStackOf(data: LayoutData, edge: BarEdge): string[];
437
+ /** The bars floating at `position`, in the order they were added. */
438
+ declare function barsFloating(data: LayoutData, position: FloatPosition): string[];
439
+ /**
440
+ * Every bar drawn floating at `position`, from the viewer's edge in: each bar floating there,
441
+ * followed by the bars that ride along it, as {@link edgeStackOf} orders an edge.
442
+ */
443
+ declare function floatStackOf(data: LayoutData, position: FloatPosition): string[];
444
+ /** The bars over a selection of this kind, in the order they were added. */
445
+ declare function barsAt(data: LayoutData, target: SelectionTarget): string[];
446
+ /** Every mode of the layout's bars, once each, in bar order. */
447
+ declare function modesOf(data: LayoutData): string[];
448
+ /** The bars shown in a mode, in bar order. */
449
+ declare function barsInMode(data: LayoutData, mode: string): string[];
450
+ /** What {@link compileBar} leaves out. */
451
+ interface CompileBarOptions {
452
+ /**
453
+ * Command ids to leave out, as if the bar didn't name them: a mode tab whose bars show nothing,
454
+ * a button whose menu is empty. With every mode tab left out, View goes too.
455
+ */
456
+ readonly omit?: ReadonlySet<string>;
457
+ }
458
+ /**
459
+ * A bar as the toolbar fits it, or `null` for a bar the layout doesn't have. Groups written as
460
+ * arrays and lone items get ids of their own (`start-0`, …); an item twice in one group shows
461
+ * once; a group with nothing left goes.
462
+ */
463
+ declare function compileBar(data: LayoutData, id: string, options?: CompileBarOptions): BarSchema | null;
464
+ /** When the document tabs show: as the layout says, else while more than one document is open. */
465
+ declare function tabsOf(data: LayoutData): TabsVisibility;
466
+ /** A menu section, read: its title and its command ids. */
467
+ interface MenuSection {
468
+ readonly title?: string;
469
+ readonly titleKey?: string;
470
+ readonly items: readonly string[];
471
+ }
472
+ /** A menu's sections, or `null` for a menu the layout doesn't have. An empty section goes. */
473
+ declare function menuOf(data: LayoutData, id: string): readonly MenuSection[] | null;
474
+ /** What {@link omittedCommandsOf} reads of a command; plugin-commands' `ResolvedCommand` satisfies it. */
475
+ interface OmissionCommand {
476
+ readonly visible: boolean;
477
+ readonly menu?: string;
478
+ }
479
+ /**
480
+ * The commands the bars leave out because what they lead to shows nothing: the tab of a mode
481
+ * whose bars have nothing visible ({@link hasVisibleUnits}: dependent groups alone don't count),
482
+ * and a button whose menu has nothing visible (or that the layout has no menu for). Sorted, so
483
+ * two equal results compare equal; pass it to {@link compileBar} as `omit`. Cheap to call on every change: what it reads of the layout is
484
+ * read once per layout data.
485
+ */
486
+ declare function omittedCommandsOf(data: LayoutData, resolve: (id: string) => OmissionCommand | null): string[];
487
+ //#endregion
488
+ //#region src/layout-validate.d.ts
489
+ /** What the viewer has, to check a layout's ids against. */
490
+ interface LayoutKnownIds {
491
+ /**
492
+ * Every command id the viewer has. The ones the layout makes itself need not be listed: the
493
+ * mode tabs (`mode:view`, `mode:<mode>`) and the panel buttons (`panel:<id>`).
494
+ */
495
+ readonly commands: Iterable<string>;
496
+ /** Whether a command id exists that `commands` can't list, such as one of a family's. */
497
+ readonly hasCommand?: (id: string) => boolean;
498
+ }
499
+ /**
500
+ * Every problem with a layout, as sentences: what its edits couldn't do first, then what its
501
+ * data names that the viewer doesn't have. Empty when there is none.
502
+ */
503
+ declare function validateLayout(layout: Layout | LayoutData, known: LayoutKnownIds): string[];
504
+ //#endregion
505
+ //#region src/suggestions.d.ts
506
+ /**
507
+ * "Did you mean …?" for ids: the closest known id to one that doesn't exist,
508
+ * by edit distance, when it is close enough to be a typo.
509
+ */
510
+ /**
511
+ * The number of single-character inserts, deletes, substitutions and swaps of two neighbours
512
+ * that turn `left` into `right`.
513
+ */
514
+ declare function editDistance(left: string, right: string): number;
515
+ /**
516
+ * The candidate closest to `id`, or `null` when none is within a typo's reach: at most a third
517
+ * of the id's length, and never more than 3 edits apart.
518
+ */
519
+ declare function closestMatch(id: string, candidates: Iterable<string>): string | null;
520
+ /** `' (did you mean "x"?)'` for the closest candidate, or `''` when there is none. */
521
+ declare function didYouMean(id: string, candidates: Iterable<string>): string;
229
522
  //#endregion
230
523
  //#region src/solver.d.ts
231
524
  interface FitMetrics {
232
- /** Width of unit `key` rendered at `variant`; undefined = not yet measured. */
525
+ /** Length of unit `key` rendered at `variant`; undefined = not yet measured. */
233
526
  unit(key: string, variant: string): number | undefined;
234
- /** Width of group `id` rendered in its collapsed form ('menu' | 'select'). */
527
+ /** Length of group `id` rendered in its collapsed form ('menu' | 'select'). */
235
528
  groupCollapsed(groupId: string): number | undefined;
236
- /** Width of group `id`'s disclosure trigger (shed groups only). */
529
+ /** Length of group `id`'s disclosure trigger (shed groups only). */
237
530
  groupTrigger(groupId: string): number | undefined;
238
- /** Width of the overflow trigger button. */
531
+ /** Length of the overflow trigger button. */
239
532
  readonly overflowTrigger: number;
240
533
  /** Gap between adjacent visible units. */
241
534
  readonly gap: number;
242
- /** Width of a derived separator between adjacent visible groups (with its gaps). */
535
+ /** Length of a derived separator between adjacent visible groups (with its gaps). */
243
536
  readonly separator: number;
244
537
  }
245
538
  type UnitAssignment = {
@@ -264,12 +557,13 @@ interface FitResult {
264
557
  readonly units: ReadonlyMap<string, UnitAssignment>;
265
558
  readonly groups: ReadonlyMap<string, GroupAssignment>;
266
559
  readonly hasOverflow: boolean;
267
- /** Total visible width at this assignment (diagnostics + tests). */
268
- readonly width: number;
560
+ /** Total visible length at this assignment (diagnostics + tests). */
561
+ readonly length: number;
269
562
  /** False when any consulted measurement was missing (treated as 0). */
270
563
  readonly complete: boolean;
271
564
  }
272
- declare function solve(bar: NormalizedBar, metrics: FitMetrics, containerWidth: number): FitResult;
565
+ /** Fit `bar` into `containerLength`, the room along its axis. */
566
+ declare function solve(bar: NormalizedBar, metrics: FitMetrics, containerLength: number): FitResult;
273
567
  //#endregion
274
568
  //#region src/projection.d.ts
275
569
  type OverflowRow =
@@ -302,8 +596,7 @@ type ResolveMenuTarget = (commandId: string) => {
302
596
  declare function projectOverflow(bar: NormalizedBar, fit: FitResult, resolve: ResolveMenuTarget): OverflowSection[];
303
597
  /**
304
598
  * The content of a group's disclosure trigger: its shed units, in bar order,
305
- * in menu form — same totality rules as the global overflow. This is v2's
306
- * hand-written `mode-tabs-overflow-menu`, derived.
599
+ * in menu form — same totality rules as the global overflow.
307
600
  */
308
601
  declare function projectShed(group: NormalizedGroup, fit: FitResult, resolve: ResolveMenuTarget): OverflowRow[];
309
602
  /** One strip group: a separator boundary, its visible commands in bar order. */
@@ -313,17 +606,188 @@ interface StripGroup {
313
606
  readonly commands: readonly string[];
314
607
  }
315
608
  /**
316
- * Strip projection — a bar projected for UN-measured rendering (a contextual
609
+ * Strip projection — a bar projected for un-measured rendering (a contextual
317
610
  * strip anchored to a selection has no fit pressure to solve). The schema
318
- * declares what COULD appear; `visible` (the command registry's runtime truth)
319
- * decides what DOES: hidden commands drop out, groups that empty out vanish,
320
- * and an all-hidden bar projects to [] — "render nothing" falls out. Custom
611
+ * declares what could appear; `visible` (the command registry's runtime truth)
612
+ * decides what does: hidden commands drop out, groups that empty out vanish,
613
+ * and an all-hidden bar projects to [] — "render nothing" falls out, as it
614
+ * does for a bar with only dependent groups left ({@link filterBar}). Custom
321
615
  * units project through their `terminal` command, same totality rule as the
322
616
  * overflow. Upgrading a strip to measured/overflowing rendering later is a
323
617
  * renderer swap (<Toolbar>), never a schema change.
324
618
  */
325
619
  declare function projectStrip(bar: NormalizedBar, visible: (command: string) => boolean): StripGroup[];
326
620
  //#endregion
621
+ //#region src/toolbar-layout.d.ts
622
+ /** What the layout reads of a resolved command; plugin-commands' `ResolvedCommand` satisfies it. */
623
+ interface ToolbarCommand {
624
+ readonly id: string;
625
+ readonly visible: boolean;
626
+ }
627
+ /** A group folded into one control: a menu button, or a `<select>`. */
628
+ interface CollapsedGroupView<Command extends ToolbarCommand = ToolbarCommand> {
629
+ readonly id: string;
630
+ readonly labelKey?: string;
631
+ readonly collapse: 'menu' | 'select';
632
+ readonly role: 'buttons' | 'tabs';
633
+ /** The group's visible commands (a custom item through its terminal command), resolved live. */
634
+ readonly commands: readonly Command[];
635
+ execute(id: string): void;
636
+ }
637
+ /**
638
+ * The button inside a group that shed some of its items. `commands` is what
639
+ * sits behind it, in bar order, resolved live. In the measurement layer it is
640
+ * measured with the whole group behind it, so a trigger that shows a count
641
+ * ("+3") is budgeted at its widest.
642
+ */
643
+ interface GroupDisclosureView<Command extends ToolbarCommand = ToolbarCommand> {
644
+ readonly id: string;
645
+ readonly labelKey?: string;
646
+ readonly role: 'buttons' | 'tabs';
647
+ readonly commands: readonly Command[];
648
+ execute(id: string): void;
649
+ }
650
+ /** The "More" menu: what didn't fit, in sections, and the calls a menu needs. */
651
+ interface OverflowMenuView<Command extends ToolbarCommand = ToolbarCommand> {
652
+ readonly sections: readonly OverflowSection[];
653
+ readonly isOpen: boolean;
654
+ close(): void;
655
+ /** A row's command, resolved live, or `null` for an unknown id. */
656
+ resolve(id: string): Command | null;
657
+ execute(id: string): void;
658
+ }
659
+ /** What a custom item's renderer receives besides the item's variant. */
660
+ interface CustomSlotCtx {
661
+ /** `'live'` in the visible row, `'measure'` in the hidden measurement layer. */
662
+ layer: 'live' | 'measure';
663
+ /**
664
+ * Report the item's length yourself (its width, or its height in a vertical
665
+ * bar), for content the measurement layer can't hold.
666
+ */
667
+ measure: (length: number) => void;
668
+ }
669
+ /**
670
+ * One thing in the toolbar. `key` is its identity in the live row, the same
671
+ * at every variant; `measureKey` is the key its length is reported under,
672
+ * unique across the whole toolbar. A `custom` part is the app's to draw;
673
+ * without a renderer for it, an adapter draws a native `<slot>` socket
674
+ * measured where it renders, and leaves it out of the measurement layer: only
675
+ * the first `<slot>` of a name gets the projected children.
676
+ */
677
+ type ToolbarPart<Command extends ToolbarCommand = ToolbarCommand> = {
678
+ readonly kind: 'command';
679
+ readonly key: string;
680
+ readonly measureKey: string;
681
+ readonly command: Command;
682
+ readonly variant: string;
683
+ readonly run: () => void;
684
+ } | {
685
+ readonly kind: 'custom';
686
+ readonly key: string;
687
+ readonly measureKey: string;
688
+ /** The item's name, from `custom(name, terminal)`. */
689
+ readonly name: string;
690
+ readonly variant: string;
691
+ /** The command it becomes in the "More" menu; drawn when no renderer draws the item. */
692
+ readonly terminal: Command | null;
693
+ readonly runTerminal: () => void;
694
+ } | {
695
+ readonly kind: 'collapsed';
696
+ readonly key: string;
697
+ readonly measureKey: string;
698
+ readonly view: CollapsedGroupView<Command>;
699
+ } | {
700
+ readonly kind: 'disclosure';
701
+ readonly key: string;
702
+ readonly measureKey: string;
703
+ readonly view: GroupDisclosureView<Command>;
704
+ };
705
+ /** A group in the live row: its visible parts. Every group but a section's first has a separator before it. */
706
+ interface LiveGroup<Command extends ToolbarCommand = ToolbarCommand> {
707
+ readonly id: string;
708
+ readonly parts: readonly ToolbarPart<Command>[];
709
+ }
710
+ /** A section of the live row (`start`, `center` or `end`), with only its visible groups. */
711
+ interface LiveSection<Command extends ToolbarCommand = ToolbarCommand> {
712
+ readonly name: 'start' | 'center' | 'end';
713
+ readonly groups: readonly LiveGroup<Command>[];
714
+ }
715
+ interface ToolbarLayout<Command extends ToolbarCommand = ToolbarCommand> {
716
+ /** Always the three sections, in order. */
717
+ readonly sections: readonly LiveSection<Command>[];
718
+ /**
719
+ * What the measurement layer draws, each reporting its length under its
720
+ * `measureKey`: every unit in every variant, each collapsible group folded,
721
+ * each shed group's trigger with the whole group behind it.
722
+ */
723
+ readonly measured: readonly ToolbarPart<Command>[];
724
+ readonly hasOverflow: boolean;
725
+ /** The "More" menu, derived from what didn't fit. */
726
+ readonly overflow: readonly OverflowSection[];
727
+ }
728
+ /** The keys a measurement layer reports lengths under; `@embedpdf/web`'s `toolbarMeasureKey` satisfies it. */
729
+ interface ToolbarMeasureKeys {
730
+ unit(unitKey: string, variant: string): string;
731
+ group(groupId: string): string;
732
+ groupTrigger(groupId: string): string;
733
+ }
734
+ /** What {@link layoutToolbar} reads. */
735
+ interface ToolbarLayoutInput<Command extends ToolbarCommand> {
736
+ /** The bar, from `normalizeBar`. */
737
+ readonly bar: NormalizedBar;
738
+ /** A command for the toolbar's document, or `null` for an id no plugin registered. */
739
+ readonly resolve: (id: string) => Command | null;
740
+ /** What an id no plugin registered draws as: a disabled command named by its id. */
741
+ readonly unregistered: (id: string) => Command;
742
+ /** Run a command for the toolbar's document. */
743
+ readonly execute: (id: string) => void;
744
+ /** Which menu a command opens, for the "More" menu's submenu rows. */
745
+ readonly menuTarget: ResolveMenuTarget;
746
+ /** The measured lengths, along the toolbar's axis. */
747
+ readonly metrics: FitMetrics;
748
+ /** The keys the measured lengths are reported under. */
749
+ readonly measureKey: ToolbarMeasureKeys;
750
+ /** The length the toolbar fills: its width, or its height when vertical. */
751
+ readonly containerLength: number;
752
+ /**
753
+ * Which way the toolbar runs. A vertical toolbar draws every command at
754
+ * `'icon'`, with no smaller step, and leaves its label to a tooltip. Default
755
+ * `'horizontal'`.
756
+ */
757
+ readonly orientation?: 'horizontal' | 'vertical';
758
+ }
759
+ /** Fit the bar into `containerLength` and describe what to draw. */
760
+ declare function layoutToolbar<Command extends ToolbarCommand>(input: ToolbarLayoutInput<Command>): ToolbarLayout<Command>;
761
+ /**
762
+ * The menu a default folded group or group trigger opens: one section of the
763
+ * group's commands, a radio group when the group is tabs.
764
+ */
765
+ declare function groupMenuView<Command extends ToolbarCommand>(view: CollapsedGroupView<Command> | GroupDisclosureView<Command>, isOpen: boolean, close: () => void): OverflowMenuView<Command>;
766
+ /** A group of a strip: its visible commands, in bar order. Groups are separator boundaries. */
767
+ interface StripViewGroup<Command extends ToolbarCommand = ToolbarCommand> {
768
+ readonly id: string;
769
+ readonly labelKey?: string;
770
+ readonly commands: readonly Command[];
771
+ }
772
+ /** A strip, resolved: only visible commands, only groups with one. */
773
+ interface StripView<Command extends ToolbarCommand = ToolbarCommand> {
774
+ readonly groups: readonly StripViewGroup<Command>[];
775
+ /** Run a command for the strip's document. */
776
+ execute(id: string): void;
777
+ }
778
+ /**
779
+ * A bar as a strip shows it now (`projectStrip`), each command resolved: the
780
+ * schema says what could appear, each command's `visible` decides what does.
781
+ * Empty while nothing applies.
782
+ */
783
+ declare function stripGroupsOf<Command extends ToolbarCommand>(bar: NormalizedBar, resolve: (id: string) => Command | null): StripViewGroup<Command>[];
784
+ /**
785
+ * Whether two resolved strips show the same, group by group and command by
786
+ * command (`sameCommand` is plugin-commands' `resolvedCommandsEqual`): a
787
+ * strip's readers pass it on only when this is false.
788
+ */
789
+ declare function sameStripGroups<Command extends ToolbarCommand>(left: readonly StripViewGroup<Command>[], right: readonly StripViewGroup<Command>[], sameCommand: (left: Command, right: Command) => boolean): boolean;
790
+ //#endregion
327
791
  //#region src/shortcuts.d.ts
328
792
  /**
329
793
  * Shortcut parsing + matching — pure. No `navigator`: platform is an input
@@ -332,7 +796,7 @@ declare function projectStrip(bar: NormalizedBar, visible: (command: string) =>
332
796
  * Grammar: modifiers and one key joined by '+', e.g. 'Mod+K', 'Ctrl+=',
333
797
  * 'Shift+Alt+D', 'Meta+NumpadAdd'. 'Mod' is ⌘ on mac and Ctrl elsewhere.
334
798
  * Keys longer than one character (F1, Escape, NumpadAdd, ArrowLeft) match
335
- * `event.key` OR `event.code` case-insensitively, so numpad shortcuts work.
799
+ * `event.key` or `event.code` case-insensitively, so numpad shortcuts work.
336
800
  */
337
801
  interface ParsedShortcut {
338
802
  readonly key: string;
@@ -352,13 +816,70 @@ interface KeyStroke {
352
816
  readonly shiftKey: boolean;
353
817
  }
354
818
  declare function parseShortcut(shortcut: string): ParsedShortcut;
355
- declare function matchShortcut(parsed: ParsedShortcut, stroke: KeyStroke, opts: {
819
+ declare function matchShortcut(parsed: ParsedShortcut, stroke: KeyStroke, options: {
820
+ isMac: boolean;
821
+ }): boolean;
822
+ /**
823
+ * Whether two shortcuts are pressed with the same keys on this platform: `'Mod+S'` and
824
+ * `'Ctrl+s'` are where `Mod` is Ctrl, and not on a Mac.
825
+ */
826
+ declare function sameShortcut(left: string, right: string, options: {
356
827
  isMac: boolean;
357
828
  }): boolean;
358
- /** Display form for menu rows: '⌘K' on mac, 'Ctrl+K' elsewhere. */
359
- declare function formatShortcut(shortcut: string, opts: {
829
+ /** A shortcut as a menu or a tooltip shows it: `'⌘K'` on a Mac, `'Ctrl+K'` elsewhere. */
830
+ declare function formatShortcut(shortcut: string, options: {
360
831
  isMac: boolean;
361
832
  }): string;
362
833
  //#endregion
363
- export { type AddItemSpec, type BarChild, type BarGroup, type BarItem, type BarSchema, type BarSections, type ChromeHelpers, type ChromeSchema, type CustomItem, DEFAULT_IMPORTANCE, type FitMetrics, type FitResult, type FrameSchema, type GroupAssignment, type Importance, type KeyStroke, type MenuSchema, type MenuSection, type NormalizedBar, type NormalizedGroup, type NormalizedSection, type NormalizedUnit, type OverflowRow, type OverflowSection, PINNED, type ParsedShortcut, type ResolveMenuTarget, type StripGroup, type UnitAssignment, type Variant, addItem, chromeHelpers, custom, defineChrome, filterBar, formatShortcut, group, item, matchShortcut, normalizeBar, parseShortcut, projectOverflow, projectShed, projectStrip, removeItems, replaceItem, solve, validateChrome };
834
+ //#region src/tree-keys.d.ts
835
+ /**
836
+ * The keyboard of a tree view, as the ARIA tree pattern has it — pure.
837
+ * A view hands in the rows that show (in order, each with its depth, whether
838
+ * it has children and whether they show), the focused row and the key
839
+ * (`KeyboardEvent.key`); it gets back what the key does, and does it. A key
840
+ * that does nothing returns `null`, so the view lets the event go on.
841
+ *
842
+ * ArrowDown, ArrowUp the next, the previous row
843
+ * ArrowRight a collapsed parent expands; an expanded one moves to its first child
844
+ * ArrowLeft an expanded parent collapses; any other row moves to its parent
845
+ * Home, End the first, the last row
846
+ * * every collapsed sibling of the focused row expands
847
+ * Enter the row activates
848
+ * F2, Delete the row is renamed or deleted, when the tree is editable
849
+ */
850
+ /** A row as the keyboard sees it. */
851
+ interface TreeKeyRow {
852
+ /** How deep it sits: 0 at the top level. */
853
+ readonly depth: number;
854
+ readonly hasChildren: boolean;
855
+ /** Whether its children show. */
856
+ readonly expanded: boolean;
857
+ }
858
+ /** What a key does, naming rows by their index in the rows handed in. */
859
+ type TreeKeyAction = {
860
+ readonly type: 'focus';
861
+ readonly row: number;
862
+ } | {
863
+ readonly type: 'expand';
864
+ readonly rows: readonly number[];
865
+ } | {
866
+ readonly type: 'collapse';
867
+ readonly row: number;
868
+ } | {
869
+ readonly type: 'activate';
870
+ readonly row: number;
871
+ } | {
872
+ readonly type: 'rename';
873
+ readonly row: number;
874
+ } | {
875
+ readonly type: 'delete';
876
+ readonly row: number;
877
+ };
878
+ interface TreeKeyOptions {
879
+ /** Whether F2 and Delete edit the tree. Off by default: a reader's tree only moves and opens. */
880
+ readonly editable?: boolean;
881
+ }
882
+ declare function treeKeyAction(rows: readonly TreeKeyRow[], focused: number, key: string, options?: TreeKeyOptions): TreeKeyAction | null;
883
+ //#endregion
884
+ export { type AddItemOptions, type BarChild, type BarEdge, type BarGroup, type BarItem, type BarPlace, type BarSchema, type BarSections, type CollapsedGroupView, type CompileBarOptions, type CustomItem, type CustomSlotCtx, DEFAULT_IMPORTANCE, EXPANDED_MIN_WIDTH_PX, FLOAT_POSITIONS, type FitMetrics, type FitResult, type FloatPosition, type GroupAssignment, type GroupDisclosureView, type Importance, type KeyStroke, type Layout, type LayoutBar, type LayoutCommandItem, type LayoutCustomItem, type LayoutData, type LayoutEnv, type LayoutFunction, type LayoutGroup, type LayoutGroupObject, type LayoutItem, type LayoutKnownIds, type LayoutMenu, type LayoutMenuSection, type LayoutOption, type LayoutPanel, type LayoutPanelPatch, type LayoutSection, type LiveGroup, type LiveSection, MEDIUM_MIN_WIDTH_PX, MODES_GROUP, type MenuSection, type NormalizedBar, type NormalizedGroup, type NormalizedSection, type NormalizedUnit, type OmissionCommand, type OverflowMenuView, type OverflowRow, type OverflowSection, PINNED, type PanelPresentation, type PanelPresentationBySize, type PanelWidth, type ParsedShortcut, type RemoveItemOptions, type ResolveMenuTarget, type SectionName, type SelectionTarget, type StripGroup, type StripView, type StripViewGroup, type TabsVisibility, type ToolbarCommand, type ToolbarLayout, type ToolbarLayoutInput, type ToolbarMeasureKeys, type ToolbarPart, type TreeKeyAction, type TreeKeyOptions, type TreeKeyRow, type UnitAssignment, VIEW_MODE_COMMAND, type Variant, type ViewerSize, barsAt, barsFloating, barsInMode, barsOnEdge, barsWith, closestMatch, commandOfUnit, compileBar, createLayout, custom, didYouMean, edgeOf, edgeStackOf, editDistance, filterBar, floatOf, floatStackOf, formatShortcut, group, groupMenuView, hasVisibleUnits, hostOf, isLayout, isStandaloneUnit, item, itemCommandOf, itemIdOf, layoutToolbar, matchShortcut, menuOf, modeCommandOf, modesOf, normalizeBar, omittedCommandsOf, panelCommandOf, panelPresentationsOf, panelWidthFieldsOf, parseShortcut, projectOverflow, projectShed, projectStrip, resolveLayout, sameLayoutEnv, sameShortcut, sameStripGroups, selectionOf, sizeOf, solve, stripGroupsOf, tabsOf, treeKeyAction, validateLayout };
364
885
  //# sourceMappingURL=index.d.ts.map