shelving 1.236.2 → 1.237.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 (219) hide show
  1. package/extract/IndexExtractor.js +9 -2
  2. package/extract/MergingExtractor.d.ts +3 -1
  3. package/extract/MergingExtractor.js +41 -3
  4. package/extract/TypescriptExtractor.d.ts +1 -0
  5. package/extract/TypescriptExtractor.js +12 -2
  6. package/package.json +1 -1
  7. package/ui/README.md +19 -274
  8. package/ui/app/App.d.ts +1 -0
  9. package/ui/app/App.js +1 -0
  10. package/ui/app/App.md +58 -0
  11. package/ui/app/App.tsx +1 -0
  12. package/ui/block/Card.d.ts +1 -0
  13. package/ui/block/Card.js +1 -0
  14. package/ui/block/Card.md +85 -0
  15. package/ui/block/Card.tsx +1 -0
  16. package/ui/block/Heading.d.ts +1 -0
  17. package/ui/block/Heading.js +1 -0
  18. package/ui/block/Heading.md +70 -0
  19. package/ui/block/Heading.tsx +1 -0
  20. package/ui/block/List.d.ts +1 -0
  21. package/ui/block/List.js +1 -0
  22. package/ui/block/List.md +51 -0
  23. package/ui/block/List.tsx +1 -0
  24. package/ui/block/Panel.d.ts +1 -0
  25. package/ui/block/Panel.js +1 -0
  26. package/ui/block/Panel.md +50 -0
  27. package/ui/block/Panel.tsx +1 -0
  28. package/ui/block/Paragraph.d.ts +1 -0
  29. package/ui/block/Paragraph.js +1 -0
  30. package/ui/block/Paragraph.md +48 -0
  31. package/ui/block/Paragraph.tsx +1 -0
  32. package/ui/block/Prose.d.ts +1 -0
  33. package/ui/block/Prose.js +1 -0
  34. package/ui/block/Prose.md +49 -0
  35. package/ui/block/Prose.tsx +1 -0
  36. package/ui/block/Section.d.ts +6 -0
  37. package/ui/block/Section.js +6 -0
  38. package/ui/block/Section.md +56 -0
  39. package/ui/block/Section.tsx +6 -0
  40. package/ui/block/Subheading.d.ts +1 -0
  41. package/ui/block/Subheading.js +1 -0
  42. package/ui/block/Subheading.md +58 -0
  43. package/ui/block/Subheading.tsx +1 -0
  44. package/ui/block/Table.d.ts +1 -0
  45. package/ui/block/Table.js +1 -0
  46. package/ui/block/Table.md +54 -0
  47. package/ui/block/Table.tsx +1 -0
  48. package/ui/block/Title.d.ts +1 -0
  49. package/ui/block/Title.js +1 -0
  50. package/ui/block/Title.md +57 -0
  51. package/ui/block/Title.tsx +1 -0
  52. package/ui/dialog/Dialog.d.ts +1 -0
  53. package/ui/dialog/Dialog.js +1 -0
  54. package/ui/dialog/Dialog.md +73 -0
  55. package/ui/dialog/Dialog.tsx +1 -0
  56. package/ui/dialog/Modal.d.ts +1 -0
  57. package/ui/dialog/Modal.js +1 -0
  58. package/ui/dialog/Modal.md +40 -0
  59. package/ui/dialog/Modal.tsx +1 -0
  60. package/ui/docs/DocumentationButtons.d.ts +2 -0
  61. package/ui/docs/DocumentationButtons.js +2 -0
  62. package/ui/docs/DocumentationButtons.md +38 -0
  63. package/ui/docs/DocumentationButtons.tsx +2 -0
  64. package/ui/docs/DocumentationCard.d.ts +1 -0
  65. package/ui/docs/DocumentationCard.js +1 -0
  66. package/ui/docs/DocumentationCard.md +35 -0
  67. package/ui/docs/DocumentationCard.tsx +1 -0
  68. package/ui/docs/DocumentationKind.d.ts +1 -1
  69. package/ui/docs/DocumentationKind.js +9 -4
  70. package/ui/docs/DocumentationKind.tsx +10 -5
  71. package/ui/docs/DocumentationPage.d.ts +1 -0
  72. package/ui/docs/DocumentationPage.js +2 -0
  73. package/ui/docs/DocumentationPage.md +46 -0
  74. package/ui/docs/DocumentationPage.tsx +2 -0
  75. package/ui/form/Button.d.ts +1 -0
  76. package/ui/form/Button.js +1 -0
  77. package/ui/form/Button.md +88 -0
  78. package/ui/form/Button.tsx +1 -0
  79. package/ui/form/Field.d.ts +6 -1
  80. package/ui/form/Field.js +6 -1
  81. package/ui/form/Field.md +59 -0
  82. package/ui/form/Field.tsx +6 -1
  83. package/ui/form/Form.d.ts +1 -0
  84. package/ui/form/Form.md +118 -0
  85. package/ui/form/Form.tsx +1 -0
  86. package/ui/form/FormStore.md +47 -0
  87. package/ui/form/SchemaInput.d.ts +1 -0
  88. package/ui/form/SchemaInput.md +64 -0
  89. package/ui/form/SchemaInput.tsx +1 -0
  90. package/ui/inline/Code.d.ts +1 -0
  91. package/ui/inline/Code.js +1 -0
  92. package/ui/inline/Code.md +58 -0
  93. package/ui/inline/Code.tsx +1 -0
  94. package/ui/inline/Link.d.ts +1 -0
  95. package/ui/inline/Link.js +1 -0
  96. package/ui/inline/Link.md +47 -0
  97. package/ui/inline/Link.tsx +1 -0
  98. package/ui/inline/Mark.d.ts +1 -0
  99. package/ui/inline/Mark.js +1 -0
  100. package/ui/inline/Mark.md +40 -0
  101. package/ui/inline/Mark.tsx +1 -0
  102. package/ui/inline/Strong.d.ts +1 -0
  103. package/ui/inline/Strong.js +1 -0
  104. package/ui/inline/Strong.md +34 -0
  105. package/ui/inline/Strong.tsx +1 -0
  106. package/ui/layout/CenteredLayout.d.ts +1 -0
  107. package/ui/layout/CenteredLayout.js +1 -0
  108. package/ui/layout/CenteredLayout.md +38 -0
  109. package/ui/layout/CenteredLayout.tsx +1 -0
  110. package/ui/layout/SidebarLayout.d.ts +1 -0
  111. package/ui/layout/SidebarLayout.js +1 -0
  112. package/ui/layout/SidebarLayout.md +65 -0
  113. package/ui/layout/SidebarLayout.tsx +1 -0
  114. package/ui/menu/Menu.d.ts +2 -0
  115. package/ui/menu/Menu.js +2 -0
  116. package/ui/menu/Menu.md +51 -0
  117. package/ui/menu/Menu.tsx +2 -0
  118. package/ui/menu/MenuItem.md +54 -0
  119. package/ui/misc/Catcher.d.ts +1 -0
  120. package/ui/misc/Catcher.js +1 -0
  121. package/ui/misc/Catcher.md +41 -0
  122. package/ui/misc/Catcher.tsx +1 -0
  123. package/ui/misc/Loading.d.ts +1 -0
  124. package/ui/misc/Loading.js +1 -0
  125. package/ui/misc/Loading.md +28 -0
  126. package/ui/misc/Loading.tsx +1 -0
  127. package/ui/misc/Mapper.md +40 -0
  128. package/ui/misc/Markup.d.ts +1 -0
  129. package/ui/misc/Markup.js +1 -0
  130. package/ui/misc/Markup.md +34 -0
  131. package/ui/misc/Markup.tsx +1 -0
  132. package/ui/misc/StatusIcon.d.ts +1 -0
  133. package/ui/misc/StatusIcon.js +1 -0
  134. package/ui/misc/StatusIcon.md +25 -0
  135. package/ui/misc/StatusIcon.tsx +1 -0
  136. package/ui/misc/Tag.d.ts +1 -0
  137. package/ui/misc/Tag.js +1 -0
  138. package/ui/misc/Tag.md +47 -0
  139. package/ui/misc/Tag.tsx +1 -0
  140. package/ui/notice/Notice.d.ts +1 -0
  141. package/ui/notice/Notice.js +1 -0
  142. package/ui/notice/Notice.md +53 -0
  143. package/ui/notice/Notice.tsx +1 -0
  144. package/ui/notice/Notices.d.ts +1 -0
  145. package/ui/notice/Notices.js +1 -0
  146. package/ui/notice/Notices.md +59 -0
  147. package/ui/notice/Notices.tsx +1 -0
  148. package/ui/page/HTML.d.ts +1 -0
  149. package/ui/page/HTML.js +1 -0
  150. package/ui/page/HTML.md +36 -0
  151. package/ui/page/HTML.tsx +1 -0
  152. package/ui/page/Head.d.ts +1 -0
  153. package/ui/page/Head.js +1 -0
  154. package/ui/page/Head.md +26 -0
  155. package/ui/page/Head.tsx +1 -0
  156. package/ui/page/Page.d.ts +1 -0
  157. package/ui/page/Page.js +1 -0
  158. package/ui/page/Page.md +42 -0
  159. package/ui/page/Page.tsx +1 -0
  160. package/ui/router/Navigation.d.ts +1 -0
  161. package/ui/router/Navigation.js +1 -0
  162. package/ui/router/Navigation.md +41 -0
  163. package/ui/router/Navigation.tsx +1 -0
  164. package/ui/router/NavigationStore.md +34 -0
  165. package/ui/router/Router.d.ts +1 -0
  166. package/ui/router/Router.js +1 -0
  167. package/ui/router/Router.md +143 -0
  168. package/ui/router/Router.tsx +1 -0
  169. package/ui/style/TINT_CLASS.md +55 -0
  170. package/ui/transition/CollapseTransition.d.ts +1 -0
  171. package/ui/transition/CollapseTransition.js +1 -0
  172. package/ui/transition/CollapseTransition.md +34 -0
  173. package/ui/transition/CollapseTransition.tsx +1 -0
  174. package/ui/transition/FadeTransition.d.ts +1 -0
  175. package/ui/transition/FadeTransition.js +1 -0
  176. package/ui/transition/FadeTransition.md +36 -0
  177. package/ui/transition/FadeTransition.tsx +1 -0
  178. package/ui/transition/HorizontalTransition.d.ts +1 -0
  179. package/ui/transition/HorizontalTransition.js +1 -0
  180. package/ui/transition/HorizontalTransition.md +44 -0
  181. package/ui/transition/HorizontalTransition.tsx +1 -0
  182. package/ui/transition/Transition.d.ts +1 -0
  183. package/ui/transition/Transition.js +1 -0
  184. package/ui/transition/Transition.md +70 -0
  185. package/ui/transition/Transition.tsx +1 -0
  186. package/ui/transition/VerticalTransition.d.ts +1 -0
  187. package/ui/transition/VerticalTransition.js +1 -0
  188. package/ui/transition/VerticalTransition.md +34 -0
  189. package/ui/transition/VerticalTransition.tsx +1 -0
  190. package/ui/tree/TreeApp.d.ts +1 -0
  191. package/ui/tree/TreeApp.js +1 -0
  192. package/ui/tree/TreeApp.md +59 -0
  193. package/ui/tree/TreeApp.tsx +1 -0
  194. package/ui/tree/TreeMenu.d.ts +1 -0
  195. package/ui/tree/TreeMenu.js +1 -0
  196. package/ui/tree/TreeMenu.md +35 -0
  197. package/ui/tree/TreeMenu.tsx +1 -0
  198. package/ui/tree/TreeSidebar.d.ts +1 -0
  199. package/ui/tree/TreeSidebar.js +1 -0
  200. package/ui/tree/TreeSidebar.md +24 -0
  201. package/ui/tree/TreeSidebar.tsx +1 -0
  202. package/ui/util/getClass.md +55 -0
  203. package/ui/util/notify.md +50 -0
  204. package/ui/util/requireContext.md +24 -0
  205. package/ui/app/README.md +0 -32
  206. package/ui/block/README.md +0 -144
  207. package/ui/dialog/README.md +0 -80
  208. package/ui/docs/README.md +0 -71
  209. package/ui/form/README.md +0 -165
  210. package/ui/inline/README.md +0 -86
  211. package/ui/layout/README.md +0 -71
  212. package/ui/menu/README.md +0 -33
  213. package/ui/misc/README.md +0 -121
  214. package/ui/notice/README.md +0 -94
  215. package/ui/page/README.md +0 -56
  216. package/ui/router/README.md +0 -186
  217. package/ui/transition/README.md +0 -80
  218. package/ui/tree/README.md +0 -78
  219. package/ui/util/README.md +0 -153
