@gjermundgaraba-designs/simple-rat 0.7.0 → 0.8.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 (159) hide show
  1. package/DESIGN.md +5 -5
  2. package/dist/highlight/highlight.d.ts.map +1 -1
  3. package/dist/highlight/highlight.js +66 -115
  4. package/dist/highlight/vite.d.ts +2 -1
  5. package/dist/highlight/vite.d.ts.map +1 -1
  6. package/dist/highlight/vite.js +5 -6
  7. package/dist/src/code/code.d.ts +4 -4
  8. package/dist/src/code/code.d.ts.map +1 -1
  9. package/dist/src/code/code.js +10 -7
  10. package/dist/src/code/index.d.ts.map +1 -1
  11. package/dist/src/{codeBlock/codeBlock.d.ts → code-block/code-block.d.ts} +2 -3
  12. package/dist/src/code-block/code-block.d.ts.map +1 -0
  13. package/dist/src/{codeBlock/codeBlock.js → code-block/code-block.js} +13 -7
  14. package/dist/src/code-block/index.d.ts +3 -0
  15. package/dist/src/code-block/index.d.ts.map +1 -0
  16. package/dist/src/code-block/index.js +1 -0
  17. package/dist/src/copy/copy.d.ts.map +1 -1
  18. package/dist/src/copy/copy.js +1 -7
  19. package/dist/src/{copyTab/copyTab.d.ts → copy-tab/copy-tab.d.ts} +3 -2
  20. package/dist/src/copy-tab/copy-tab.d.ts.map +1 -0
  21. package/dist/src/{copyTab/copyTab.js → copy-tab/copy-tab.js} +13 -13
  22. package/dist/src/copy-tab/index.d.ts +3 -0
  23. package/dist/src/copy-tab/index.d.ts.map +1 -0
  24. package/dist/src/{copyTab → copy-tab}/index.js +1 -1
  25. package/dist/src/diagram/diagram.d.ts.map +1 -1
  26. package/dist/src/diagram/index.d.ts.map +1 -1
  27. package/dist/src/footer/footer.d.ts.map +1 -1
  28. package/dist/src/footer/index.d.ts.map +1 -1
  29. package/dist/src/footnotes/footnotes.d.ts.map +1 -1
  30. package/dist/src/footnotes/footnotes.js +7 -2
  31. package/dist/src/footnotes/index.d.ts.map +1 -1
  32. package/dist/src/header/header.d.ts +1 -1
  33. package/dist/src/header/header.d.ts.map +1 -1
  34. package/dist/src/header/index.d.ts.map +1 -1
  35. package/dist/src/heading/heading.d.ts.map +1 -1
  36. package/dist/src/heading/index.d.ts.map +1 -1
  37. package/dist/src/index.d.ts +6 -6
  38. package/dist/src/index.d.ts.map +1 -1
  39. package/dist/src/index.js +6 -8
  40. package/dist/src/nav-link/index.d.ts +3 -0
  41. package/dist/src/nav-link/index.d.ts.map +1 -0
  42. package/dist/src/nav-link/index.js +1 -0
  43. package/dist/src/{navLink/navLink.d.ts → nav-link/nav-link.d.ts} +1 -1
  44. package/dist/src/nav-link/nav-link.d.ts.map +1 -0
  45. package/dist/src/{navLink/navLink.js → nav-link/nav-link.js} +1 -1
  46. package/dist/src/note/index.d.ts.map +1 -1
  47. package/dist/src/note/note.d.ts.map +1 -1
  48. package/dist/src/pager/index.d.ts.map +1 -1
  49. package/dist/src/pager/pager.d.ts.map +1 -1
  50. package/dist/src/post-list/index.d.ts +3 -0
  51. package/dist/src/post-list/index.d.ts.map +1 -0
  52. package/dist/src/post-list/index.js +1 -0
  53. package/dist/src/{postList/postList.d.ts → post-list/post-list.d.ts} +3 -2
  54. package/dist/src/post-list/post-list.d.ts.map +1 -0
  55. package/dist/src/post-list/post-list.js +6 -0
  56. package/dist/src/post-meta/index.d.ts +3 -0
  57. package/dist/src/post-meta/index.d.ts.map +1 -0
  58. package/dist/src/post-meta/index.js +1 -0
  59. package/dist/src/{postMeta/postMeta.d.ts → post-meta/post-meta.d.ts} +1 -1
  60. package/dist/src/post-meta/post-meta.d.ts.map +1 -0
  61. package/dist/src/{postMeta/postMeta.js → post-meta/post-meta.js} +3 -3
  62. package/dist/src/scheme/index.d.ts +1 -1
  63. package/dist/src/scheme/index.d.ts.map +1 -1
  64. package/dist/src/scheme/index.js +1 -1
  65. package/dist/src/scheme/{schemeSwitch.d.ts → scheme-switch.d.ts} +3 -2
  66. package/dist/src/scheme/scheme-switch.d.ts.map +1 -0
  67. package/dist/src/scheme/{schemeSwitch.js → scheme-switch.js} +7 -5
  68. package/dist/src/scheme/scheme.d.ts +0 -2
  69. package/dist/src/scheme/scheme.d.ts.map +1 -1
  70. package/dist/src/scheme/scheme.js +0 -2
  71. package/dist/src/scheme/switch.d.ts.map +1 -1
  72. package/dist/src/scheme/switch.js +12 -17
  73. package/dist/src/scrolls/scrolls.d.ts.map +1 -1
  74. package/dist/src/scrolls/scrolls.js +7 -9
  75. package/dist/src/skip-link/index.d.ts +2 -0
  76. package/dist/src/skip-link/index.d.ts.map +1 -0
  77. package/dist/src/skip-link/index.js +1 -0
  78. package/dist/src/{skipLink/skipLink.d.ts → skip-link/skip-link.d.ts} +1 -1
  79. package/dist/src/skip-link/skip-link.d.ts.map +1 -0
  80. package/dist/src/{skipLink/skipLink.js → skip-link/skip-link.js} +1 -1
  81. package/dist/src/table/index.d.ts.map +1 -1
  82. package/dist/src/table/table.d.ts +1 -1
  83. package/dist/src/table/table.d.ts.map +1 -1
  84. package/dist/src/table/table.js +3 -1
  85. package/highlight/highlight.ts +88 -118
  86. package/highlight/vite.ts +20 -10
  87. package/package.json +15 -16
  88. package/src/code/code.ts +18 -11
  89. package/src/code/index.ts +1 -0
  90. package/src/code/lines.d.ts +0 -5
  91. package/src/{codeBlock/codeBlock.ts → code-block/code-block.ts} +32 -14
  92. package/src/code-block/index.ts +3 -0
  93. package/src/copy/copy.ts +8 -17
  94. package/src/{copyTab/copyTab.ts → copy-tab/copy-tab.ts} +24 -8
  95. package/src/copy-tab/index.ts +12 -0
  96. package/src/diagram/diagram.ts +8 -4
  97. package/src/diagram/index.ts +1 -0
  98. package/src/footer/footer.ts +4 -2
  99. package/src/footer/index.ts +1 -0
  100. package/src/footnotes/footnotes.ts +26 -8
  101. package/src/footnotes/index.ts +1 -0
  102. package/src/header/header.ts +8 -5
  103. package/src/header/index.ts +1 -0
  104. package/src/heading/heading.ts +10 -2
  105. package/src/heading/index.ts +1 -0
  106. package/src/index.ts +23 -8
  107. package/src/nav-link/index.ts +3 -0
  108. package/src/{navLink/navLink.ts → nav-link/nav-link.ts} +14 -4
  109. package/src/note/index.ts +1 -0
  110. package/src/note/note.ts +6 -2
  111. package/src/pager/index.ts +1 -0
  112. package/src/pager/pager.ts +6 -2
  113. package/src/post-list/index.ts +3 -0
  114. package/src/post-list/post-list.ts +30 -0
  115. package/src/post-meta/index.ts +3 -0
  116. package/src/{postMeta/postMeta.ts → post-meta/post-meta.ts} +5 -2
  117. package/src/scheme/index.ts +3 -1
  118. package/src/scheme/{schemeSwitch.ts → scheme-switch.ts} +20 -8
  119. package/src/scheme/scheme.ts +3 -4
  120. package/src/scheme/switch.ts +9 -20
  121. package/src/scrolls/scrolls.ts +19 -13
  122. package/src/simple-rat.css +0 -47
  123. package/src/skip-link/index.ts +1 -0
  124. package/src/table/index.ts +1 -0
  125. package/src/table/table.ts +18 -9
  126. package/src/tokens.css +23 -32
  127. package/dist/src/codeBlock/codeBlock.d.ts.map +0 -1
  128. package/dist/src/codeBlock/index.d.ts +0 -3
  129. package/dist/src/codeBlock/index.d.ts.map +0 -1
  130. package/dist/src/codeBlock/index.js +0 -1
  131. package/dist/src/copyTab/copyTab.d.ts.map +0 -1
  132. package/dist/src/copyTab/index.d.ts +0 -3
  133. package/dist/src/copyTab/index.d.ts.map +0 -1
  134. package/dist/src/navLink/index.d.ts +0 -3
  135. package/dist/src/navLink/index.d.ts.map +0 -1
  136. package/dist/src/navLink/index.js +0 -1
  137. package/dist/src/navLink/navLink.d.ts.map +0 -1
  138. package/dist/src/postList/index.d.ts +0 -3
  139. package/dist/src/postList/index.d.ts.map +0 -1
  140. package/dist/src/postList/index.js +0 -1
  141. package/dist/src/postList/postList.d.ts.map +0 -1
  142. package/dist/src/postList/postList.js +0 -3
  143. package/dist/src/postMeta/index.d.ts +0 -3
  144. package/dist/src/postMeta/index.d.ts.map +0 -1
  145. package/dist/src/postMeta/index.js +0 -1
  146. package/dist/src/postMeta/postMeta.d.ts.map +0 -1
  147. package/dist/src/scheme/schemeSwitch.d.ts.map +0 -1
  148. package/dist/src/skipLink/index.d.ts +0 -2
  149. package/dist/src/skipLink/index.d.ts.map +0 -1
  150. package/dist/src/skipLink/index.js +0 -1
  151. package/dist/src/skipLink/skipLink.d.ts.map +0 -1
  152. package/src/codeBlock/index.ts +0 -2
  153. package/src/copyTab/index.ts +0 -2
  154. package/src/navLink/index.ts +0 -2
  155. package/src/postList/index.ts +0 -2
  156. package/src/postList/postList.ts +0 -19
  157. package/src/postMeta/index.ts +0 -2
  158. package/src/skipLink/index.ts +0 -1
  159. /package/src/{skipLink/skipLink.ts → skip-link/skip-link.ts} +0 -0
