@wildwinter/app-shell 0.38.0 → 0.40.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.
Files changed (168) hide show
  1. package/LICENSES.md +62 -0
  2. package/README.md +8 -0
  3. package/dist/about.css +17 -38
  4. package/dist/about.css.map +1 -1
  5. package/dist/anchored.css +9 -9
  6. package/dist/anchored.css.map +1 -1
  7. package/dist/app-store.cjs +15 -0
  8. package/dist/app-store.cjs.map +1 -1
  9. package/dist/app-store.d.cts +25 -1
  10. package/dist/app-store.d.ts +25 -1
  11. package/dist/app-store.js +14 -1
  12. package/dist/app-store.js.map +1 -1
  13. package/dist/chunk-2ECJUTSX.js +97 -0
  14. package/dist/chunk-2ECJUTSX.js.map +1 -0
  15. package/dist/chunk-DS4XXAZS.js +56 -0
  16. package/dist/chunk-DS4XXAZS.js.map +1 -0
  17. package/dist/chunk-EHR2KBZC.js +82 -0
  18. package/dist/chunk-EHR2KBZC.js.map +1 -0
  19. package/dist/chunk-IU7EY6BI.js +26 -0
  20. package/dist/chunk-IU7EY6BI.js.map +1 -0
  21. package/dist/chunk-OPZPFOPS.js +66 -0
  22. package/dist/chunk-OPZPFOPS.js.map +1 -0
  23. package/dist/chunk-P4G4ERG6.js +60 -0
  24. package/dist/chunk-P4G4ERG6.js.map +1 -0
  25. package/dist/chunk-P6WLAEKZ.js +71 -0
  26. package/dist/chunk-P6WLAEKZ.js.map +1 -0
  27. package/dist/chunk-R3NXPHRZ.js +534 -0
  28. package/dist/chunk-R3NXPHRZ.js.map +1 -0
  29. package/dist/chunk-SDOKZTAR.js +87 -0
  30. package/dist/chunk-SDOKZTAR.js.map +1 -0
  31. package/dist/chunk-SEWJLUOD.js +70 -0
  32. package/dist/chunk-SEWJLUOD.js.map +1 -0
  33. package/dist/chunk-UG2P777F.js +587 -0
  34. package/dist/chunk-UG2P777F.js.map +1 -0
  35. package/dist/chunk-YRFJLJUH.js +55 -0
  36. package/dist/chunk-YRFJLJUH.js.map +1 -0
  37. package/dist/chunk-YWMSQFXX.js +146 -0
  38. package/dist/chunk-YWMSQFXX.js.map +1 -0
  39. package/dist/comments.css +16 -14
  40. package/dist/comments.css.map +1 -1
  41. package/dist/confirm.css +2 -55
  42. package/dist/confirm.css.map +1 -1
  43. package/dist/context-menu.cjs +250 -0
  44. package/dist/context-menu.cjs.map +1 -0
  45. package/dist/context-menu.css +64 -0
  46. package/dist/context-menu.css.map +1 -0
  47. package/dist/context-menu.d.cts +25 -0
  48. package/dist/context-menu.d.ts +25 -0
  49. package/dist/context-menu.js +5 -0
  50. package/dist/context-menu.js.map +1 -0
  51. package/dist/controls.css +214 -0
  52. package/dist/controls.css.map +1 -0
  53. package/dist/dialog.cjs +222 -0
  54. package/dist/dialog.cjs.map +1 -0
  55. package/dist/dialog.css +56 -0
  56. package/dist/dialog.css.map +1 -0
  57. package/dist/dialog.d.cts +28 -0
  58. package/dist/dialog.d.ts +28 -0
  59. package/dist/dialog.js +5 -0
  60. package/dist/dialog.js.map +1 -0
  61. package/dist/floating.cjs +83 -0
  62. package/dist/floating.cjs.map +1 -0
  63. package/dist/floating.d.cts +25 -0
  64. package/dist/floating.d.ts +25 -0
  65. package/dist/floating.js +4 -0
  66. package/dist/floating.js.map +1 -0
  67. package/dist/identity.css +15 -50
  68. package/dist/identity.css.map +1 -1
  69. package/dist/index.cjs +1553 -260
  70. package/dist/index.cjs.map +1 -1
  71. package/dist/index.d.cts +385 -152
  72. package/dist/index.d.ts +385 -152
  73. package/dist/index.js +264 -823
  74. package/dist/index.js.map +1 -1
  75. package/dist/job.css +24 -1
  76. package/dist/job.css.map +1 -1
  77. package/dist/keys.cjs +155 -0
  78. package/dist/keys.cjs.map +1 -0
  79. package/dist/keys.css +41 -0
  80. package/dist/keys.css.map +1 -0
  81. package/dist/keys.d.cts +57 -0
  82. package/dist/keys.d.ts +57 -0
  83. package/dist/keys.js +3 -0
  84. package/dist/keys.js.map +1 -0
  85. package/dist/link-status.cjs +430 -0
  86. package/dist/link-status.cjs.map +1 -0
  87. package/dist/link-status.css +76 -0
  88. package/dist/link-status.css.map +1 -0
  89. package/dist/link-status.d.cts +53 -0
  90. package/dist/link-status.d.ts +53 -0
  91. package/dist/link-status.js +5 -0
  92. package/dist/link-status.js.map +1 -0
  93. package/dist/menu.cjs +62 -1
  94. package/dist/menu.cjs.map +1 -1
  95. package/dist/menu.d.cts +88 -1
  96. package/dist/menu.d.ts +88 -1
  97. package/dist/menu.js +1 -1
  98. package/dist/notes-editor.css +9 -52
  99. package/dist/notes-editor.css.map +1 -1
  100. package/dist/pane-shell.css +23 -5
  101. package/dist/pane-shell.css.map +1 -1
  102. package/dist/problems.cjs +61 -0
  103. package/dist/problems.cjs.map +1 -0
  104. package/dist/problems.d.cts +57 -0
  105. package/dist/problems.d.ts +57 -0
  106. package/dist/problems.js +3 -0
  107. package/dist/problems.js.map +1 -0
  108. package/dist/property-list-D3VZCJzi.d.cts +162 -0
  109. package/dist/property-list-D3VZCJzi.d.ts +162 -0
  110. package/dist/property-list.cjs +784 -0
  111. package/dist/property-list.cjs.map +1 -0
  112. package/dist/property-list.d.cts +1 -0
  113. package/dist/property-list.d.ts +1 -0
  114. package/dist/property-list.js +4 -0
  115. package/dist/property-list.js.map +1 -0
  116. package/dist/save.css +1 -1
  117. package/dist/save.css.map +1 -1
  118. package/dist/settings.css +62 -18
  119. package/dist/settings.css.map +1 -1
  120. package/dist/stale.css +4 -1
  121. package/dist/stale.css.map +1 -1
  122. package/dist/stepper.css +47 -3
  123. package/dist/stepper.css.map +1 -1
  124. package/dist/toast.css +5 -5
  125. package/dist/toast.css.map +1 -1
  126. package/dist/tokens.css +20 -0
  127. package/dist/tokens.css.map +1 -1
  128. package/dist/tool-window.cjs +63 -0
  129. package/dist/tool-window.cjs.map +1 -1
  130. package/dist/tool-window.css +8 -4
  131. package/dist/tool-window.css.map +1 -1
  132. package/dist/tool-window.d.cts +67 -1
  133. package/dist/tool-window.d.ts +67 -1
  134. package/dist/tool-window.js +63 -1
  135. package/dist/tool-window.js.map +1 -1
  136. package/dist/tooltip.css +3 -3
  137. package/dist/tooltip.css.map +1 -1
  138. package/dist/updater-view.cjs +283 -0
  139. package/dist/updater-view.cjs.map +1 -0
  140. package/dist/updater-view.d.cts +23 -0
  141. package/dist/updater-view.d.ts +23 -0
  142. package/dist/updater-view.js +6 -0
  143. package/dist/updater-view.js.map +1 -0
  144. package/dist/updater.cjs +12 -16
  145. package/dist/updater.cjs.map +1 -1
  146. package/dist/updater.css +44 -0
  147. package/dist/updater.css.map +1 -0
  148. package/dist/updater.js +12 -16
  149. package/dist/updater.js.map +1 -1
  150. package/dist/util.cjs +78 -0
  151. package/dist/util.cjs.map +1 -0
  152. package/dist/util.d.cts +37 -0
  153. package/dist/util.d.ts +37 -0
  154. package/dist/util.js +3 -0
  155. package/dist/util.js.map +1 -0
  156. package/dist/vc.css +4 -3
  157. package/dist/vc.css.map +1 -1
  158. package/dist/welcome.cjs +215 -0
  159. package/dist/welcome.cjs.map +1 -0
  160. package/dist/welcome.css +112 -0
  161. package/dist/welcome.css.map +1 -0
  162. package/dist/welcome.d.cts +55 -0
  163. package/dist/welcome.d.ts +55 -0
  164. package/dist/welcome.js +4 -0
  165. package/dist/welcome.js.map +1 -0
  166. package/package.json +72 -2
  167. package/dist/chunk-QDPFU4WX.js +0 -43
  168. package/dist/chunk-QDPFU4WX.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,61 +1,28 @@