@@ -0,0 +1,54 @@
1
+ # MenuItem
2
+
3
+ A single `<li>` link entry inside a [`Menu`](/ui/Menu). It reads the current page URL from the `Meta` context and automatically marks itself `active` (exact match) or `proud` (an ancestor of the current page) — and when proud, reveals its submenu children.
4
+
5
+ **Things to know:**
6
+
7
+ - The first child is the link label (rendered inside the `<a>`). Any additional children form the submenu and are rendered only when the item is proud (the current URL starts with the item's `href`). Wrap that submenu in a nested [`Menu`](/ui/Menu) to get the `.menu .menu` indentation.
8
+ - It forwards all `ClickableProps` — `href`, `onClick`, `disabled`, and so on — to the underlying [`Clickable`](/ui/Clickable).
9
+ - `active` and `proud` are computed against the URL from [`Router`](/ui/Router) / [`Navigation`](/ui/Navigation) context.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { Menu, MenuItem } from "shelving/ui";
15
+
16
+ <Menu>
17
+ <MenuItem href="/users">
18
+ Users
19
+ <Menu>
20
+ <MenuItem href="/users/active">Active</MenuItem>
21
+ <MenuItem href="/users/archived">Archived</MenuItem>
22
+ </Menu>
23
+ </MenuItem>
24
+ <MenuItem href="/settings">Settings</MenuItem>
25
+ </Menu>
26
+ ```
27
+
28
+ ## Styling
29
+
30
+ The item link's hooks (defined in `Menu.module.css`):
31
+
32
+ | Variable | Styles | Default |
33
+ |---|---|---|
34
+ | `--menu-padding` | Link inner padding | `var(--space-xxsmall)` |
35
+ | `--menu-radius` | Link corner radius | `var(--radius-xxsmall)` |
36
+ | `--menu-focus-border` | Focus outline | `var(--stroke-focus) solid var(--color-focus)` |
37
+ | `--menu-hover-background` | Link fill on hover/focus | `var(--tint-90)` |
38
+ | `--menu-hover-color` | Link text colour on hover/focus | `var(--tint-00)` |
39
+ | `--menu-proud-background` | Fill when proud (ancestor of current page) | `transparent` |
40
+ | `--menu-proud` | Text colour when proud | `var(--tint-00)` |
41
+ | `--menu-proud-weight` | Font weight when proud | `var(--weight-strong)` |
42
+ | `--menu-active-background` | Fill when active (current page) | `var(--tint-100)` |
43
+ | `--menu-active-color` | Text colour when active | `var(--tint-00)` |
44
+ | `--menu-active-weight` | Font weight when active | `var(--weight-strong)` |
45
+
46
+ List-level hooks (`--menu-gap`, `--menu-color`, the nested-submenu hooks, etc.) are documented on [`Menu`](/ui/Menu).
47
+
48
+ **Global tokens it reads** — the tint ladder `--tint-00` / `--tint-90` / `--tint-100`, plus `--space-xxsmall`, `--radius-xxsmall`, `--stroke-focus`, `--stroke-normal`, `--color-focus`, and `--weight-strong`.
49
+
50
+ ## See also
51
+
52
+ - [`Menu`](/ui/Menu) — the `<menu>` container these go inside
53
+ - [`Clickable`](/ui/Clickable) — the link primitive `MenuItem` forwards its props to
54
+ - [`Router`](/ui/Router) — provides the URL context used to compute `active`/`proud`
@@ -48,6 +48,7 @@ type CatcherState = {
48
48
  * - Catches render-time errors below it and shows the `as` component (defaults to `<ErrorNotice>`) with the caught `reason`.
49
49
  * - Provides a retry callback to descendant `<RetryButton>`s that clears the error and re-renders `children`.
50
50
  *
51
+ * @kind component
51
52
  * @example <Catcher><RiskyComponent /></Catcher>
52
53
  * @example <Catcher as={ErrorPage}><RiskyComponent /></Catcher>
53
54
  * @see https://dhoulb.github.io/shelving/ui/misc/Catcher/Catcher
@@ -36,6 +36,7 @@ export function RetryButton({ children = RETRY_CHILDREN, ...props }) {
36
36
  * - Catches render-time errors below it and shows the `as` component (defaults to `<ErrorNotice>`) with the caught `reason`.
37
37
  * - Provides a retry callback to descendant `<RetryButton>`s that clears the error and re-renders `children`.
38
38
  *
39
+ * @kind component
39
40
  * @example <Catcher><RiskyComponent /></Catcher>
40
41
  * @example <Catcher as={ErrorPage}><RiskyComponent /></Catcher>
41
42
  * @see https://dhoulb.github.io/shelving/ui/misc/Catcher/Catcher
@@ -0,0 +1,41 @@
1
+ # Catcher
2
+
3
+ A React error boundary that catches errors thrown anywhere in its subtree and replaces the failed region with a fallback component. Pass `as` to supply a custom error renderer; it defaults to `ErrorNotice` (an inline error notice with a retry button).
4
+
5
+ **Things to know:**
6
+
7
+ - `PageCatcher` is a convenience wrapper that renders `ErrorPage` instead — a full-page error display inside a `<CenteredLayout>`.
8
+ - `RetryButton` reads the retry callback from the nearest `Catcher` via context and renders a `<Button>`. It returns `null` when there is no parent catcher to retry.
9
+ - `ErrorNotice` and `ErrorPage` can be used standalone when you need to display a known error without a boundary. Both use `getMessage()` to extract a human-readable message, falling back to `"Unknown error"`.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { PageCatcher, Catcher, ErrorNotice } from "shelving/ui";
15
+
16
+ // Catch and display errors for a whole page.
17
+ <PageCatcher>
18
+ <MyPage />
19
+ </PageCatcher>
20
+
21
+ // Localised error boundary inside a panel.
22
+ <Catcher as={ErrorNotice}>
23
+ <LiveFeed />
24
+ </Catcher>
25
+ ```
26
+
27
+ ```tsx
28
+ import { Catcher, ErrorPage, RetryButton } from "shelving/ui";
29
+
30
+ // Custom error renderer plus a retry button anywhere in the subtree.
31
+ <Catcher as={ErrorPage}>
32
+ <RiskyComponent />
33
+ <RetryButton small />
34
+ </Catcher>
35
+ ```
36
+
37
+ ## See also
38
+
39
+ - [`Notice`](/ui/Notice) — the callout `ErrorNotice` renders inside.
40
+ - [`Button`](/ui/Button) — the element `RetryButton` renders.
41
+ - [`Page`](/ui/Page) — the full-page shell `ErrorPage` renders inside.
@@ -80,6 +80,7 @@ type CatcherState = {
80
80
  * - Catches render-time errors below it and shows the `as` component (defaults to `<ErrorNotice>`) with the caught `reason`.
81
81
  * - Provides a retry callback to descendant `<RetryButton>`s that clears the error and re-renders `children`.
82
82
  *
83
+ * @kind component
83
84
  * @example <Catcher><RiskyComponent /></Catcher>
84
85
  * @example <Catcher as={ErrorPage}><RiskyComponent /></Catcher>
85
86
  * @see https://dhoulb.github.io/shelving/ui/misc/Catcher/Catcher
@@ -14,6 +14,7 @@ export interface LoadingProps {
14
14
  * - Self-contained inline SVG with a rotating indicator arc; inherits its colour and size from the surrounding text.
15
15
  *
16
16
  * @returns The spinner element.
17
+ * @kind component
17
18
  * @example <Loading />
18
19
  * @see https://dhoulb.github.io/shelving/ui/misc/Loading/Loading
19
20
  */
@@ -6,6 +6,7 @@ import styles from "./Loading.module.css";
6
6
  * - Self-contained inline SVG with a rotating indicator arc; inherits its colour and size from the surrounding text.
7
7
  *
8
8
  * @returns The spinner element.
9
+ * @kind component
9
10
  * @example <Loading />
10
11
  * @see https://dhoulb.github.io/shelving/ui/misc/Loading/Loading
11
12
  */
@@ -0,0 +1,28 @@
1
+ # Loading
2
+
3
+ An animated SVG spinner used as a loading indicator. Self-contained inline SVG with a rotating indicator arc that inherits its colour and size from the surrounding text.
4
+
5
+ **Things to know:**
6
+
7
+ - Takes no props.
8
+ - `LOADING` is a pre-keyed `<Loading />` element with a stable `key` — drop it straight into `Suspense` fallbacks and lists to avoid unnecessary reconciliation overhead.
9
+
10
+ ## Usage
11
+
12
+ ```tsx
13
+ import { Loading, LOADING } from "shelving/ui";
14
+
15
+ <Loading />
16
+
17
+ // Pre-keyed constant for fallbacks and lists.
18
+ <Suspense fallback={LOADING}>
19
+ <SlowComponent />
20
+ </Suspense>
21
+
22
+ {busy ? LOADING : children}
23
+ ```
24
+
25
+ ## See also
26
+
27
+ - [`StatusIcon`](/ui/StatusIcon) — uses `<Loading>` for the `"loading"` status.
28
+ - [`Notice`](/ui/Notice) — shows `<Loading>` for a loading notice.
@@ -18,6 +18,7 @@ export interface LoadingProps {
18
18
  * - Self-contained inline SVG with a rotating indicator arc; inherits its colour and size from the surrounding text.
19
19
  *
20
20
  * @returns The spinner element.
21
+ * @kind component
21
22
  * @example <Loading />
22
23
  * @see https://dhoulb.github.io/shelving/ui/misc/Loading/Loading
23
24
  */
@@ -0,0 +1,40 @@
1
+ # createMapper
2
+
3
+ Creates a `[Mapping, Mapper]` component pair backed by a private React context. `Mapper` walks a pre-walked element tree and replaces each matching element type with the registered component; `Mapping` lets a subtree override or extend the dispatch table. This is the right tool when a component renders a tree of typed elements and callers need to swap in their own renderers for specific types.
4
+
5
+ **Things to know:**
6
+
7
+ - Each call to `createMapper()` creates its own context — independent mappers don't interfere with each other.
8
+ - Unmapped element types fall through and render as themselves (e.g. an unmapped `<tree-foo>` appears as a raw `<tree-foo>` element).
9
+ - Any extra props passed to `Mapper` (the type parameter `E`) are spread onto every dispatched child, so you can thread shared context like a `path` into each renderer.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { createMapper } from "shelving/ui";
15
+
16
+ const [TreeMapping, TreeMapper] = createMapper({
17
+ "tree-element": TreeRow,
18
+ });
19
+
20
+ // In a consumer — dispatch a pre-walked element tree.
21
+ <TreeMapper>{walkElements(children)}</TreeMapper>
22
+
23
+ // Override one entry inside a subtree.
24
+ <TreeMapping mapping={{ "tree-element": SpecialTreeRow }}>
25
+ <TreeMapper>{walkElements(children)}</TreeMapper>
26
+ </TreeMapping>
27
+ ```
28
+
29
+ ```tsx
30
+ // With extra props threaded into every dispatched child.
31
+ const [TreeMenuMapping, TreeMenuMapper] = createMapper<{ path?: AbsolutePath }>({
32
+ "tree-element": TreeMenuItem,
33
+ });
34
+
35
+ <TreeMenuMapper path="/foo">{queryElements(children, query)}</TreeMenuMapper>
36
+ ```
37
+
38
+ ## See also
39
+
40
+ - [`ui`](/ui) — the component library these element trees are rendered with.
@@ -18,6 +18,7 @@ export interface MarkupProps extends Partial<MarkupOptions> {
18
18
  * @param children The source markup string to parse and render (renders `null` when empty).
19
19
  * @param options Optional `MarkupOptions` overrides (`rules`, `rel`, `url`, `root`, `schemes`).
20
20
  * @returns The parsed markup as React nodes, or `null` when `children` is empty.
21
+ * @kind component
21
22
  * @example <Prose><Markup>{`A *bold* word with \`code\`.`}</Markup></Prose>
22
23
  * @see https://dhoulb.github.io/shelving/ui/misc/Markup/Markup
23
24
  */
package/ui/misc/Markup.js CHANGED
@@ -9,6 +9,7 @@ import { requireMeta } from "./MetaContext.js";
9
9
  * @param children The source markup string to parse and render (renders `null` when empty).
10
10
  * @param options Optional `MarkupOptions` overrides (`rules`, `rel`, `url`, `root`, `schemes`).
11
11
  * @returns The parsed markup as React nodes, or `null` when `children` is empty.
12
+ * @kind component
12
13
  * @example <Prose><Markup>{`A *bold* word with \`code\`.`}</Markup></Prose>
13
14
  * @see https://dhoulb.github.io/shelving/ui/misc/Markup/Markup
14
15
  */
@@ -0,0 +1,34 @@
1
+ # Markup
2
+
3
+ Parses a markup string and renders the resulting React nodes inline. Defaults to the full block + inline rule set and resolves links against the current `<Meta>` context, so it's the standard way to render user- or content-authored markup in the UI.
4
+
5
+ **Things to know:**
6
+
7
+ - `url` and `root` default to the current `<Meta>` context, so link rules resolve site-absolute and relative hrefs correctly. Override any `MarkupOptions` prop (`rules`, `rel`, `url`, `root`, `schemes`) directly on `<Markup>` for a custom rule set or base URL.
8
+ - Renders `null` when `children` is empty.
9
+ - Wrap in `<Prose>` to give the produced `<p>` / `<ul>` / `<pre>` / etc. the standard prose typography.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { Prose, Markup } from "shelving/ui";
15
+
16
+ <Prose>
17
+ <Markup>{article.body}</Markup>
18
+ </Prose>
19
+ ```
20
+
21
+ ```tsx
22
+ import { Markup } from "shelving/ui";
23
+
24
+ // Custom rule set or base URL via MarkupOptions props.
25
+ <Markup rules={INLINE_ONLY} root="https://example.com">
26
+ {comment.body}
27
+ </Markup>
28
+ ```
29
+
30
+ ## See also
31
+
32
+ - [`Prose`](/ui/Prose) — longform typography wrapper for the rendered markup.
33
+ - [`markup`](/markup) — the markup parser and rule set underlying `<Markup>`.
34
+ - [`Meta`](/ui/Meta) — the page metadata `<Markup>` reads to resolve links.
@@ -21,6 +21,7 @@ export interface MarkupProps extends Partial<MarkupOptions> {
21
21
  * @param children The source markup string to parse and render (renders `null` when empty).
22
22
  * @param options Optional `MarkupOptions` overrides (`rules`, `rel`, `url`, `root`, `schemes`).
23
23
  * @returns The parsed markup as React nodes, or `null` when `children` is empty.
24
+ * @kind component
24
25
  * @example <Prose><Markup>{`A *bold* word with \`code\`.`}</Markup></Prose>
25
26
  * @see https://dhoulb.github.io/shelving/ui/misc/Markup/Markup
26
27
  */
@@ -18,6 +18,7 @@ export interface StatusIconProps {
18
18
  * @param status The status to represent (defaults to `"info"`).
19
19
  * @param size Optional icon size (defaults to the current line height).
20
20
  * @returns The status icon element.
21
+ * @kind component
21
22
  * @example <StatusIcon status="error" size="large" />
22
23
  * @see https://dhoulb.github.io/shelving/ui/misc/StatusIcon/StatusIcon
23
24
  */
@@ -19,6 +19,7 @@ const STATUS_ICONS = {
19
19
  * @param status The status to represent (defaults to `"info"`).
20
20
  * @param size Optional icon size (defaults to the current line height).
21
21
  * @returns The status icon element.
22
+ * @kind component
22
23
  * @example <StatusIcon status="error" size="large" />
23
24
  * @see https://dhoulb.github.io/shelving/ui/misc/StatusIcon/StatusIcon
24
25
  */
@@ -0,0 +1,25 @@
1
+ # StatusIcon
2
+
3
+ Renders the icon for a given status, coloured to match. Picks a heroicon per status (`success`, `error`, `warning`, etc.) and uses the animated `<Loading>` spinner for `"loading"`.
4
+
5
+ **Things to know:**
6
+
7
+ - `status` defaults to `"info"` (an info icon) when unset.
8
+ - Size it via the `size` prop (`"small"`, `"normal"`, `"large"`, `"xlarge"`, or `"xxlarge"`); defaults to the current line height.
9
+ - Has no own styling hooks — it paints from the shared status colours and inherits its size from the surrounding text.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { StatusIcon } from "shelving/ui";
15
+
16
+ <StatusIcon status="success" size="large" />
17
+ <StatusIcon status="error" />
18
+ <StatusIcon status="loading" size="small" />
19
+ ```
20
+
21
+ ## See also
22
+
23
+ - [`Loading`](/ui/Loading) — the spinner used for the `"loading"` status.
24
+ - [`Notice`](/ui/Notice) — uses `<StatusIcon>` as its default icon.
25
+ - [`Tag`](/ui/Tag) — inline label sharing the same status vocabulary.
@@ -35,6 +35,7 @@ export interface StatusIconProps {
35
35
  * @param status The status to represent (defaults to `"info"`).
36
36
  * @param size Optional icon size (defaults to the current line height).
37
37
  * @returns The status icon element.
38
+ * @kind component
38
39
  * @example <StatusIcon status="error" size="large" />
39
40
  * @see https://dhoulb.github.io/shelving/ui/misc/StatusIcon/StatusIcon
40
41
  */
package/ui/misc/Tag.d.ts CHANGED
@@ -33,6 +33,7 @@ export interface TagProps extends TagVariants, ClickableProps {
33
33
  *
34
34
  * @param props Tag styling variants and clickable props.
35
35
  * @returns The tag element.
36
+ * @kind component
36
37
  * @example <Tag success>Active</Tag>
37
38
  * @example <Tag color="purple" href="/beta">Beta</Tag>
38
39
  * @see https://dhoulb.github.io/shelving/ui/misc/Tag/Tag
package/ui/misc/Tag.js CHANGED
@@ -25,6 +25,7 @@ export function getTagClass(variants) {
25
25
  *
26
26
  * @param props Tag styling variants and clickable props.
27
27
  * @returns The tag element.
28
+ * @kind component
28
29
  * @example <Tag success>Active</Tag>
29
30
  * @example <Tag color="purple" href="/beta">Beta</Tag>
30
31
  * @see https://dhoulb.github.io/shelving/ui/misc/Tag/Tag
package/ui/misc/Tag.md ADDED
@@ -0,0 +1,47 @@
1
+ # Tag
2
+
3
+ A small inline label used to annotate other content. Accepts a status variant or a raw colour, and can be static or interactive depending on whether `href` / `onClick` is set.
4
+
5
+ **Things to know:**
6
+
7
+ - Delegates to `<Clickable>` — renders as `<a>` when `href` is set, otherwise `<button>`.
8
+ - Accepts a status variant (`success`, `info`, `error`, etc.) _or_ a raw colour (`color="red"`, `color="purple"`, etc.). Use `status` for semantic meaning and `color` for purely decorative differentiation.
9
+ - Composes status, colour, and typography styling variants.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { Tag } from "shelving/ui";
15
+
16
+ <Tag success>Active</Tag>
17
+ <Tag warning href="/billing">Overdue</Tag>
18
+ <Tag color="purple" size="small">Beta</Tag>
19
+ ```
20
+
21
+ ## Styling
22
+
23
+ `Tag` paints from the [tint ladder](/ui/TINT_CLASS); override these hooks at `:root` (or any ancestor scope) to retheme. Move `--tag-tint` to recolour the whole tag at once.
24
+
25
+ | Variable | Styles | Default |
26
+ |---|---|---|
27
+ | `--tag-tint` | Tint anchor for the tag scope | `inherit` (flows from `color=` / `status=` / parent) |
28
+ | `--tag-background` | Surface fill | `var(--tint-50)` |
29
+ | `--tag-hover-background` | Surface fill when an interactive tag is hovered | `var(--tint-55)` |
30
+ | `--tag-color` | Text colour | `var(--tint-100)` |
31
+ | `--tag-padding` | Inner padding | `0 var(--space-xxsmall)` |
32
+ | `--tag-border` | Border shorthand | `0` |
33
+ | `--tag-radius` | Corner radius | `var(--radius-xxsmall)` |
34
+ | `--tag-font` | Font family | `var(--font-body)` |
35
+ | `--tag-size` | Font size | `var(--size-small)` |
36
+ | `--tag-weight` | Font weight | `var(--weight-strong)` |
37
+ | `--tag-leading` | Line height | `var(--leading)` |
38
+ | `--tag-case` | Text transform | `var(--case-label)` |
39
+ | `--tag-focus-border` | Focus outline | `var(--stroke-focus) solid var(--color-focus)` |
40
+
41
+ **Global tokens it reads** — the tint ladder `--tint-50` / `--tint-55` / `--tint-100`, plus `--space-xxsmall`, `--radius-xxsmall`, `--font-body`, `--size-small`, `--weight-strong`, `--leading`, `--case-label`, `--stroke-normal`, `--stroke-focus`, and `--color-focus`.
42
+
43
+ ## See also
44
+
45
+ - [`StatusIcon`](/ui/StatusIcon) — pairs a status with its matching icon.
46
+ - [`Notice`](/ui/Notice) — block-level status callout sharing the same status vocabulary.
47
+ - [`ui`](/ui) — the styling system: tint ladder, cascade layers, and theming.
package/ui/misc/Tag.tsx CHANGED
@@ -46,6 +46,7 @@ export interface TagProps extends TagVariants, ClickableProps {}
46
46
  *
47
47
  * @param props Tag styling variants and clickable props.
48
48
  * @returns The tag element.
49
+ * @kind component
49
50
  * @example <Tag success>Active</Tag>
50
51
  * @example <Tag color="purple" href="/beta">Beta</Tag>
51
52
  * @see https://dhoulb.github.io/shelving/ui/misc/Tag/Tag
@@ -22,6 +22,7 @@ export interface NoticeProps extends FlexVariants, ColorVariants, StatusVariants
22
22
  * @param icon Optional icon override (`false`/`null` hides it; defaults to the matching `<StatusIcon>`).
23
23
  * @param props Flex, colour, and status styling variants.
24
24
  * @returns The notice callout element.
25
+ * @kind component
25
26
  * @example <Notice status="success">Saved your changes</Notice>
26
27
  * @see https://dhoulb.github.io/shelving/ui/notice/Notice/Notice
27
28
  */
@@ -16,6 +16,7 @@ import NOTICE_CSS from "./Notice.module.css";
16
16
  * @param icon Optional icon override (`false`/`null` hides it; defaults to the matching `<StatusIcon>`).
17
17
  * @param props Flex, colour, and status styling variants.
18
18
  * @returns The notice callout element.
19
+ * @kind component
19
20
  * @example <Notice status="success">Saved your changes</Notice>
20
21
  * @see https://dhoulb.github.io/shelving/ui/notice/Notice/Notice
21
22
  */
@@ -0,0 +1,53 @@
1
+ # Notice
2
+
3
+ A block-level status callout with an icon and message, used to highlight feedback. Rendered as an `<aside>` with a status icon and a message, mapping its `status` to the appropriate colour and ARIA role.
4
+
5
+ **Things to know:**
6
+
7
+ - Shows a `<StatusIcon>` for the current `status` by default; pass `icon` to override, or `false` / `null` to hide it.
8
+ - Sets an ARIA `role` of `"alert"` for `error` / `danger` statuses, otherwise `"status"`.
9
+ - `LOADING_NOTICE` is a shared `<Notice status="loading" />` element ready to drop into `Suspense` fallbacks.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { Notice } from "shelving/ui";
15
+
16
+ <Notice status="success">Your changes have been saved.</Notice>
17
+ <Notice status="error">Something went wrong.</Notice>
18
+ <Notice status="loading" />
19
+ ```
20
+
21
+ ```tsx
22
+ import { LOADING_NOTICE } from "shelving/ui";
23
+
24
+ <Suspense fallback={LOADING_NOTICE}>
25
+ <SlowPanel />
26
+ </Suspense>
27
+ ```
28
+
29
+ ## Styling
30
+
31
+ `Notice` paints from the [tint ladder](/ui/TINT_CLASS); override these hooks at `:root` (or any ancestor scope) to retheme. Move `--notice-tint` to recolour everything at once.
32
+
33
+ | Variable | Styles | Default |
34
+ |---|---|---|
35
+ | `--notice-tint` | Tint anchor for the notice scope | `inherit` (flows from `color=` / `status=` / parent) |
36
+ | `--notice-background` | Surface fill | `var(--tint-90)` |
37
+ | `--notice-color` | Text colour | `var(--tint-50)` |
38
+ | `--notice-border` | Border shorthand | `var(--notice-stroke) solid var(--tint-80)` |
39
+ | `--notice-stroke` | Border thickness | `var(--stroke-normal)` (2px) |
40
+ | `--notice-radius` | Corner radius | `var(--radius-xsmall)` |
41
+ | `--notice-padding` | Inner padding | `var(--space-small)` |
42
+ | `--notice-space` | Outer block margin (top + bottom) | `var(--space-paragraph)` |
43
+ | `--notice-size` | Font size | `var(--size-normal)` |
44
+ | `--notice-weight` | Font weight | `var(--weight-strong)` |
45
+
46
+ **Global tokens it reads** — the tint ladder `--tint-50` / `--tint-80` / `--tint-90`, plus `--space-paragraph`, `--space-small`, `--radius-xsmall`, `--stroke-normal`, `--size-normal`, and `--weight-strong`.
47
+
48
+ ## See also
49
+
50
+ - [`Notices`](/ui/Notices) — the global list that renders incoming notices as `<Notice>` elements.
51
+ - [`StatusIcon`](/ui/StatusIcon) — the default icon shown for the notice's status.
52
+ - [`notify`](/ui/notify) — dispatch notices into the global `<Notices>` list.
53
+ - [`ui`](/ui) — the styling system: tint ladder, cascade layers, and theming.
@@ -28,6 +28,7 @@ export interface NoticeProps extends FlexVariants, ColorVariants, StatusVariants
28
28
  * @param icon Optional icon override (`false`/`null` hides it; defaults to the matching `<StatusIcon>`).
29
29
  * @param props Flex, colour, and status styling variants.
30
30
  * @returns The notice callout element.
31
+ * @kind component
31
32
  * @example <Notice status="success">Saved your changes</Notice>
32
33
  * @see https://dhoulb.github.io/shelving/ui/notice/Notice/Notice
33
34
  */
@@ -14,6 +14,7 @@ export interface NoticesProps extends FlexVariants {
14
14
  *
15
15
  * @param props Flex styling variants for the container.
16
16
  * @returns The notices container element.
17
+ * @kind component
17
18
  * @example <Notices column />
18
19
  * @see https://dhoulb.github.io/shelving/ui/notice/Notices/Notices
19
20
  */
@@ -15,6 +15,7 @@ const NOTICES_CLASS = getModuleClass(NOTICES_CSS, "notices");
15
15
  *
16
16
  * @param props Flex styling variants for the container.
17
17
  * @returns The notices container element.
18
+ * @kind component
18
19
  * @example <Notices column />
19
20
  * @see https://dhoulb.github.io/shelving/ui/notice/Notices/Notices
20
21
  */
@@ -0,0 +1,59 @@
1
+ # Notices
2
+
3
+ Renders the global list of active notices and subscribes to incoming `"notice"` events. It listens for `"notice"` events on `window` (dispatched by the `notify` helpers) and shows each one as a `<Notice>` — this is how components like `<Button>` and `<FormNotify>` send notices into the global list.
4
+
5
+ **Things to know:**
6
+
7
+ - Mount `<Notices>` once near the root of your app. It renders at that point in the DOM and listens automatically — no context required.
8
+ - Notices auto-dismiss after a short delay unless they carry a `"loading"` status.
9
+ - Backed by the `NOTICES` store singleton; for advanced use you can keep a reference to a notice to update or close it manually.
10
+
11
+ ## Usage
12
+
13
+ Mount once near the root of your app:
14
+
15
+ ```tsx
16
+ import { Notices } from "shelving/ui";
17
+
18
+ export function AppLayout({ children }) {
19
+ return (
20
+ <>
21
+ {children}
22
+ <Notices />
23
+ </>
24
+ );
25
+ }
26
+ ```
27
+
28
+ Dispatch notices from anywhere — no context required:
29
+
30
+ ```tsx
31
+ import { notifySuccess, notifyError, callNotified } from "shelving/ui";
32
+
33
+ notifySuccess("Profile updated.");
34
+ notifyError("Could not connect.");
35
+
36
+ // Wrap an async callback — dispatches success or error automatically.
37
+ callNotified(async () => {
38
+ await saveProfile(data);
39
+ return "Profile updated.";
40
+ });
41
+ ```
42
+
43
+ Programmatic control via the `NOTICES` singleton:
44
+
45
+ ```tsx
46
+ import { NOTICES } from "shelving/ui";
47
+
48
+ // Show a loading notice and hold a reference to it.
49
+ const notice = NOTICES.show(undefined, "loading");
50
+ await uploadFile(file);
51
+ notice.show("Upload complete.", "success"); // Update in place.
52
+ notice.close(); // Or close it immediately.
53
+ ```
54
+
55
+ ## See also
56
+
57
+ - [`Notice`](/ui/Notice) — the callout each entry in the list is rendered as.
58
+ - [`notify`](/ui/notify) — `notify`, `notifySuccess`, `notifyError`, `callNotified`, and `subscribeNotices`.
59
+ - [`store`](/store) — `ArrayStore` and `DataStore` that the notices store layer extends.
@@ -23,6 +23,7 @@ export interface NoticesProps extends FlexVariants {}
23
23
  *
24
24
  * @param props Flex styling variants for the container.
25
25
  * @returns The notices container element.
26
+ * @kind component
26
27
  * @example <Notices column />
27
28
  * @see https://dhoulb.github.io/shelving/ui/notice/Notices/Notices
28
29
  */
package/ui/page/HTML.d.ts CHANGED
@@ -12,6 +12,7 @@ export interface HTMLProps extends PossibleMeta, ChildProps {
12
12
  * Render the full `<html>` document shell wrapping `<head>` and `<body>`.
13
13
  * - Emits the literal `<head>` with `<base>` and other shell-level metadata; per-page hoistable elements (title, meta, links, stylesheets, scripts) come from `<Head>` inside `<Page>` and are hoisted into this `<head>` by React 19.
14
14
  *
15
+ * @kind component
15
16
  * @param children The document body content.
16
17
  * @param meta Initial meta (language/root/app) merged with the surrounding `<Meta>` context.
17
18
  * @returns The `<html>` document element.
package/ui/page/HTML.js CHANGED
@@ -4,6 +4,7 @@ import { MetaContext, requireMeta } from "../misc/MetaContext.js";
4
4
  * Render the full `<html>` document shell wrapping `<head>` and `<body>`.
5
5
  * - Emits the literal `<head>` with `<base>` and other shell-level metadata; per-page hoistable elements (title, meta, links, stylesheets, scripts) come from `<Head>` inside `<Page>` and are hoisted into this `<head>` by React 19.
6
6
  *
7
+ * @kind component
7
8
  * @param children The document body content.
8
9
  * @param meta Initial meta (language/root/app) merged with the surrounding `<Meta>` context.
9
10
  * @returns The `<html>` document element.
@@ -0,0 +1,36 @@
1
+ # HTML
2
+
3
+ The full `<html>` document shell, wrapping `<head>` and `<body>`. Use it as the outermost wrapper for server-side rendering — it owns the literal `<head>` (charset, `<base>`, app `<title>`) while per-page hoistable tags come from [`Page`](/ui/Page).
4
+
5
+ **Things to know:**
6
+
7
+ - Accepts `PossibleMeta` props (`app`, `root`, `url`, `title`, `description`, `language`, `tags`, `links`, `stylesheets`, `modules`, `scripts`) and merges them into the `Meta` context it provides to children.
8
+ - `<base>` lives only here — it is not a hoistable element, unlike the title/meta/link/script tags that [`Page`](/ui/Page) emits and React 19 lifts into this `<head>`.
9
+ - Pass the request URL so the tree can match routes during SSR.
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { HTML, Page } from "shelving/ui";
15
+ import { Navigation, Router } from "shelving/ui";
16
+
17
+ // Server-side render — pass the request URL to <HTML>.
18
+ renderToString(
19
+ <HTML app="My App" root="https://example.com/" url={requestUrl} language="en">
20
+ <Navigation>
21
+ <Router routes={{
22
+ "/": HomePage,
23
+ "/about": AboutPage,
24
+ }}/>
25
+ </Navigation>
26
+ </HTML>
27
+ );
28
+ ```
29
+
30
+ For client-side-only roots that don't need an `<html>` shell, use `<App>` from [`ui`](/ui) instead.
31
+
32
+ ## See also
33
+
34
+ - [`Page`](/ui/Page) — wraps a single page and emits its hoistable head tags
35
+ - [`Head`](/ui/Head) — the low-level emitter `Page` renders for you
36
+ - [`Navigation`](/ui/Navigation) / [`Router`](/ui/Router) — URL-driven rendering inside the shell