package/DESIGN.md CHANGED
@@ -298,7 +298,7 @@ The components are Foldkit: Views and Submodels over `foldkit`, each a namespace
298
298
  ### Code
299
299
 
300
300
  - **Inline:** code fill, 1px code-rule border, 0.1em 0.25em padding, body size.
301
- - **`CodeBlock`** writes `pre > code`: code fill, 1px code-rule border, 0.75rem 1rem padding, 0.875em / 1.25, scrolls sideways. `lang` (one of `Code.LANGUAGES`: `ts`, `tsx`, `sh`, `json`, `css`, `html`, `diff`) sets `code.language-*`, which gives the block the code-ink. `lines` colours the code: spans whose inline colour is a `var(--t-*)` token, italic for comments and shell commands; the rest takes code-ink, and a block without `lines` is plain text. The lines are data, made by Shiki with the package's theme while the site is built, so a page carries the colours and no highlighter: an import with the query `?lines=<lang>` is a file's `{ code, lines }`, spread into the config (`codeLines()`, see Adopting the system). Only a block that actually overflows takes focus: `Scrolls.WatchOverflow`, a Mount on the `pre`, makes it `role="region"` named "Code: <file or first line>, scrolls sideways" with `tabindex="0"`, re-checked whenever the block changes size, and takes the attributes away when the block leaves the page; blocks that fit stay out of the tab order. The Mount reports through `toParentMessage`, which the page may ignore.
301
+ - **`CodeBlock`** writes `pre > code`: code fill, 1px code-rule border, 0.75rem 1rem padding, 0.875em / 1.25, scrolls sideways. `lang` (one of `Code.LANGUAGES`: `ts`, `tsx`, `sh`, `json`, `css`, `html`, `diff`) sets `code.language-*`, which gives the block the code-ink. `lines` colours the code: spans whose inline colour is a `var(--t-*)` token, italic for comments and shell commands; the rest takes code-ink, and a block without `lines` is plain text. The lines are data, made by Highlights with the package's theme while the site is built, so a page carries the colours and no highlighter: an import with the query `?lines=<lang>` is a file's `{ code, lines }`, spread into the config (`codeLines()`, see Adopting the system). Only a block that actually overflows takes focus: `Scrolls.WatchOverflow`, a Mount on the `pre`, makes it `role="region"` named "Code: <file or first line>, scrolls sideways" with `tabindex="0"`, re-checked whenever the block changes size, and takes the attributes away when the block leaves the page; blocks that fit stay out of the tab order. The Mount reports through `toParentMessage`, which the page may ignore.
302
302
  - **Prose block:** a block with a `copy` tab and no `lang`; same fill and border, body size, 1.5 leading, wrapping.
303
303
  - **File tab:** a `file` wraps the block in `figure.file` with the name in its `figcaption`, a muted tab on the top-left edge. The tabs stand in a row of their own on the block's top edge: a long name wraps inside its tab, and the copy tab keeps its width beside it, so the two never overlap and the page never widens.
304
304
  - **Copy tab:** `copy` is the page's **`CopyTab`** (a Submodel) rendered through `h.submodel` with `CodeBlock.copyInputs(code, file?)` and the block's `toBlockView`; it sets `pre[data-copy]` and wraps it in `div.copyable` with a `button[type=button][tabindex="0"]` after it, built on `@foldkit/ui`'s Button, and a visually hidden `role="status"`. The link-blue `copy` tab on the top-right answers `copied` (or `select and copy` when the clipboard refuses) and turns back after 1.6s; it takes a press only while it reads `copy`, so one answer ends before the next copy starts (from the press until it reads `copy` again, the button is held: `aria-disabled="true"` and `data-disabled`, with no click handler); its accessible name is "Copy <file name or first line>". It writes through Effect's `Clipboard` port: provide `Clipboard.layer` from `@effect/platform-browser` in the application's `resources`. Both tabs: code fill, 1px code-rule border with no bottom edge, 0 1ch padding, 1.5 leading; a block with only the copy tab gets 2.25rem of room above for it.
