@wildwinter/app-shell 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -76,6 +76,15 @@ declare const icon: {
76
76
  readonly dot: "●";
77
77
  /** Play, in the sense of "run this". */
78
78
  readonly play: "▶";
79
+ /** Start the thing again from the top: a play session, a sweep. Named for the
80
+ * act, not the arrow, which is the table's rule. */
81
+ readonly restart: "⟲";
82
+ /** The three ways a collection can be shown. Named by what you get rather than
83
+ * by the glyph, so a second app can pick the same three without copying
84
+ * somebody's taste in symbols. */
85
+ readonly viewCards: "▦";
86
+ readonly viewTable: "☰";
87
+ readonly viewNode: "◈";
79
88
  /** The drag grip on a reorderable row. */
80
89
  readonly grip: "⠿";
81
90
  /** Add one of whatever this list holds. */
@@ -561,4 +570,81 @@ interface SaveController {
561
570
  }
562
571
  declare function createSaveController(opts: SaveControllerOptions): SaveController;
563
572
 
564
- 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 Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, type SaveController, type SaveControllerOptions, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type TipRect, type TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, showAbout, tagChips, tipAt, tipBold, vcBadgeFor };
573
+ interface SaveIndicator {
574
+ /** Put it in the topbar. */
575
+ readonly el: HTMLElement;
576
+ /** Wire straight to the controller's `onStatus`. */
577
+ set(status: SaveStatus): void;
578
+ }
579
+ declare function saveIndicator(initial?: SaveStatus): SaveIndicator;
580
+
581
+ interface StaleBarOptions {
582
+ /**
583
+ * What went out of date, as a capitalised noun phrase: "The project", "The
584
+ * scene". Written into "<subject> changed in the editor."
585
+ */
586
+ subject: string;
587
+ /** Start again from the current source. */
588
+ onRestart: () => void;
589
+ /** The button, when "Restart" is not the app's word for it. */
590
+ restartLabel?: string;
591
+ /**
592
+ * The rest of the sentence, for an app whose session is not a PLAY: the
593
+ * default is "Restart to play the new version."
594
+ */
595
+ advice?: string;
596
+ }
597
+ declare function staleBar(opts: StaleBarOptions): HTMLElement;
598
+
599
+ interface StepperItem {
600
+ /**
601
+ * One word for what kind of thing this is: "error", "comment", "resolved".
602
+ * Absent when the bar carries one kind of thing only.
603
+ */
604
+ kind?: string;
605
+ /** An extra class on the kind chip, so an app can colour its own kinds
606
+ * (Storyletter's `sev-error`, and `done` for a resolved thread). */
607
+ kindClass?: string;
608
+ /** Where it is, in the app's own address. Set in the mono face. */
609
+ where?: string;
610
+ /** The entry itself, in one line. Overflow is clipped, not wrapped: the bar
611
+ * is one row high and stays that way however long the sentence is. */
612
+ text: string;
613
+ }
614
+ /** How loud the count is. The app picks; the palette supplies the value. */
615
+ type StepperTone = "danger" | "warn" | "accent" | "muted";
616
+ interface StepperBarOptions {
617
+ items: StepperItem[];
618
+ /** Which one is current. Clamped, so a shrinking list cannot point off the end. */
619
+ at: number;
620
+ tone?: StepperTone;
621
+ /** Go to another index. The bar wraps, so this is always in range. */
622
+ onStep: (next: number) => void;
623
+ /** Take me to what the current entry is about. */
624
+ onGo: (index: number) => void;
625
+ /** What the three controls say they do. Keyboard shortcuts belong in here. */
626
+ tips?: {
627
+ prev?: string;
628
+ next?: string;
629
+ go?: string;
630
+ };
631
+ /**
632
+ * What to say when the list is empty.
633
+ *
634
+ * Absent hides the bar, which is right for an AMBIENT bar: no problems, no
635
+ * problems bar. Present keeps it up, which is right for a MODE: entering the
636
+ * walk and seeing nothing at all reads as a broken command rather than as
637
+ * "there is no feedback".
638
+ */
639
+ empty?: string;
640
+ /** Leave the mode. Drawn as the last control, hard right. */
641
+ onClose?: () => void;
642
+ closeTip?: string;
643
+ /** The right-hand end before the close: a quick fix, say. Nulls are skipped,
644
+ * so a caller can pass a conditional straight in. */
645
+ actions?: (HTMLElement | null | undefined)[];
646
+ }
647
+ /** Draw (or hide) the bar in `host`. Idempotent: call it again with new state. */
648
+ declare function renderStepperBar(host: HTMLElement, opts: StepperBarOptions): void;
649
+
650
+ 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 Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, 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 TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
package/dist/index.d.ts CHANGED
@@ -76,6 +76,15 @@ declare const icon: {
76
76
  readonly dot: "●";
77
77
  /** Play, in the sense of "run this". */
78
78
  readonly play: "▶";
79
+ /** Start the thing again from the top: a play session, a sweep. Named for the
80
+ * act, not the arrow, which is the table's rule. */
81
+ readonly restart: "⟲";
82
+ /** The three ways a collection can be shown. Named by what you get rather than
83
+ * by the glyph, so a second app can pick the same three without copying
84
+ * somebody's taste in symbols. */
85
+ readonly viewCards: "▦";
86
+ readonly viewTable: "☰";
87
+ readonly viewNode: "◈";
79
88
  /** The drag grip on a reorderable row. */
80
89
  readonly grip: "⠿";
81
90
  /** Add one of whatever this list holds. */
@@ -561,4 +570,81 @@ interface SaveController {
561
570
  }
562
571
  declare function createSaveController(opts: SaveControllerOptions): SaveController;
563
572
 
564
- 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 Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, type SaveController, type SaveControllerOptions, type SaveStatus, type SettingsDialog, type SettingsDialogOptions, type SettingsSection, type SettingsSectionHandle, type ShardVc, type TipRect, type TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, showAbout, tagChips, tipAt, tipBold, vcBadgeFor };
573
+ interface SaveIndicator {
574
+ /** Put it in the topbar. */
575
+ readonly el: HTMLElement;
576
+ /** Wire straight to the controller's `onStatus`. */
577
+ set(status: SaveStatus): void;
578
+ }
579
+ declare function saveIndicator(initial?: SaveStatus): SaveIndicator;
580
+
581
+ interface StaleBarOptions {
582
+ /**
583
+ * What went out of date, as a capitalised noun phrase: "The project", "The
584
+ * scene". Written into "<subject> changed in the editor."
585
+ */
586
+ subject: string;
587
+ /** Start again from the current source. */
588
+ onRestart: () => void;
589
+ /** The button, when "Restart" is not the app's word for it. */
590
+ restartLabel?: string;
591
+ /**
592
+ * The rest of the sentence, for an app whose session is not a PLAY: the
593
+ * default is "Restart to play the new version."
594
+ */
595
+ advice?: string;
596
+ }
597
+ declare function staleBar(opts: StaleBarOptions): HTMLElement;
598
+
599
+ interface StepperItem {
600
+ /**
601
+ * One word for what kind of thing this is: "error", "comment", "resolved".
602
+ * Absent when the bar carries one kind of thing only.
603
+ */
604
+ kind?: string;
605
+ /** An extra class on the kind chip, so an app can colour its own kinds
606
+ * (Storyletter's `sev-error`, and `done` for a resolved thread). */
607
+ kindClass?: string;
608
+ /** Where it is, in the app's own address. Set in the mono face. */
609
+ where?: string;
610
+ /** The entry itself, in one line. Overflow is clipped, not wrapped: the bar
611
+ * is one row high and stays that way however long the sentence is. */
612
+ text: string;
613
+ }
614
+ /** How loud the count is. The app picks; the palette supplies the value. */
615
+ type StepperTone = "danger" | "warn" | "accent" | "muted";
616
+ interface StepperBarOptions {
617
+ items: StepperItem[];
618
+ /** Which one is current. Clamped, so a shrinking list cannot point off the end. */
619
+ at: number;
620
+ tone?: StepperTone;
621
+ /** Go to another index. The bar wraps, so this is always in range. */
622
+ onStep: (next: number) => void;
623
+ /** Take me to what the current entry is about. */
624
+ onGo: (index: number) => void;
625
+ /** What the three controls say they do. Keyboard shortcuts belong in here. */
626
+ tips?: {
627
+ prev?: string;
628
+ next?: string;
629
+ go?: string;
630
+ };
631
+ /**
632
+ * What to say when the list is empty.
633
+ *
634
+ * Absent hides the bar, which is right for an AMBIENT bar: no problems, no
635
+ * problems bar. Present keeps it up, which is right for a MODE: entering the
636
+ * walk and seeing nothing at all reads as a broken command rather than as
637
+ * "there is no feedback".
638
+ */
639
+ empty?: string;
640
+ /** Leave the mode. Drawn as the last control, hard right. */
641
+ onClose?: () => void;
642
+ closeTip?: string;
643
+ /** The right-hand end before the close: a quick fix, say. Nulls are skipped,
644
+ * so a caller can pass a conditional straight in. */
645
+ actions?: (HTMLElement | null | undefined)[];
646
+ }
647
+ /** Draw (or hide) the bar in `host`. Idempotent: call it again with new state. */
648
+ declare function renderStepperBar(host: HTMLElement, opts: StepperBarOptions): void;
649
+
650
+ 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 Notes, type NotesEditorOptions, PALETTE, PALETTE_SIZE, type PaneShell, type PaneShellOptions, type PaneShellState, type PaneSide, type PaneSideConfig, type PinButtonOptions, 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 TooltipOptions, type VcMap, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
package/dist/index.js CHANGED
@@ -137,6 +137,15 @@ var icon = {
137
137
  dot: "\u25CF",
138
138
  /** Play, in the sense of "run this". */
139
139
  play: "\u25B6",
140
+ /** Start the thing again from the top: a play session, a sweep. Named for the
141
+ * act, not the arrow, which is the table's rule. */
142
+ restart: "\u27F2",
143
+ /** The three ways a collection can be shown. Named by what you get rather than
144
+ * by the glyph, so a second app can pick the same three without copying
145
+ * somebody's taste in symbols. */
146
+ viewCards: "\u25A6",
147
+ viewTable: "\u2630",
148
+ viewNode: "\u25C8",
140
149
  // --- handling -------------------------------------------------------------
141
150
  /** The drag grip on a reorderable row. */
142
151
  grip: "\u283F",
@@ -1364,6 +1373,99 @@ function createSaveController(opts) {
1364
1373
  };
1365
1374
  }