1
- export { EDIT_MENU, GO_MENU, MenuLabel, PANE_MENU } from './menu.js';
1
+ export { EDIT_MENU, FILE_MENU, GO_MENU, MenuLabel, PANE_MENU, PLAY_MENU, PUBLISH_MENU, REVIEW_MENU, VIEW_MENU } from './menu.js';
2
+ export { HintBarItem, KeyHintOptions, KeyPlatform, hintBar, isKeyCombo, keyHint, keyLabel, keyLegends, keyPlatform, setKeyPlatform, tipWithKey } from './keys.js';
3
+ export { ProblemCopy, ProblemCopyEntry, ProblemCopyTable, ProblemLike, defaultProblemCopy, describeProblem, problemLine, problemName } from './problems.js';
4
+ export { D as DefaultControlOptions, a as DupGuard, P as PROPERTY_TYPES, b as PropertyDeclLike, c as PropertyListHandle, d as PropertyListOptions, e as PropertyListType, S as SettingsDialog, f as SettingsDialogOptions, g as SettingsSection, h as SettingsSectionHandle, i as defaultControl, j as dupGuard, k as expandableRow, l as focusNewRow, m as mountPropertyList, n as mountSettingsDialog, r as revealRow, o as revealRowWhenReady } from './property-list-D3VZCJzi.js';
5
+ export { DialogFrame, DialogFrameOptions, dialogFrame } from './dialog.js';
6
+ export { Floating, FloatingOptions, createFloating } from './floating.js';
7
+ export { ContextItem, PopoverOptions, openContextMenu, openPopover } from './context-menu.js';
2
8
  export { JOB_PROGRESS, JobProgress } from './job.js';
9
+ export { UpdaterLink, UpdaterViewOptions, feedUpdaterDownloadProgress, showUpdaterDialog } from './updater-view.js';
10
+ export { UpdaterDownloadProgress, UpdaterPromptOptions } from './updater.js';
11
+ export { Welcome, WelcomeAction, WelcomeGroup, WelcomeGroupItem, WelcomeOptions, WelcomeRecent, mountWelcome } from './welcome.js';
12
+ export { LinkStatus, LinkStatusChip, LinkStatusClass, LinkStatusOptions, linkAddress, linkStatusClass, linkStatusTip, mountLinkStatus } from './link-status.js';
13
+ export { Debounced, copyWithFeedback, debounce, formatCount, isEditableTarget, plural, relativeTime } from './util.js';
14
+ import './app-store.js';
15
+ import 'electron';
3
16
 