@@ -339,8 +339,8 @@ The components are Foldkit: Views and Submodels over `foldkit`, each a namespace
339
339
 
340
340
  Install the package (README.md beside this file says how), install its peers (`foldkit`, `@foldkit/ui`, `effect`, `@effect/platform-browser`, and `@foldkit/vite-plugin` for `./highlight/vite`) and import the stylesheet once. The package is compiled JavaScript with its types and its views already branded, so the site's build needs only `foldkit()` beside what it imports:
341
341
 
342
- - `.`: every component above as a namespace, `Code` (`LANGUAGES` and the types of a block's coloured lines), `Scheme` (`Scheme`, `SchemeSwitch`, `schemeScript`) and `Scrolls`. Nothing it reaches imports Shiki. Every component renders on a server.
343
- - `./highlight`: `highlight(code, lang)`, which colours code with Shiki and the package's theme (its scopes mapped to the `--t-*` tokens) and returns the lines `CodeBlock` takes. It is for a build, never a page: importing it builds the highlighter. Shiki comes with the package.
342
+ - `.`: every component above as a namespace, `Code` (`LANGUAGES` and the types of a block's coloured lines), `Scheme` (`Scheme`, `SchemeSwitch`, `schemeScript`) and `Scrolls`. Nothing it reaches imports the highlighter. Every component renders on a server.
343
+ - `./highlight`: `highlight(code, lang)`, which colours code with Highlights (`@pierre/highlights`) and the package's theme (its token types mapped to the `--t-*` tokens) and returns the lines `CodeBlock` takes. It is for a build, never a page: importing it loads the highlighter's WebAssembly. Highlights comes with the package.
344
344
  - `./highlight/vite`: `codeLines()`, a Vite plugin that runs `highlight` while the site is built; add it to the build's `plugins`, beside `foldkit()`. An import with the query `?lines=<lang>`, as in `import retry from "./code/retry.txt?lines=ts"`, is the file's text and its lines, `{ code, lines }`, and the file is watched, so a change colours it again. Code the toolchain should not check or format goes in a `.txt`; a source file can be imported twice, to run and to show. The imports are typed by `src/code/lines.d.ts`, an ambient module declaration for each language, which `src/code/code.ts` references: a program that imports `simple-rat` has them, with nothing to add to its `tsconfig`. A build without Vite calls `highlight` itself and passes the lines on.
345
345
  - `./scheme`: `schemeScript`, `SCHEME_STORAGE_KEY` and `SCHEME_ATTRIBUTE` alone, for a build that writes `schemeScript` into a page's head.
346
346
  - `./tokens.css`: the tokens alone.
@@ -352,7 +352,7 @@ Without Foldkit, link `simple-rat.css` (with `tokens.css` beside it) and write t
352
352
 
353
353
  How a component in this package is made. The components follow these rules, and a new one follows them too; a review finding against one of them is a defect, not a style note.
354
354
 
355
- **The two kinds.** A **View** is a stateless render helper, `X.view(config, h)`: the caller owns any state and passes its Messages in the config. Copy `src/note/` or `src/footer/`; a View that owns a Mount (`src/codeBlock/`, `src/diagram/`) takes a required `toParentMessage`. A **Submodel** has a Model, Message, `init`, `update` and a `view` made with `defineView`, embedded with `h.submodel`. Copy `src/copyTab/` (a Command through a platform port; `src/copy/copy.ts` holds the Model, Messages, Commands and update, the same file in every system, and `copyTab.ts` adds this system's view) or `src/scheme/` (Commands that touch the document directly and a Command from `init`; `switch.ts` holds the Model, Messages, Commands and update, the same file in every system, and `schemeSwitch.ts` adds this system's view). A browser service that Effect already ports (`Clipboard`) is required from the application; what the component can do itself in a Command (an attribute on `<html>`, a `localStorage` entry) it does there, with no service.
355
+ **The two kinds.** A **View** is a stateless render helper, `X.view(config, h)`: the caller owns any state and passes its Messages in the config. Copy `src/note/` or `src/footer/`; a View that owns a Mount (`src/code-block/`, `src/diagram/`) takes a required `toParentMessage`. A **Submodel** has a Model, Message, `init`, `update` and a `view` made with `defineView`, embedded with `h.submodel`. Copy `src/copy-tab/` (a Command through a platform port; `src/copy/copy.ts` holds the Model, Messages, Commands and update, the same file in every system, and `copy-tab.ts` adds this system's view) or `src/scheme/` (Commands that touch the document directly and a Command from `init`; `switch.ts` holds the Model, Messages, Commands and update, the same file in every system, and `scheme-switch.ts` adds this system's view). A browser service that Effect already ports (`Clipboard`) is required from the application; what the component can do itself in a Command (an attribute on `<html>`, a `localStorage` entry) it does there, with no service.
356
356
 
357
357
  Each component is `src/<name>/<name>.ts` with an explicit `index.ts` (its public surface, which only `src/index.ts` imports; a sibling or a test imports the file that defines what it needs), a colocated `<name>.test.ts` (a Story for update, a Scene for view), an `export * as` line in `src/index.ts`, a place on the specimen (the reference page, or for the blog pieces the blog and post pages), and an entry in this document.
358
358
 
@@ -365,7 +365,7 @@ Each component is `src/<name>/<name>.ts` with an explicit `index.ts` (its public
365
365
  7. **Platform services are the application's.** A component that needs one says so in its TSDoc and here (`CopyTab` writes through Effect's `Clipboard`), and the application provides the Layer in its `resources`; `SchemeSwitch` needs none.
366
366
  8. **A Scene test for every accessibility contract** a component adds: roles, accessible names, `aria-pressed`, `aria-current`, `data-label`, the status region. Behaviour that only a real element shows (the overflow Mount) gets a test with real DOM in happy-dom, no mocks.
367
367
  9. **Fragment links go back to the browser.** A link to `#id` (the skip link, footnotes, heading links) is routed by Foldkit, so the application hands a fragment on the page being read back to the browser with `load(href)` from `foldkit/navigation`, which marks `:target` and moves the keyboard.
368
- 10. **No module-level state and no clocks in views.** Build-time code lives in `highlight/`, beside `src/` and never inside it: Shiki's highlighter, built once as a module constant (`highlight/highlight.ts`), and the Vite plugin that reads files (`highlight/vite.ts`), published as `./highlight` and `./highlight/vite`. The folder is the boundary: `highlight/` may import from `src/`, and nothing in `src/` imports from `highlight/`. Everything that changes lives in a Model or inside a Mount's scope.
368
+ 10. **No module-level state and no clocks in views.** Build-time code lives in `highlight/`, beside `src/` and never inside it: the highlighter and its themes, made once as module constants (`highlight/highlight.ts`), and the Vite plugin that reads files (`highlight/vite.ts`), published as `./highlight` and `./highlight/vite`. The folder is the boundary: `highlight/` may import from `src/`, and nothing in `src/` imports from `highlight/`. Everything that changes lives in a Model or inside a Mount's scope.
369
369
 
370
370
  ## Do's and Don'ts
371
371
 
@@ -1 +1 @@
1
- {"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../../highlight/highlight.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAwG3D;8BAC8B;AAC9B,eAAO,MAAM,SAAS,SAAU,MAAM,QAAQ,QAAQ,KAAG,KAQtD,CAAC"}
1
+ {"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../../highlight/highlight.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AA4D3D;8BAC8B;AAC9B,eAAO,MAAM,SAAS,SAAU,MAAM,QAAQ,QAAQ,KAAG,KAgCxD,CAAC"}
@@ -1,120 +1,71 @@
1
1
  import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
2
- // Syntax colours for code blocks, by Shiki, for a build to run: the theme maps TextMate
3
- // scopes to the --t-* tokens in tokens.css (Catppuccin: Latte in light, darkened for AA;
4
- // Mocha in dark), so the colours switch with the page. It sits outside src/, which never
5
- // imports it: a page is given the lines `highlight` made (vite.ts makes them of a file).
6
- import { createHighlighterCoreSync } from "shiki/core";
7
- import { createJavaScriptRawEngine } from "shiki/engine/javascript";
8
- import css from "@shikijs/langs-precompiled/css";
9
- import diff from "@shikijs/langs-precompiled/diff";
10
- import html from "@shikijs/langs-precompiled/html";
11
- import json from "@shikijs/langs-precompiled/json";
12
- import shellscript from "@shikijs/langs-precompiled/shellscript";
13
- import tsx from "@shikijs/langs-precompiled/tsx";
14
- const t = (token) => __foldkitBrandViewResult((`var(--t-${token})`), "@gjermundgaraba-designs/simple-rat/highlight/highlight.js#t");
15
- const codeTheme = {
2
+ import { codeToTokens } from "@pierre/highlights";
3
+ const ITALIC_FONT_STYLE_BIT = 1;
4
+ const SYNTAX = {
5
+ comment: { color: "com", font_style: "italic" },
6
+ string: "str",
7
+ "diff.plus": "str",
8
+ number: "num",
9
+ boolean: "num",
10
+ constant: "num",
11
+ "variable.special": "num",
12
+ keyword: "kw",
13
+ "keyword.operator": "op",
14
+ operator: "op",
15
+ "punctuation.bracket.html": "op",
16
+ "punctuation.bracket.jsx": "op",
17
+ type: "ty",
18
+ attribute: "ty",
19
+ selector: "ty",
20
+ function: "fn",
21
+ tag: "fn",
22
+ "property.json_key": "fn",
23
+ property: "prop",
24
+ "diff.minus": "del",
25
+ };
26
+ const OVERRIDES = {
27
+ css: { property: "fn", variable: "prop", function: "kw", tag: "ty" },
28
+ sh: { function: { color: "fn", font_style: "italic" } },
29
+ diff: { attribute: "kw" },
30
+ };
31
+ const themeOf = (syntax) => (__foldkitBrandViewResult(({
16
32
  name: "simple-rat",
17
- type: "light",
18
- colors: { "editor.foreground": "var(--code-ink)", "editor.background": "var(--code-fill)" },
19
- tokenColors: [
20
- {
21
- scope: ["comment", "punctuation.definition.comment", "meta.diff.header"],
22
- settings: { foreground: t("com"), fontStyle: "italic" },
23
- },
24
- {
25
- scope: [
26
- "string",
27
- "punctuation.definition.string",
28
- "string.unquoted.argument",
29
- "markup.inserted",
30
- ],
31
- settings: { foreground: t("str") },
32
- },
33
- {
34
- scope: [
35
- "constant.numeric",
36
- "constant.language",
37
- "constant.character",
38
- "constant.other.color",
39
- "keyword.other.unit",
40
- "support.constant.property-value",
41
- "variable.language.this",
42
- ],
43
- settings: { foreground: t("num") },
44
- },
45
- {
46
- scope: [
47
- "keyword",
48
- "storage.type",
49
- "storage.modifier",
50
- "keyword.control.at-rule",
51
- "support.function.misc.css",
52
- "support.function.transform.css",
53
- "meta.diff.range",
54
- ],
55
- settings: { foreground: t("kw") },
56
- },
57
- {
58
- scope: [
59
- "keyword.operator",
60
- "punctuation.definition.tag",
61
- "storage.type.function.arrow",
62
- "punctuation.separator.pipe",
63
- ],
64
- settings: { foreground: t("op") },
65
- },
66
- {
67
- scope: [
68
- "entity.name.type",
69
- "support.type.primitive",
70
- "support.class",
71
- "entity.other.inherited-class",
72
- "entity.other.attribute-name",
73
- "entity.name.tag.css",
74
- "support.type.builtin",
75
- ],
76
- settings: { foreground: t("ty") },
77
- },
78
- {
79
- scope: [
80
- "entity.name.function",
81
- "support.function",
82
- "entity.name.tag",
83
- "support.class.component",
84
- "support.type.property-name",
85
- "variable.css",
86
- ],
87
- settings: { foreground: t("fn") },
88
- },
89
- {
90
- scope: ["entity.name.command", "support.function.builtin.shell"],
91
- settings: { foreground: t("fn"), fontStyle: "italic" },
92
- },
93
- {
94
- scope: [
95
- "variable.other.property",
96
- "variable.other.object.property",
97
- "meta.object-literal.key",
98
- "variable.argument.css",
99
- ],
100
- settings: { foreground: t("prop") },
101
- },
102
- { scope: "markup.deleted", settings: { foreground: t("del") } },
103
- ],
33
+ appearance: "light",
34
+ style: { syntax },
35
+ cssVariables: { prefix: "--t-" },
36
+ }), "@gjermundgaraba-designs/simple-rat/highlight/highlight.js#themeOf"));
37
+ const BASE = themeOf(SYNTAX);
38
+ const THEMES = {
39
+ ts: BASE,
40
+ tsx: BASE,
41
+ json: BASE,
42
+ html: BASE,
43
+ css: themeOf({ ...SYNTAX, ...OVERRIDES.css }),
44
+ sh: themeOf({ ...SYNTAX, ...OVERRIDES.sh }),
45
+ diff: themeOf({ ...SYNTAX, ...OVERRIDES.diff }),
104
46
  };
105
- // Built once, when a build first imports this file. The grammars come precompiled, so
106
- // nothing translates their patterns. TypeScript is read with the TSX grammar.
107
- const highlighter = createHighlighterCoreSync({
108
- themes: [codeTheme],
109
- langs: [css, diff, html, json, shellscript, tsx],
110
- langAlias: { ts: "tsx" },
111
- engine: createJavaScriptRawEngine(),
112
- });
113
47
  /** A block's runs, line by line, for `CodeBlock`'s `lines`. A run in the plain code ink,
114
48
  upright, has no colour. */
115
- export const highlight = (code, lang) => __foldkitBrandViewResult((highlighter.codeToTokens(code, { lang, theme: "simple-rat" }).tokens.map((line) => __foldkitBrandViewResult((line.map((token) => {
116
- // Italic is bit 1 of Shiki's font style.
117
- const isItalic = ((token.fontStyle ?? 0) & 1) === 1;
118
- const isPlain = token.color === "var(--code-ink)" && !isItalic;
119
- return __foldkitBrandViewResult(({ content: token.content, color: isPlain ? undefined : token.color, isItalic }), "@gjermundgaraba-designs/simple-rat/highlight/highlight.js#anonymous~2");
120
- })), "@gjermundgaraba-designs/simple-rat/highlight/highlight.js#anonymous"))), "@gjermundgaraba-designs/simple-rat/highlight/highlight.js#highlight");
49
+ export const highlight = (code, lang) => {
50
+ const { tokens, fg } = codeToTokens(code, { lang, theme: THEMES[lang] });
51
+ return __foldkitBrandViewResult((tokens.map((line) => {
52
+ const runs = [];
53
+ for (const token of line) {
54
+ const isBlank = token.content.trim() === "";
55
+ const isItalic = !isBlank &&
56
+ ((token.fontStyle ?? 0) & ITALIC_FONT_STYLE_BIT) ===
57
+ ITALIC_FONT_STYLE_BIT;
58
+ const color = isBlank || (token.color === fg && !isItalic) ? undefined : token.color;
59
+ const last = runs.at(-1);
60
+ if (last !== undefined &&
61
+ last.color === color &&
62
+ last.isItalic === isItalic) {
63
+ last.content += token.content;
64
+ }
65
+ else {
66
+ runs.push({ content: token.content, color, isItalic });
67
+ }
68
+ }
69
+ return __foldkitBrandViewResult((runs), "@gjermundgaraba-designs/simple-rat/highlight/highlight.js#anonymous");
70
+ })), "@gjermundgaraba-designs/simple-rat/highlight/highlight.js#highlight");
71
+ };
@@ -1,4 +1,5 @@
1
- type Plugin = ReturnType<typeof import("@foldkit/vite-plugin").foldkitViewIdentity>;
1
+ import type { foldkitViewIdentity } from "@foldkit/vite-plugin";
2
+ type Plugin = ReturnType<typeof foldkitViewIdentity>;
2
3
  /**
3
4
  * Colours code while the site is built, so no page loads the highlighter. An import with the
4
5
  * query `?lines=<lang>` (one of `LANGUAGES`) is the file's text and its coloured lines,
@@ -1 +1 @@
1
- {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../highlight/vite.ts"],"names":[],"mappings":"AAKA,KAAK,MAAM,GAAG,UAAU,CAAC,cAAc,sBAAsB,EAAE,mBAAmB,CAAC,CAAC;AAOpF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,QAAO,MAc3B,CAAC"}
1
+ {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../../highlight/vite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAMhE,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAOrD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,QAAO,MAqB3B,CAAC"}
@@ -2,8 +2,7 @@ import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { LANGUAGES } from "../src/code/code.js";
4
4
  import { highlight } from "./highlight.js";
5
- // A file's path, then `lines=<lang>` anywhere in its query.
6
- const LINES_IMPORT = /^([^?]+)\?(?:.*&)?lines=([^&]*)/;
5
+ const LINES_IMPORT = /^(?<file>[^?]+)\?(?:.*&)?lines=(?<lang>[^&]*)/u;
7
6
  const isLanguage = (lang) => __foldkitBrandViewResult((LANGUAGES.some((known) => __foldkitBrandViewResult((known === lang), "@gjermundgaraba-designs/simple-rat/highlight/vite.js#anonymous"))), "@gjermundgaraba-designs/simple-rat/highlight/vite.js#isLanguage");
8
7
  /**
9
8
  * Colours code while the site is built, so no page loads the highlighter. An import with the
@@ -22,17 +21,17 @@ const isLanguage = (lang) => __foldkitBrandViewResult((LANGUAGES.some((known) =>
22
21
  */
23
22
  export const codeLines = () => (__foldkitBrandViewResult(({
24
23
  name: "simple-rat:code-lines",
25
- // Before Vite's own loaders, which would take a .txt for an asset.
26
24
  enforce: "pre",
27
25
  async load(id) {
28
- const [, file, lang] = LINES_IMPORT.exec(id) ?? [];
29
- if (file === undefined || lang === undefined)
26
+ const { file, lang } = LINES_IMPORT.exec(id)?.groups ?? {};
27
+ if (file === undefined || lang === undefined) {
30
28
  return __foldkitBrandViewResult((null), "@gjermundgaraba-designs/simple-rat/highlight/vite.js#load");
29
+ }
31
30
  if (!isLanguage(lang)) {
32
31
  return __foldkitBrandViewResult((this.error(`simple-rat: ?lines=${lang} is none of ${LANGUAGES.join(", ")}`)), "@gjermundgaraba-designs/simple-rat/highlight/vite.js#load");
33
32
  }
34
33
  this.addWatchFile(file);
35
- const code = await readFile(file, "utf8");
34
+ const code = await readFile(file, "utf-8");
36
35
  return __foldkitBrandViewResult((`export default ${JSON.stringify({ code, lines: highlight(code, lang) })};`), "@gjermundgaraba-designs/simple-rat/highlight/vite.js#load");
37
36
  },
38
37
  }), "@gjermundgaraba-designs/simple-rat/highlight/vite.js#codeLines"));
@@ -1,20 +1,20 @@
1
+ /// <reference path="../../../src/code/lines.d.ts" preserve="true" />
1
2
  /** The languages a block can be coloured in. */
2
3
  export declare const LANGUAGES: readonly ["ts", "tsx", "sh", "json", "css", "html", "diff"];
3
4
  export type Language = (typeof LANGUAGES)[number];
4
- /** One coloured run of a line: its text, the `--t-*` colour Shiki gave it, and whether it
5
+ /** One coloured run of a line: its text, the `--t-*` colour the highlighter gave it, and whether it
5
6
  is italic. */
6
- type Run = Readonly<{
7
+ export type Run = Readonly<{
7
8
  content: string;
8
9
  color: string | undefined;
9
10
  isItalic: boolean;
10
11
  }>;
11
12
  /** A block's runs, line by line. A run in the plain code ink, upright, has no colour. */
12
- export type Lines = ReadonlyArray<ReadonlyArray<Run>>;
13
+ export type Lines = ReadonlyArray<readonly Run[]>;
13
14
  /** A file's text and its coloured lines: what an import with `?lines=<lang>` gives (see
14
15
  lines.d.ts). */
15
16
  export type Highlighted = Readonly<{
16
17
  code: string;
17
18
  lines: Lines;
18
19
  }>;
19
- export {};
20
20
  //# sourceMappingURL=code.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../src/code/code.ts"],"names":[],"mappings":"AASA,gDAAgD;AAChD,eAAO,MAAM,SAAS,YAAI,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AACrF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD;iBACiB;AACjB,KAAK,GAAG,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEvF,yFAAyF;AACzF,MAAM,MAAM,KAAK,GAAG,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtD;mBACmB;AACnB,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../src/code/code.ts"],"names":[],"mappings":";AAGA,gDAAgD;AAChD,eAAO,MAAM,SAAS,YACpB,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,MAAM,EACN,MAAM,CACE,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD;iBACiB;AACjB,MAAM,MAAM,GAAG,GAAG,QAAQ,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC,CAAC;AAEH,yFAAyF;AACzF,MAAM,MAAM,KAAK,GAAG,aAAa,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;AAElD;mBACmB;AACnB,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC"}
@@ -1,9 +1,12 @@
1
- // The `?lines=<lang>` imports are declared for every program that reaches this file, which
2
- // is every one that imports the package: an ambient declaration has no import to travel by.
3
1
  // oxlint-disable-next-line typescript/triple-slash-reference
4
- /// <reference path="./lines.d.ts" />
5
- // A code block's colours as data, with no highlighter: what `CodeBlock` renders and what a
6
- // build makes with `highlight` (highlight/highlight.ts), so a page carries the colours and
7
- // not Shiki.
2
+ /// <reference path="./lines.d.ts" preserve="true" />
8
3
  /** The languages a block can be coloured in. */
9
- export const LANGUAGES = ["ts", "tsx", "sh", "json", "css", "html", "diff"];
4
+ export const LANGUAGES = [
5
+ "ts",
6
+ "tsx",
7
+ "sh",
8
+ "json",
9
+ "css",
10
+ "html",
11
+ "diff",
12
+ ];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { Html, HtmlBuilder } from "foldkit/html";
2
2
  import type { Language, Lines } from "../code/code.ts";
3
- import type { ViewInputs as CopyInputs } from "../copyTab/copyTab.ts";
3
+ import type { ViewInputs as CopyInputs } from "../copy-tab/copy-tab.ts";
4
4
  import * as Scrolls from "../scrolls/scrolls.ts";
5
5
  /** Configuration for rendering a code block with `view`. */
6
6
  export type ViewConfig<ParentMessage> = Readonly<{
@@ -21,7 +21,6 @@ export type ViewConfig<ParentMessage> = Readonly<{
21
21
  /** The overflow Mount's report, lifted into the page's Messages, which may ignore it. */
22
22
  toParentMessage: (message: Scrolls.Message) => ParentMessage;
23
23
  }>;
24
- /** The block's name for assistive technology: its file, or its first line. */
25
24
  export declare const nameOf: (code: string, file?: string) => string;
26
25
  /** What a block's `CopyTab` is given: the block's name and its code, without a trailing
27
26
  newline. */
@@ -29,4 +28,4 @@ export declare const copyInputs: (code: string, file?: string) => Omit<CopyInput
29
28
  /** A code block: coloured where it is given its lines, optionally with a file tab and a
30
29
  copy tab. Only a block that overflows takes focus, through `Scrolls.WatchOverflow`. */
31
30
  export declare const view: <ParentMessage>(config: ViewConfig<ParentMessage>, h: HtmlBuilder<ParentMessage>) => Html;
32
- //# sourceMappingURL=codeBlock.d.ts.map
31
+ //# sourceMappingURL=code-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../../src/code-block/code-block.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AAEjD,4DAA4D;AAC5D,MAAM,MAAM,UAAU,CAAC,aAAa,IAAI,QAAQ,CAAC;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb;wEACoE;IACpE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;2DAEuD;IACvD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;yBAEqB;IACrB,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACvD,yFAAyF;IACzF,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,aAAa,CAAC;CAC9D,CAAC,CAAC;AAEH,eAAO,MAAM,MAAM,SAAU,MAAM,SAAS,MAAM,KAAG,MAMpD,CAAC;AAEF;eACe;AACf,eAAO,MAAM,UAAU,SACf,MAAM,SACL,MAAM,KACZ,IAAI,CAAC,UAAU,EAAE,aAAa,CAG/B,CAAC;AAuBH;0FAC0F;AAC1F,eAAO,MAAM,IAAI,GAAI,aAAa,UACxB,UAAU,CAAC,aAAa,CAAC,KAC9B,WAAW,CAAC,aAAa,CAAC,KAC5B,IA4BF,CAAC"}
@@ -2,23 +2,27 @@ import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
2
2
  import { Option } from "effect";
3
3
  import * as Mount from "foldkit/mount";
4
4
  import * as Scrolls from "../scrolls/scrolls.js";
5
- /** The block's name for assistive technology: its file, or its first line. */
6
5
  export const nameOf = (code, file) => {
7
6
  const firstLine = code.trim().split("\n")[0] ?? "";
8
- return __foldkitBrandViewResult((file ?? (firstLine.length > 40 ? `${firstLine.slice(0, 40)}…` : firstLine)), "@gjermundgaraba-designs/simple-rat/src/codeBlock/codeBlock.js#nameOf");
7
+ return (__foldkitBrandViewResult((file ?? (firstLine.length > 40 ? `${firstLine.slice(0, 40)}…` : firstLine)), "@gjermundgaraba-designs/simple-rat/src/code-block/code-block.js#nameOf"));
9
8
  };
10
9
  /** What a block's `CopyTab` is given: the block's name and its code, without a trailing
11
10
  newline. */
12
11
  export const copyInputs = (code, file) => (__foldkitBrandViewResult(({
13
12
  name: nameOf(code, file),
14
13
  text: code.trimEnd(),
15
- }), "@gjermundgaraba-designs/simple-rat/src/codeBlock/codeBlock.js#copyInputs"));
14
+ }), "@gjermundgaraba-designs/simple-rat/src/code-block/code-block.js#copyInputs"));
16
15
  const linesView = (lines, h) => __foldkitBrandViewResult((lines.flatMap((line, index) => __foldkitBrandViewResult(([
17
16
  ...(index > 0 ? ["\n"] : []),
18
17
  ...line.map((run) => __foldkitBrandViewResult((run.color === undefined
19
18
  ? run.content
20
- : h.span([h.Style({ color: run.color, ...(run.isItalic ? { fontStyle: "italic" } : {}) })], [run.content])), "@gjermundgaraba-designs/simple-rat/src/codeBlock/codeBlock.js#anonymous~2")),
21
- ]), "@gjermundgaraba-designs/simple-rat/src/codeBlock/codeBlock.js#anonymous"))), "@gjermundgaraba-designs/simple-rat/src/codeBlock/codeBlock.js#linesView");
19
+ : h.span([
20
+ h.Style({
21
+ color: run.color,
22
+ ...(run.isItalic ? { fontStyle: "italic" } : {}),
23
+ }),
24
+ ], [run.content])), "@gjermundgaraba-designs/simple-rat/src/code-block/code-block.js#anonymous~2")),
25
+ ]), "@gjermundgaraba-designs/simple-rat/src/code-block/code-block.js#anonymous"))), "@gjermundgaraba-designs/simple-rat/src/code-block/code-block.js#linesView");
22
26
  /** A code block: coloured where it is given its lines, optionally with a file tab and a
23
27
  copy tab. Only a block that overflows takes focus, through `Scrolls.WatchOverflow`. */