1366
1375
 
1367
- export { PALETTE, PALETTE_SIZE, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, showAbout, tagChips, tipAt, tipBold, vcBadgeFor };
1376
+ // src/save-view.ts
1377
+ var WORDS = {
1378
+ saved: "Saved",
1379
+ saving: "Saving\u2026",
1380
+ unsaved: "Unsaved"
1381
+ };
1382
+ function saveIndicator(initial = "saved") {
1383
+ const node = el("span");
1384
+ const set = (status) => {
1385
+ node.className = `savestat ${status}`;
1386
+ node.textContent = WORDS[status];
1387
+ };
1388
+ set(initial);
1389
+ return { el: node, set };
1390
+ }
1391
+
1392
+ // src/stale.ts
1393
+ function staleBar(opts) {
1394
+ const label2 = opts.restartLabel ?? "Restart";
1395
+ return el(
1396
+ "div",
1397
+ { className: "stale-bar" },
1398
+ el("span", {
1399
+ className: "stale-bar-msg",
1400
+ text: `${opts.subject} changed in the editor. ${opts.advice ?? "Restart to play the new version."}`
1401
+ }),
1402
+ el("button", {
1403
+ className: "stale-bar-go",
1404
+ text: `${icon.restart} ${label2}`,
1405
+ onClick: () => opts.onRestart()
1406
+ })
1407
+ );
1408
+ }
1409
+
1410
+ // src/stepper.ts
1411
+ function renderStepperBar(host, opts) {
1412
+ const { items } = opts;
1413
+ const close = opts.onClose === void 0 ? null : el("button", {
1414
+ className: "stepbar-nav stepbar-close",
1415
+ text: icon.close,
1416
+ tip: opts.closeTip ?? "Close",
1417
+ onClick: opts.onClose
1418
+ });
1419
+ const actions = (opts.actions ?? []).filter((a) => a !== null && a !== void 0);
1420
+ if (items.length === 0) {
1421
+ if (opts.empty === void 0) {
1422
+ host.hidden = true;
1423
+ host.replaceChildren();
1424
+ return;
1425
+ }
1426
+ host.hidden = false;
1427
+ host.replaceChildren(
1428
+ el("span", { className: "stepbar-count muted", text: "0" }),
1429
+ el("span", { className: "stepbar-empty", text: opts.empty }),
1430
+ ...actions,
1431
+ ...close ? [close] : []
1432
+ );
1433
+ return;
1434
+ }
1435
+ host.hidden = false;
1436
+ const index = Math.min(Math.max(opts.at, 0), items.length - 1);
1437
+ const item = items[index];
1438
+ const step = (delta) => opts.onStep((index + delta + items.length) % items.length);
1439
+ const nav = items.length > 1 ? [
1440
+ el("button", {
1441
+ className: "stepbar-nav",
1442
+ text: icon.back,
1443
+ tip: opts.tips?.prev ?? "Previous",
1444
+ onClick: () => step(-1)
1445
+ }),
1446
+ el("span", { className: "stepbar-of", text: `${index + 1}/${items.length}` }),
1447
+ el("button", {
1448
+ className: "stepbar-nav",
1449
+ text: icon.forward,
1450
+ tip: opts.tips?.next ?? "Next",
1451
+ onClick: () => step(1)
1452
+ })
1453
+ ] : [];
1454
+ host.replaceChildren(
1455
+ el("span", { className: `stepbar-count ${opts.tone ?? "muted"}`, text: String(items.length) }),
1456
+ ...nav,
1457
+ el(
1458
+ "button",
1459
+ { className: "stepbar-cur", tip: opts.tips?.go ?? "Go to this", onClick: () => opts.onGo(index) },
1460
+ item.kind === void 0 ? null : el("span", { className: `stepbar-cat${item.kindClass ? ` ${item.kindClass}` : ""}`, text: item.kind }),
1461
+ item.where === void 0 ? null : el("span", { className: "stepbar-where", text: item.where }),
1462
+ el("span", { className: "stepbar-msg", text: item.text })
1463
+ ),
1464
+ ...actions,
1465
+ ...close ? [close] : []
1466
+ );
1467
+ }
1468
+
1469
+ export { PALETTE, PALETTE_SIZE, askIdentity, closeAnchoredPanel, colourFor, colourIndex, confirmDialog, createSaveController, dupGuard, el, expandableRow, focusNewRow, foldVc, gameIdify, hideTip, icon, iconBtn, iconSvg, initTooltips, isValidGameId, labelled, lockControls, lockNotice, mountJobProgress, mountPaneShell, mountSettingsDialog, moveItem, openAnchoredPanel, openComments, openGameIdEditor, openNotesEditor, paintVcBadges, pinButton, placeAnchored, renderStepperBar, saveIndicator, showAbout, staleBar, tagChips, tipAt, tipBold, vcBadgeFor };
1368
1470
  //# sourceMappingURL=index.js.map
1369
1471
  //# sourceMappingURL=index.js.map