@gjermundgaraba-designs/pixel-paper 0.20.0 → 0.21.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 (37) hide show
  1. package/DESIGN.md +3 -3
  2. package/dist/src/commandPalette/commandPalette.d.ts +4 -3
  3. package/dist/src/commandPalette/commandPalette.d.ts.map +1 -1
  4. package/dist/src/commandPalette/commandPalette.js +34 -35
  5. package/dist/src/commandPalette/match.d.ts +5 -2
  6. package/dist/src/commandPalette/match.d.ts.map +1 -1
  7. package/dist/src/commandPalette/match.js +14 -3
  8. package/dist/src/field/field.d.ts +3 -0
  9. package/dist/src/field/field.d.ts.map +1 -1
  10. package/dist/src/field/field.js +2 -2
  11. package/dist/src/lineDiff/index.d.ts +2 -0
  12. package/dist/src/lineDiff/index.d.ts.map +1 -1
  13. package/dist/src/lineDiff/index.js +1 -0
  14. package/dist/src/lineDiff/lineDiff.d.ts +8 -4
  15. package/dist/src/lineDiff/lineDiff.d.ts.map +1 -1
  16. package/dist/src/lineDiff/lineDiff.js +19 -15
  17. package/dist/src/lineDiff/patch.d.ts +35 -0
  18. package/dist/src/lineDiff/patch.d.ts.map +1 -0
  19. package/dist/src/lineDiff/patch.js +146 -0
  20. package/dist/src/menu/menu.d.ts +6 -6
  21. package/dist/src/reel/layout.d.ts +2 -1
  22. package/dist/src/reel/layout.d.ts.map +1 -1
  23. package/dist/src/reel/layout.js +22 -4
  24. package/dist/src/sortable/sortable.d.ts +30 -30
  25. package/dist/src/toast/toast.d.ts +12 -12
  26. package/dist/src/window/window.d.ts +3 -1
  27. package/dist/src/window/window.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/src/commandPalette/commandPalette.ts +11 -15
  30. package/src/commandPalette/match.ts +22 -5
  31. package/src/field/field.ts +5 -1
  32. package/src/lineDiff/index.ts +2 -0
  33. package/src/lineDiff/lineDiff.ts +29 -24
  34. package/src/lineDiff/patch.ts +218 -0
  35. package/src/pixel-paper.css +6 -0
  36. package/src/reel/layout.ts +27 -4
  37. package/src/window/window.ts +3 -1
package/DESIGN.md CHANGED
@@ -1057,7 +1057,7 @@ The printed button: a paper rectangle in a 2px ink frame that casts a 3px shadow
1057
1057
  - **Banner** → `div.banner > span.glyph (.error, .ok, .quiet) + span`: a fixed paper slip on the 3px shadow with a 26px glyph box in the Notice's tones and a sentence that says what happens to the reader's work. It holds a state the whole interface is in, for as long as it lasts, one at a time. It is not a live region (it arrives already holding its sentence, which would go unheard): the application says the state once, when it begins, with the `Announcer.Announce` Command. `"Error"` (the default; red, bang): a state that stops work (offline). `"Warn"` (amber): a state that is passing (reconnecting). `"Ok"` (ink, check): the state just ended (back online), shown briefly and then taken away. `"Quiet"` (head, info): news. With the connection word it is one pair: LinkState `"Reconnecting"` beside a warn Banner, `"Offline"` beside an error Banner with a retry, then `"Online"` beside an ok Banner for a moment; `"Connecting"` takes none.
1058
1058
  - **Rail** (Submodel) → `div.railed > main.deck#main + aside.rail[popover="auto"][aria-label]`: the rail's panels (a tree, places, filters) beside the deck's, after it in the markup so the page's main content and its h1 come first in reading order; the stylesheet fixes the rail at the left under the top bar. One element serves both layouts, so nothing in it renders twice or loses its state: at rest it stands there (its `popover` attribute is inert until opened), and at 900px and under it is hidden and `span.rail-open > button.btn.small[aria-expanded]` at the top of the deck opens it as a drawer: a slice of the dithered ground, `min(320px, 100vw - 40px)` wide from the left edge, closed by a 2px ink rule and the 8px card shadow, entering from the left in three steps over a veil. Its head (`div.rail-head`: the name in the label register and a close IconButton) shows only in the drawer. Opening focuses its first control; Escape, a click on the veil, the close glyph or focus leaving closes it, and all but the last return focus to the button. Widening the window past 900px closes it. The parent reads whether the drawer is open with `Rail.isOpen`, to hold its own page keys while the drawer covers the page. A file tree flush in a rail panel (or any panel) drops its own border.
1059
1059
  - **Stage** → `main.stage#main > div.stage-work > div.stage-canvas + div.stage-tools + div.stage-bar`: see Layout. `paused` (a Notice saying why: the link dropped, the page is read-only) veils the work when editing stops: `div.stage-paused[role="status"]` lays the dialog veil and its ink grain over everything and centres that Notice on the 3px button shadow, while the work beneath is `inert`. It lifts when `paused` is not given; the connection word says reconnecting meanwhile.
1060
- - **Window** → `section.panel.window (.flush) > header.panel-tb + div.window-body + div.panel-foot`: a Panel for a stage or a reel, as tall and wide as whatever places it (and moved by it, if anything moves it). Its title bar is the panel's, trimmed to hold tools: 30px tall (`3px 3px 3px 10px`, its left trimmed to 3px under a `lead`), centred, with an optional `lead` (`span.panel-lead`, a quiet IconButton: a Reel's grip), an optional kind glyph, the title (clipped with an ellipsis), a status chip (its border turns paper so it reads on ink), tools and a close IconButton, both in the bar's paper. The body scrolls inside (`16px`, a 14px grid); flush, what fills it (a code surface, a file tree, a diff) drops its border and fills it. A foot is a panel foot; a notice there takes the whole line.
1060
+ - **Window** → `section.panel.window (.flush) > header.panel-tb + div.window-body + div.panel-foot`: a Panel for a stage or a reel, as tall and wide as whatever places it (and moved by it, if anything moves it). Its title bar is the panel's, trimmed to hold tools: 30px tall (`3px 3px 3px 10px`, its left trimmed to 3px under a `lead`), centred, with an optional `lead` (`span.panel-lead`, a quiet IconButton: a Reel's grip), an optional kind glyph, the title (clipped with an ellipsis), a status chip (its border turns paper so it reads on ink), tools and a close IconButton, both in the bar's paper. Tools a child Submodel hands back come as one element, `span.window-tools`, which is no box of its own (`display: contents`), so its buttons sit in the bar as the others do. The body scrolls inside (`16px`, a 14px grid); flush, what fills it (a code surface, a file tree, a diff) drops its border and fills it. A foot is a panel foot; a notice there takes the whole line.
1061
1061
  - **Loading** → `div.loading[role="status"]`: where content is on its way, centred like an EmptyState at `26px 16px`, a 12px uppercase 0.08em (`--tracking-title`) muted line ("loading the items") ending in the 6×11px working cursor. Its status element stays in the page and only its words change: with `isLoading` false it is `div.loading-idle[role="status"]`, empty and out of the flow (`position: absolute`, never `display: none`, which would drop the live region), so it takes no room and no gap at the top of a panel's or a card's body, and a screen reader hears the line when it arrives. The content or an EmptyState takes its place on screen; the line never prints beside either. It is not the page's live region (the Announcer's).
1062
1062
  - **Remote** → spread where content goes: data that loads, in each of Foldkit's `AsyncData` states, with the retry built in, so a failure is never shown without its way back. A Loading line (`loading <label>`) leads in every state, in place, so its status is heard, and holds its words only while the first load runs: a refresh over data already shown is quiet, so a page that polls is not heard each time. Retry takes its button away with the notice, so the update returns focus to the line (its `id`) with the retry, where a first load is heard. A failure with nothing to show is an error Notice titled "<Label> not loaded", the reason (`toErrorText`) under it and a small "retry" button (`onRetry`); a refresh that failed over data already shown (stale) is a warn Notice titled "<Label> not refreshed" with the same reason and retry, above the last data; loaded and refreshing data is the caller's `toDataView` alone, an EmptyState for none included.