24
28
  export const view = (config, h) => {
@@ -29,7 +33,9 @@ export const view = (config, h) => {
29
33
  h.OnMount(Mount.mapMessage(Scrolls.WatchOverflow({ maybeName: Option.some(name) }), toParentMessage)),
30
34
  ], [
31
35
  h.code(lang === undefined ? [] : [h.Class(`language-${lang}`)], lines === undefined ? [code] : linesView(lines, h)),
32
- ])), "@gjermundgaraba-designs/simple-rat/src/codeBlock/codeBlock.js#toBlockView");
36
+ ])), "@gjermundgaraba-designs/simple-rat/src/code-block/code-block.js#toBlockView");
33
37
  const body = copy === undefined ? toBlockView() : copy(toBlockView);
34
- return __foldkitBrandViewResult((file === undefined ? body : h.figure([h.Class("file")], [h.figcaption([], [file]), body])), "@gjermundgaraba-designs/simple-rat/src/codeBlock/codeBlock.js#view");
38
+ return __foldkitBrandViewResult((file === undefined
39
+ ? body
40
+ : h.figure([h.Class("file")], [h.figcaption([], [file]), body])), "@gjermundgaraba-designs/simple-rat/src/code-block/code-block.js#view");
35
41
  };
@@ -0,0 +1,3 @@
1
+ export { copyInputs, view } from "./code-block.ts";
2
+ export type { ViewConfig } from "./code-block.ts";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code-block/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEnD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1 @@
1
+ export { copyInputs, view } from "./code-block.js";
@@ -1 +1 @@
1
- {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../../src/copy/copy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAY,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAI3C,OAAO,KAAK,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAM9C,4FAA4F;AAC5F,eAAO,MAAM,SAAS;;;;;EAKpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC;AAE9C,2DAA2D;AAC3D,eAAO,MAAM,KAAK;;;;;;;;EAGhB,CAAC;AACH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAItC,wDAAwD;AACxD,eAAO,MAAM,OAAO;;QACH,IAAI;;;;;EAInB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAI1C,6FAA6F;AAC7F,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD,sDAAsD;AACtD,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAGxC,CAAC;AAIH,gDAAgD;AAChD,eAAO,MAAM,EAAE,UAAW,KAAK,KAAG,MAAkB,CAAC;AAOrD;0FAC0F;AAC1F,eAAO,MAAM,QAAQ;;;;;;+BASnB,CAAC;AAEH,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB;;iBAG7B,CAAC;AAWH;;mCAEmC;AACnC,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAcjD,CAAC"}
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../../src/copy/copy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAY,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAI3C,OAAO,KAAK,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAE9C,4FAA4F;AAC5F,eAAO,MAAM,SAAS;;;;;EAKpB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC;AAE9C,2DAA2D;AAC3D,eAAO,MAAM,KAAK;;;;;;;;EAGhB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAC;AAEtC,wDAAwD;AACxD,eAAO,MAAM,OAAO;;QACH,IAAI;;;;;EAInB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAE1C,6FAA6F;AAC7F,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElD,sDAAsD;AACtD,eAAO,MAAM,IAAI,WAAY,UAAU,KAAG,KAGxC,CAAC;AAEH,gDAAgD;AAChD,eAAO,MAAM,EAAE,UAAW,KAAK,KAAG,MAAkB,CAAC;AAIrD;0FAC0F;AAC1F,eAAO,MAAM,QAAQ;;;;;;+BAUnB,CAAC;AAEH,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB;;iBAK7B,CAAC;AASH;;mCAEmC;AACnC,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAcjD,CAAC"}
@@ -5,8 +5,6 @@ import * as Command from "foldkit/command";
5
5
  import { defineMessageUnion } from "foldkit/message";
6
6
  import { defineTaggedUnion } from "foldkit/schema";
7
7
  import { modifyFields } from "foldkit/struct";
8
- // A copy to the clipboard, without its view: the system's own control renders it.
9
- // MODEL
10
8
  /** Where a copy is: nothing yet, writing to the clipboard, just copied, or just refused. */
11
9
  export const CopyState = defineTaggedUnion({
12
10
  Idle: {},
@@ -19,7 +17,6 @@ export const Model = Schema.Struct({
19
17
  id: Schema.String,
20
18
  state: CopyState,
21
19
  });
22
- // MESSAGE
23
20
  /** Union of all Messages a copy control can produce. */
24
21
  export const Message = defineMessageUnion({
25
22
  ClickedCopy: { text: Schema.String },
@@ -32,11 +29,8 @@ export const init = (config) => (__foldkitBrandViewResult(({
32
29
  id: config.id,
33
30
  state: CopyState.Idle(),
34
31
  }), "@gjermundgaraba-designs/simple-rat/src/copy/copy.js#init"));
35
- // ACCESSORS
36
32
  /** The control's id, unique in the document. */
37
33
  export const id = (model) => __foldkitBrandViewResult((model.id), "@gjermundgaraba-designs/simple-rat/src/copy/copy.js#id");
38
- // COMMAND
39
- /** How long the control answers for: that it copied, or that the copy failed. */
40
34
  const WORD_BEAT = Duration.millis(1600);
41
35
  /** Writes the text to the clipboard through Effect's `Clipboard` port. Provide
42
36
  `Clipboard.layer` from `@effect/platform-browser` in the application's `resources`. */
@@ -47,7 +41,7 @@ export const CopyText = Command.define("CopyText", {
47
41
  const clipboard = yield* Clipboard.Clipboard;
48
42
  yield* clipboard.writeString(text);
49
43
  return __foldkitBrandViewResult((Message.SucceededCopyText()), "@gjermundgaraba-designs/simple-rat/src/copy/copy.js#anonymous");
50
- }).pipe(Effect.catch(() => __foldkitBrandViewResult((Effect.succeed(Message.FailedCopyText())), "@gjermundgaraba-designs/simple-rat/src/copy/copy.js#anonymous~2")))), "@gjermundgaraba-designs/simple-rat/src/copy/copy.js#execute"),
44
+ }).pipe(Effect.orElseSucceed(() => __foldkitBrandViewResult((Message.FailedCopyText()), "@gjermundgaraba-designs/simple-rat/src/copy/copy.js#anonymous~2")))), "@gjermundgaraba-designs/simple-rat/src/copy/copy.js#execute"),
51
45
  });
