@gjermundgaraba-designs/pixel-paper 0.14.1 → 0.16.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/DESIGN.md +7 -6
- package/dist/src/card/card.d.ts +10 -5
- package/dist/src/card/card.d.ts.map +1 -1
- package/dist/src/card/card.js +4 -4
- package/dist/src/commandPalette/commandPalette.d.ts +0 -4
- package/dist/src/commandPalette/commandPalette.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.d.ts +17 -24
- package/dist/src/confirmDialog/confirmDialog.d.ts.map +1 -1
- package/dist/src/confirmDialog/confirmDialog.js +16 -22
- package/dist/src/confirmDialog/index.d.ts +1 -1
- package/dist/src/confirmDialog/index.d.ts.map +1 -1
- package/dist/src/confirmDialog/index.js +1 -1
- package/dist/src/dialog/dialog.d.ts +14 -20
- package/dist/src/dialog/dialog.d.ts.map +1 -1
- package/dist/src/dialog/dialog.js +10 -23
- package/dist/src/dialog/fold.d.ts +9 -1
- package/dist/src/dialog/fold.d.ts.map +1 -1
- package/dist/src/dialog/fold.js +9 -5
- package/dist/src/dialog/index.d.ts +2 -2
- package/dist/src/dialog/index.d.ts.map +1 -1
- package/dist/src/dialog/index.js +1 -1
- package/dist/src/keyHelp/keyHelp.d.ts +0 -4
- package/dist/src/keyHelp/keyHelp.d.ts.map +1 -1
- package/dist/src/panel/panel.d.ts +3 -0
- package/dist/src/panel/panel.d.ts.map +1 -1
- package/dist/src/panel/panel.js +2 -1
- package/dist/src/sortable/sortable.d.ts +19 -7
- package/dist/src/sortable/sortable.d.ts.map +1 -1
- package/dist/src/sortable/sortable.js +30 -21
- package/package.json +1 -1
- package/src/card/card.ts +12 -6
- package/src/confirmDialog/confirmDialog.ts +20 -27
- package/src/confirmDialog/index.ts +0 -2
- package/src/dialog/dialog.ts +23 -30
- package/src/dialog/fold.ts +25 -6
- package/src/dialog/index.ts +1 -3
- package/src/panel/panel.ts +5 -1
- package/src/pixel-paper.css +87 -10
- package/src/sortable/sortable.ts +55 -23
package/DESIGN.md
CHANGED
|
@@ -1037,7 +1037,7 @@ The printed button: a paper rectangle in a 2px ink frame that casts a 3px shadow
|
|
|
1037
1037
|
|
|
1038
1038
|
### Panels
|
|
1039
1039
|
|
|
1040
|
-
- **Panel** → `section.panel[aria-labelledby] > header.panel-tb > h2 + span.meta`, then `div.panel-body` (or the body directly when `isFlush`), then `div.panel-foot`. The section is keyed by its `id`, so a panel among siblings that come and go keeps its own element, and a panel under another id is another element: one that replaces another in the same place is built anew (a live region inside it is inserted, not kept), so keep one panel under one id across states that should share it. Square, 2px ink border, Paper White, panel shadow. The title bar is inverted Departure Mono 13px uppercase 0.08em (`--tracking-title`), `padding: 6px 12px`; its meta is 11px at 75% opacity. A control in a title bar (a panel's, a window's or a card's) rings in paper, 2px inside its own edge, because the ink ring would vanish on the ink bar. The body pads 16px with a 14px grid gap; the foot pads `10px 12px` over a 1px rule, with a `.push` slot that goes right. `actions` puts small Buttons and IconButtons in `span.panel-acts` (6px apart) at the title bar's right end, after the meta; the bar trims to `3px 3px 3px 12px` at 31px or more. On the ink bar a button is a paper outline (a primary one fills paper), flat, nudged 1px when pressed, its ring 4px inside in its own colour; disabled, it prints at 60%.
|
|
1040
|
+
- **Panel** → `section.panel[aria-labelledby] > header.panel-tb > span.panel-lead + h2 + span.meta`, then `div.panel-body` (or the body directly when `isFlush`), then `div.panel-foot`. The section is keyed by its `id`, so a panel among siblings that come and go keeps its own element, and a panel under another id is another element: one that replaces another in the same place is built anew (a live region inside it is inserted, not kept), so keep one panel under one id across states that should share it. Square, 2px ink border, Paper White, panel shadow. The title bar is inverted Departure Mono 13px uppercase 0.08em (`--tracking-title`), `padding: 6px 12px`; its meta is 11px at 75% opacity. A control in a title bar (a panel's, a window's or a card's) rings in paper, 2px inside its own edge, because the ink ring would vanish on the ink bar. The body pads 16px with a 14px grid gap; the foot pads `10px 12px` over a 1px rule, with a `.push` slot that goes right. `actions` puts small Buttons and IconButtons in `span.panel-acts` (6px apart) at the title bar's right end, after the meta; the bar trims to `3px 3px 3px 12px` at 31px or more. `lead` puts a quiet IconButton in `span.panel-lead` before the title (a Sortable's grip), and the bar trims its left to 3px the same way; a quiet icon button there prints in paper, hovered too, and held at 60%. On the ink bar a button is a paper outline (a primary one fills paper), flat, nudged 1px when pressed, its ring 4px inside in its own colour; disabled, it prints at 60%.
|
|
1041
1041
|
- **Deck** → `main.deck#main`: the column of panels.
|
|
1042
1042
|
- **EmptyState** → `div.empty > h3.empty-title + p`: `headingLevel` is required and picks the title's element, which looks the same at every level. Where the empty state is a page's or a section's main content it is a heading, `3` inside a Panel (whose title is an `h2`), `1` for a gate or a missing page; `"Strong"` prints `strong.empty-title` where it is not (a chart with nothing to chart, a picture of the state). Centred, `26px 16px`, a 12px uppercase 0.08em (`--tracking-title`) headline, a muted 46ch sentence, an optional action 6px below.
|
|
1043
1043
|
- **Wall** → `main.wall`, `Wall.markView` → `div.wall-mark` (a 30px ink-bordered glyph box beside the 22px wordmark). `Wall.cornerView` → `aside.wall-corner[aria-label]`, rendered just before the Wall: a paper slip in a 2px ink box on the 3px shadow, `6px 8px`, holding what a top bar would (see Layout).
|
|
@@ -1055,11 +1055,11 @@ The printed button: a paper rectangle in a 2px ink frame that casts a 3px shadow
|
|
|
1055
1055
|
|
|
1056
1056
|
### Cards (dialogs)
|
|
1057
1057
|
|
|
1058
|
-
**Dialog** is a Submodel over `@foldkit/ui`'s Dialog: a `<dialog class="veil">` that fills the viewport, opened with `show()` in place rather than `showModal()` in the top layer. That is a deliberate exception to the baseline's "prefer the platform" for overlays: Foldkit's Dialog (through `Dom.showDialog`) makes everything outside the dialog `inert` and `aria-hidden`, traps focus, handles Escape on the topmost dialog and returns focus on close, so the platform's modal behaviour is reproduced, not dropped; what is lost is the top layer and its `::backdrop`. The veil is therefore an element of its own, `div.veil-backdrop` (fixed, Veil with the ink checker grain, entering in 3 steps over 0.12s), under `div.veil-pad` (`.top` for the palette), which lets a press through everywhere but on the card it holds; a press on the veil, Escape, or a control given the `closeButton` group closes it and reports `Closed`. While its work must land in it (a save whose failure the reader has to see), the
|
|
1058
|
+
**Dialog** is a Submodel over `@foldkit/ui`'s Dialog: a `<dialog class="veil">` that fills the viewport, opened with `show()` in place rather than `showModal()` in the top layer. That is a deliberate exception to the baseline's "prefer the platform" for overlays: Foldkit's Dialog (through `Dom.showDialog`) makes everything outside the dialog `inert` and `aria-hidden`, traps focus, handles Escape on the topmost dialog and returns focus on close, so the platform's modal behaviour is reproduced, not dropped; what is lost is the top layer and its `::backdrop`. The veil is therefore an element of its own, `div.veil-backdrop` (fixed, Veil with the ink checker grain, entering in 3 steps over 0.12s), under `div.veil-pad` (`.top` for the palette), which lets a press through everywhere but on the card it holds; a press on the veil, Escape, or a control given the `closeButton` group closes it and reports `Closed`. While its work must land in it (a save whose failure the reader has to see), the parent holds those three: its update passes `isCloseHeld` to the dialog's (`Dialog.update(model, message, { isCloseHeld })`, or `foldDialog`'s `isCloseHeld: (model) => model.isSaving`), read from its own state as each Message arrives, so the hold starts with the work, ends with it, and covers a key pressed before the next render: the dialog stays open and reports no `Closed`. Nothing is stored, so there is nothing to let go of. Opening and closing are the parent's, through `Dialog.open` and `Dialog.close` in its update, and a step the parent asked for reports nothing; `Dialog.foldDialog` lifts a dialog the parent always holds (its update, `open` and `close`) into the parent at once, `Closed` reported only where the parent maps it. The content is the parent's `toView`, which receives the attribute groups to spread (`title`, `description`, `initialFocus`, `closeButton`, `actionBar`). Focus starts on the element given the `initialFocus` group, else the first control. The Card inside names the dialog through its title (the `title` group, `aria-labelledby`); a dialog without a heading takes `label`, printed for screen readers only. `isAlert` makes it an `alertdialog`, and `hasDescription` points `aria-describedby` at the element given the `description` group. Because the page outside is inert and hidden, anything that must be heard or reached while it is open renders inside it: the topmost open dialog hosts the page's live region and the toast stack, both outside the card, through its `toLiveRegionView` (see Building components).
|
|
1059
1059
|
|
|
1060
|
-
**Card** → `div.card` (`.narrow`; `form.card` from `Card.formView`, named by its title (`aria-label`), so a form landmark; no role of its own, the Dialog around it is the dialog): a paper panel with the card shadow, `min(680px, 100%)` (440px narrow), entering in 3 steps over 0.14s from `scale(0.97)`. An inverted title bar `header.card-tb` (`6px 8px 6px 12px`, 13px uppercase 0.06em (`--tracking-head`), a close IconButton when it has `closeAttributes`, held by `Card.formView`'s `isBusy` while work the reader may not walk away from runs: `aria-disabled`, in the keyboard, its `closeAttributes` and so its handler dropped, faded to 0.6 on the bar, as a held button in a panel's title bar), a scrolling `div.card-body` (16px, 14px gap; a word longer than the card, a path or an id, breaks rather than widening it), and `div.card-actions` (`12px 16px`) over a 2px ink rule: `lead` first, then `span.card-acts` holding the actions at the right, which drop below the lead together when the bar wraps. Inside a Dialog, where the page's keys wait, the bar moves focus between its actions: `h` or ← to the one before, `l` or → to the one after, in the order they print, stopping at the ends, never pressing one (Enter, Space and Tab stay the browser's). The keys are bound by a Mount on the bar (`BindActionKeys`), which reads the real key event: only a key whose target is one of that bar's own buttons or links, unmodified, outside an IME and not already handled, and only when there is an action that way, moves focus and has its default prevented. A field, the title bar's close, a menu's items and a nested dialog's bar keep their keys. A disabled action is passed over; an `aria-disabled` one (held: busy, done or disabled) is still a stop and still ignores presses. **Card.formView** is the one way to make a form card: its `body` in one Fields group, then the action bar's `lead` (a form's own delete, before the push), cancel (`cancel`, closing through `closeAttributes`) and the primary default submit button (`submit`, its id `Card.submitId(id)`). One flag, `isBusy`, holds every way the form could change or leave while its work runs: the submit button prints busy and turns `type="button"`, the close glyph and cancel are held with their close attributes dropped, and the Fields group is natively disabled and `aria-busy`, so nothing changes under the send and nothing sends twice. In a Dialog, the
|
|
1060
|
+
**Card** → `div.card` (`.narrow`; `form.card` from `Card.formView`, named by its title (`aria-label`), so a form landmark; no role of its own, the Dialog around it is the dialog): a paper panel with the card shadow, `min(680px, 100%)` (440px narrow), entering in 3 steps over 0.14s from `scale(0.97)`. An inverted title bar `header.card-tb` (`6px 8px 6px 12px`, 13px uppercase 0.06em (`--tracking-head`), a close IconButton when it has `closeAttributes`, held by `Card.formView`'s `isBusy` while work the reader may not walk away from runs: `aria-disabled`, in the keyboard, its `closeAttributes` and so its handler dropped, faded to 0.6 on the bar, as a held button in a panel's title bar), a scrolling `div.card-body` (16px, 14px gap; a word longer than the card, a path or an id, breaks rather than widening it), and `div.card-actions` (`12px 16px`) over a 2px ink rule: `lead` first, then `span.card-acts` holding the actions at the right, which drop below the lead together when the bar wraps. Inside a Dialog, where the page's keys wait, the bar moves focus between its actions: `h` or ← to the one before, `l` or → to the one after, in the order they print, stopping at the ends, never pressing one (Enter, Space and Tab stay the browser's). The keys are bound by a Mount on the bar (`BindActionKeys`), which reads the real key event: only a key whose target is one of that bar's own buttons or links, unmodified, outside an IME and not already handled, and only when there is an action that way, moves focus and has its default prevented. A field, the title bar's close, a menu's items and a nested dialog's bar keep their keys. A disabled action is passed over; an `aria-disabled` one (held: busy, done or disabled) is still a stop and still ignores presses. **Card.formView** is the one way to make a form card: its `body` in one Fields group, then the action bar's `lead` (a form's own delete, before the push), cancel (`cancel`, closing through `closeAttributes`) and the primary default submit button (`submit`, its id `Card.submitId(id)`). One flag, `isBusy`, holds every way the form could change or leave while its work runs: the submit button prints busy and turns `type="button"`, the close glyph and cancel are held with their close attributes dropped, and the Fields group is natively disabled and `aria-busy`, so nothing changes under the send and nothing sends twice. In a Dialog, the state that sets `isBusy` is the `isCloseHeld` the parent passes the Dialog's update, so Escape and the veil are held with it, and a failed send frees both, the reason on the field (the specimen's rename refuses a name with a slash). `notices` print above the Fields group, outside the hold: what the page says while the form is open (a lost connection with its retry), whose controls stay live while it sends. `isSubmitDisabled` holds the submit button alone while there is nothing to send (a name unchanged), the fields and cancel live. The fields leave the keyboard as they are held, so the update moves focus to the submit button as it sends (`Focus.Focus({ id: Card.submitId(id) })`), and it still ignores `onSubmit` while busy, for an Enter that raced the render. A ConfirmDialog with `isDanger` still opens on cancel.
|
|
1061
1061
|
|
|
1062
|
-
- **ConfirmDialog** → a Submodel over Dialog (an `alertdialog` when `isDanger`, a `dialog` otherwise) holding a narrow Card whose body is an Outcome (warn, or error when `isDanger`), the Outcome's body describing the dialog. Its view inputs follow the system's words: `title` (the title bar), `question` (the Outcome's title), `body`, and `label` (the confirming button's word). Without `isDanger` the confirm is primary and default; with it the confirm is the red button and cancel is the default, where focus starts. `Confirmed` does not close it: work that takes a while stays in the dialog. `isBusy` holds the confirming button (its word, the working cursor, focus kept, a second press ignored)
|
|
1062
|
+
- **ConfirmDialog** → a Submodel over Dialog (an `alertdialog` when `isDanger`, a `dialog` otherwise) holding a narrow Card whose body is an Outcome (warn, or error when `isDanger`), the Outcome's body describing the dialog. Its view inputs follow the system's words: `title` (the title bar), `question` (the Outcome's title), `body`, and `label` (the confirming button's word). Without `isDanger` the confirm is primary and default; with it the confirm is the red button and cancel is the default, where focus starts. `Confirmed` does not close it: work that takes a while stays in the dialog. `isBusy` holds the confirming button (its word, the working cursor, focus kept, a second press ignored) and cancel (`aria-disabled`, in the keyboard, no ring and no shadow while the busy commit keeps focus); the parent calls `ConfirmDialog.close` when the work lands, or keeps it open while it is not done. `isDisabled` holds it the same way without the working cursor, for an action that is blocked rather than running (writes not accepted yet). `toDetailView` prints the application's own content under the sentence, inside the Outcome's body and so in the dialog's description: what the work said back (a refused delete's reason as an error Notice) or a notice with its own retry. Cancel, Escape and the veil report `Cancelled`; the parent decides whether that also stops work already running, and ignores the work's result once cancelled. The parent passes the same state as `isCloseHeld` to `ConfirmDialog.update`, so cancel, Escape and a press on the veil change nothing while the work runs: the dialog stays open and reports no `Cancelled`, and the reader sees how it ends.
|
|
1063
1063
|
- **CommandPalette** (Submodel over Dialog and `@foldkit/ui`'s Input with a listbox of its own, since a combobox would not let the cursor land on held rows or Escape reach the Dialog) → a card at 18vh holding `div.palette-q` (a `span.palette-scope` and a combobox input), `div.palette-detail` when the app gives `toDetailView`, `div.palette-list[role="listbox"]` of `div.palette-group` headings and `div.palette-row[role="option"][aria-selected]` rows (control register; `isAuthored` titles, `.authored`, set in sans with a glyph and wait for a query), a `div.sr-only[role="status"]`, and `div.palette-more`. Once a query is typed the status says how many rows it finds ("3 results.", "Nothing matches."); it is empty as the card opens and on a fresh page, so it is never mounted holding its words (rule 12). Labels and hints wrap within their row, including long names and destination paths. One cursor: the inverted row, moved by the keys only. ↑ ↓ move it and stop at the ends, each key one row from where the last left it however fast they come (the field's own handler, in the view, reports `PressedArrowKey` with the rows its render showed, and update steps from the Model's cursor); Home and End stay the field's, moving the caret; Enter does what a click on its row does, decided in update from what the render showed each row to be (held, opening a page, a choice on a page): a command closes the palette first so what it opens takes focus, and reports `SelectedCommand`. An arrow or an Enter pressed before the list has caught up with the keys before it (straight after a letter, or before the arrows already waiting have moved the cursor) cannot name a row yet, so it waits for the next render: the row that render shows the cursor on becomes the cursor, and a waiting Enter acts on it as on any row. So arrows typed straight after a letter step through the new query's rows, and an Enter acts on the keys before it, never on letters typed after it. While the palette is open, ↑ ↓ and Enter pressed before its field has focus (straight after the key that opened it) are its own too: `CommandPalette.subscriptions(keyPrefix)` takes them on the window before the page's bindings see them, and they wait as above. A key an IME is composing stays the IME's. The pointer shades the row under it (Header Grey, as a list's row) and a click runs that row; it never moves the cursor and never scrolls. The cursor comes into view on every key that moves it, when the view or the query changes, and when its row leaves the list (it falls back to the first): the app, which changes the list, returns `CommandPalette.ScrollToCursor` with the palette's id; a row that only reflows is not followed. The cursor holds to its row by id while the app updates the list; `CommandPalette.maybeCursorId` reads the row it shows for a list of commands, so the app can compare it before and after its change. A row with `isDisabled` prints muted (`[aria-disabled="true"]`), its `reason` in the hint, and the cursor still lands on it but Enter and a click do nothing. **Pages:** a command with a `page` (a status, a date, a destination) ends in a caret and opens that page in place instead of closing: `div.palette-q` holds a Back IconButton, the scope chip (what the commands act on, kept on every page), the page's title (`span.palette-title`, pixel caps), then the page's own field (placeholder `find`, else "type to narrow"), focused. A long scope wraps inside its chip and the field takes its own line when too little is left beside it, so nothing leaves the card at 390px. The choices are found in like the commands. The choice in force now (`current`) carries a `current` tag and cannot be picked again. The cursor starts on the page's `start` (the next status; the first choice a typed query finds), else on `current`, else on the first choice, read while the reader has not moved it, so an application that keeps `start` steady across a change made elsewhere moves the tag, not the cursor. Back, or Backspace in an empty field, returns to the commands with their query and cursor as they were, also when the palette opened straight on a page (`CommandPalette.openAt`). A pick (`SelectedChoice`) holds the page until the parent answers: the row prints the working cursor, the list is `aria-busy`, and moving, picking, typing and Back wait. With `CommandPalette.pickSucceeded` the palette closes; with `pickFailed` the page stays with its query, focus and the cursor on that choice, and the app says why in `toDetailView`, which shows on the commands and on every page alike. Escape closes the whole palette, even while a pick is out, and reports `Closed`; an answer arriving after that, or after the page was left, changes nothing. A page whose command leaves the list gives way to the commands. One level: choices do not open pages.
|
|
1064
1064
|
- **Keymap** → `div.keymap > div > h3 + div.keymap-row > kbd + span`: keys in the 11px pixel face under 10px muted group heads, for a narrow Card.
|
|
1065
1065
|
|
|
@@ -1097,7 +1097,7 @@ One keyboard for the page, Vim first, with the arrows beside the letters. The ke
|
|
|
1097
1097
|
|
|
1098
1098
|
### Sortable
|
|
1099
1099
|
|
|
1100
|
-
**Sortable** (Submodel over `@foldkit/ui`'s DragAndDrop, for items the reader puts in order: a list of rows or a grid of
|
|
1100
|
+
**Sortable** (Submodel over `@foldkit/ui`'s DragAndDrop, for items the reader puts in order: a list of rows, a grid of tiles, or a grid of the page's panels) → `div.sortable (.grid, .panels)` holding `ul.sortable-items[aria-label]` (a plain list: no listbox, so an item's content may hold anything) of `li.sortable-item (.movable, .drag-dim, .drop-before, .drop-after)`, each a grip, then `div.sortable-body` with the parent's content, and the list's keyboard help in a `p.sr-only`. `"List"` (the default) prints rows edge to edge between 1px rules, for a flush panel, `8px 16px 8px 10px`, tinted head on hover; `"Grid"` prints tiles that wrap, 180px and up, 12px apart: paper slips in a 2px ink border on the 3px print shadow. `"Panels"` prints each item as the parent's own Panel, up to three across in the deck's 24px gutter and 300px and up, so two across and then one as the column narrows; a row takes its tallest panel's height, each panel's foot sits at its bottom, and the list hands each item its grip (`render.grip`) for the panel's `lead` instead of printing it beside the item. The held copy is the whole panel, tinted head on the 8px card shadow, under ids of its own, and the drop line runs down the middle of the gutter. `isReadOnly`, for a reader who may look but not reorder, prints every grip held and lifts nothing, as holding moves does. Each item starts with a quiet `button.iconbtn` grip (in a panel's title bar, for `"Panels"`) (the grip glyph, named "Move <label>", `aria-roledescription="draggable"`, `aria-pressed`, described by the keyboard help); while moves are held it stays, held (`aria-disabled`, in the keyboard), so focus on it stays put when holding moves cancels one. A mouse drags an item by its body or its grip (`cursor: grab`); touch takes the grip alone (`touch-action: none` on a movable grip only, so a finger on a row scrolls the page); the keyboard takes the grip too: Space or Enter picks the item up, every arrow moves it one place in reading order, Space or Enter drops it, Escape puts it back (taken before a dialog or the page's keys see it), and Tab leaves it where it is. A press on a control inside an item, or on anything `[data-no-lift]`, never lifts it. Only the pointer that pressed moves the item; the browser cancelling it puts the item back. The held item dims to 40% in place (`.drag-dim`) and keeps its own print; a copy of it, `.lifted`, tinted head on the 8px card shadow in a 2px ink border (`aria-hidden`, `inert`, rendered with `isLifted`, so it carries no ids), follows the pointer in `div.sortable-lift`, or, held by the keyboard, prints in the list where it would land, in `li.sortable-slot`, counted as no item. Where a pointer would drop it, a 2px dashed ink line prints beside the item it lands next to (`.drop-before`, or `.drop-after` past the last), over the layout, so nothing moves under the pointer. The pointer's place is read from the item whose centre is closest, across where items sit side by side and down a column, and read again where the pointer is let go, so a page that scrolled under a still pointer drops where the pointer is. Each step is said through the page's live region in words from the item's `label` and its place, counted from one ("Beta, 3 of 4."). The items are the parent's: a drop reports `Moved`, and the parent moves the item, or decides not to, and flashes it; a drop where the item was, outside the list, or while moves are held reports nothing. While a pointer presses or carries an item the page's root carries `data-pixel-paper-dragging`, which prints the grabbing cursor everywhere and holds text selection.
|
|
1101
1101
|
|
|
1102
1102
|
### Inputs / Fields
|
|
1103
1103
|
|
|
@@ -1221,7 +1221,8 @@ Each component is `src/<name>/<name>.ts` with an explicit `index.ts`, a colocate
|
|
|
1221
1221
|
15. **A Mount reports through the parent.** A View that owns a Mount takes a required `toParentMessage: (message: X.Message) => ParentMessage` (TopBar, StatusBar, Toolbar, the mermaid adapter), and a fire-and-forget Mount maps to a caller `Completed*` Message the parent may ignore. A bare `onX: Message` is used only where the parent's Model acts on the fact (ImageFrame's `onBroken`). In a Scene, resolve the Mount by name with the lifted Message: `Scene.Mount.resolve({ name: X.Mount.name }, toParentMessage(...))`. Where every application's Scene must resolve a component's Mounts to render a page at all, the namespace exports `sceneMounts`, the matchers paired with Messages that change nothing, for `Scene.Mount.resolveAll(...X.sceneMounts)`: `TopBar.sceneMounts(toParentMessage)`, `Toast.sceneMounts` and `Dialog.sceneMounts` (which serves ConfirmDialog, KeyHelp and CommandPalette too).
|
|
1222
1222
|
16. **Fragment links focus through the application.** A link to `#id` (SkipLink, an ErrorSummary's links) needs the application's URL handler to return `SkipLink.ScrollToFragment` for the changed URL, since Foldkit routes the click.
|
|
1223
1223
|
17. **Platform services are the application's.** A component that needs a platform service says so in its TSDoc and here (CopyButton writes through Effect's `Clipboard`), and the application provides the Layer in its `resources`.
|
|
1224
|
-
18. **
|
|
1224
|
+
18. **Held work gives up.** Work that holds a dialog's ways out (a save, a delete) waits on something outside the page, which can hang, and a hang would shut the reader in. Its Command ends in a timeout mapped to its failure Message (`Effect.timeoutOrElse({ duration, orElse: () => Effect.succeed(FailedSave({ … })) })`), so the hold always ends with the reason in the dialog.
|
|
1225
|
+
19. **Upstream gaps.** Where `@foldkit/ui` lacks a capability, the workaround carries `// NOTE: @foldkit/ui gap: <what>` at its site, and that note is the record: there is no list beside it. A wrapper that must build a child Message itself says so in the same note, with a lint disable on that line alone.
|
|
1225
1226
|
|
|
1226
1227
|
## Do's and Don'ts
|
|
1227
1228
|
|
package/dist/src/card/card.d.ts
CHANGED
|
@@ -32,6 +32,10 @@ export type FormViewConfig<Message> = Omit<ViewConfig<Message>, "body" | "closeA
|
|
|
32
32
|
/** The form's content, fields and all, in one Fields group that `isBusy` holds. A link in
|
|
33
33
|
* it (an ErrorSummary's) stays live. */
|
|
34
34
|
body: ReadonlyArray<Html | string>;
|
|
35
|
+
/** Above the fields, outside the group `isBusy` holds: what the page says about the form
|
|
36
|
+
* while it is open (a lost connection with its retry), whose controls stay live while it
|
|
37
|
+
* sends. */
|
|
38
|
+
notices?: ReadonlyArray<Html | string>;
|
|
35
39
|
/** The submit button's words. It prints primary, the card's default. */
|
|
36
40
|
submit: string;
|
|
37
41
|
/** The cancel button's words, before the submit. It closes through `closeAttributes`. */
|
|
@@ -41,9 +45,10 @@ export type FormViewConfig<Message> = Omit<ViewConfig<Message>, "body" | "closeA
|
|
|
41
45
|
closeAttributes?: Attributes<Message>;
|
|
42
46
|
/** The form's work is running (it sends): the submit button is busy, the close glyph and
|
|
43
47
|
* cancel are held without `closeAttributes`, and the body is natively disabled, so
|
|
44
|
-
* nothing changes under the send and nothing sends twice. In a Dialog,
|
|
45
|
-
*
|
|
46
|
-
* so the update still ignores `onSubmit` while
|
|
48
|
+
* nothing changes under the send and nothing sends twice. In a Dialog, pass the same state
|
|
49
|
+
* as `isCloseHeld` to its update, so Escape and the veil are held too. Enter in a field
|
|
50
|
+
* can submit before the fields are held, so the update still ignores `onSubmit` while
|
|
51
|
+
* busy. */
|
|
47
52
|
isBusy?: boolean;
|
|
48
53
|
/** The form cannot be sent yet (nothing to send): the submit button is held as a Button
|
|
49
54
|
* is, and the fields and cancel stay live. Enter in a field can still submit, so the
|
|
@@ -56,7 +61,7 @@ export type FormViewConfig<Message> = Omit<ViewConfig<Message>, "body" | "closeA
|
|
|
56
61
|
* to the page: the form's update moves it here as it sends, with
|
|
57
62
|
* `Focus.Focus({ id: Card.submitId(id) })`. */
|
|
58
63
|
export declare const submitId: (id: string) => string;
|
|
59
|
-
/** A card that is a form, named by its title, so a form landmark: its body in
|
|
60
|
-
* group, then cancel and the primary submit button in the action bar. */
|
|
64
|
+
/** A card that is a form, named by its title, so a form landmark: its notices, its body in
|
|
65
|
+
* one Fields group, then cancel and the primary submit button in the action bar. */
|
|
61
66
|
export declare const formView: <Message>(config: FormViewConfig<Message>, h: HtmlBuilder<Message>) => Html;
|
|
62
67
|
//# sourceMappingURL=card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../src/card/card.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAQ9D,sDAAsD;AACtD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC;gDAC4C;IAC5C,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACvC,uEAAuE;IACvE,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACpC;6DACyD;IACzD,mBAAmB,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CAC3C,CAAC,CAAC;AAsDH,6FAA6F;AAC7F,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IACd,CAAC;AAIxE;;yDAEyD;AACzD,MAAM,MAAM,cAAc,CAAC,OAAO,IAAI,IAAI,CACxC,UAAU,CAAC,OAAO,CAAC,EACnB,MAAM,GAAG,iBAAiB,GAAG,SAAS,CACvC,GACC,QAAQ,CAAC;IACP,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX;6CACyC;IACzC,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;wEACoE;IACpE,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../src/card/card.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAQ9D,sDAAsD;AACtD,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC;gDAC4C;IAC5C,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACvC,uEAAuE;IACvE,IAAI,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACpC;6DACyD;IACzD,mBAAmB,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CAC3C,CAAC,CAAC;AAsDH,6FAA6F;AAC7F,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IACd,CAAC;AAIxE;;yDAEyD;AACzD,MAAM,MAAM,cAAc,CAAC,OAAO,IAAI,IAAI,CACxC,UAAU,CAAC,OAAO,CAAC,EACnB,MAAM,GAAG,iBAAiB,GAAG,SAAS,CACvC,GACC,QAAQ,CAAC;IACP,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX;6CACyC;IACzC,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC;;iBAEa;IACb,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACvC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;wEACoE;IACpE,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACtC;;;;;gBAKY;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;6DAEyD;IACzD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEL;;gDAEgD;AAChD,eAAO,MAAM,QAAQ,OAAQ,MAAM,KAAG,MAAwB,CAAC;AAE/D;qFACqF;AACrF,eAAO,MAAM,QAAQ,GAAI,OAAO,UACtB,cAAc,CAAC,OAAO,CAAC,KAC5B,WAAW,CAAC,OAAO,CAAC,KACtB,IAyDF,CAAC"}
|
package/dist/src/card/card.js
CHANGED
|
@@ -33,10 +33,10 @@ export const view = (config, h) => __foldkitBrandViewResult((h.div([h.Class(clas
|
|
|
33
33
|
* to the page: the form's update moves it here as it sends, with
|
|
34
34
|
* `Focus.Focus({ id: Card.submitId(id) })`. */
|
|
35
35
|
export const submitId = (id) => __foldkitBrandViewResult((`${id}-submit`), "@gjermundgaraba-designs/pixel-paper/src/card/card.js#submitId");
|
|
36
|
-
/** A card that is a form, named by its title, so a form landmark: its body in
|
|
37
|
-
* group, then cancel and the primary submit button in the action bar. */
|
|
36
|
+
/** A card that is a form, named by its title, so a form landmark: its notices, its body in
|
|
37
|
+
* one Fields group, then cancel and the primary submit button in the action bar. */
|
|
38
38
|
export const formView = (config, h) => {
|
|
39
|
-
const { id, title, submit, cancel, closeAttributes, isBusy = false, isSubmitDisabled = false, onSubmit, } = config;
|
|
39
|
+
const { id, title, submit, cancel, closeAttributes, notices = [], isBusy = false, isSubmitDisabled = false, onSubmit, } = config;
|
|
40
40
|
const cancelButton = cancel === undefined
|
|
41
41
|
? []
|
|
42
42
|
: [
|
|
@@ -62,7 +62,7 @@ export const formView = (config, h) => {
|
|
|
62
62
|
h.OnSubmit(onSubmit),
|
|
63
63
|
], childrenView({
|
|
64
64
|
...config,
|
|
65
|
-
body: [Fields.view({ body: config.body, isBusy }, h)],
|
|
65
|
+
body: [...notices, Fields.view({ body: config.body, isBusy }, h)],
|
|
66
66
|
isCloseHeld: isBusy,
|
|
67
67
|
actions: [...cancelButton, submitButton],
|
|
68
68
|
}, h))), "@gjermundgaraba-designs/pixel-paper/src/card/card.js#formView");
|
|
@@ -31,7 +31,6 @@ export declare const Model: Schema.Struct<{
|
|
|
31
31
|
}>;
|
|
32
32
|
readonly maybeFocusSelector: Schema.Option<Schema.String>;
|
|
33
33
|
}>;
|
|
34
|
-
readonly isCloseHeld: Schema.Boolean;
|
|
35
34
|
}>;
|
|
36
35
|
readonly query: Schema.String;
|
|
37
36
|
readonly maybeCursor: Schema.Option<Schema.String>;
|
|
@@ -127,7 +126,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
127
126
|
};
|
|
128
127
|
readonly maybeFocusSelector: Option.Option<string>;
|
|
129
128
|
};
|
|
130
|
-
readonly isCloseHeld: boolean;
|
|
131
129
|
};
|
|
132
130
|
readonly query: string;
|
|
133
131
|
readonly maybeCursor: Option.Option<string>;
|
|
@@ -291,7 +289,6 @@ export declare const subscriptions: <Prefix extends string>(keyPrefix: Prefix) =
|
|
|
291
289
|
};
|
|
292
290
|
readonly maybeFocusSelector: Option.Option<string>;
|
|
293
291
|
};
|
|
294
|
-
readonly isCloseHeld: boolean;
|
|
295
292
|
};
|
|
296
293
|
readonly query: string;
|
|
297
294
|
readonly maybeCursor: Option.Option<string>;
|
|
@@ -460,7 +457,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
460
457
|
};
|
|
461
458
|
readonly maybeFocusSelector: Option.Option<string>;
|
|
462
459
|
};
|
|
463
|
-
readonly isCloseHeld: boolean;
|
|
464
460
|
};
|
|
465
461
|
readonly query: string;
|
|
466
462
|
readonly maybeCursor: Option.Option<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandPalette.d.ts","sourceRoot":"","sources":["../../../src/commandPalette/commandPalette.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,MAAM,EAAS,MAAM,EAAE,MAAM,EAAwB,MAAM,QAAQ,CAAC;AACpF,OAAO,KAAK,cAAc,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,EAAa,IAAI,EAAkC,MAAM,cAAc,CAAC;AAKpF,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAoBzC,OAAO,KAAK,EAAU,OAAO,EAAQ,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAavC;;;;;;;;;;;kDAWkD;AAClD,eAAO,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"commandPalette.d.ts","sourceRoot":"","sources":["../../../src/commandPalette/commandPalette.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import type { Html } from "foldkit/html";
|
|
3
3
|
import * as Update from "foldkit/update";
|
|
4
|
+
import * as Dialog from "../dialog/dialog.ts";
|
|
4
5
|
/** Schema for a confirm dialog: the pixel-paper Dialog it opens in. */
|
|
5
6
|
export declare const Model: Schema.Struct<{
|
|
6
7
|
readonly dialog: Schema.Struct<{
|
|
@@ -16,7 +17,6 @@ export declare const Model: Schema.Struct<{
|
|
|
16
17
|
}>;
|
|
17
18
|
readonly maybeFocusSelector: Schema.Option<Schema.String>;
|
|
18
19
|
}>;
|
|
19
|
-
readonly isCloseHeld: Schema.Boolean;
|
|
20
20
|
}>;
|
|
21
21
|
}>;
|
|
22
22
|
export type Model = typeof Model.Type;
|
|
@@ -61,7 +61,7 @@ export type Message = typeof Message.Type;
|
|
|
61
61
|
/** Union of OutMessages a confirm dialog reports. `Confirmed`: the reader pressed the action;
|
|
62
62
|
* the dialog stays open until the parent calls `close`. `Cancelled`: cancel, Escape or a click
|
|
63
63
|
* on the veil; the dialog has closed, and whether that also stops work already running is
|
|
64
|
-
* the parent's to decide. Never reported while its ways out are held (`
|
|
64
|
+
* the parent's to decide. Never reported while its ways out are held (`Dialog.UpdateContext`). */
|
|
65
65
|
export declare const OutMessage: import("foldkit/message").MessageUnion<{
|
|
66
66
|
readonly Confirmed: {};
|
|
67
67
|
readonly Cancelled: {};
|
|
@@ -73,8 +73,9 @@ export type InitConfig = Readonly<{
|
|
|
73
73
|
}>;
|
|
74
74
|
/** Creates a closed confirm dialog. */
|
|
75
75
|
export declare const init: (config: InitConfig) => Model;
|
|
76
|
-
/** Processes a confirm dialog Message and returns the next Model, Commands and OutMessage.
|
|
77
|
-
|
|
76
|
+
/** Processes a confirm dialog Message and returns the next Model, Commands and OutMessage.
|
|
77
|
+
* While `context.isCloseHeld`, cancel, Escape and the veil change nothing. */
|
|
78
|
+
export declare const update: (model: Model, message: Message, context?: Dialog.UpdateContext) => Readonly<{
|
|
78
79
|
model: {
|
|
79
80
|
readonly dialog: {
|
|
80
81
|
readonly dialog: {
|
|
@@ -89,7 +90,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
89
90
|
};
|
|
90
91
|
readonly maybeFocusSelector: import("effect/Option").Option<string>;
|
|
91
92
|
};
|
|
92
|
-
readonly isCloseHeld: boolean;
|
|
93
93
|
};
|
|
94
94
|
};
|
|
95
95
|
commands?: Update.Commands<{
|
|
@@ -143,23 +143,15 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
143
143
|
readonly _tag: "Confirmed";
|
|
144
144
|
};
|
|
145
145
|
}>;
|
|
146
|
-
/** Opens the confirm dialog
|
|
147
|
-
* when it is `isDanger`. */
|
|
146
|
+
/** Opens the confirm dialog: focus starts on the action, or on cancel when it is `isDanger`. */
|
|
148
147
|
export declare const open: (model: Model) => Update.Return<Model, Message>;
|
|
149
|
-
/** Closes the confirm dialog without reporting `Cancelled
|
|
150
|
-
*
|
|
148
|
+
/** Closes the confirm dialog without reporting `Cancelled`: call it once confirmed work has
|
|
149
|
+
* landed. */
|
|
151
150
|
export declare const close: (model: Model) => Update.Return<Model, Message>;
|
|
152
|
-
/** Holds cancel, Escape and the veil, or lets them go: while held the dialog stays open and
|
|
153
|
-
* reports no `Cancelled`, and cancel prints held (`aria-disabled`, in the keyboard). Hold it
|
|
154
|
-
* in the update that starts confirmed work whose failure must land here, and let go in the
|
|
155
|
-
* update where the work fails; `close` lets go once it lands. */
|
|
156
|
-
export declare const setCloseHeld: (model: Model, isHeld: boolean) => Model;
|
|
157
151
|
/** The confirm dialog's id, unique in the document. */
|
|
158
152
|
export declare const id: (model: Model) => string;
|
|
159
153
|
/** Whether the confirm dialog is open. */
|
|
160
154
|
export declare const isOpen: (model: Model) => boolean;
|
|
161
|
-
/** Whether its ways out are held (`setCloseHeld`). */
|
|
162
|
-
export declare const isCloseHeld: (model: Model) => boolean;
|
|
163
155
|
/** Per-render inputs passed to `view` through `h.submodel`'s `viewInputs`. */
|
|
164
156
|
export type ViewInputs = Readonly<{
|
|
165
157
|
/** The title bar: the action's name (`"Delete"`). */
|
|
@@ -179,8 +171,9 @@ export type ViewInputs = Readonly<{
|
|
|
179
171
|
/** Destructive: the confirming button turns red and cancel becomes the default. */
|
|
180
172
|
isDanger?: boolean;
|
|
181
173
|
/** The confirmed work is running: the confirming button is held (its word stays, the
|
|
182
|
-
* working cursor prints, a second press does nothing) and keeps focus
|
|
183
|
-
*
|
|
174
|
+
* working cursor prints, a second press does nothing) and keeps focus, and cancel is held
|
|
175
|
+
* with it. Pair it with `isCloseHeld` in `update`'s context, from the same state, so
|
|
176
|
+
* Escape and the veil change nothing either. */
|
|
184
177
|
isBusy?: boolean;
|
|
185
178
|
/** The action cannot run now (nothing is running; it is blocked): the confirming button is
|
|
186
179
|
* held, `aria-disabled` without the working cursor, and stays in the keyboard, so focus
|
|
@@ -199,9 +192,9 @@ export type ViewInputs = Readonly<{
|
|
|
199
192
|
* arm-then-confirm button: red never rests on a button, and an armed button is easy to
|
|
200
193
|
* double-click through.
|
|
201
194
|
*
|
|
202
|
-
* Work that takes a while stays in the dialog: set `isBusy` while it runs
|
|
203
|
-
* has landed, and on failure keep it open with the
|
|
204
|
-
*
|
|
195
|
+
* Work that takes a while stays in the dialog: set `isBusy` while it runs (and `isCloseHeld`
|
|
196
|
+
* in `update`'s context), `close` once it has landed, and on failure keep it open with the
|
|
197
|
+
* error in `toDetailView`.
|
|
205
198
|
*/
|
|
206
199
|
export declare const view: import("foldkit/submodel").View<{
|
|
207
200
|
readonly dialog: {
|
|
@@ -217,7 +210,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
217
210
|
};
|
|
218
211
|
readonly maybeFocusSelector: import("effect/Option").Option<string>;
|
|
219
212
|
};
|
|
220
|
-
readonly isCloseHeld: boolean;
|
|
221
213
|
};
|
|
222
214
|
}, {
|
|
223
215
|
readonly _tag: "ClickedCancel";
|
|
@@ -281,8 +273,9 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
281
273
|
/** Destructive: the confirming button turns red and cancel becomes the default. */
|
|
282
274
|
isDanger?: boolean;
|
|
283
275
|
/** The confirmed work is running: the confirming button is held (its word stays, the
|
|
284
|
-
* working cursor prints, a second press does nothing) and keeps focus
|
|
285
|
-
*
|
|
276
|
+
* working cursor prints, a second press does nothing) and keeps focus, and cancel is held
|
|
277
|
+
* with it. Pair it with `isCloseHeld` in `update`'s context, from the same state, so
|
|
278
|
+
* Escape and the veil change nothing either. */
|
|
286
279
|
isBusy?: boolean;
|
|
287
280
|
/** The action cannot run now (nothing is running; it is blocked): the confirming button is
|
|
288
281
|
* held, `aria-disabled` without the working cursor, and stays in the keyboard, so focus
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmDialog.d.ts","sourceRoot":"","sources":["../../../src/confirmDialog/confirmDialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAQ,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,cAAc,CAAC;AAItD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"confirmDialog.d.ts","sourceRoot":"","sources":["../../../src/confirmDialog/confirmDialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAQ,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,cAAc,CAAC;AAItD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAIzC,OAAO,KAAK,MAAM,MAAM,qBAAqB,CAAC;AAM9C,uEAAuE;AACvE,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;EAEhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAItC,0DAA0D;AAC1D,eAAO,MAAM,OAAO;;QACE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG3B,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAI1C;;;mGAGmG;AACnG,eAAO,MAAM,UAAU;;;EAGrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;AAIhD,+DAA+D;AAC/D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD,uCAAuC;AACvC,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAExC,CAAC;AAkBH;+EAC+E;AAC/E,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO,YAAW,MAAM,CAAC,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAShF,CAAC;AAEL,gGAAgG;AAChG,eAAO,MAAM,IAAI,UAAW,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAA2B,CAAC;AAE5F;cACc;AACd,eAAO,MAAM,KAAK,UAAW,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAA4B,CAAC;AAI9F,uDAAuD;AACvD,eAAO,MAAM,EAAE,UAAW,KAAK,KAAG,MAAiC,CAAC;AAEpE,0CAA0C;AAC1C,eAAO,MAAM,MAAM,UAAW,KAAK,KAAG,OAAsC,CAAC;AAI7E,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,QAAQ,EAAE,MAAM,CAAC;IACjB;;uCAEmC;IACnC,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACnC;;oBAEgB;IAChB,YAAY,CAAC,EAAE,MAAM,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IAClD,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;qDAGiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;wDAEoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;0CACsC;IACtC,gBAAgB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7C,CAAC,CAAC;AAwDH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAjGf,qDAAqD;WAC9C,MAAM;IACb,6FAA6F;cACnF,MAAM;IAChB;;uCAEmC;UAC7B,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC;IAClC;;oBAEgB;mBACD,MAAM,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC;IACjD,iDAAiD;WAC1C,MAAM;IACb,mFAAmF;eACxE,OAAO;IAClB;;;qDAGiD;aACxC,OAAO;IAChB;;wDAEoD;iBACvC,OAAO;IACpB;0CACsC;uBACnB,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;GAmF5C,CAAC"}
|
|
@@ -25,7 +25,7 @@ export const Message = defineMessageUnion({
|
|
|
25
25
|
/** Union of OutMessages a confirm dialog reports. `Confirmed`: the reader pressed the action;
|
|
26
26
|
* the dialog stays open until the parent calls `close`. `Cancelled`: cancel, Escape or a click
|
|
27
27
|
* on the veil; the dialog has closed, and whether that also stops work already running is
|
|
28
|
-
* the parent's to decide. Never reported while its ways out are held (`
|
|
28
|
+
* the parent's to decide. Never reported while its ways out are held (`Dialog.UpdateContext`). */
|
|
29
29
|
export const OutMessage = defineMessageUnion({
|
|
30
30
|
Confirmed: {},
|
|
31
31
|
Cancelled: {},
|
|
@@ -44,33 +44,27 @@ const dialogFold = foldDialog(Dialog, {
|
|
|
44
44
|
toParentMessage: (message) => __foldkitBrandViewResult((Message.GotDialogMessage({ message })), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#toParentMessage"),
|
|
45
45
|
toParentOutMessage: toCancelled,
|
|
46
46
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const FREE = { isCloseHeld: false };
|
|
48
|
+
/** Processes a confirm dialog Message and returns the next Model, Commands and OutMessage.
|
|
49
|
+
* While `context.isCloseHeld`, cancel, Escape and the veil change nothing. */
|
|
50
|
+
export const update = (model, message, context = FREE) => __foldkitBrandViewResult((Message.match(message, {
|
|
51
|
+
GotDialogMessage: ({ message: dialogMessage }) => __foldkitBrandViewResult((dialogFold.updateWith(context)(model, dialogMessage)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#GotDialogMessage"),
|
|
50
52
|
ClickedConfirm: () => (__foldkitBrandViewResult(({ model, outMessage: OutMessage.Confirmed() }), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#ClickedConfirm")),
|
|
51
|
-
ClickedCancel: () => __foldkitBrandViewResult((
|
|
53
|
+
ClickedCancel: () => __foldkitBrandViewResult((context.isCloseHeld
|
|
52
54
|
? { model }
|
|
53
55
|
: pipe(dialogFold.close(model), Update.withOutMessage(OutMessage.Cancelled()))), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#ClickedCancel"),
|
|
54
56
|
})), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#update");
|
|
55
|
-
/** Opens the confirm dialog
|
|
56
|
-
* when it is `isDanger`. */
|
|
57
|
+
/** Opens the confirm dialog: focus starts on the action, or on cancel when it is `isDanger`. */
|
|
57
58
|
export const open = (model) => __foldkitBrandViewResult((dialogFold.open(model)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#open");
|
|
58
|
-
/** Closes the confirm dialog without reporting `Cancelled
|
|
59
|
-
*
|
|
59
|
+
/** Closes the confirm dialog without reporting `Cancelled`: call it once confirmed work has
|
|
60
|
+
* landed. */
|
|
60
61
|
export const close = (model) => __foldkitBrandViewResult((dialogFold.close(model)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#close");
|
|
61
|
-
/** Holds cancel, Escape and the veil, or lets them go: while held the dialog stays open and
|
|
62
|
-
* reports no `Cancelled`, and cancel prints held (`aria-disabled`, in the keyboard). Hold it
|
|
63
|
-
* in the update that starts confirmed work whose failure must land here, and let go in the
|
|
64
|
-
* update where the work fails; `close` lets go once it lands. */
|
|
65
|
-
export const setCloseHeld = (model, isHeld) => __foldkitBrandViewResult((modifyFields(model, { dialog: (dialog) => __foldkitBrandViewResult((Dialog.setCloseHeld(dialog, isHeld)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#dialog~2") })), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#setCloseHeld");
|
|
66
62
|
// ACCESSORS
|
|
67
63
|
/** The confirm dialog's id, unique in the document. */
|
|
68
64
|
export const id = (model) => __foldkitBrandViewResult((Dialog.id(model.dialog)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#id");
|
|
69
65
|
/** Whether the confirm dialog is open. */
|
|
70
66
|
export const isOpen = (model) => __foldkitBrandViewResult((Dialog.isOpen(model.dialog)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#isOpen");
|
|
71
|
-
|
|
72
|
-
export const isCloseHeld = (model) => __foldkitBrandViewResult((Dialog.isCloseHeld(model.dialog)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#isCloseHeld");
|
|
73
|
-
const cardView = (model, viewInputs, render, h) => {
|
|
67
|
+
const cardView = (viewInputs, render, h) => {
|
|
74
68
|
const { isDanger = false, isBusy = false, isDisabled = false, toDetailView } = viewInputs;
|
|
75
69
|
const commit = Button.view({
|
|
76
70
|
label: viewInputs.label,
|
|
@@ -84,7 +78,7 @@ const cardView = (model, viewInputs, render, h) => {
|
|
|
84
78
|
const cancel = Button.view({
|
|
85
79
|
label: "cancel",
|
|
86
80
|
isDefault: isDanger,
|
|
87
|
-
isDisabled:
|
|
81
|
+
isDisabled: isBusy,
|
|
88
82
|
onClick: Message.ClickedCancel(),
|
|
89
83
|
attributes: isDanger ? render.initialFocus : [],
|
|
90
84
|
}, h);
|
|
@@ -114,9 +108,9 @@ const cardView = (model, viewInputs, render, h) => {
|
|
|
114
108
|
* arm-then-confirm button: red never rests on a button, and an armed button is easy to
|
|
115
109
|
* double-click through.
|
|
116
110
|
*
|
|
117
|
-
* Work that takes a while stays in the dialog: set `isBusy` while it runs
|
|
118
|
-
* has landed, and on failure keep it open with the
|
|
119
|
-
*
|
|
111
|
+
* Work that takes a while stays in the dialog: set `isBusy` while it runs (and `isCloseHeld`
|
|
112
|
+
* in `update`'s context), `close` once it has landed, and on failure keep it open with the
|
|
113
|
+
* error in `toDetailView`.
|
|
120
114
|
*/
|
|
121
115
|
export const view = defineView((model, viewInputs, h) => __foldkitBrandViewResult((h.submodel({
|
|
122
116
|
slotId: id(model),
|
|
@@ -126,7 +120,7 @@ export const view = defineView((model, viewInputs, h) => __foldkitBrandViewResul
|
|
|
126
120
|
isAlert: viewInputs.isDanger ?? false,
|
|
127
121
|
hasDescription: true,
|
|
128
122
|
toLiveRegionView: viewInputs.toLiveRegionView,
|
|
129
|
-
toView: (render) => __foldkitBrandViewResult((cardView(
|
|
123
|
+
toView: (render) => __foldkitBrandViewResult((cardView(viewInputs, render, h)), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#toView"),
|
|
130
124
|
},
|
|
131
125
|
toParentMessage: (message) => __foldkitBrandViewResult((Message.GotDialogMessage({ message })), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#toParentMessage~2"),
|
|
132
126
|
})), "@gjermundgaraba-designs/pixel-paper/src/confirmDialog/confirmDialog.js#anonymous"));
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Message, Model, OutMessage, close, id, init,
|
|
1
|
+
export { Message, Model, OutMessage, close, id, init, isOpen, open, update, view, } from "./confirmDialog.ts";
|
|
2
2
|
export type { InitConfig, ViewInputs } from "./confirmDialog.ts";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/confirmDialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,EACL,EAAE,EACF,IAAI,EACJ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/confirmDialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,EACL,UAAU,EACV,KAAK,EACL,EAAE,EACF,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,MAAM,EACN,IAAI,GACL,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Message, Model, OutMessage, close, id, init,
|
|
1
|
+
export { Message, Model, OutMessage, close, id, init, isOpen, open, update, view, } from "./confirmDialog.js";
|
|
@@ -2,8 +2,7 @@ import { Option, Schema } from "effect";
|
|
|
2
2
|
import { type ChildAttribute, type Html } from "foldkit/html";
|
|
3
3
|
import * as Mount from "foldkit/mount";
|
|
4
4
|
import type * as Update from "foldkit/update";
|
|
5
|
-
/** Schema for a pixel-paper dialog: the `@foldkit/ui` Dialog it is built on
|
|
6
|
-
* ways out are held (`setCloseHeld`). */
|
|
5
|
+
/** Schema for a pixel-paper dialog: the `@foldkit/ui` Dialog it is built on. */
|
|
7
6
|
export declare const Model: Schema.Struct<{
|
|
8
7
|
readonly dialog: Schema.Struct<{
|
|
9
8
|
readonly id: Schema.String;
|
|
@@ -17,7 +16,6 @@ export declare const Model: Schema.Struct<{
|
|
|
17
16
|
}>;
|
|
18
17
|
readonly maybeFocusSelector: Schema.Option<Schema.String>;
|
|
19
18
|
}>;
|
|
20
|
-
readonly isCloseHeld: Schema.Boolean;
|
|
21
19
|
}>;
|
|
22
20
|
export type Model = typeof Model.Type;
|
|
23
21
|
/** Which way h, l and the side arrows move focus in a dialog's action bar. */
|
|
@@ -75,10 +73,17 @@ export declare const init: (config: InitConfig) => Model;
|
|
|
75
73
|
export declare const id: (model: Model) => string;
|
|
76
74
|
/** Whether the dialog is open. */
|
|
77
75
|
export declare const isOpen: (model: Model) => boolean;
|
|
78
|
-
/**
|
|
79
|
-
export
|
|
76
|
+
/** What a dialog's update reads from its parent as a Message arrives. */
|
|
77
|
+
export type UpdateContext = Readonly<{
|
|
78
|
+
/** The reader may not walk away from the work running now (a save whose failure must land
|
|
79
|
+
* in this dialog): Escape, a press on the veil and a control given the `closeButton` group
|
|
80
|
+
* change nothing and report no `Closed`. Read it from the parent's own state as the
|
|
81
|
+
* Message arrives (`isSaving(model)`), so it holds exactly while the work runs, however
|
|
82
|
+
* soon after the start a key comes. */
|
|
83
|
+
isCloseHeld: boolean;
|
|
84
|
+
}>;
|
|
80
85
|
/** Processes a dialog Message and returns the next Model, Commands and OutMessage. */
|
|
81
|
-
export declare const update: (model: Model, message: Message) => Readonly<{
|
|
86
|
+
export declare const update: (model: Model, message: Message, context?: UpdateContext) => Readonly<{
|
|
82
87
|
model: {
|
|
83
88
|
readonly dialog: {
|
|
84
89
|
readonly id: string;
|
|
@@ -92,7 +97,6 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
92
97
|
};
|
|
93
98
|
readonly maybeFocusSelector: Option.Option<string>;
|
|
94
99
|
};
|
|
95
|
-
readonly isCloseHeld: boolean;
|
|
96
100
|
};
|
|
97
101
|
commands?: Update.Commands<{
|
|
98
102
|
readonly _tag: "GotDialogMessage";
|
|
@@ -136,20 +140,11 @@ export declare const update: (model: Model, message: Message) => Readonly<{
|
|
|
136
140
|
readonly _tag: "Closed";
|
|
137
141
|
};
|
|
138
142
|
}>;
|
|
139
|
-
/** Opens the dialog
|
|
140
|
-
*
|
|
141
|
-
* dialog closes. */
|
|
143
|
+
/** Opens the dialog: focus moves to the element given the `initialFocus` group, else to the
|
|
144
|
+
* first control, and returns to where it was when the dialog closes. */
|
|
142
145
|
export declare const open: (model: Model) => Update.Return<Model, Message>;
|
|
143
|
-
/** Closes the dialog without reporting `Closed
|
|
146
|
+
/** Closes the dialog without reporting `Closed`. */
|
|
144
147
|
export declare const close: (model: Model) => Update.Return<Model, Message>;
|
|
145
|
-
/** Holds the dialog's ways out, or lets them go: while held, Escape, a press on the veil and
|
|
146
|
-
* a control given the `closeButton` group leave it open and report no `Closed`, so the
|
|
147
|
-
* result of work the reader may not walk away from (a save whose failure must land here)
|
|
148
|
-
* lands in it. Hold it in the update that starts the work, and let go in the update where
|
|
149
|
-
* the work fails, or the reader is shut in with the failure; `close` lets go once it lands,
|
|
150
|
-
* and `open` opens it free.
|
|
151
|
-
* Hold the card's own close controls too (`Card.formView`'s `isBusy`). */
|
|
152
|
-
export declare const setCloseHeld: (model: Model, isHeld: boolean) => Model;
|
|
153
148
|
/** Moves focus for one keydown in an action bar, and says which way it moved. It moves only
|
|
154
149
|
* when the key's target is one of the bar's own actions and there is an action that way:
|
|
155
150
|
* a key typed in a field, a menu's item or a nested dialog inside the bar, a key an IME is
|
|
@@ -237,7 +232,6 @@ export declare const view: import("foldkit/submodel").View<{
|
|
|
237
232
|
};
|
|
238
233
|
readonly maybeFocusSelector: Option.Option<string>;
|
|
239
234
|
};
|
|
240
|
-
readonly isCloseHeld: boolean;
|
|
241
235
|
}, {
|
|
242
236
|
readonly _tag: "GotDialogMessage";
|
|
243
237
|
readonly message: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../src/dialog/dialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAQ,MAAM,QAAQ,CAAC;AAE5D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAmB,MAAM,cAAc,CAAC;AAE/E,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AAGvC,OAAO,KAAK,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAO9C;
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../src/dialog/dialog.ts"],"names":[],"mappings":"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"}
|