4
- type Child = Node | string | null | undefined;
5
- interface ElProps {
6
- className?: string;
7
- text?: string;
8
- /** A NATIVE rollover. Prefer `tip`: `title` is OS chrome on the platform's own
9
- * slow delay, which is the seam the themed tooltip exists to close. */
10
- title?: string;
11
- /** A themed rollover (`data-tip`, picked up by the delegated controller that
12
- * `initTooltips()` wires). Also the accessible name, since the elements that
13
- * want one are usually icon buttons with no text of their own. */
14
- tip?: string;
15
- onClick?: (event: MouseEvent) => void;
16
- }
17
- declare function el<K extends keyof HTMLElementTagNameMap>(tag: K, classNameOrProps?: string | ElProps, ...children: Child[]): HTMLElementTagNameMap[K];
18
- /** A small square glyph button (the move/delete controls list editors share).
19
- * Its rollover is the THEMED one (`data-tip`), so an app that has called
20
- * `initTooltips()` gets our bubble rather than the platform's. */
21
- declare function iconBtn(glyph: string, title: string, onClick: () => void, disabled?: boolean, danger?: boolean): HTMLButtonElement;
22
17
  /**
23
- * A captioned field: `<label class="shell-labelled"><span class="shell-fieldcap">…</span>control</label>`.
24
- *
25
- * The label is pointed at the field it captions, EXPLICITLY, and never at a button. A `<label>` with no
26
- * `for` forwards a click to its first labelable descendant, and buttons are labelable - so a caption
27
- * wrapped around a control containing buttons (`tagChips`, whose every chip carries a remove button)
28
- * turns every click on the row's dead space into a press of the FIRST button in it. That shipped:
29
- * patterkit/patter#44, where clicking a Game Data list value anywhere but its ✕ deleted the first value
30
- * in the list. Reported as "clicking a value removes the wrong one", which is not a wrong-index bug at
31
- * all - the click never reached the chip.
18
+ * The typed glyphs the vocabulary used to draw.
32
19
  *
33
- * When the control holds no labelable field (a chips editor with the add input removed, say), this is a
34
- * plain `<div>`: no caption behaviour is better than a caption that presses something.
35
- */
36
- declare function labelled(label: string, control: HTMLElement): HTMLElement;
37
- /** Swap item `i` with its neighbour `i + delta` IN PLACE (the up/down reorder list editors share);
38
- * a no-op when the target is out of range. Returns whether anything moved. */
39
- declare function moveItem<T>(arr: T[], i: number, delta: number): boolean;
40
- /** A tag-style editor for a string-list field (an enum's allowed values / flags): removable chips + an
41
- * add input (Enter or "," commits; blank / duplicate ignored). Mutates `holder.values` in place (read
42
- * back on save). `onChange` fires after any add / remove so callers can refresh a dependent control. */
43
- declare function tagChips(holder: {
44
- values?: string[];
45
- }, onChange?: () => void): HTMLElement;
46
-
47
- /** Curated colour slots; must match the `--char-*` set defined per theme. */
48
- declare const PALETTE_SIZE = 12;
49
- declare const PALETTE: readonly string[];
50
- /** Hash a name to a palette slot: FNV-1a + an fmix32 avalanche, well
51
- * distributed even for short, similar names. */
52
- declare function colourIndex(name: string): number;
53
- /** The theme-aware CSS variable reference for a name's slot. */
54
- declare function colourFor(name: string): string;
55
-
56
- /**
57
- * Named by what it MEANS. Grouped by the job, because that is how a caller
58
- * looks for one.
20
+ * @deprecated Since the move to drawn icons (design-language.md, "Icons are
21
+ * drawn"). Kept byte-for-byte so a consumer still doing
22
+ * `textContent = icon.close` keeps working while each app moves; a new call
23
+ * site uses `iconNode(name)` (a node to append) or `iconHtml(name)` (for an
24
+ * innerHTML build). The names are the same in all three. Removed once both
25
+ * apps have moved.
59
26
  */