52
46
  /** Waits out the beat the answer shows for. */
53
47
  export const WaitBeforeSettling = Command.define("WaitBeforeSettling", {
@@ -1,5 +1,6 @@
1
1
  import type { Html } from "foldkit/html";
2
- export * from "../copy/copy.ts";
2
+ export { CopyState, CopyText, Message, Model, WaitBeforeSettling, id, init, update, } from "../copy/copy.ts";
3
+ export type { InitConfig } from "../copy/copy.ts";
3
4
  /** Per-render inputs passed to `view` through `h.submodel`'s `viewInputs`. */
4
5
  export type ViewInputs = Readonly<{
5
6
  /** What is copied, for the tab's accessible name: the block's file or first line. */
@@ -44,4 +45,4 @@ export declare const view: import("foldkit/submodel").View<{
44
45
  boundary, so its Mount reports to the page). */
45
46
  toBlockView: () => Html;
46
47
  }>>;
47
- //# sourceMappingURL=copyTab.d.ts.map
48
+ //# sourceMappingURL=copy-tab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy-tab.d.ts","sourceRoot":"","sources":["../../../src/copy-tab/copy-tab.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMzC,OAAO,EACL,SAAS,EACT,QAAQ,EACR,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,EAAE,EACF,IAAI,EACJ,MAAM,GACP,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,8EAA8E;AAC9E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb;uDACmD;IACnD,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC,CAAC;AAkBH;;;;sEAIsE;AACtE,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;IA9Bf,qFAAqF;UAC/E,MAAM;IACZ,kCAAkC;UAC5B,MAAM;IACZ;uDACmD;iBACtC,MAAM,IAAI;GAgDxB,CAAC"}
@@ -2,19 +2,19 @@ import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
2
2
  import { Button as UiButton } from "@foldkit/ui";
3
3
  import { defineView } from "foldkit/submodel";
4
4
  import { CopyState, Message } from "../copy/copy.js";
5
- export * from "../copy/copy.js";
5
+ export { CopyState, CopyText, Message, Model, WaitBeforeSettling, id, init, update, } from "../copy/copy.js";
6
6
  const word = (state) => __foldkitBrandViewResult((CopyState.match(state, {
7
- Idle: () => __foldkitBrandViewResult(("copy"), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Idle"),
8
- Copying: () => __foldkitBrandViewResult(("copy"), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Copying"),
9
- Copied: () => __foldkitBrandViewResult(("copied"), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Copied"),
10
- Failed: () => __foldkitBrandViewResult(("select and copy"), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Failed"),
11
- })), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#word");
7
+ Idle: () => __foldkitBrandViewResult(("copy"), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Idle"),
8
+ Copying: () => __foldkitBrandViewResult(("copy"), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Copying"),
9
+ Copied: () => __foldkitBrandViewResult(("copied"), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Copied"),
10
+ Failed: () => __foldkitBrandViewResult(("select and copy"), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Failed"),
11
+ })), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#word");
12
12
  const said = (state) => __foldkitBrandViewResult((CopyState.match(state, {
13
- Idle: () => __foldkitBrandViewResult((""), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Idle~2"),
14
- Copying: () => __foldkitBrandViewResult((""), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Copying~2"),
15
- Copied: () => __foldkitBrandViewResult(("Copied"), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Copied~2"),
16
- Failed: () => __foldkitBrandViewResult(("Copy failed. Select the text and copy it by hand."), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#Failed~2"),
17
- })), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#said");
13
+ Idle: () => __foldkitBrandViewResult((""), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Idle~2"),
14
+ Copying: () => __foldkitBrandViewResult((""), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Copying~2"),
15
+ Copied: () => __foldkitBrandViewResult(("Copied"), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Copied~2"),
16
+ Failed: () => __foldkitBrandViewResult(("Copy failed. Select the text and copy it by hand."), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#Failed~2"),
17
+ })), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#said");
18
18
  /** `div.copyable`: the block, a `copy` tab on its top-right edge, built on `@foldkit/ui`'s
19
19
  Button, that answers `copied` (or `select and copy` when the browser refuses) for a beat
20
20
  and says so to screen readers through a visually hidden status. The tab takes a press only
@@ -25,7 +25,7 @@ export const view = defineView((model, { name, text, toBlockView }, h) => __fold
25
25
  UiButton.view({
26
26
  isDisabled: !CopyState.guards.Idle(model.state),
27
27
  onClick: Message.ClickedCopy({ text }),
28
- toView: ({ button }) => __foldkitBrandViewResult((h.button([...button, h.AriaLabel(`Copy ${name}`)], [word(model.state)])), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#toView"),
28
+ toView: ({ button }) => __foldkitBrandViewResult((h.button([...button, h.AriaLabel(`Copy ${name}`)], [word(model.state)])), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#toView"),
29
29
  }, h),
30
30
  h.span([h.Class("visually-hidden"), h.Role("status")], [said(model.state)]),
31
- ])), "@gjermundgaraba-designs/simple-rat/src/copyTab/copyTab.js#anonymous"));
31
+ ])), "@gjermundgaraba-designs/simple-rat/src/copy-tab/copy-tab.js#anonymous"));
@@ -0,0 +1,3 @@
1
+ export { CopyText, Message, Model, WaitBeforeSettling, id, init, update, view, } from "./copy-tab.ts";
2
+ export type { InitConfig, ViewInputs } from "./copy-tab.ts";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/copy-tab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,EAAE,EACF,IAAI,EACJ,MAAM,EACN,IAAI,GACL,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- export { CopyText, Message, Model, WaitBeforeSettling, id, init, update, view } from "./copyTab.js";
1
+ export { CopyText, Message, Model, WaitBeforeSettling, id, init, update, view, } from "./copy-tab.js";
@@ -1 +1 @@
1
- {"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../../src/diagram/diagram.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AAEjD,yDAAyD;AACzD,MAAM,MAAM,UAAU,CAAC,aAAa,IAAI,QAAQ,CAAC;IAC/C,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACvC,yFAAyF;IACzF,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,aAAa,CAAC;CAC9D,CAAC,CAAC;AAEH;;oDAEoD;AACpD,eAAO,MAAM,IAAI,GAAI,aAAa,UACxB,UAAU,CAAC,aAAa,CAAC,KAC9B,WAAW,CAAC,aAAa,CAAC,KAC5B,IAkBF,CAAC"}
1
+ {"version":3,"file":"diagram.d.ts","sourceRoot":"","sources":["../../../src/diagram/diagram.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AAEjD,yDAAyD;AACzD,MAAM,MAAM,UAAU,CAAC,aAAa,IAAI,QAAQ,CAAC;IAC/C,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,OAAO,CAAC,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;IACvC,yFAAyF;IACzF,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,aAAa,CAAC;CAC9D,CAAC,CAAC;AAEH;;oDAEoD;AACpD,eAAO,MAAM,IAAI,GAAI,aAAa,UACxB,UAAU,CAAC,aAAa,CAAC,KAC9B,WAAW,CAAC,aAAa,CAAC,KAC5B,IAsBF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/diagram/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/diagram/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../src/footer/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,oBAAoB;IACpB,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;CACpC,CAAC,CAAC;AAEH,2BAA2B;AAC3B,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAC5B,CAAC"}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../src/footer/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,oBAAoB;IACpB,IAAI,EAAE,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;CACpC,CAAC,CAAC;AAEH,2BAA2B;AAC3B,eAAO,MAAM,IAAI,GAAI,OAAO,UAClB,UAAU,KACf,WAAW,CAAC,OAAO,CAAC,KACtB,IAAsD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/footer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/footer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"footnotes.d.ts","sourceRoot":"","sources":["../../../src/footnotes/footnotes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,8FAA8F;AAC9F,eAAO,MAAM,OAAO,GAAI,OAAO,cAAc,MAAM,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IACgB,CAAC;AAEhG,yDAAyD;AACzD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,kCAAkC;IAClC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;CACpD,CAAC,CAAC;AAEH;kDACkD;AAClD,eAAO,MAAM,IAAI,GAAI,OAAO,UAAU,UAAU,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAuBzE,CAAC"}
1
+ {"version":3,"file":"footnotes.d.ts","sourceRoot":"","sources":["../../../src/footnotes/footnotes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD,8FAA8F;AAC9F,eAAO,MAAM,OAAO,GAAI,OAAO,cACjB,MAAM,KACf,WAAW,CAAC,OAAO,CAAC,KACtB,IASA,CAAC;AAEJ,yDAAyD;AACzD,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,kCAAkC;IAClC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC;CACpD,CAAC,CAAC;AAEH;kDACkD;AAClD,eAAO,MAAM,IAAI,GAAI,OAAO,UAClB,UAAU,KACf,WAAW,CAAC,OAAO,CAAC,KACtB,IA2BA,CAAC"}