1063
1063
  - **Disclosure** (a View over `@foldkit/ui`'s Disclosure; the caller keeps whether it is open) → `div.disclosure > button.disclosure-summary[aria-expanded] + div.disclosure-body`. The summary is a control-register line (`3px 0`) of a 12px `caret-right` glyph, `span.disclosure-label` (a dotted underline on hover) and an optional `span.meta` pushed right; open, the caret turns a quarter in one step (a right angle keeps the grid). The body hangs from the caret on a 1px Rule Grey guide, its content level with the summary's words (`margin-left: 5px`, `padding-left: 14px`), in a 14px grid. For what a reader opens on purpose (grants to edit, details, a danger zone), never to hide the one thing the screen is for.
@@ -1130,7 +1130,7 @@ Focus is the reel's: one pane is focused (`.focused`, its window on the 8px card
1130
1130
 
1131
1131
  ### Inputs / Fields
1132
1132
 
1133
- - **Field** (a View over `@foldkit/ui`'s Input) → `div.field (.boxed, .mono) > label + input + p.field-error + p.field-help`, the label naming the input and the help describing it; a failed field prints why in `p.field-error` (sans, Urgent Red) under the control, which is `aria-invalid` and described by it before its help, and the ErrorSummary above the fields says it again; a required field's control is `aria-required`; the input's `type` the platform's (`"date"` for the browser's date control) when given. **SelectField** (over `@foldkit/ui`'s Select) → `div.field > label + select + p.field-error + p.field-help`, its options in order and a group's under an `optgroup` heading, an option that is listed but not choosable `disabled`; **TextareaField** (over `@foldkit/ui`'s Textarea) → `div.field (.mono) > label + textarea + p.field-error + p.field-help`, opening at `rows` lines. Both name, describe and mark their control as a Field does. **Fieldset** → `fieldset.field > legend.field-label`, then the controls, `p.field-error` and `p.field-help`, its error and its help linked with `aria-describedby`; **FieldGrid** → `div.field-grid` (auto-fit, 160px minimum); **Fields** → `fieldset.stack.gap-m`: a form's fields as one column `--space-m` (14px) apart, a body's gap, on the layout primitives with no rule of its own. `isBusy` (a save in flight) sets `disabled` and `aria-busy` on it, so every control holds at once and nothing changes under the save; the submit Button stays outside it, `isBusy`, so it keeps focus. A disabled control prints its value in Muted Ink; a boxless one also drops its dotted baseline (the mark of a place to type), a boxed one or a select mutes its box and caret.
1133
+ - **Field** (a View over `@foldkit/ui`'s Input) → `div.field (.boxed, .mono) > label + input + p.field-error + p.field-help`, the label naming the input and the help describing it; a failed field prints why in `p.field-error` (sans, Urgent Red) under the control, which is `aria-invalid` and described by it before its help, and the ErrorSummary above the fields says it again; a required field's control is `aria-required`; the input's `type` the platform's (`"date"` for the browser's date control) when given. A field whose place says what it is (a browser's address bar) hides its label (`label.sr-only`), which still names the input. **SelectField** (over `@foldkit/ui`'s Select) → `div.field > label + select + p.field-error + p.field-help`, its options in order and a group's under an `optgroup` heading, an option that is listed but not choosable `disabled`; **TextareaField** (over `@foldkit/ui`'s Textarea) → `div.field (.mono) > label + textarea + p.field-error + p.field-help`, opening at `rows` lines. Both name, describe and mark their control as a Field does. **Fieldset** → `fieldset.field > legend.field-label`, then the controls, `p.field-error` and `p.field-help`, its error and its help linked with `aria-describedby`; **FieldGrid** → `div.field-grid` (auto-fit, 160px minimum); **Fields** → `fieldset.stack.gap-m`: a form's fields as one column `--space-m` (14px) apart, a body's gap, on the layout primitives with no rule of its own. `isBusy` (a save in flight) sets `disabled` and `aria-busy` on it, so every control holds at once and nothing changes under the save; the submit Button stays outside it, `isBusy`, so it keeps focus. A disabled control prints its value in Muted Ink; a boxless one also drops its dotted baseline (the mark of a place to type), a boxed one or a select mutes its box and caret.
1134
1134
  - **Label:** 10px uppercase 0.1em Muted Ink, 4px above; turns red when the field is invalid, as a fieldset's legend does when a control in it is.
1135
1135
  - **Boxless (default):** full width, sans body, no box, a 1px dotted Muted Ink baseline, `padding: 2px 0`. On keyboard the baseline becomes 2px solid ink; invalid, 2px solid red.
1136
1136
  - **Boxed:** the field that is the whole job of its form (sign-in, a quick-add field): 2px ink border, `padding: 5px 8px`; keyboard ring 2px outside; invalid turns the border red. A date is always boxed.
@@ -1164,7 +1164,7 @@ Focus is the reel's: one pane is focused (`.focused`, its window on the 8px card
1164
1164
  - **CodeSurface** → `pre.code-surface[tabindex="0"][role="group"]`, named by its label: a 2px ink-bordered head-tinted block in 12px/1.6 system mono, `10px 12px`, `tab-size: 2`, wrapping. It takes a string or a highlighter's spans: `tok-keyword`; `tok-string`, `tok-string2`, `tok-url`; `tok-number`, `tok-bool`, `tok-atom`, `tok-literal`; `tok-definition`, `tok-variableName2`, `tok-macroName`, `tok-link` (underlined); `tok-typeName`, `tok-className`, `tok-namespace`; `tok-comment`, `tok-meta`, `tok-punctuation` take their syntax roles; `tok-heading` and `tok-strong` are bold, `tok-emphasis` italic, `tok-inserted` green ink, `tok-deleted` and `tok-invalid` red ink (invalid on a dotted underline). Anything unnamed stays ink. **CodeEditor** (a View over `@foldkit/ui`'s Textarea) → `textarea.code-surface`, spelling, capitals and autocomplete off: 220px minimum, grows to 60vh, vertically resizable, scrolls sideways (wraps on phones).
1165
1165
  - **Secret** → `div.secret > code[role="group"] + button.btn.small`, the code named by its label: the same box at `6px 6px 6px 12px` with a scrolling nowrap code at 0.02em (wrapping anywhere on a phone, so the end is never hidden) and, in its `actions`, a copy button whose word turns "copied". **CopyButton** (Submodel; `CopyButton.isCopied` is for a parent that follows the copy) → the quiet copy glyph (a check once copied) or, as `"Button"`, a small button whose word turns "copied", for a beat; either says it to screen readers, and a copy that fails says so. It writes through Effect's `Clipboard` service: the application provides `Clipboard.layer` from `@effect/platform-browser` in its `resources`. A `div.save-row` with a `span.push` holds what follows it (the "I've stored it" commit).
1166
1166
  - **History** → `ol.history-list (.checks) > li (.current, [aria-current="true"]) > span.v + span.who + span.what (.failed)`: ruled rows, the version in 11px pixel face in a fixed `4ch + 8px` box (inverted when current, so nothing moves, a Time in it taking the paper too), who in 10px muted at 10ch (20ch for checks), what in sans, a failed line red with "(failed)" after it for screen readers (`span.sr-only`), so the state never rests on colour. `isWrapped` → `ol.history-list.wrapped` (never `.wrap`, which is Wrap's row), for an activity log whose words matter more than a tidy column, compact enough for a rail's panel: when (a whole timestamp, its box as wide as it, muted and flush with the what under it, padded `0 4px` and inverted only when current) and who share the first line with the action pushed to its end, and what runs on its own line below in the note size (12px/1.45 sans, in ink), wrapping anywhere. Entries are `6px 0` apart over 1px rules with a 2px gap between their lines; there is no rule above the first and no padding before the first or after the last, so the list starts where a body's content starts.
1167
- - **LineDiff** → `div.diff-wrap > table.diff > tr.add | tr.del | tr.same | tr.fold`: a Myers line diff (jsdiff's `diff`, a runtime dependency) in a 2px ink box on paper that scrolls sideways; 12px/1.6 system-mono lines, each with two 10px pixel-face line numbers behind a 1px rule, a sign column, and the line. Added lines are Head Tint behind an ink `+`; deleted lines muted behind a red `−`; unchanged runs beyond two lines of context fold into a head-tinted row labelled in 10px uppercase On Head. On phones lines wrap. `LineDiff.patchView` draws the same table from one file's unified diff, the lines between its hunks folded into the counted row; anything else prints a note line.
1167
+ - **LineDiff** → `div.diff-wrap > table.diff > tr.add | tr.del | tr.same | tr.fold`: a Myers line diff (jsdiff's `diff`, a runtime dependency) in a 2px ink box on paper that scrolls sideways; 12px/1.6 system-mono lines, each with two 10px pixel-face line numbers behind a 1px rule, a sign column, and the line. Added lines are Head Tint behind an ink `+`; deleted lines muted behind a red `−`; unchanged runs beyond two lines of context fold into a head-tinted row labelled in 10px uppercase On Head. On phones lines wrap. `LineDiff.patchView` draws the same table from one file's unified diff, the lines between its hunks folded into the counted row. What git's header says prints as one note line, above the table or in its place: a rename (its path unquoted), a mode change, a new or deleted empty file, a binary change; a file whose type changed (a file that became a symlink) is one note over a table for each side, named for its side, the note and tables in a `div.stack.gap-s`. A lone table or note is drawn bare, so a flush window's body still meets it. Text that is not a diff, or holds several files, prints a note line that says it cannot be shown as lines. `LineDiff.describePatch` gives the notes, for a caller that prints them itself.
1168
1168
 
1169
1169
  ### Meters and cells
1170
1170
 
@@ -425,9 +425,10 @@ export type ViewInputs = Readonly<{
425
425
  }>;
426
426
  /** The row the cursor is on as the view shows it with `commands`: the row the reader moved it
427
427
  * to while that row is listed, else the page's `start` or `current` while the query finds it,
428
- * else the first row the query finds; none when nothing is listed. Compare it before and after the caller's commands change to know
429
- * when the cursor fell to another row (its row left) and should be scrolled into view with
430
- * `ScrollToCursor`; a cursor whose row is still listed keeps it, and the list its scroll. */
428
+ * else the first row the query finds; none when nothing is listed. Compare it before and after
429
+ * the caller's commands change to know when the cursor fell to another row (its row left) and
430
+ * should be scrolled into view with `ScrollToCursor`; a cursor whose row is still listed keeps
431
+ * it, and the list its scroll. */
431
432
  export declare const maybeCursorId: (model: Model, commands: ReadonlyArray<Command>) => Option.Option<string>;
432
433
  /**
433
434
  * Type to find a command or a title; one inverted cursor row, moved by ↑ and ↓ only
@@ -1 +1 @@
1
- {"version":3,"file":"commandPalette.d.ts","sourceRoot":"","sources":["../../../src/commandPalette/commandPalette.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,MAAM,EAAkB,MAAM,EAAE,MAAM,EAAwB,MAAM,QAAQ,CAAC;AAC7F,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;;;;;;;;;;;;;;;;;;;;;;;;;EAQhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAItC;;;;;2EAK2E;AAC3E,eAAO,MAAM,UAAU;;QACF,EAAE;;;QACH,SAAS;QAAiB,QAAQ;;;EAEpD,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;AAIhD;gBACgB;AAChB,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAKlD,wCAAwC;AACxC,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAQxC,CAAC;AAIH,gDAAgD;AAChD,eAAO,MAAM,EAAE,UAAW,KAAK,KAAG,MAAiC,CAAC;AAEpE,mCAAmC;AACnC,eAAO,MAAM,MAAM,UAAW,KAAK,KAAG,OAAsC,CAAC;AAE7E;+CAC+C;AAC/C,eAAO,MAAM,KAAK,UAAW,KAAK,KAAG,MACuD,CAAC;AAE7F,sCAAsC;AACtC,eAAO,MAAM,WAAW,UAAW,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CACR,CAAC;AAExD,kEAAkE;AAClE,eAAO,MAAM,SAAS,UAAW,KAAK,KAAG,OAA4C,CAAC;AAStF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc;;;;iBAOzB,CAAC;AAyBH;;;mFAGmF;AACnF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;iBAS5B,CAAC;AA4RH,+FAA+F;AAC/F,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBjD,CAAC;AAEL;;2FAE2F;AAC3F,eAAO,MAAM,IAAI,UAAW,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAClB,CAAC;AAE/C,kCAAkC;AAClC,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC;8BAC0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,wFAAwF;AACxF,eAAO,MAAM,MAAM,UAAW,KAAK,UAAU,YAAY,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CACf,CAAC;AAE1E;;mDAEmD;AACnD,eAAO,MAAM,aAAa,UAAW,KAAK,YAAY,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAG5E,CAAC;AAEhB;;uBAEuB;AACvB,eAAO,MAAM,UAAU,UAAW,KAAK,YAAY,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAGzE,CAAC;AAiBhB;;;;6FAI6F;AAC7F,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,MAAM,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mGACxB,CAAC;AAI/C,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC;oFACgF;IAChF,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACjC;wBACoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;kCAE8B;IAC9B,YAAY,CAAC,EAAE,MAAM,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IAClD;0CACsC;IACtC,gBAAgB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CAC7C,CAAC,CAAC;AA2FH;;;;8FAI8F;AAC9F,eAAO,MAAM,aAAa,UACjB,KAAK,YACF,aAAa,CAAC,OAAO,CAAC,KAC/B,MAAM,CAAC,MAAM,CAAC,MAAM,CAA2C,CAAC;AA4TnE;;;;;;;;;;;;;GAaG;AAOH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAlcf;oFACgF;cACtE,aAAa,CAAC,OAAO,CAAC;IAChC;wBACoB;YACZ,MAAM;IACd,mFAAmF;WAC5E,MAAM;IACb;;kCAE8B;mBACf,MAAM,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC;IACjD;0CACsC;uBACnB,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;GAic5C,CAAC"}
1
+ {"version":3,"file":"commandPalette.d.ts","sourceRoot":"","sources":["../../../src/commandPalette/commandPalette.ts"],"names":[],"mappings":"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"}
@@ -211,7 +211,7 @@ const maybeCurrentCursor = (model) => __foldkitBrandViewResult((Option.match(mod
211
211
  onSome: (page) => __foldkitBrandViewResult((page.maybeCursor), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onSome~5"),
212
212
  })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#maybeCurrentCursor");
213
213
  const ARROW_STEP = { ArrowUp: -1, ArrowDown: 1 };
214
- const isListedIn = (rows, rowId) => __foldkitBrandViewResult((Array.some(rows, (row) => __foldkitBrandViewResult((row.id === rowId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~8"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#isListedIn");
214
+ const isListed = (rows, rowId) => __foldkitBrandViewResult((Array.some(rows, (row) => __foldkitBrandViewResult((row.id === rowId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~8"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#isListed");
215
215
  // NOTE: where the cursor is among the rows a key carries (see `Model`). With no arrows waiting
216
216
  // it is the Model's cursor while that row is listed, else the shown one, so each key acts from
217
217
  // where the last left it, also when several come before the next render; with arrows waiting,
@@ -219,11 +219,11 @@ const isListedIn = (rows, rowId) => __foldkitBrandViewResult((Array.some(rows, (
219
219
  // key waits for the next render.
220
220
  const cursorAsShown = (model, shown) => {
221
221
  const { rows, maybeShownCursor, shownQuery, shownShift } = shown;
222
- const isListed = shownQuery === query(model);
223
- if (isListed && model.cursorShift === 0) {
224
- return __foldkitBrandViewResult((Option.some(Option.orElse(Option.filter(maybeCurrentCursor(model), (rowId) => __foldkitBrandViewResult((isListedIn(rows, rowId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~9")), () => __foldkitBrandViewResult((maybeShownCursor), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~10")))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#cursorAsShown");
222
+ const isTheList = shownQuery === query(model);
223
+ if (isTheList && model.cursorShift === 0) {
224
+ return __foldkitBrandViewResult((Option.some(Option.orElse(Option.filter(maybeCurrentCursor(model), (rowId) => __foldkitBrandViewResult((isListed(rows, rowId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~9")), () => __foldkitBrandViewResult((maybeShownCursor), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~10")))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#cursorAsShown");
225
225
  }
226
- else if (isListed && shownShift === model.cursorShift) {
226
+ else if (isTheList && shownShift === model.cursorShift) {
227
227
  return __foldkitBrandViewResult((Option.some(maybeShownCursor)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#cursorAsShown");
228
228
  }
229
229
  else {
@@ -347,12 +347,11 @@ const earlyKeySubscriptions = Subscription.make()((entry) => (__foldkitBrandView
347
347
  * other record on the page uses: `subscriptions("palette")` is keyed `paletteEarlyKeys`. */
348
348
  export const subscriptions = (keyPrefix) => __foldkitBrandViewResult((prefixKeys(keyPrefix, earlyKeySubscriptions)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#subscriptions");
349
349
  const pageOf = (commands, state) => __foldkitBrandViewResult((pipe(Array.findFirst(commands, (command) => __foldkitBrandViewResult((command.id === state.commandId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~23")), Option.flatMap((command) => __foldkitBrandViewResult((Option.fromNullishOr(command.page)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~24")), Option.map((page) => (__foldkitBrandViewResult(({ commandId: state.commandId, page, state }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~25"))))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#pageOf");
350
- const isListed = (rows, rowId) => __foldkitBrandViewResult((Array.some(rows, (row) => __foldkitBrandViewResult((row.id === rowId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~26"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#isListed");
351
- const firstListed = (rows, candidates) => __foldkitBrandViewResult((Array.findFirst(Array.getSomes(candidates), (cursorId) => __foldkitBrandViewResult((isListed(rows, cursorId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~27"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#firstListed");
352
- const firstId = (rows) => __foldkitBrandViewResult((Option.map(Array.head(rows), (row) => __foldkitBrandViewResult((row.id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~28"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#firstId");
350
+ const firstListed = (rows, candidates) => __foldkitBrandViewResult((Array.findFirst(Array.getSomes(candidates), (cursorId) => __foldkitBrandViewResult((isListed(rows, cursorId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~26"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#firstListed");
351
+ const firstId = (rows) => __foldkitBrandViewResult((Option.map(Array.head(rows), (row) => __foldkitBrandViewResult((row.id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~27"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#firstId");
353
352
  const shifted = (shown, shift) => (__foldkitBrandViewResult(({
354
353
  ...shown,
355
- maybeCursorId: Option.map(rowAfter(shown.rows, shown.maybeCursorId, shift), (row) => __foldkitBrandViewResult((row.id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~29")),
354
+ maybeCursorId: Option.map(rowAfter(shown.rows, shown.maybeCursorId, shift), (row) => __foldkitBrandViewResult((row.id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~28")),
356
355
  }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#shifted"));
357
356
  // NOTE: arrows waiting for the view count from the cursor's row. When that row has left the
358
357
  // list (the application changed it in between), they are dropped rather than counted from
@@ -371,7 +370,7 @@ const shownOf = (model, commands) => {
371
370
  // `start`, else its `current`, else the first row, these three only among the rows the query
372
371
  // finds; none when nothing is listed.
373
372
  const unshiftedOf = (model, commands) => {
374
- const maybePage = Option.flatMap(model.maybePage, (state) => __foldkitBrandViewResult((pageOf(commands, state)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~30"));
373
+ const maybePage = Option.flatMap(model.maybePage, (state) => __foldkitBrandViewResult((pageOf(commands, state)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~29"));
375
374
  return __foldkitBrandViewResult((Option.match(maybePage, {
376
375
  onNone: () => {
377
376
  const rows = findCommands(commands, model.query);
@@ -379,32 +378,32 @@ const unshiftedOf = (model, commands) => {
379
378
  maybePage,
380
379
  rows,
381
380
  contextIds: HashSet.empty(),
382
- maybeCursorId: pipe(Option.filter(model.maybeCursor, (rowId) => __foldkitBrandViewResult((isListed(rows, rowId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~31")), Option.orElse(() => __foldkitBrandViewResult((firstId(rows)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~32"))),
381
+ maybeCursorId: pipe(Option.filter(model.maybeCursor, (rowId) => __foldkitBrandViewResult((isListed(rows, rowId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~30")), Option.orElse(() => __foldkitBrandViewResult((firstId(rows)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~31"))),
383
382
  }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onNone~14");
384
383
  },
385
384
  onSome: ({ page, state }) => {
386
- const { rows, found } = pageChoices(page, state.query);
387
- const idsOf = (choices) => __foldkitBrandViewResult((HashSet.fromIterable(Array.map(choices, ({ id }) => __foldkitBrandViewResult((id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~33")))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#idsOf");
385
+ const { rows, found, contextIds } = pageChoices(page, state.query);
388
386
  return __foldkitBrandViewResult(({
389
387
  maybePage,
390
388
  rows,
391
- contextIds: HashSet.difference(idsOf(rows), idsOf(found)),
392
- maybeCursorId: pipe(Option.filter(state.maybeCursor, (rowId) => __foldkitBrandViewResult((isListed(rows, rowId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~34")), Option.orElse(() => __foldkitBrandViewResult((firstListed(found, [
389
+ contextIds,
390
+ maybeCursorId: pipe(Option.filter(state.maybeCursor, (rowId) => __foldkitBrandViewResult((isListed(rows, rowId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~32")), Option.orElse(() => __foldkitBrandViewResult((firstListed(found, [
393
391
  Option.fromNullishOr(page.start),
394
392
  Option.fromNullishOr(page.current),
395
- ])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~35")), Option.orElse(() => __foldkitBrandViewResult((firstId(found)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~36"))),
393
+ ])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~33")), Option.orElse(() => __foldkitBrandViewResult((firstId(found)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~34"))),
396
394
  }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onSome~13");
397
395
  },
398
396
  })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#unshiftedOf");
399
397
  };
400
398
  /** The row the cursor is on as the view shows it with `commands`: the row the reader moved it
401
399
  * to while that row is listed, else the page's `start` or `current` while the query finds it,
402
- * else the first row the query finds; none when nothing is listed. Compare it before and after the caller's commands change to know
403
- * when the cursor fell to another row (its row left) and should be scrolled into view with
404
- * `ScrollToCursor`; a cursor whose row is still listed keeps it, and the list its scroll. */
400
+ * else the first row the query finds; none when nothing is listed. Compare it before and after
401
+ * the caller's commands change to know when the cursor fell to another row (its row left) and
402
+ * should be scrolled into view with `ScrollToCursor`; a cursor whose row is still listed keeps
403
+ * it, and the list its scroll. */
405
404
  export const maybeCursorId = (model, commands) => __foldkitBrandViewResult((shownOf(model, commands).maybeCursorId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#maybeCursorId");
406
405
  const isCommand = (row) => __foldkitBrandViewResult(("group" in row), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#isCommand");
407
- const isCurrentRow = (shown, row) => __foldkitBrandViewResult((Option.exists(shown.maybePage, ({ page }) => __foldkitBrandViewResult((page.current === row.id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~37"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#isCurrentRow");
406
+ const isCurrentRow = (shown, row) => __foldkitBrandViewResult((Option.exists(shown.maybePage, ({ page }) => __foldkitBrandViewResult((page.current === row.id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~35"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#isCurrentRow");
408
407
  const isContextRow = (shown, row) => __foldkitBrandViewResult((HashSet.has(shown.contextIds, row.id)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#isContextRow");
409
408
  const levelOf = (row) => __foldkitBrandViewResult(("level" in row ? Option.fromNullishOr(row.level) : Option.none()), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#levelOf");
410
409
  // What a row is as this render shows it, which Enter acts on as a click would.
@@ -417,14 +416,14 @@ const shownRowFor = (shown, row) => (__foldkitBrandViewResult(({
417
416
  // shows them (also for a page whose command left).
418
417
  const shownQueryOf = (model, shown) => __foldkitBrandViewResult((Option.match(shown.maybePage, { onNone: () => __foldkitBrandViewResult((model.query), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onNone~15"), onSome: ({ state }) => __foldkitBrandViewResult((state.query), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onSome~14") })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#shownQueryOf");
419
418
  // The command whose page the view shows.
420
- const shownPageIdOf = (shown) => __foldkitBrandViewResult((Option.map(shown.maybePage, ({ commandId }) => __foldkitBrandViewResult((commandId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~38"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#shownPageIdOf");
419
+ const shownPageIdOf = (shown) => __foldkitBrandViewResult((Option.map(shown.maybePage, ({ commandId }) => __foldkitBrandViewResult((commandId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~36"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#shownPageIdOf");
421
420
  // NOTE: the field's keys that act on the rows are taken here, where the rows are known, as a
422
421
  // Mount on the document cannot know them: ↑, ↓ and Enter carry what this render shows (see
423
422
  // `Model`), and each is taken from the field (its default prevented). A modified key and every
424
423
  // key while a pick is out are left to the field.
425
424
  const fieldKeyDown = (model, shown) => __foldkitBrandViewResult(((key, modifiers) => {
426
425
  const list = {
427
- rows: Array.map(shown.rows, (row) => __foldkitBrandViewResult((shownRowFor(shown, row)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~40")),
426
+ rows: Array.map(shown.rows, (row) => __foldkitBrandViewResult((shownRowFor(shown, row)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~38")),
428
427
  maybeShownCursor: shown.maybeCursorId,
429
428
  maybeShownPage: shownPageIdOf(shown),
430
429
  shownQuery: shownQueryOf(model, shown),
@@ -432,7 +431,7 @@ const fieldKeyDown = (model, shown) => __foldkitBrandViewResult(((key, modifiers
432
431
  };
433
432
  return __foldkitBrandViewResult((isPicking(model) || !isPlain(modifiers)
434
433
  ? Option.none()
435
- : Match.value(key).pipe(Match.withReturnType(), Match.whenOr("ArrowDown", "ArrowUp", (arrow) => __foldkitBrandViewResult((Option.some(Message.PressedArrowKey({ key: arrow, ...list }))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~41")), Match.when("Enter", () => __foldkitBrandViewResult((Option.some(Message.PressedEnter(list))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~42")), Match.orElse(() => __foldkitBrandViewResult((Option.none()), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~43")))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~39");
434
+ : Match.value(key).pipe(Match.withReturnType(), Match.whenOr("ArrowDown", "ArrowUp", (arrow) => __foldkitBrandViewResult((Option.some(Message.PressedArrowKey({ key: arrow, ...list }))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~39")), Match.when("Enter", () => __foldkitBrandViewResult((Option.some(Message.PressedEnter(list))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~40")), Match.orElse(() => __foldkitBrandViewResult((Option.none()), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~41")))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~37");
436
435
  }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#fieldKeyDown");
437
436
  const optionId = (paletteId, index) => __foldkitBrandViewResult((`${paletteId}-option-${index}`), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#optionId");
438
437
  const NOTHING_FOUND = "nothing matches · try fewer letters";
@@ -483,31 +482,31 @@ const rowView = (model, shown, row, index, h) => {
483
482
  ], rowPartsView(model, shown, row, h))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#rowView");
484
483
  };
485
484
  const groupedRows = (model, shown, h) => {
486
- const indexed = Array.map(shown.rows, (row, index) => (__foldkitBrandViewResult(({ row, index }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~44")));
485
+ const indexed = Array.map(shown.rows, (row, index) => (__foldkitBrandViewResult(({ row, index }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~42")));
487
486
  return __foldkitBrandViewResult((Option.match(shown.maybePage, {
488
- onSome: () => __foldkitBrandViewResult((Array.map(indexed, ({ row, index }) => __foldkitBrandViewResult((rowView(model, shown, row, index, h)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~45"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onSome~16"),
487
+ onSome: () => __foldkitBrandViewResult((Array.map(indexed, ({ row, index }) => __foldkitBrandViewResult((rowView(model, shown, row, index, h)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~43"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onSome~16"),
489
488
  onNone: () => {
490
- const groups = Array.dedupe(Array.map(shown.rows, (row) => (__foldkitBrandViewResult((isCommand(row) ? row.group : ""), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~46"))));
489
+ const groups = Array.dedupe(Array.map(shown.rows, (row) => (__foldkitBrandViewResult((isCommand(row) ? row.group : ""), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~44"))));
491
490
  return __foldkitBrandViewResult((Array.map(groups, (group, groupIndex) => {
492
491
  const headingId = `${id(model)}-group-${groupIndex}`;
493
492
  return __foldkitBrandViewResult((h.keyed("div")(`group-${group}`, [h.Role("group"), h.AriaLabelledBy(headingId)], [
494
493
  h.div([h.Id(headingId), h.Role("presentation"), h.Class("palette-group")], [group]),
495
- ...Array.map(Array.filter(indexed, ({ row }) => __foldkitBrandViewResult((isCommand(row) && row.group === group), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~48")), ({ row, index }) => __foldkitBrandViewResult((rowView(model, shown, row, index, h)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~49")),
496
- ])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~47");
494
+ ...Array.map(Array.filter(indexed, ({ row }) => __foldkitBrandViewResult((isCommand(row) && row.group === group), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~46")), ({ row, index }) => __foldkitBrandViewResult((rowView(model, shown, row, index, h)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~47")),
495
+ ])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~45");
497
496
  })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onNone~17");
498
497
  },
499
498
  })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#groupedRows");
500
499
  };
501
500
  const comboboxAttributes = (model, shown, noun, h) => {
502
501
  const paletteId = id(model);
503
- const maybeCursorIndex = Option.flatMap(shown.maybeCursorId, (cursorId) => __foldkitBrandViewResult((Array.findFirstIndex(shown.rows, (row) => __foldkitBrandViewResult((row.id === cursorId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~51"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~50"));
502
+ const maybeCursorIndex = Option.flatMap(shown.maybeCursorId, (cursorId) => __foldkitBrandViewResult((Array.findFirstIndex(shown.rows, (row) => __foldkitBrandViewResult((row.id === cursorId), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~49"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~48"));
504
503
  return __foldkitBrandViewResult(([
505
504
  h.OnKeyDownPreventDefault(fieldKeyDown(model, shown)),
506
505
  h.Role("combobox"),
507
506
  h.AriaExpanded(true),
508
507
  h.AriaControls(listIdOf(paletteId)),
509
508
  h.AriaAutocomplete("list"),
510
- ...Option.toArray(Option.map(maybeCursorIndex, (index) => __foldkitBrandViewResult((h.AriaActiveDescendant(optionId(paletteId, index))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~52"))),
509
+ ...Option.toArray(Option.map(maybeCursorIndex, (index) => __foldkitBrandViewResult((h.AriaActiveDescendant(optionId(paletteId, index))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~50"))),
511
510
  h.AriaLabel(Option.match(shown.maybePage, {
512
511
  onNone: () => __foldkitBrandViewResult((`Command or ${noun}`), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onNone~18"),
513
512
  onSome: ({ page }) => __foldkitBrandViewResult((page.title), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#onSome~17"),
@@ -541,9 +540,9 @@ const headView = (model, shown, scope, field, h) => __foldkitBrandViewResult((h.
541
540
  isQuiet: true,
542
541
  isDisabled: isPicking(model),
543
542
  onClick: Message.ClickedBack(),
544
- }, h)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~53"))),
543
+ }, h)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~51"))),
545
544
  h.span([h.Class("palette-scope")], [scope]),
546
- ...Option.toArray(Option.map(shown.maybePage, ({ page }) => __foldkitBrandViewResult((h.span([h.Class("palette-title")], [page.title])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~54"))),
545
+ ...Option.toArray(Option.map(shown.maybePage, ({ page }) => __foldkitBrandViewResult((h.span([h.Class("palette-title")], [page.title])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~52"))),
547
546
  field,
548
547
  ])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#headView");
549
548
  const listView = (model, shown, h) => __foldkitBrandViewResult((h.div([
@@ -569,10 +568,10 @@ const countView = (model, shown, h) => {
569
568
  : [countWords(shown.rows.length - HashSet.size(shown.contextIds))])), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#countView");
570
569
  };
571
570
  const cardView = (model, viewInputs, render, h) => {
572
- const { commands, scope = "commands", noun = "title", toDetailView = () => __foldkitBrandViewResult(([]), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~55") } = viewInputs;
571
+ const { commands, scope = "commands", noun = "title", toDetailView = () => __foldkitBrandViewResult(([]), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~53") } = viewInputs;
573
572
  const shown = shownOf(model, commands);
574
573
  return __foldkitBrandViewResult((h.div([
575
- ...Option.toArray(Option.map(shownPageIdOf(shown), (commandId) => __foldkitBrandViewResult((h.DataAttribute(PAGE_ATTRIBUTE, commandId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~56"))),
574
+ ...Option.toArray(Option.map(shownPageIdOf(shown), (commandId) => __foldkitBrandViewResult((h.DataAttribute(PAGE_ATTRIBUTE, commandId)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~54"))),
576
575
  h.OnMount(BindPaletteKeys()),
577
576
  h.Class("card palette"),
578
577
  ], [
@@ -614,4 +613,4 @@ export const view = defineView((model, viewInputs, h) => __foldkitBrandViewResul
614
613
  toView: (render) => __foldkitBrandViewResult((cardView(model, viewInputs, render, h)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#toView~2"),
615
614
  },
616
615
  toParentMessage: (message) => __foldkitBrandViewResult((Message.GotDialogMessage({ message })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#toParentMessage~2"),
617
- })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~57"));
616
+ })), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/commandPalette.js#anonymous~55"));
@@ -1,3 +1,4 @@
1
+ import { HashSet } from "effect";
1
2
  import type { GlyphName } from "../glyph/glyphs.ts";
2
3
  /** One row of the palette: a command, or a choice on a page. */
3
4
  export type Choice = Readonly<{
@@ -45,11 +46,13 @@ export declare const matches: (query: string, label: string) => boolean;
45
46
  export declare const findCommands: (commands: ReadonlyArray<Command>, query: string) => ReadonlyArray<Command>;
46
47
  /** The choices a page's query finds. */
47
48
  export declare const findChoices: (page: Page, query: string) => ReadonlyArray<Choice>;
48
- /** What a page shows for its query: the choices it finds, and the rows, which are those
49
- * choices each with the choices it sits under in the page's tree, in the page's order. */
49
+ /** What a page shows for its query: the choices it finds; the rows, which are those choices
50
+ * each with the choices it sits under in the page's tree, in the page's order; and the rows
51
+ * kept only for the choices under them. */
50
52
  export type PageChoices = Readonly<{
51
53
  rows: ReadonlyArray<Choice>;
52
54
  found: ReadonlyArray<Choice>;
55
+ contextIds: HashSet.HashSet<string>;
53
56
  }>;
54
57
  export declare const pageChoices: (page: Page, query: string) => PageChoices;
55
58
  //# sourceMappingURL=match.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../src/commandPalette/match.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAIpD,gEAAgE;AAChE,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uBACmB;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;2CACuC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;kGAC8F;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,oFAAoF;AACpF,MAAM,MAAM,IAAI,GAAG,QAAQ,CAAC;IAC1B,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;kFAE8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH;yBACyB;AACzB,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AASvF,sFAAsF;AACtF,eAAO,MAAM,OAAO,UAAW,MAAM,SAAS,MAAM,KAAG,OAGtD,CAAC;AAEF;+EAC+E;AAC/E,eAAO,MAAM,YAAY,aACb,aAAa,CAAC,OAAO,CAAC,SACzB,MAAM,KACZ,aAAa,CAAC,OAAO,CAevB,CAAC;AAEF,wCAAwC;AACxC,eAAO,MAAM,WAAW,SAAU,IAAI,SAAS,MAAM,KAAG,aAAa,CAAC,MAAM,CAGF,CAAC;AAM3E;2FAC2F;AAC3F,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9B,CAAC,CAAC;AAEH,eAAO,MAAM,WAAW,SAAU,IAAI,SAAS,MAAM,KAAG,WAavD,CAAC"}
1
+ {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../src/commandPalette/match.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,OAAO,EAA+B,MAAM,QAAQ,CAAC;AAErE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAIpD,gEAAgE;AAChE,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uBACmB;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;2CACuC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;kGAC8F;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,oFAAoF;AACpF,MAAM,MAAM,IAAI,GAAG,QAAQ,CAAC;IAC1B,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;kFAE8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH;yBACyB;AACzB,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AASvF,sFAAsF;AACtF,eAAO,MAAM,OAAO,UAAW,MAAM,SAAS,MAAM,KAAG,OAGtD,CAAC;AAEF;+EAC+E;AAC/E,eAAO,MAAM,YAAY,aACb,aAAa,CAAC,OAAO,CAAC,SACzB,MAAM,KACZ,aAAa,CAAC,OAAO,CAevB,CAAC;AAIF,wCAAwC;AACxC,eAAO,MAAM,WAAW,SAAU,IAAI,SAAS,MAAM,KAAG,aAAa,CAAC,MAAM,CAGF,CAAC;AAM3E;;4CAE4C;AAC5C,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC,CAAC;AA2BH,eAAO,MAAM,WAAW,SAAU,IAAI,SAAS,MAAM,KAAG,WACM,CAAC"}
@@ -21,12 +21,18 @@ export const findCommands = (commands, query) => {
21
21
  const groupIndex = (command) => __foldkitBrandViewResult((Option.getOrElse(Array.findFirstIndex(groups, (group) => __foldkitBrandViewResult((group === command.group), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#anonymous~7")), () => __foldkitBrandViewResult((groups.length), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#anonymous~8"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#groupIndex");
22
22
  return __foldkitBrandViewResult((Array.sort(ordered, Order.mapInput(Order.Number, groupIndex))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#findCommands");
23
23
  };
24
+ const isBlank = (query) => __foldkitBrandViewResult((String.isEmpty(String.trim(query))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#isBlank");
24
25
  /** The choices a page's query finds. */
25
- export const findChoices = (page, query) => __foldkitBrandViewResult((String.isEmpty(String.trim(query))
26
+ export const findChoices = (page, query) => __foldkitBrandViewResult((isBlank(query)
26
27
  ? page.choices
27
28
  : Array.filter(page.choices, (choice) => __foldkitBrandViewResult((matches(query, choice.label)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#anonymous~9"))), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#findChoices");
28
29
  const WALK_START = { chain: [], keptIds: HashSet.empty() };
29
- export const pageChoices = (page, query) => {
30
+ const unfiltered = (page) => (__foldkitBrandViewResult(({
31
+ rows: page.choices,
32
+ found: page.choices,
33
+ contextIds: HashSet.empty(),
34
+ }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#unfiltered"));
35
+ const treeChoices = (page, query) => {
30
36
  const found = findChoices(page, query);
31
37
  const foundIds = HashSet.fromIterable(Array.map(found, ({ id }) => __foldkitBrandViewResult((id), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#anonymous~10")));
32
38
  const { keptIds } = Array.reduce(page.choices, WALK_START, ({ chain, keptIds }, choice) => {
@@ -38,5 +44,10 @@ export const pageChoices = (page, query) => {
38
44
  : keptIds,
39
45
  }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#anonymous~11");
40
46
  });
41
- return __foldkitBrandViewResult(({ rows: Array.filter(page.choices, ({ id }) => __foldkitBrandViewResult((HashSet.has(keptIds, id)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#anonymous~13")), found }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#pageChoices");
47
+ return __foldkitBrandViewResult(({
48
+ rows: Array.filter(page.choices, ({ id }) => __foldkitBrandViewResult((HashSet.has(keptIds, id)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#anonymous~13")),
49
+ found,
50
+ contextIds: HashSet.difference(keptIds, foundIds),
51
+ }), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#treeChoices");
42
52
  };
53
+ export const pageChoices = (page, query) => __foldkitBrandViewResult((isBlank(query) ? unfiltered(page) : treeChoices(page, query)), "@gjermundgaraba-designs/pixel-paper/src/commandPalette/match.js#pageChoices");
@@ -24,6 +24,9 @@ export type ViewConfig<Message> = Readonly<{
24
24
  isBoxed?: boolean;
25
25
  /** Code and identifiers: the system monospace. */
26
26
  isMono?: boolean;
27
+ /** The label is for screen readers only (`.sr-only`): a field whose place says what it is,
28
+ * such as a browser's address bar. It still names the input. */
29
+ isLabelHidden?: boolean;
27
30
  /** The input's type (`"date"` for the browser's date control, always boxed); text when not
28
31
  * given. */
29
32
  type?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/field/field.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAM9D,wFAAwF;AACxF,eAAO,MAAM,SAAS,GAAI,OAAO,MAC3B,MAAM,SACH,MAAM,GAAG,SAAS,KACtB,WAAW,CAAC,OAAO,CAAC,KACtB,aAAa,CAAC,IAAI,CACmE,CAAC;AAEzF;;+EAE+E;AAC/E,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAClC,MAAM,SACH,MAAM,GAAG,SAAS,WAChB,OAAO,KACb,WAAW,CAAC,OAAO,CAAC,KACtB,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAGqD,CAAC;AAIjG,4DAA4D;AAC5D,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;uCAEmC;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,yFAAyF;IACzF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;iBACa;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;iBACa;IACb,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CACvC,CAAC,CAAC;AAEH;;;6EAG6E;AAC7E,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IA4CpF,CAAC"}
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/field/field.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAM9D,wFAAwF;AACxF,eAAO,MAAM,SAAS,GAAI,OAAO,MAC3B,MAAM,SACH,MAAM,GAAG,SAAS,KACtB,WAAW,CAAC,OAAO,CAAC,KACtB,aAAa,CAAC,IAAI,CACmE,CAAC;AAEzF;;+EAE+E;AAC/E,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAClC,MAAM,SACH,MAAM,GAAG,SAAS,WAChB,OAAO,KACb,WAAW,CAAC,OAAO,CAAC,KACtB,aAAa,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAGqD,CAAC;AAIjG,4DAA4D;AAC5D,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;uCAEmC;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,yFAAyF;IACzF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;qEACiE;IACjE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;iBACa;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;iBACa;IACb,eAAe,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CACvC,CAAC,CAAC;AAEH;;;6EAG6E;AAC7E,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IA6CpF,CAAC"}
@@ -15,7 +15,7 @@ export const describedByError = (id, error, hasHelp, h) => __foldkitBrandViewRes
15
15
  * `aria-invalid` and describes it before the help, and `isRequired` sets `aria-required`.
16
16
  * The input is boxless, a dotted baseline that turns solid ink on focus. */
17
17
  export const view = (config, h) => {
18
- const { id, label, value, onInput, help, error, isRequired = false, isBoxed = false, isMono = false, type, inputAttributes = [], } = config;
18
+ const { id, label, value, onInput, help, error, isRequired = false, isBoxed = false, isMono = false, isLabelHidden = false, type, inputAttributes = [], } = config;
19
19
  return __foldkitBrandViewResult((UiInput.view({
20
20
  id,
21
21
  value,
@@ -24,7 +24,7 @@ export const view = (config, h) => {
24
24
  ...(type !== undefined && { type }),
25
25
  hasDescription: help !== undefined,
26
26
  toView: (groups) => __foldkitBrandViewResult((h.div([h.Class(`field${isBoxed || type === "date" ? " boxed" : ""}${isMono ? " mono" : ""}`)], [
27
- h.label(groups.label, [label]),
27
+ h.label([...groups.label, ...(isLabelHidden ? [h.Class("sr-only")] : [])], [label]),
28
28
  // NOTE: @foldkit/ui gap: Input has no required option, so the wrapper says it.
29
29
  h.input([
30
30
  ...inputAttributes,
@@ -1,3 +1,5 @@
1
1
  export { patchView, view } from "./lineDiff.ts";
2
2
  export type { PatchViewConfig, ViewConfig } from "./lineDiff.ts";
3
+ export { describePatch } from "./patch.ts";
4
+ export type { PatchDescription } from "./patch.ts";
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +1,2 @@
1
1
  export { patchView, view } from "./lineDiff.js";
2
+ export { describePatch } from "./patch.js";
@@ -11,7 +11,8 @@ export type ViewConfig = Readonly<{
11
11
  }>;
12
12
  /** Configuration for rendering a unified diff with `patchView`. */
13
13
  export type PatchViewConfig = Readonly<{
14
- /** One file's unified diff, as `diff -u` or `git diff -- <path>` writes it. */
14
+ /** One file's unified diff, as `diff -u` or `git diff -- <path>` writes it, its git header
15
+ * included. */
15
16
  patch: string;
16
17
  /** Names the two sides for screen readers: `"Version 3 against version 4"`. */
17
18
  label: string;
@@ -23,8 +24,11 @@ export declare const view: <Message>(config: ViewConfig, h: HtmlBuilder<Message>
23
24
  /** A unified diff the caller already has (from a server, or `git diff -- <path>`) as `view`'s
24
25
  * table: its hunks' lines, numbered from their headers, and the unchanged lines between hunks
25
26
  * folded into a counted row. Lines past the last hunk are not in the patch, so nothing counts
26
- * them. An empty patch says there is no difference, as `view` does; anything but one file
27
- * with a hunk (text that is not a diff, a binary change, several files) says it cannot be
28
- * shown as lines. */
27
+ * them. What git's header says beyond the lines prints as a note line above the table, or in
28
+ * its place: a rename, a mode change, an empty or binary file (`describePatch` has the
29
+ * sentences). A file whose type changed (a file that became a symlink) is two sections, each
30
+ * its own table under one note, named for its side (`"<label>, as it was"`). An empty patch
31
+ * says there is no difference, as `view` does; text that is not a diff, or holds several
32
+ * files, says it cannot be shown as lines. */
29
33
  export declare const patchView: <Message>(config: PatchViewConfig, h: HtmlBuilder<Message>) => Html;
30
34
  //# sourceMappingURL=lineDiff.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lineDiff.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/lineDiff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAiBtD,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd;mBACe;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AA2EH;;kFAEkF;AAClF,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAO3E,CAAC;AAEF;;;;;sBAKsB;AACtB,eAAO,MAAM,SAAS,GAAI,OAAO,UAAU,eAAe,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAWrF,CAAC"}
1
+ {"version":3,"file":"lineDiff.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/lineDiff.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAWtD,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd;mBACe;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC;oBACgB;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAyEH;;kFAEkF;AAClF,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAO3E,CAAC;AAEF;;;;;;;;+CAQ+C;AAC/C,eAAO,MAAM,SAAS,GAAI,OAAO,UAAU,eAAe,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAoBrF,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
2
- import { Array, Option, String } from "effect";
2
+ import { Array, Option } from "effect";
3
3
  import { LOCALE } from "../locale/locale.js";
4
- import { DiffRow, diffRowsOf, diffRowsOfPatch, foldUnchanged, hasChanges, } from "./diff.js";
4
+ import { DiffRow, diffRowsOf, foldUnchanged, hasChanges } from "./diff.js";
5
+ import { SAME_NOTE, readPatch } from "./patch.js";
5
6
  // VIEW
6
7
  const DEFAULT_CONTEXT = 2;
7
8
  const COLUMN_COUNT = 4;
@@ -29,7 +30,6 @@ const rowView = (row, h) => __foldkitBrandViewResult((DiffRow.match(row, {
29
30
  Fold: ({ count, firstOldNumber }) => __foldkitBrandViewResult((foldView(count, firstOldNumber, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#Fold"),
30
31
  })), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#rowView");
31
32
  const noteView = (note, h) => __foldkitBrandViewResult((h.p([h.Class("note-line")], [note])), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#noteView");
32
- const SAME_NOTE = "No difference: both sides hold the same text.";
33
33
  const tableView = (rows, label, h) => __foldkitBrandViewResult((h.div([h.Class("diff-wrap")], [
34
34
  h.table([h.AriaLabel(label), h.Class("diff")], [
35
35
  h.tbody([], Array.map(rows, (row) => __foldkitBrandViewResult((rowView(row, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#anonymous"))),
@@ -48,18 +48,22 @@ export const view = (config, h) => {
48
48
  /** A unified diff the caller already has (from a server, or `git diff -- <path>`) as `view`'s
49
49
  * table: its hunks' lines, numbered from their headers, and the unchanged lines between hunks
50
50
  * folded into a counted row. Lines past the last hunk are not in the patch, so nothing counts
51
- * them. An empty patch says there is no difference, as `view` does; anything but one file
52
- * with a hunk (text that is not a diff, a binary change, several files) says it cannot be
53
- * shown as lines. */
51
+ * them. What git's header says beyond the lines prints as a note line above the table, or in
52
+ * its place: a rename, a mode change, an empty or binary file (`describePatch` has the
53
+ * sentences). A file whose type changed (a file that became a symlink) is two sections, each
54
+ * its own table under one note, named for its side (`"<label>, as it was"`). An empty patch
55
+ * says there is no difference, as `view` does; text that is not a diff, or holds several
56
+ * files, says it cannot be shown as lines. */
54
57
  export const patchView = (config, h) => {
55
58
  const { patch, label } = config;
56
- if (String.isEmpty(String.trim(patch))) {
57
- return __foldkitBrandViewResult((noteView(SAME_NOTE, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#patchView");
58
- }
59
- else {
60
- return __foldkitBrandViewResult((Option.match(diffRowsOfPatch(patch), {
61
- onNone: () => __foldkitBrandViewResult((noteView("This diff cannot be shown as lines.", h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onNone"),
62
- onSome: (rows) => __foldkitBrandViewResult((tableView(rows, label, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onSome"),
63
- })), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#patchView");
64
- }
59
+ const { notes, tables } = readPatch(patch);
60
+ const parts = [
61
+ ...(Array.isReadonlyArrayNonEmpty(notes) ? [noteView(Array.join(notes, " "), h)] : []),
62
+ ...Array.map(tables, ({ rows, maybeSide }) => __foldkitBrandViewResult((tableView(rows, Option.match(maybeSide, { onNone: () => __foldkitBrandViewResult((label), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onNone"), onSome: (side) => __foldkitBrandViewResult((`${label}, ${side}`), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onSome") }), h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#anonymous~2")),
63
+ ];
64
+ // a lone table or note is drawn bare, so a flush window's body still meets its table
65
+ return __foldkitBrandViewResult((Array.match(parts, {
66
+ onEmpty: () => __foldkitBrandViewResult((noteView(SAME_NOTE, h)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onEmpty"),
67
+ onNonEmpty: ([part, ...others]) => __foldkitBrandViewResult((Array.isArrayEmpty(others) ? part : h.div([h.Class("stack gap-s")], parts)), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#onNonEmpty"),
68
+ })), "@gjermundgaraba-designs/pixel-paper/src/lineDiff/lineDiff.js#patchView");
65
69
  };
@@ -0,0 +1,35 @@
1
+ import { Option } from "effect";
2
+ import { type DiffRow } from "./diff.ts";
3
+ /** The name a path in git's header stands for: git C-quotes a name with unusual bytes
4
+ * (`"caf\303\251.txt"`), and leaves any other as it is. */
5
+ export declare const unquoted: (path: string) => string;
6
+ /** What a diff of two same texts says. */
7
+ export declare const SAME_NOTE = "No difference: both sides hold the same text.";
8
+ /** A table of the patch's lines; `maybeSide` says which side of a type change it is. */
9
+ type Table = Readonly<{
10
+ rows: ReadonlyArray<DiffRow>;
11
+ maybeSide: Option.Option<string>;
12
+ }>;
13
+ /** What `patchView` draws: its notes as a line, then its tables. */
14
+ export type PatchReading = Readonly<{
15
+ maybeRenamedFrom: Option.Option<string>;
16
+ notes: ReadonlyArray<string>;
17
+ tables: ReadonlyArray<Table>;
18
+ }>;
19
+ /** What `patchView` makes of a patch: the notes it prints and the tables it draws. */
20
+ export declare const readPatch: (patch: string) => PatchReading;
21
+ /** What a patch says beyond its lines, as `patchView` prints it. */
22
+ export type PatchDescription = Readonly<{
23
+ /** The path a rename left, unquoted: for a heading such as `old.txt → new.txt`. */
24
+ maybeRenamedFrom: Option.Option<string>;
25
+ /** The sentences `patchView` prints above the patch's lines, or in their place: a rename,
26
+ * a mode change, a type change, an empty or binary file, no difference, or a patch it
27
+ * cannot show as lines. */
28
+ notes: ReadonlyArray<string>;
29
+ }>;
30
+ /** What `patchView` says about a patch from `git diff`, read from its header: the notes it
31
+ * prints (`["Renamed from old.txt."]`), for a caller that prints them itself, and the path a
32
+ * rename left. */
33
+ export declare const describePatch: (patch: string) => PatchDescription;
34
+ export {};
35
+ //# sourceMappingURL=patch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../../src/lineDiff/patch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAErD,OAAO,EAAE,KAAK,OAAO,EAAmB,MAAM,WAAW,CAAC;AAgC1D;4DAC4D;AAC5D,eAAO,MAAM,QAAQ,SAAU,MAAM,KAAG,MAO9B,CAAC;AAsCX,0CAA0C;AAC1C,eAAO,MAAM,SAAS,kDAAkD,CAAC;AAIzE,wFAAwF;AACxF,KAAK,KAAK,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAE1F,oEAAoE;AACpE,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;CAC9B,CAAC,CAAC;AAoFH,sFAAsF;AACtF,eAAO,MAAM,SAAS,UAAW,MAAM,KAAG,YAiBzC,CAAC;AAIF,oEAAoE;AACpE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,mFAAmF;IACnF,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC;;gCAE4B;IAC5B,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC9B,CAAC,CAAC;AAEH;;mBAEmB;AACnB,eAAO,MAAM,aAAa,UAAW,MAAM,KAAG,gBAI7C,CAAC"}