60
27
  declare const icon: {
61
28
  /** Close a panel, a dialog, a popover. Patterpad's, twelve times over. */
@@ -117,24 +84,210 @@ declare const icon: {
117
84
  * comments are the conversation, and the two must never look alike. */
118
85
  readonly comment: "❝";
119
86
  };
120
- type IconName = keyof typeof icon;
121
87
  /**
122
- * The few shapes no glyph says honestly, as inline SVG.
123
- *
124
- * `currentColor` throughout, so they take the colour of the button they sit in
125
- * exactly as the glyphs do, and sized in the markup for the same reason: an icon
126
- * that needs a CSS rule to be the right size is an icon that will be the wrong
127
- * size somewhere.
88
+ * Every word in the vocabulary. The 26 the glyph table had, plus the seven the
89
+ * 2026-09 review found the apps drawing by hand with nothing to check against.
90
+ */
91
+ type IconName = keyof typeof icon
92
+ /** History back, the topbar's quiet arrow pair (nav-history.ts). An ARROW,
93
+ * not a chevron: a chevron says structure, an arrow says time (the author's
94
+ * ruling, 2026-08-28). Added beside `arrowRight` so the pair share a set. */
95
+ | "arrowLeft"
96
+ /** History forward; also the one honest "go there" arrow where a link used
97
+ * to carry a typed one. */
98
+ | "arrowRight"
99
+ /** Connect to a server, a live link, a running game. */
100
+ | "connect"
101
+ /** Search. */
102
+ | "search"
103
+ /** Keep this window on top (tool-window-web.ts). */
104
+ | "pin"
105
+ /** Settings. */
106
+ | "settings"
107
+ /** Record. The icon is the DISC; painting it in the danger colour while
108
+ * recording is the caller's job, through the button's own colour. */
109
+ | "record";
110
+ /**
111
+ * The drawings as strings, by word, for a caller that builds markup itself.
112
+ * Prefer `iconHtml(name, size)`, which sizes it; these carry no width/height.
128
113
  *
129
- * Lifted from Patterpad, which drew them first.
114
+ * Two legacy entries ride along unchanged: `noteFilled` and `noteOutline`, the
115
+ * has-notes / no-notes pair Patterpad drew on a 16-unit grid before the set
116
+ * existed. They are sized in the markup (13px) and on their own grid, so they
117
+ * are NOT part of the vocabulary above and `iconNode` does not know them; no
118
+ * app uses them today. They stay until a 24-grid pair replaces them, because
119
+ * their two-state meaning (there are notes / there are none) has no Lucide
120
+ * shape, and re-weighting the 16-grid drawing to the family stroke merges its
121
+ * text lines.
130
122
  */
131
123
  declare const iconSvg: {
132
- /** A document with lines: notes exist on this thing. */
124
+ /** A document with lines: notes exist on this thing. (legacy, 16 grid) */
133
125
  readonly noteFilled: "<svg viewBox=\"0 0 16 16\" width=\"13\" height=\"13\" fill=\"currentColor\" fill-rule=\"evenodd\" aria-hidden=\"true\"><path d=\"M3.4 1.4h5.3L12.6 5.3v8.1a1.2 1.2 0 0 1-1.2 1.2H3.4a1.2 1.2 0 0 1-1.2-1.2V2.6A1.2 1.2 0 0 1 3.4 1.4ZM4.9 6.8h6.2v1.1H4.9Zm0 2.1h6.2v1.1H4.9Zm0 2.1h3.7v1.1H4.9Z\"/></svg>";
134
- /** The same document, empty: nothing written here yet. */
126
+ /** The same document, empty: nothing written here yet. (legacy, 16 grid) */
135
127
  readonly noteOutline: "<svg viewBox=\"0 0 16 16\" width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.1\" stroke-linejoin=\"round\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M3.4 2h4.9l3.9 3.9v7.5a1 1 0 0 1-1 1H3.4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1Z\"/><path d=\"M8.3 2.2v3.8h3.8\"/><path d=\"M4.9 8h6.2M4.9 10h6.2M4.9 12h3.7\" stroke-width=\"0.95\"/></svg>";
128
+ readonly search: string;
129
+ readonly close: string;
130
+ readonly play: string;
131
+ readonly more: string;
132
+ readonly collapsed: string;
133
+ readonly expanded: string;
134
+ readonly dropdown: string;
135
+ readonly back: string;
136
+ readonly forward: string;
137
+ readonly up: string;
138
+ readonly down: string;
139
+ readonly tick: string;
140
+ readonly locked: string;
141
+ readonly readOnly: string;
142
+ readonly checkedOut: string;
143
+ readonly modified: string;
144
+ readonly untracked: string;
145
+ readonly warning: string;
146
+ readonly dot: string;
147
+ readonly restart: string;
148
+ readonly viewCards: string;
149
+ readonly viewTable: string;
150
+ readonly viewNode: string;
151
+ readonly grip: string;
152
+ readonly add: string;
153
+ readonly note: string;
154
+ readonly comment: string;
155
+ readonly arrowLeft: string;
156
+ readonly arrowRight: string;
157
+ readonly connect: string;
158
+ readonly pin: string;
159
+ readonly settings: string;
160
+ readonly record: string;
136
161
  };
137
162
  type IconSvgName = keyof typeof iconSvg;
163
+ /** Every word, in table order, for a test or a gallery to walk. */
164
+ declare const ICON_NAMES: IconName[];
165
+ /** The default size: 14px, the family's icon inside its small square button. */
166
+ declare const ICON_SIZE = 14;
167
+ /**
168
+ * The drawing as markup with its size set, for a caller building innerHTML.
169
+ * `data-icon` carries the word, so a stylesheet or a test can find it.
170
+ */
171
+ declare function iconHtml(name: IconName, size?: number): string;
172
+ /**
173
+ * The drawing as a fresh SVG node, sized. Append it where the glyph used to be
174
+ * set as text; it is `aria-hidden`, so the button's accessible name stays the
175
+ * button's (`aria-label` / `data-tip`), as it always had to.
176
+ */
177
+ declare function iconNode(name: IconName, size?: number): SVGSVGElement;
178
+ /** The word a deprecated glyph stood for, or undefined for any other string. */
179
+ declare function iconNameOfGlyph(glyph: string): IconName | undefined;
180
+ /** Whether a string is a word in the vocabulary. */
181
+ declare function isIconName(s: string): s is IconName;
182
+
183
+ type Child = Node | string | null | undefined;
184
+ interface ElProps {
185
+ className?: string;
186
+ text?: string;
187
+ /** A NATIVE rollover. Prefer `tip`: `title` is OS chrome on the platform's own
188
+ * slow delay, which is the seam the themed tooltip exists to close. */
189
+ title?: string;
190
+ /** A themed rollover (`data-tip`, picked up by the delegated controller that
191
+ * `initTooltips()` wires). Also the accessible name, since the elements that
192
+ * want one are usually icon buttons with no text of their own. */
193
+ tip?: string;
194
+ onClick?: (event: MouseEvent) => void;
195
+ }
196
+ declare function el<K extends keyof HTMLElementTagNameMap>(tag: K, classNameOrProps?: string | ElProps, ...children: Child[]): HTMLElementTagNameMap[K];
197
+ /** A small square icon button (the move/delete controls list editors share).
198
+ * Its rollover is the THEMED one (`data-tip`), so an app that has called
199
+ * `initTooltips()` gets our bubble rather than the platform's.
200
+ *
201
+ * `name` is a word from the vocabulary ("up", "close"), drawn at 14px. A
202
+ * typed glyph from the deprecated `icon` table ("↑", "✕") is accepted for
203
+ * now and drawn as the word it stood for, so an app that has not moved its
204
+ * call sites yet still gets the drawn set; any other string is set as text,
205
+ * which is the old behaviour and on its way out. */
206
+ declare function iconBtn(name: IconName | (string & {}), title: string, onClick: () => void, disabled?: boolean, danger?: boolean): HTMLButtonElement;
207
+ /**
208
+ * A captioned field: `<label class="shell-labelled"><span class="shell-fieldcap">…</span>control</label>`.
209
+ *
210
+ * The label is pointed at the field it captions, EXPLICITLY, and never at a button. A `<label>` with no
211
+ * `for` forwards a click to its first labelable descendant, and buttons are labelable - so a caption
212
+ * wrapped around a control containing buttons (`tagChips`, whose every chip carries a remove button)
213
+ * turns every click on the row's dead space into a press of the FIRST button in it. That shipped:
214
+ * patterkit/patter#44, where clicking a Game Data list value anywhere but its ✕ deleted the first value
215
+ * in the list. Reported as "clicking a value removes the wrong one", which is not a wrong-index bug at
216
+ * all - the click never reached the chip.
217
+ *
218
+ * When the control holds no labelable field (a chips editor with the add input removed, say), this is a
219
+ * plain `<div>`: no caption behaviour is better than a caption that presses something.
220
+ */
221
+ declare function labelled(label: string, control: HTMLElement): HTMLElement;
222
+ /** Swap item `i` with its neighbour `i + delta` IN PLACE (the up/down reorder list editors share);
223
+ * a no-op when the target is out of range. Returns whether anything moved. */
224
+ declare function moveItem<T>(arr: T[], i: number, delta: number): boolean;
225
+ /** A tag-style editor for a string-list field (an enum's allowed values / flags): removable chips + an
226
+ * add input (Enter or "," commits; blank / duplicate ignored). Mutates `holder.values` in place (read
227
+ * back on save). `onChange` fires after any add / remove so callers can refresh a dependent control. */
228
+ declare function tagChips(holder: {
229
+ values?: string[];
230
+ }, onChange?: () => void): HTMLElement;
231
+ /**
232
+ * An ORDERED chips editor for a string-list field whose order means something
233
+ * (a quality's stages: `advance()` walks them, so 2 comes after 1): numbered
234
+ * chips, each with move-earlier / move-later / remove, plus an add input
235
+ * (Enter or "," commits; blank / duplicate ignored). Mutates `holder.stages`
236
+ * in place; `onChange` fires after any add / move / remove.
237
+ *
238
+ * Patterpad's, lifted (ui-review-2026-09, finding 3); Storyletter had been
239
+ * faking it with `tagChips` over a `values` holder, which loses the order
240
+ * controls. Same class family as `tagChips` (`.shell-tags`), so it is styled by
241
+ * settings.css already.
242
+ */
243
+ declare function stageChips(holder: {
244
+ stages?: string[];
245
+ }, onChange?: () => void): HTMLElement;
246
+ /**
247
+ * Make `el` a drag source and a drop target for HTML5 drag-to-reorder among
248
+ * its siblings. While carried it wears `.dragging`; a hovered target wears
249
+ * `.drop-before` or `.drop-after` by the midpoint test on `axis` ("y" for
250
+ * rows, "x" for a wrapping grid); a drop calls `onMove(draggedId, before,
251
+ * targetId)` and the caller reorders its model and re-renders.
252
+ *
253
+ * Storyletter's `wireCardDrag`, lifted (ui-review-2026-09, finding 30);
254
+ * Patterpad's `wireSceneDrag` is the same idea fixed on "y". The marks are
255
+ * classes only: the app draws them (Patterpad's `box-shadow: 0 -2px 0 0
256
+ * var(--accent)` pair is the family's look).
257
+ */
258
+ declare function wireReorder(el: HTMLElement, id: string, axis: "x" | "y", onMove: (id: string, before: boolean, targetId: string) => void): void;
259
+ /**
260
+ * A metadata line: `parts` as spans in a flex row, separated by a drawn
261
+ * 3px disc (a `::before` on every part after the first, in controls.css),
262
+ * so `metaLine(["6 runs", "200 max steps", "seed 4"])` is what
263
+ * "6 runs · 200 max steps · seed 4" used to be, without the typed dot.
264
+ * Empty, null and undefined parts are skipped, so a caller can pass an
265
+ * optional segment without branching.
266
+ */
267
+ declare function metaLine(parts: (string | Node | null | undefined)[]): HTMLElement;
268
+ interface Crumb {
269
+ label: string;
270
+ /** Makes the crumb a button. Ignored on the last crumb, which is where the
271
+ * reader already is. */
272
+ onClick?: (event: MouseEvent) => void;
273
+ }
274
+ /**
275
+ * A breadcrumb trail: each crumb a span, or a button when it carries
276
+ * `onClick` and is not the last, with `iconNode("forward", 12)` drawn between
277
+ * them. `breadcrumb(["Box", "Deck", "Card"])` is what "Box › Deck › Card"
278
+ * used to be; the chevrons are the family's own drawing, not a symbol-font
279
+ * character.
280
+ */
281
+ declare function breadcrumb(parts: (string | Crumb)[]): HTMLElement;
282
+
283
+ /** Curated colour slots; must match the `--char-*` set defined per theme. */
284
+ declare const PALETTE_SIZE = 12;
285
+ declare const PALETTE: readonly string[];
286
+ /** Hash a name to a palette slot: FNV-1a + an fmix32 avalanche, well
287
+ * distributed even for short, similar names. */
288
+ declare function colourIndex(name: string): number;
289
+ /** The theme-aware CSS variable reference for a name's slot. */
290
+ declare function colourFor(name: string): string;
138
291
 
139
292
  type PaneSide = "nav" | "inspector";
140
293
  interface PaneSideConfig {
@@ -148,7 +301,10 @@ interface PaneSideConfig {
148
301
  resizable?: boolean;
149
302
  /** Noun for the toggle's tooltip/aria, e.g. "navigator" / "inspector". */
150
303
  label?: string;
151
- /** Shortcut hint appended to the tooltip, e.g. "Cmd+1". */
304
+ /** The key that toggles the pane, bracketed after the tooltip. A combo in
305
+ * the portable spelling ("Mod+1") is drawn for the platform through
306
+ * `tipWithKey`: "(⌘1)" on a Mac, "(Ctrl+1)" elsewhere. Anything else is a
307
+ * literal and goes in verbatim, as it always has ("Cmd+1" stays "Cmd+1"). */
152
308
  shortcutHint?: string;
153
309
  /** false = the pane is not offered at all: no toggle, togglePane ignored,
154
310
  * forced closed whatever the remembered state says. For a slot a host has
@@ -168,6 +324,18 @@ interface PaneShellOptions {
168
324
  initial?: Partial<PaneShellState>;
169
325
  /** Persist state after any toggle or resize (host wires it to its store). */
170
326
  onChange?: (state: PaneShellState) => void;
327
+ /** The toggle's rollover for a side in a given state. Default: "Show
328
+ * navigator" / "Hide navigator" from the side's `label`, with the
329
+ * `shortcutHint` in brackets (platform-true when it is a combo). Written as
330
+ * `data-tip` (the themed tooltip) and as the accessible name; never as
331
+ * `title`. */
332
+ tipFor?: (side: PaneSide, open: boolean) => string;
333
+ /** An extra class per side, toggled on the `.panes` grid whenever that side
334
+ * is collapsed, beside the shell's own `no-nav` / `no-inspector`. For an
335
+ * app whose stylesheet already keys on its own name for the state
336
+ * (Patterpad's `props-doc-open`), so its rules ride the shell's collapse
337
+ * rather than a second copy of it. */
338
+ collapseAlso?: Partial<Record<PaneSide, string>>;
171
339
  }
172
340
  interface PaneShell {
173
341
  /** The frame element (top bar + panes); mount it into the app container. */
@@ -182,7 +350,13 @@ interface PaneShell {
182
350
  readonly inspector: HTMLElement;
183
351
  togglePane(side: PaneSide): void;
184
352
  setPaneOpen(side: PaneSide, open: boolean): void;
353
+ /** Whether the pane is showing: open, and not held closed. */
185
354
  isOpen(side: PaneSide): boolean;
355
+ /** Fold a side away WITHOUT changing what the person chose: a mode that has
356
+ * no use for the inspector (Patterpad's properties page) holds it closed,
357
+ * and releasing the hold restores whatever was remembered. Not persisted;
358
+ * the toggle keeps reporting the remembered state. */
359
+ holdClosed(side: PaneSide, held: boolean): void;
186
360
  /** Clear dragged widths back to the config defaults. */
187
361
  resetWidths(): void;
188
362
  /** A snapshot of the current state (open + widths). */
@@ -191,78 +365,6 @@ interface PaneShell {
191
365
  }
192
366
  declare function mountPaneShell(host: HTMLElement, opts: PaneShellOptions): PaneShell;
193
367
 
194
- /** A compact list row: a single `.set-rowline` (inline controls) plus, when
195
- * `details` are given, a disclosure that reveals a `.set-details` panel below,
196
- * so a list scans like a table with secondary fields tucked away. `name` is
197
- * what the row declares (a property's name, a field's), stamped on it as
198
- * `data-name` so `revealRow` can land on it. */
199
- declare function expandableRow(opts: {
200
- line: HTMLElement[];
201
- details?: HTMLElement[];
202
- name?: string;
203
- }): HTMLElement;
204
- /**
205
- * Land on one row of a list by the `name` it was built with: open its details
206
- * (an enum's values sit behind the disclosure, and they are usually what the
207
- * jump was for), bring it to the middle of its scroller, and light it for a
208
- * moment (`.set-row.landed` in settings.css). "Go to definition" in both apps
209
- * used to open the page a property is declared on and stop there, with the
210
- * declaration below the fold and nothing marking it (Storyletter, 2026-09-14).
211
- *
212
- * Returns false when no row carries the name, so a host whose page fills in
213
- * asynchronously can ask again on a later frame; asking again is the host's,
214
- * since only the host knows what opens on its own time. The row is matched by
215
- * reading the stamp rather than by an attribute selector, so a name needs no
216
- * escaping.
217
- */
218
- declare function revealRow(within: ParentNode, name: string): boolean;
219
- /** After a "+ Add" re-renders a list, bring the new (last) row into view and
220
- * focus its name input (`.set-name`, else the first input). */
221
- declare function focusNewRow(listEl: HTMLElement | null | undefined): void;
222
- interface DupGuard {
223
- /** Forget the previous render's inputs (call at the top of render). */
224
- reset(): void;
225
- /** Register a name input; `key` returns the comparison string (default the
226
- * input's value). Re-checks live on input. `also` = extra inputs that change the key. */
227
- track(input: HTMLInputElement, key?: () => string, also?: HTMLInputElement[]): void;
228
- /** Re-paint duplicates; true if any two non-blank keys collide. */
229
- check(): boolean;
230
- /** The first input currently flagged (after a fresh check), or null. */
231
- firstDuplicate(): HTMLInputElement | null;
232
- }
233
- /** Case-insensitive duplicate-name detection: paints clashing inputs `.invalid`
234
- * and lets a Save gate block + jump via `firstDuplicate()`. */
235
- declare function dupGuard(): DupGuard;
236
- interface SettingsSectionHandle {
237
- /** The first invalid control to jump to, blocking Save (e.g. a duplicate name). */
238
- firstInvalid?(): HTMLElement | null;
239
- }
240
- interface SettingsSection {
241
- id: string;
242
- label: string;
243
- /** Optional left-rail group heading above this tab. */
244
- group?: string;
245
- /** Build the section body into `host`; called fresh on each open so it reads
246
- * the current data. Return a handle (for the Save gate). */
247
- mount(host: HTMLElement): SettingsSectionHandle;
248
- }
249
- interface SettingsDialogOptions {
250
- title: string;
251
- sections: SettingsSection[];
252
- /** Fired when Save is clicked and every section validates. The app reads its
253
- * own section state and persists. May be async; the dialog stays open until
254
- * it resolves, then closes. */
255
- onSave: () => void | Promise<void>;
256
- }
257
- interface SettingsDialog {
258
- /** Open (optionally on a given tab id). Sections re-mount from current data. */
259
- open(tabId?: string): void;
260
- destroy(): void;
261
- }
262
- /** Build a settings dialog. The frame owns the modal, the tab rail, save-on-Save
263
- * (with a validation gate), and Cancel; the sections own their content + state. */
264
- declare function mountSettingsDialog(opts: SettingsDialogOptions): SettingsDialog;
265
-
266
368
  interface PinButtonOptions {
267
369
  pinned: boolean;
268
370
  /** Persist the choice. The button reflects the click itself. */
@@ -284,11 +386,93 @@ interface PinButton {
284
386
  /** The always-on-top pin: `.swin-pin`, aria-pressed, and a tooltip that says
285
387
  * what a click will do (the richest of the family's variants, kept). */
286
388
  declare function pinButton(opts: PinButtonOptions): PinButton;
389
+ interface ToolWindowHeadOptions {
390
+ /** The window's own name. Constant: it says which window this is, so it must
391
+ * not change as projects open and close. Omitted by a window whose mode
392
+ * tabs stand where the title would be (Find): pass them as `tabs`. */
393
+ title?: string;
394
+ /** Mode tabs in the title's place (Find's bar: modes left, pin and close right). */
395
+ tabs?: HTMLElement;
396
+ /** A pin BUILT ALREADY, for a window that mounts its chrome once and drives
397
+ * the button with `pin.set(on)` rather than rebuilding the bar. That is the
398
+ * better shape (no re-entrancy question, survives a partial repaint), so the
399
+ * helper takes either. */
400
+ pin?: {
401
+ el: HTMLElement;
402
+ };
403
+ pinned?: boolean;
404
+ onPin?: (on: boolean) => void;
405
+ onClose: () => void;
406
+ /** Between the title and the spacer: a subtitle, the project name. */
407
+ lead?: (Node | string | null)[];
408
+ /** Between the spacer and the pin: this window's own controls. */
409
+ trail?: (Node | string | null)[];
410
+ /** An extra class beside `swin-head`, for a window that styles its own bar. */
411
+ className?: string;
412
+ /**
413
+ * Escape closes the window (default true): the family's rule, written once
414
+ * here rather than per window.
415
+ *
416
+ * The listener stands aside on its own for a field's Escape (an input,
417
+ * textarea, select or contenteditable target: clearing, cancelling an edit)
418
+ * and for an Escape a deeper handler has already `preventDefault()`ed.
419
+ * `"always"` drops the first of those: a window whose focus LIVES in a
420
+ * field (Find, whose query box is where the typing is) still closes on
421
+ * Escape from it. `false` turns the listener off for a window that owns
422
+ * Escape entirely; it calls `onClose` itself when nothing smaller is left.
423
+ */
424
+ esc?: boolean | "always";
425
+ /**
426
+ * A window that layers Escape (a selection to clear, a pending outcome to
427
+ * drop, a sweep that must not be closed out from under) says so here:
428
+ * return true when the key was consumed and the window stays open, false
429
+ * to let it close. Innermost first; the window is last.
430
+ */
431
+ onEscape?: () => boolean;
432
+ }
433
+ /** The `.swin-head` bar every tool window wears: title (or tabs), lead, spacer,
434
+ * trail, pin, close. The close button says "Close (Esc)" once, here, rather
435
+ * than in every window. */
436
+ declare function toolWindowHead(opts: ToolWindowHeadOptions): HTMLElement;
437
+ interface FollowButtonOptions {
438
+ on: boolean;
439
+ /** Persist the choice. The button reflects the click itself. */
440
+ onToggle: (on: boolean) => void;
441
+ /** What the editor opens as the run goes: "line" (Patterpad), "card"
442
+ * (Storyletter). Default "line". */
443
+ what?: string;
444
+ }
445
+ /** A toggle and the handle to drive it, the same shape `pinButton` returns. */
446
+ interface FollowButton {
447
+ el: HTMLButtonElement;
448
+ /** Reflect a state decided elsewhere, without calling `onToggle`. */
449
+ set: (on: boolean) => void;
450
+ }
451
+ /**
452
+ * "Follow in the editor": the play surface's toggle that makes the EDITOR
453
+ * follow the run, opening each line / card as it plays. Both play surfaces
454
+ * built one (patterpad play.ts, studio table.ts) with the same label and
455
+ * paraphrased tips; this is the one wording.
456
+ *
457
+ * The LABEL is the careful part. "Follow" alone would match the vocabulary of
458
+ * a window that follows the editor; this is the other direction, the editor
459
+ * following the run. Off by default and remembered by the host: following is
460
+ * the author asking for it.
461
+ */
462
+ declare function followButton(opts: FollowButtonOptions): FollowButton;
287
463
 
288
464
  interface ConfirmOptions {
289
465
  title: string;
290
- body: string;
291
- /** The destructive button's label ("Delete box", "Restart"). */
466
+ /** One plain sentence, ending with what undo does. */
467
+ body?: string;
468
+ /**
469
+ * Content that is evidence rather than a sentence: a list of the scenes that
470
+ * refer to the thing, a warning line. Rendered after `body` when both are
471
+ * given. The caller styles it; the frame's body is a column with a gap.
472
+ */
473
+ bodyNode?: HTMLElement;
474
+ /** The destructive button's label, which names its object ("Delete scene",
475
+ * "Remove language"). */
292
476
  confirmLabel: string;
293
477
  }
294
478
  /** Resolves true on confirm; false on Cancel / Esc / backdrop. */
@@ -353,6 +537,11 @@ interface AnchoredPanelOptions {
353
537
  ignoreDown?: string;
354
538
  /** While something matching this exists, Escape belongs to it, not to us. */
355
539
  deferEscape?: string;
540
+ /** Where the panel is appended. Default <body>. A panel opened from inside a
541
+ * modal <dialog> passes the dialog: a body-level node sits behind the scrim,
542
+ * inert, while one inside the dialog paints in its top layer. Placement is
543
+ * viewport-relative either way (`position: fixed`). */
544
+ host?: HTMLElement;
356
545
  onClose?: () => void;
357
546
  }
358
547
  declare function openAnchoredPanel(opts: AnchoredPanelOptions): AnchoredPanel | null;
@@ -381,7 +570,7 @@ declare function isValidGameId(gameId: string): boolean;
381
570
  * app probes the real parser to prove the list is still true. */
382
571
  declare const RESERVED_PROPERTY_NAMES: readonly string[];
383
572
  /** What an editor should tell an author, in one line. */
384
- declare const PROPERTY_NAME_HINT = "Lower case letters, digits and underscores. Cannot start with a digit. No hyphens or spaces.";
573
+ declare const PROPERTY_NAME_HINT = "Lower case letters, digits, and underscores. It can't start with a digit. No hyphens or spaces.";
385
574
  /**
386
575
  * Coerce a label into a legal property name: lower case, apostrophes dropped,
387
576
  * runs of anything else to a single underscore, no trailing underscore, an
@@ -523,14 +712,20 @@ type VcMap = ReadonlyMap<string, ShardVc>;
523
712
  * box + tags + hands shards), most actionable winning: any holder locks it,
524
713
  * any stale shard makes it stale, any read-only shard makes it read-only. */
525
714
  declare function foldVc(shards: VcMap, keys: string | undefined): ShardVc | undefined;
526
- /** The one badge an item flies, by priority, or null when there is nothing to
527
- * say. Monochrome typographic glyphs (never colour emoji), so each inherits
528
- * its themed colour and reads the same in Linen and Baize. */
529
- declare function vcBadgeFor(s: ShardVc | undefined): {
715
+ /** What a row flies: the word to draw (`name`), the class that colours it,
716
+ * and the rollover. `glyph` is the deprecated typed character for a caller
717
+ * still setting text; it goes when `icon` does. */
718
+ interface VcBadge {
719
+ name: IconName;
720
+ /** @deprecated Draw `name` with `iconNode` instead. */
530
721
  glyph: string;
531
722
  cls: string;
532
723
  title: string;
533
- } | null;
724
+ }
725
+ /** The one badge an item flies, by priority, or null when there is nothing to
726
+ * say. Drawn monochrome (never colour emoji), so each inherits its themed
727
+ * colour and reads the same in Linen and Baize. */
728
+ declare function vcBadgeFor(s: ShardVc | undefined): VcBadge | null;
534
729
  /** Repaint the badge on every item under `root` that names a shard (its
535
730
  * `data-vc`). In place: no re-render, so nothing loses focus or scroll. */
536
731
  declare function paintVcBadges(root: ParentNode, shards: VcMap): void;
@@ -550,6 +745,21 @@ interface IdentityOptions {
550
745
  current?: Identity;
551
746
  /** A name to offer when there is none: the VCS's, one day. */
552
747
  suggested?: Identity;
748
+ /**
749
+ * `"welcome"` is the first run ("Welcome to <appName>", Continue); `"edit"`
750
+ * is the menu item ("User information", Save). Absent, the title is the
751
+ * shell's "Who is working here?" and the button is Save.
752
+ */
753
+ mode?: "welcome" | "edit";
754
+ /** Names the app in the welcome title. Without it the title is "Welcome". */
755
+ appName?: string;
756
+ /**
757
+ * By default a skip resolves `undefined` and the app asks again next launch.
758
+ * With this on, a skip resolves `{ name: "" }`: the app stores the blank and
759
+ * never asks again (Patterpad's first run, where main fills in a default).
760
+ * A Save with an empty name counts as a skip either way.
761
+ */
762
+ neverAskAgainOnSkip?: boolean;
553
763
  }
554
764
  /** Ask, and record the answer. Resolves when the dialog closes, either way. */
555
765
  declare function askIdentity(opts?: IdentityOptions): Promise<Identity | undefined>;
@@ -651,23 +861,42 @@ interface CommentsOptions {
651
861
  }
652
862
  declare function openComments(opts: CommentsOptions): void;
653
863
 
864
+ /** Per-run overrides for a strip that serves several kinds of job (the main
865
+ * window's: a countable export beside an uncountable pull). Each begin()
866
+ * starts from the mount options and applies these on top. */
867
+ interface JobBeginOptions {
868
+ /** Pin the band regardless of what the job reports. */
869
+ indeterminate?: boolean;
870
+ /** Show Cancel for this run. */
871
+ cancellable?: boolean;
872
+ }
654
873
  interface JobProgressView {
655
874
  /** The strip; mount it where the job belongs. */
656
875
  readonly element: HTMLElement;
657
876
  /** Show the strip, reset to zero, and (optionally) name what is running. */
658
- begin(label?: string): void;
659
- /** Feed it a progress message from the main-side host. */
877
+ begin(label?: string, run?: JobBeginOptions): void;
878
+ /** Feed it a progress message from the main-side host. A `total` of 0
879
+ * (the host's "no idea yet") draws the indeterminate band; the first
880
+ * positive total flips the strip to the determinate bar. */
660
881
  update(done: number, total: number, elapsedMs: number): void;
661
882
  /** Hide the strip (the job finished, failed, or was cancelled). */
662
883
  end(): void;
663
884
  readonly visible: boolean;
885
+ /** True while the strip is drawing the band rather than the bar. */
886
+ readonly indeterminate: boolean;
664
887
  }
665
888
  interface JobProgressOptions {
666
889
  /** Called when Cancel is clicked. The button disables itself and says so;
667
- * the job stops at its next yield, and the host then calls end(). */
668
- onCancel: () => void;
890
+ * the job stops at its next yield, and the host then calls end(). Omit it
891
+ * for a strip whose jobs cannot be stopped: Cancel is then not drawn. */
892
+ onCancel?: () => void;
669
893
  /** The word for the units, for the count readout (default "runs"). */
670
894
  units?: string;
895
+ /** Always draw the band and never the count, whatever the job reports.
896
+ * Default: follow the data (band until a total arrives). */
897
+ indeterminate?: boolean;
898
+ /** Draw Cancel. Default: only when `onCancel` was given. */
899
+ cancellable?: boolean;
671
900
  }
672
901
  declare function mountJobProgress(host: HTMLElement, opts: JobProgressOptions): JobProgressView;
673
902
 
@@ -831,8 +1060,12 @@ interface StepperItem {
831
1060
  /** An extra class on the kind chip, so an app can colour its own kinds
832
1061
  * (Storyletter's `sev-error`, and `done` for a resolved thread). */
833
1062
  kindClass?: string;
834
- /** Where it is, in the app's own address. Set in the mono face. */
835
- where?: string;
1063
+ /** Where it is. A string is the app's own address, set in the mono face; a
1064
+ * Node is a made element, a `breadcrumb(["Box", "Deck", "Card"])` say,
1065
+ * drawn as it is. Give the bar plain crumbs: the whole entry is already
1066
+ * the button that goes there, so a crumb with its own click has nowhere
1067
+ * else to take you. */
1068
+ where?: string | Node;
836
1069
  /** The entry itself, in one line. Overflow is clipped, not wrapped: the bar
837
1070
  * is one row high and stays that way however long the sentence is. */
838
1071
  text: string;
@@ -918,4 +1151,4 @@ declare function historyNav(onBack: () => void, onForward: () => void): {
918
1151
  set(canBack: boolean, canForward: boolean): void;
919
1152
  };
920
1153
 
921
- export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type DocLine, type DupGuard, type ElProps, type GameIdEditorOptions, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobProgressOptions, type JobProgressView, type NavHistory, type NavHistoryOptions, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type ToastKind, type ToastOptions, type TooltipOptions, type VcMap, askIdentity, bindPropertyName, bindPropertyRef, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dismissToast, dupGuard, el, expandableRow, firstIllegalPropertyName, focusNewRow, foldVc, gameIdify, hideTip, historyNav, icon, iconBtn, iconSvg, initTooltips, isCaseOnlyPropertyName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, revealRow, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, toast, vcBadgeFor };
1154
+ export { type AboutOptions, type AnchoredPanel, type AnchoredPanelOptions, type Child, type Comment, type CommentMessage, type CommentsOptions, type ConfirmOptions, type Crumb, type DocLine, type ElProps, type FollowButton, type FollowButtonOptions, type GameIdEditorOptions, ICON_NAMES, ICON_SIZE, type IconName, type IconSvgName, type Identity, type IdentityOptions, type JobBeginOptions, type JobProgressOptions, type JobProgressView, type NavHistory, type NavHistoryOptions, type Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, PROPERTY_NAME_HINT, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButton, type PinButtonOptions, type PropertyRefOptions, RESERVED_PROPERTY_NAMES, type SaveController, type SaveControllerOptions, type SaveIndicator, type SaveStatus, type ShardVc, type StaleBarOptions, type StepperBarOptions, type StepperItem, type StepperTone, type TipRect, type ToastKind, type ToastOptions, type ToolWindowHeadOptions, type TooltipOptions, type VcBadge, type VcMap, askIdentity, bindPropertyName, bindPropertyRef, breadcrumb, closeAnchoredPanel, closeWithExit, colourFor, colourIndex, confirmDialog, createNavHistory, createSaveController, dismissToast, el, firstIllegalPropertyName, foldVc, followButton, gameIdify, hideTip, historyNav, icon, iconBtn, iconHtml, iconNameOfGlyph, iconNode, iconSvg, initTooltips, isCaseOnlyPropertyName, isIconName, isValidGameId, isValidPropertyName, labelled, lockControls, lockNotice, metaLine, mountJobProgress, mountPaneShell, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, propertyNameProblem, propertyNameify, propertyRefProblem, renderStepperBar, revalidatePropertyRefs, saveIndicator, showAbout, stageChips, staleBar, tagChips, tipAt, tipBold, toast, toolWindowHead, vcBadgeFor, wireReorder };