shelving 1.251.0 → 1.251.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shelving",
3
- "version": "1.251.0",
3
+ "version": "1.251.1",
4
4
  "author": "Dave Houlbrooke <dave@shax.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +1,4 @@
1
- import { type ReactNode } from "react";
1
+ import type { ReactNode } from "react";
2
2
  import type { DocumentationElementProps } from "../../util/tree.js";
3
3
  /**
4
4
  * Page renderer for a `tree-documentation` element — the full detail page for a documented symbol.
@@ -1,5 +1,4 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Fragment } from "react";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
2
  import { walkElements } from "../../util/element.js";
4
3
  import { Block } from "../block/Block.js";
5
4
  import { Heading } from "../block/Heading.js";
@@ -8,31 +7,18 @@ import { Preformatted } from "../block/Preformatted.js";
8
7
  import { Prose } from "../block/Prose.js";
9
8
  import { Header, Section } from "../block/Section.js";
10
9
  import { Title } from "../block/Title.js";
11
- import { Code } from "../inline/Code.js";
12
10
  import { Markup } from "../misc/Markup.js";
13
11
  import { Page } from "../page/Page.js";
14
12
  import { Row } from "../style/Flex.js";
15
- import { Scroll } from "../style/Scroll.js";
16
- import { Cell } from "../table/Cell.js";
17
- import { Table } from "../table/Table.js";
18
13
  import { TreeBreadcrumbs } from "../tree/TreeBreadcrumbs.js";
19
14
  import { TreeCards } from "../tree/TreeCards.js";
20
- import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
21
- import { TreeLink } from "../tree/TreeLink.js";
22
15
  import { DocumentationButtons } from "./DocumentationButtons.js";
23
16
  import { DocumentationKind, getDocumentationKindColor } from "./DocumentationKind.js";
17
+ import { DocumentationParams } from "./DocumentationParams.js";
18
+ import { DocumentationReferences } from "./DocumentationReferences.js";
19
+ import { DocumentationReturns } from "./DocumentationReturns.js";
24
20
  import { DocumentationSignatures } from "./DocumentationSignatures.js";
25
- const DEFAULT_TYPE = "unknown";
26
- /** Resolve a table row's description — the manually-written one, falling back to the referenced type's own `description` from the tree map (exact-match only). */
27
- function _getRowDescription(map, type, description) {
28
- return description || getTreeElement(map, type)?.props.description || "";
29
- }
30
- /** Render a parameter/property row's description, appending a `Defaults to …` line (linking the value if it's a documented token) when a default exists. */
31
- function _renderRowDescription(description, def) {
32
- if (!def)
33
- return description;
34
- return (_jsxs(_Fragment, { children: [description, description && _jsx("br", {}), "Defaults to ", _jsx(TreeLink, { name: def })] }));
35
- }
21
+ import { DocumentationThrows } from "./DocumentationThrows.js";
36
22
  /** Documentation `kind`s grouped into card sections, in display order — pluralised, sentence-case headings. */
37
23
  const KIND_SECTIONS = {
38
24
  component: "Components",
@@ -84,10 +70,5 @@ function DocumentationChildren({ elements }) {
84
70
  * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationPage/DocumentationPage
85
71
  */
86
72
  export function DocumentationPage({ title, name, kind = "unknown", description, content, signatures, params, returns, throws, types, examples, children, ...props }) {
87
- const map = useTreeMap();
88
- return (_jsx(Page, { title: title ?? name, description: description, children: _jsxs(Block, { color: getDocumentationKindColor(kind), children: [_jsx(Panel, { children: _jsxs(Header, { children: [_jsx(TreeBreadcrumbs, {}), _jsx(Title, { children: _jsxs(Row, { left: true, wrap: true, children: [title ?? name, kind && _jsx(DocumentationKind, { kind: kind, size: "normal" })] }) }), _jsx(DocumentationButtons, { ...props })] }) }), signatures?.length || params?.length || returns?.length || throws?.length || types?.length ? (_jsxs(Section, { children: [_jsx(DocumentationSignatures, { signatures: signatures }), params?.length && (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx(Cell, { header: true, width: "fit", children: "Param" }), _jsx(Cell, { header: true, width: "fit", children: "Type" }), _jsx(Cell, { header: true, width: "xxnarrow", grow: true })] }) }), _jsx("tbody", { children: params.map(({ name, type = DEFAULT_TYPE, description, default: def }) => {
89
- // An options-bag param whose type resolves to a documented interface/object type is flattened into its individual fields as indented child rows.
90
- const resolved = getTreeElement(map, type)?.props;
91
- return (_jsxs(Fragment, { children: [_jsxs("tr", { children: [_jsx("td", { children: _jsx(Code, { nowrap: true, children: name }) }), _jsx("td", { children: _jsx(TreeLink, { name: type, nowrap: true }) }), _jsx("td", { children: _renderRowDescription(description || resolved?.description || "", def) })] }), resolved?.properties?.map(prop => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(Code, { nowrap: true, children: `.${prop.name}` }) }), _jsx("td", { children: _jsx(TreeLink, { name: prop.type ?? DEFAULT_TYPE, nowrap: true }) }), _jsx("td", { children: _renderRowDescription(_getRowDescription(map, prop.type ?? DEFAULT_TYPE, prop.description), prop.default) })] }, `${name}.${prop.name}`)))] }, `${name}-${type}`));
92
- }) })] }) }) })), returns?.length && (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsx("tr", { children: _jsx("th", { children: "Return" }) }) }), _jsx("tbody", { children: returns.map(({ type = DEFAULT_TYPE, description }) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(TreeLink, { name: type, nowrap: true }) }), _jsx("td", { children: _getRowDescription(map, type, description) })] }, `${type}-${description}`))) })] }) }) })), throws?.length && (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsx("tr", { children: _jsx("th", { children: "Throws" }) }) }), _jsx("tbody", { children: throws.map(({ type = DEFAULT_TYPE, description }) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(TreeLink, { name: type, nowrap: true }) }), _jsx("td", { children: _getRowDescription(map, type, description) })] }, `${type}-${description}`))) })] }) }) })), types?.length && (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsx("tr", { children: _jsx("th", { children: "Type" }) }) }), _jsx("tbody", { children: types.map(type => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(TreeLink, { name: type }) }), _jsx("td", { children: _getRowDescription(map, type) })] }, type))) })] }) }) }))] })) : null, content && (_jsx(Section, { children: _jsx(Prose, { children: _jsx(Markup, { children: content }) }) })), examples?.length && (_jsxs(Section, { children: [_jsx(Heading, { children: "Examples" }), examples.map(({ description }) => (_jsx(Preformatted, { children: description }, description)))] })), _jsx(DocumentationChildren, { elements: children })] }) }));
73
+ return (_jsx(Page, { title: title ?? name, description: description, children: _jsxs(Block, { color: getDocumentationKindColor(kind), children: [_jsx(Panel, { children: _jsxs(Header, { children: [_jsx(TreeBreadcrumbs, {}), _jsx(Title, { children: _jsxs(Row, { left: true, wrap: true, children: [title ?? name, kind && _jsx(DocumentationKind, { kind: kind, size: "normal" })] }) }), _jsx(DocumentationButtons, { ...props })] }) }), signatures?.length || params?.length || returns?.length || throws?.length || types?.length ? (_jsxs(Section, { children: [_jsx(DocumentationSignatures, { signatures: signatures }), _jsx(DocumentationParams, { params: params }), _jsx(DocumentationReturns, { returns: returns }), _jsx(DocumentationThrows, { throws: throws }), _jsx(DocumentationReferences, { types: types })] })) : null, content && (_jsx(Section, { children: _jsx(Prose, { children: _jsx(Markup, { children: content }) }) })), examples?.length && (_jsxs(Section, { children: [_jsx(Heading, { children: "Examples" }), examples.map(({ description }) => (_jsx(Preformatted, { children: description }, description)))] })), _jsx(DocumentationChildren, { elements: children })] }) }));
93
74
  }
@@ -1,4 +1,4 @@
1
- import { Fragment, type ReactNode } from "react";
1
+ import type { ReactNode } from "react";
2
2
  import { walkElements } from "../../util/element.js";
3
3
  import type { DocumentationElementProps, TreeElement, TreeElements } from "../../util/tree.js";
4
4
  import { Block } from "../block/Block.js";
@@ -8,39 +8,18 @@ import { Preformatted } from "../block/Preformatted.js";
8
8
  import { Prose } from "../block/Prose.js";
9
9
  import { Header, Section } from "../block/Section.js";
10
10
  import { Title } from "../block/Title.js";
11
- import { Code } from "../inline/Code.js";
12
11
  import { Markup } from "../misc/Markup.js";
13
12
  import { Page } from "../page/Page.js";
14
13
  import { Row } from "../style/Flex.js";
15
- import { Scroll } from "../style/Scroll.js";
16
- import { Cell } from "../table/Cell.js";
17
- import { Table } from "../table/Table.js";
18
14
  import { TreeBreadcrumbs } from "../tree/TreeBreadcrumbs.js";
19
15
  import { TreeCards } from "../tree/TreeCards.js";
20
- import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
21
- import { TreeLink } from "../tree/TreeLink.js";
22
16
  import { DocumentationButtons } from "./DocumentationButtons.js";
23
17
  import { DocumentationKind, getDocumentationKindColor } from "./DocumentationKind.js";
18
+ import { DocumentationParams } from "./DocumentationParams.js";
19
+ import { DocumentationReferences } from "./DocumentationReferences.js";
20
+ import { DocumentationReturns } from "./DocumentationReturns.js";
24
21
  import { DocumentationSignatures } from "./DocumentationSignatures.js";
25
-
26
- const DEFAULT_TYPE = "unknown";
27
-
28
- /** Resolve a table row's description — the manually-written one, falling back to the referenced type's own `description` from the tree map (exact-match only). */
29
- function _getRowDescription(map: ReadonlyMap<string, TreeElement>, type: string, description?: string | undefined): string {
30
- return description || getTreeElement(map, type)?.props.description || "";
31
- }
32
-
33
- /** Render a parameter/property row's description, appending a `Defaults to …` line (linking the value if it's a documented token) when a default exists. */
34
- function _renderRowDescription(description: string, def?: string | undefined): ReactNode {
35
- if (!def) return description;
36
- return (
37
- <>
38
- {description}
39
- {description && <br />}
40
- Defaults to <TreeLink name={def} />
41
- </>
42
- );
43
- }
22
+ import { DocumentationThrows } from "./DocumentationThrows.js";
44
23
 
45
24
  /** Documentation `kind`s grouped into card sections, in display order — pluralised, sentence-case headings. */
46
25
  const KIND_SECTIONS = {
@@ -116,7 +95,6 @@ export function DocumentationPage({
116
95
  children,
117
96
  ...props
118
97
  }: DocumentationElementProps): ReactNode {
119
- const map = useTreeMap();
120
98
  return (
121
99
  <Page title={title ?? name} description={description}>
122
100
  <Block color={getDocumentationKindColor(kind)}>
@@ -135,129 +113,10 @@ export function DocumentationPage({
135
113
  {signatures?.length || params?.length || returns?.length || throws?.length || types?.length ? (
136
114
  <Section>
137
115
  <DocumentationSignatures signatures={signatures} />
138
- {params?.length && (
139
- <Section>
140
- <Scroll horizontal>
141
- <Table>
142
- <thead>
143
- <tr>
144
- <Cell header width="fit">
145
- Param
146
- </Cell>
147
- <Cell header width="fit">
148
- Type
149
- </Cell>
150
- <Cell header width="xxnarrow" grow />
151
- </tr>
152
- </thead>
153
- <tbody>
154
- {params.map(({ name, type = DEFAULT_TYPE, description, default: def }) => {
155
- // An options-bag param whose type resolves to a documented interface/object type is flattened into its individual fields as indented child rows.
156
- const resolved = getTreeElement(map, type)?.props as DocumentationElementProps | undefined;
157
- return (
158
- <Fragment key={`${name}-${type}`}>
159
- <tr>
160
- <td>
161
- <Code nowrap>{name}</Code>
162
- </td>
163
- <td>
164
- <TreeLink name={type} nowrap />
165
- </td>
166
- <td>{_renderRowDescription(description || resolved?.description || "", def)}</td>
167
- </tr>
168
- {resolved?.properties?.map(prop => (
169
- <tr key={`${name}.${prop.name}`}>
170
- <td>
171
- <Code nowrap>{`.${prop.name}`}</Code>
172
- </td>
173
- <td>
174
- <TreeLink name={prop.type ?? DEFAULT_TYPE} nowrap />
175
- </td>
176
- <td>
177
- {_renderRowDescription(
178
- _getRowDescription(map, prop.type ?? DEFAULT_TYPE, prop.description),
179
- prop.default,
180
- )}
181
- </td>
182
- </tr>
183
- ))}
184
- </Fragment>
185
- );
186
- })}
187
- </tbody>
188
- </Table>
189
- </Scroll>
190
- </Section>
191
- )}
192
- {returns?.length && (
193
- <Section>
194
- <Scroll horizontal>
195
- <Table>
196
- <thead>
197
- <tr>
198
- <th>Return</th>
199
- </tr>
200
- </thead>
201
- <tbody>
202
- {returns.map(({ type = DEFAULT_TYPE, description }) => (
203
- <tr key={`${type}-${description}`}>
204
- <td>
205
- <TreeLink name={type} nowrap />
206
- </td>
207
- <td>{_getRowDescription(map, type, description)}</td>
208
- </tr>
209
- ))}
210
- </tbody>
211
- </Table>
212
- </Scroll>
213
- </Section>
214
- )}
215
- {throws?.length && (
216
- <Section>
217
- <Scroll horizontal>
218
- <Table>
219
- <thead>
220
- <tr>
221
- <th>Throws</th>
222
- </tr>
223
- </thead>
224
- <tbody>
225
- {throws.map(({ type = DEFAULT_TYPE, description }) => (
226
- <tr key={`${type}-${description}`}>
227
- <td>
228
- <TreeLink name={type} nowrap />
229
- </td>
230
- <td>{_getRowDescription(map, type, description)}</td>
231
- </tr>
232
- ))}
233
- </tbody>
234
- </Table>
235
- </Scroll>
236
- </Section>
237
- )}
238
- {types?.length && (
239
- <Section>
240
- <Scroll horizontal>
241
- <Table>
242
- <thead>
243
- <tr>
244
- <th>Type</th>
245
- </tr>
246
- </thead>
247
- <tbody>
248
- {types.map(type => (
249
- <tr key={type}>
250
- <td>
251
- <TreeLink name={type} />
252
- </td>
253
- <td>{_getRowDescription(map, type)}</td>
254
- </tr>
255
- ))}
256
- </tbody>
257
- </Table>
258
- </Scroll>
259
- </Section>
260
- )}
116
+ <DocumentationParams params={params} />
117
+ <DocumentationReturns returns={returns} />
118
+ <DocumentationThrows throws={throws} />
119
+ <DocumentationReferences types={types} />
261
120
  </Section>
262
121
  ) : null}
263
122
  {content && (
@@ -0,0 +1,25 @@
1
+ import { type ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ import type { DocumentationParam } from "../../util/tree.js";
4
+ /**
5
+ * Props for `DocumentationParams` — the parameter list to render, one row per parameter.
6
+ *
7
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationParams/DocumentationParamsProps
8
+ */
9
+ export interface DocumentationParamsProps {
10
+ /** Parameters to render — one row each, with options-bag params flattened into indented child rows. */
11
+ readonly params?: ImmutableArray<DocumentationParam> | undefined;
12
+ }
13
+ /**
14
+ * Render a documented symbol's parameters as a scrollable table — one row per parameter.
15
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
16
+ * - A row with no hand-written description falls back to the referenced type's own `description`, and a default renders as a `Defaults to …` line at the foot of the description cell (linking the value when it's a documented token).
17
+ * - An options-bag parameter whose type resolves to a documented interface/object type is flattened into indented child rows (one per property), so readers see the individual fields inline.
18
+ * - Renders nothing when there are no parameters.
19
+ *
20
+ * @kind component
21
+ * @returns A [`<Section>`](/ui/Section) containing the parameters table, or `null` when there are none.
22
+ * @example <DocumentationParams params={params} />
23
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationParams/DocumentationParams
24
+ */
25
+ export declare function DocumentationParams({ params }: DocumentationParamsProps): ReactNode;
@@ -0,0 +1,32 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from "react";
3
+ import { Section } from "../block/Section.js";
4
+ import { Code } from "../inline/Code.js";
5
+ import { Scroll } from "../style/Scroll.js";
6
+ import { Cell } from "../table/Cell.js";
7
+ import { Table } from "../table/Table.js";
8
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
9
+ import { TreeLink } from "../tree/TreeLink.js";
10
+ const DEFAULT_TYPE = "unknown";
11
+ /**
12
+ * Render a documented symbol's parameters as a scrollable table — one row per parameter.
13
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
14
+ * - A row with no hand-written description falls back to the referenced type's own `description`, and a default renders as a `Defaults to …` line at the foot of the description cell (linking the value when it's a documented token).
15
+ * - An options-bag parameter whose type resolves to a documented interface/object type is flattened into indented child rows (one per property), so readers see the individual fields inline.
16
+ * - Renders nothing when there are no parameters.
17
+ *
18
+ * @kind component
19
+ * @returns A [`<Section>`](/ui/Section) containing the parameters table, or `null` when there are none.
20
+ * @example <DocumentationParams params={params} />
21
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationParams/DocumentationParams
22
+ */
23
+ export function DocumentationParams({ params }) {
24
+ const map = useTreeMap();
25
+ if (!params?.length)
26
+ return null;
27
+ return (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx(Cell, { header: true, width: "fit", children: "Param" }), _jsx(Cell, { header: true, width: "fit", children: "Type" }), _jsx(Cell, { header: true, width: "xxnarrow", grow: true })] }) }), _jsx("tbody", { children: params.map(({ name, type = DEFAULT_TYPE, description, default: def }) => {
28
+ // An options-bag param whose type resolves to a documented interface/object type is flattened into its individual fields as indented child rows.
29
+ const resolved = getTreeElement(map, type)?.props;
30
+ return (_jsxs(Fragment, { children: [_jsxs("tr", { children: [_jsx("td", { children: _jsx(Code, { nowrap: true, children: name }) }), _jsx("td", { children: _jsx(TreeLink, { name: type, nowrap: true }) }), _jsxs("td", { children: [description || getTreeElement(map, type)?.props.description, def && (_jsxs(_Fragment, { children: ["Defaults to ", _jsx(TreeLink, { name: def })] }))] })] }), resolved?.properties?.map(({ name: propName, type: propType = DEFAULT_TYPE, description: propDescription, default: propDef }) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(Code, { nowrap: true, children: `.${propName}` }) }), _jsx("td", { children: _jsx(TreeLink, { name: propType, nowrap: true }) }), _jsxs("td", { children: [propDescription || getTreeElement(map, propType)?.props.description, propDef && (_jsxs(_Fragment, { children: ["Defaults to ", _jsx(TreeLink, { name: propDef })] }))] })] }, `${propName}-${propType}-${propDescription}`)))] }, `${name}-${type}`));
31
+ }) })] }) }) }));
32
+ }
@@ -0,0 +1,104 @@
1
+ import { Fragment, type ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ import type { DocumentationElementProps, DocumentationParam } from "../../util/tree.js";
4
+ import { Section } from "../block/Section.js";
5
+ import { Code } from "../inline/Code.js";
6
+ import { Scroll } from "../style/Scroll.js";
7
+ import { Cell } from "../table/Cell.js";
8
+ import { Table } from "../table/Table.js";
9
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
10
+ import { TreeLink } from "../tree/TreeLink.js";
11
+
12
+ const DEFAULT_TYPE = "unknown";
13
+
14
+ /**
15
+ * Props for `DocumentationParams` — the parameter list to render, one row per parameter.
16
+ *
17
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationParams/DocumentationParamsProps
18
+ */
19
+ export interface DocumentationParamsProps {
20
+ /** Parameters to render — one row each, with options-bag params flattened into indented child rows. */
21
+ readonly params?: ImmutableArray<DocumentationParam> | undefined;
22
+ }
23
+
24
+ /**
25
+ * Render a documented symbol's parameters as a scrollable table — one row per parameter.
26
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
27
+ * - A row with no hand-written description falls back to the referenced type's own `description`, and a default renders as a `Defaults to …` line at the foot of the description cell (linking the value when it's a documented token).
28
+ * - An options-bag parameter whose type resolves to a documented interface/object type is flattened into indented child rows (one per property), so readers see the individual fields inline.
29
+ * - Renders nothing when there are no parameters.
30
+ *
31
+ * @kind component
32
+ * @returns A [`<Section>`](/ui/Section) containing the parameters table, or `null` when there are none.
33
+ * @example <DocumentationParams params={params} />
34
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationParams/DocumentationParams
35
+ */
36
+ export function DocumentationParams({ params }: DocumentationParamsProps): ReactNode {
37
+ const map = useTreeMap();
38
+ if (!params?.length) return null;
39
+ return (
40
+ <Section>
41
+ <Scroll horizontal>
42
+ <Table>
43
+ <thead>
44
+ <tr>
45
+ <Cell header width="fit">
46
+ Param
47
+ </Cell>
48
+ <Cell header width="fit">
49
+ Type
50
+ </Cell>
51
+ <Cell header width="xxnarrow" grow />
52
+ </tr>
53
+ </thead>
54
+ <tbody>
55
+ {params.map(({ name, type = DEFAULT_TYPE, description, default: def }) => {
56
+ // An options-bag param whose type resolves to a documented interface/object type is flattened into its individual fields as indented child rows.
57
+ const resolved = getTreeElement(map, type)?.props as DocumentationElementProps | undefined;
58
+ return (
59
+ <Fragment key={`${name}-${type}`}>
60
+ <tr>
61
+ <td>
62
+ <Code nowrap>{name}</Code>
63
+ </td>
64
+ <td>
65
+ <TreeLink name={type} nowrap />
66
+ </td>
67
+ <td>
68
+ {description || getTreeElement(map, type)?.props.description}
69
+ {def && (
70
+ <>
71
+ Defaults to <TreeLink name={def} />
72
+ </>
73
+ )}
74
+ </td>
75
+ </tr>
76
+ {resolved?.properties?.map(
77
+ ({ name: propName, type: propType = DEFAULT_TYPE, description: propDescription, default: propDef }) => (
78
+ <tr key={`${propName}-${propType}-${propDescription}`}>
79
+ <td>
80
+ <Code nowrap>{`.${propName}`}</Code>
81
+ </td>
82
+ <td>
83
+ <TreeLink name={propType} nowrap />
84
+ </td>
85
+ <td>
86
+ {propDescription || getTreeElement(map, propType)?.props.description}
87
+ {propDef && (
88
+ <>
89
+ Defaults to <TreeLink name={propDef} />
90
+ </>
91
+ )}
92
+ </td>
93
+ </tr>
94
+ ),
95
+ )}
96
+ </Fragment>
97
+ );
98
+ })}
99
+ </tbody>
100
+ </Table>
101
+ </Scroll>
102
+ </Section>
103
+ );
104
+ }
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ /**
4
+ * Props for `DocumentationReferences` — the referenced type names to render, one row each.
5
+ *
6
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReferences/DocumentationReferencesProps
7
+ */
8
+ export interface DocumentationReferencesProps {
9
+ /** Type names referenced by a `type` alias's body — one row each, resolved to links at render time. */
10
+ readonly types?: ImmutableArray<string> | undefined;
11
+ }
12
+ /**
13
+ * Render a `type` alias's referenced type names as a scrollable table — one row per referenced type.
14
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so each name links to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; unresolved names stay plain text), with the row carrying the resolved element's `description`.
15
+ * - Renders nothing when there are no referenced types.
16
+ *
17
+ * @kind component
18
+ * @returns A [`<Section>`](/ui/Section) containing the references table, or `null` when there are none.
19
+ * @example <DocumentationReferences types={types} />
20
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReferences/DocumentationReferences
21
+ */
22
+ export declare function DocumentationReferences({ types }: DocumentationReferencesProps): ReactNode;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Section } from "../block/Section.js";
3
+ import { Scroll } from "../style/Scroll.js";
4
+ import { Cell } from "../table/Cell.js";
5
+ import { Table } from "../table/Table.js";
6
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
7
+ import { TreeLink } from "../tree/TreeLink.js";
8
+ /**
9
+ * Render a `type` alias's referenced type names as a scrollable table — one row per referenced type.
10
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so each name links to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; unresolved names stay plain text), with the row carrying the resolved element's `description`.
11
+ * - Renders nothing when there are no referenced types.
12
+ *
13
+ * @kind component
14
+ * @returns A [`<Section>`](/ui/Section) containing the references table, or `null` when there are none.
15
+ * @example <DocumentationReferences types={types} />
16
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReferences/DocumentationReferences
17
+ */
18
+ export function DocumentationReferences({ types }) {
19
+ const map = useTreeMap();
20
+ if (!types?.length)
21
+ return null;
22
+ return (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx(Cell, { header: true, width: "fit", children: "Type" }), _jsx(Cell, { header: true, width: "xxnarrow", grow: true })] }) }), _jsx("tbody", { children: types.map(type => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(TreeLink, { name: type }) }), _jsx("td", { children: getTreeElement(map, type)?.props.description })] }, type))) })] }) }) }));
23
+ }
@@ -0,0 +1,59 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ import { Section } from "../block/Section.js";
4
+ import { Scroll } from "../style/Scroll.js";
5
+ import { Cell } from "../table/Cell.js";
6
+ import { Table } from "../table/Table.js";
7
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
8
+ import { TreeLink } from "../tree/TreeLink.js";
9
+
10
+ /**
11
+ * Props for `DocumentationReferences` — the referenced type names to render, one row each.
12
+ *
13
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReferences/DocumentationReferencesProps
14
+ */
15
+ export interface DocumentationReferencesProps {
16
+ /** Type names referenced by a `type` alias's body — one row each, resolved to links at render time. */
17
+ readonly types?: ImmutableArray<string> | undefined;
18
+ }
19
+
20
+ /**
21
+ * Render a `type` alias's referenced type names as a scrollable table — one row per referenced type.
22
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so each name links to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; unresolved names stay plain text), with the row carrying the resolved element's `description`.
23
+ * - Renders nothing when there are no referenced types.
24
+ *
25
+ * @kind component
26
+ * @returns A [`<Section>`](/ui/Section) containing the references table, or `null` when there are none.
27
+ * @example <DocumentationReferences types={types} />
28
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReferences/DocumentationReferences
29
+ */
30
+ export function DocumentationReferences({ types }: DocumentationReferencesProps): ReactNode {
31
+ const map = useTreeMap();
32
+ if (!types?.length) return null;
33
+ return (
34
+ <Section>
35
+ <Scroll horizontal>
36
+ <Table>
37
+ <thead>
38
+ <tr>
39
+ <Cell header width="fit">
40
+ Type
41
+ </Cell>
42
+ <Cell header width="xxnarrow" grow />
43
+ </tr>
44
+ </thead>
45
+ <tbody>
46
+ {types.map(type => (
47
+ <tr key={type}>
48
+ <td>
49
+ <TreeLink name={type} />
50
+ </td>
51
+ <td>{getTreeElement(map, type)?.props.description}</td>
52
+ </tr>
53
+ ))}
54
+ </tbody>
55
+ </Table>
56
+ </Scroll>
57
+ </Section>
58
+ );
59
+ }
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ import type { DocumentationReturn } from "../../util/tree.js";
4
+ /**
5
+ * Props for `DocumentationReturns` — the `@returns` entries to render, one row each.
6
+ *
7
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReturns/DocumentationReturnsProps
8
+ */
9
+ export interface DocumentationReturnsProps {
10
+ /** Return entries to render — one row per documented return type. */
11
+ readonly returns?: ImmutableArray<DocumentationReturn> | undefined;
12
+ }
13
+ /**
14
+ * Render a documented symbol's `@returns` entries as a scrollable table — one row per return type.
15
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
16
+ * - A row with no hand-written description falls back to the referenced type's own `description`.
17
+ * - Renders nothing when there are no return entries.
18
+ *
19
+ * @kind component
20
+ * @returns A [`<Section>`](/ui/Section) containing the returns table, or `null` when there are none.
21
+ * @example <DocumentationReturns returns={returns} />
22
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReturns/DocumentationReturns
23
+ */
24
+ export declare function DocumentationReturns({ returns }: DocumentationReturnsProps): ReactNode;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Section } from "../block/Section.js";
3
+ import { Scroll } from "../style/Scroll.js";
4
+ import { Cell } from "../table/Cell.js";
5
+ import { Table } from "../table/Table.js";
6
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
7
+ import { TreeLink } from "../tree/TreeLink.js";
8
+ const DEFAULT_TYPE = "unknown";
9
+ /**
10
+ * Render a documented symbol's `@returns` entries as a scrollable table — one row per return type.
11
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
12
+ * - A row with no hand-written description falls back to the referenced type's own `description`.
13
+ * - Renders nothing when there are no return entries.
14
+ *
15
+ * @kind component
16
+ * @returns A [`<Section>`](/ui/Section) containing the returns table, or `null` when there are none.
17
+ * @example <DocumentationReturns returns={returns} />
18
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReturns/DocumentationReturns
19
+ */
20
+ export function DocumentationReturns({ returns }) {
21
+ const map = useTreeMap();
22
+ if (!returns?.length)
23
+ return null;
24
+ return (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx(Cell, { header: true, width: "fit", children: "Return" }), _jsx(Cell, { header: true, width: "xxnarrow", grow: true })] }) }), _jsx("tbody", { children: returns.map(({ type = DEFAULT_TYPE, description }) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(TreeLink, { name: type, nowrap: true }) }), _jsx("td", { children: description || getTreeElement(map, type)?.props.description })] }, `${type}-${description}`))) })] }) }) }));
25
+ }
@@ -0,0 +1,63 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ import type { DocumentationReturn } from "../../util/tree.js";
4
+ import { Section } from "../block/Section.js";
5
+ import { Scroll } from "../style/Scroll.js";
6
+ import { Cell } from "../table/Cell.js";
7
+ import { Table } from "../table/Table.js";
8
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
9
+ import { TreeLink } from "../tree/TreeLink.js";
10
+
11
+ const DEFAULT_TYPE = "unknown";
12
+
13
+ /**
14
+ * Props for `DocumentationReturns` — the `@returns` entries to render, one row each.
15
+ *
16
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReturns/DocumentationReturnsProps
17
+ */
18
+ export interface DocumentationReturnsProps {
19
+ /** Return entries to render — one row per documented return type. */
20
+ readonly returns?: ImmutableArray<DocumentationReturn> | undefined;
21
+ }
22
+
23
+ /**
24
+ * Render a documented symbol's `@returns` entries as a scrollable table — one row per return type.
25
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
26
+ * - A row with no hand-written description falls back to the referenced type's own `description`.
27
+ * - Renders nothing when there are no return entries.
28
+ *
29
+ * @kind component
30
+ * @returns A [`<Section>`](/ui/Section) containing the returns table, or `null` when there are none.
31
+ * @example <DocumentationReturns returns={returns} />
32
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationReturns/DocumentationReturns
33
+ */
34
+ export function DocumentationReturns({ returns }: DocumentationReturnsProps): ReactNode {
35
+ const map = useTreeMap();
36
+ if (!returns?.length) return null;
37
+ return (
38
+ <Section>
39
+ <Scroll horizontal>
40
+ <Table>
41
+ <thead>
42
+ <tr>
43
+ <Cell header width="fit">
44
+ Return
45
+ </Cell>
46
+ <Cell header width="xxnarrow" grow />
47
+ </tr>
48
+ </thead>
49
+ <tbody>
50
+ {returns.map(({ type = DEFAULT_TYPE, description }) => (
51
+ <tr key={`${type}-${description}`}>
52
+ <td>
53
+ <TreeLink name={type} nowrap />
54
+ </td>
55
+ <td>{description || getTreeElement(map, type)?.props.description}</td>
56
+ </tr>
57
+ ))}
58
+ </tbody>
59
+ </Table>
60
+ </Scroll>
61
+ </Section>
62
+ );
63
+ }
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ import type { DocumentationThrow } from "../../util/tree.js";
4
+ /**
5
+ * Props for `DocumentationThrows` — the `@throws` entries to render, one row each.
6
+ *
7
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationThrows/DocumentationThrowsProps
8
+ */
9
+ export interface DocumentationThrowsProps {
10
+ /** Throw entries to render — one row per documented thrown type. */
11
+ readonly throws?: ImmutableArray<DocumentationThrow> | undefined;
12
+ }
13
+ /**
14
+ * Render a documented symbol's `@throws` entries as a scrollable table — one row per thrown type.
15
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
16
+ * - A row with no hand-written description falls back to the referenced type's own `description`.
17
+ * - Renders nothing when there are no throw entries.
18
+ *
19
+ * @kind component
20
+ * @returns A [`<Section>`](/ui/Section) containing the throws table, or `null` when there are none.
21
+ * @example <DocumentationThrows throws={throws} />
22
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationThrows/DocumentationThrows
23
+ */
24
+ export declare function DocumentationThrows({ throws }: DocumentationThrowsProps): ReactNode;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Section } from "../block/Section.js";
3
+ import { Scroll } from "../style/Scroll.js";
4
+ import { Cell } from "../table/Cell.js";
5
+ import { Table } from "../table/Table.js";
6
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
7
+ import { TreeLink } from "../tree/TreeLink.js";
8
+ const DEFAULT_TYPE = "unknown";
9
+ /**
10
+ * Render a documented symbol's `@throws` entries as a scrollable table — one row per thrown type.
11
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
12
+ * - A row with no hand-written description falls back to the referenced type's own `description`.
13
+ * - Renders nothing when there are no throw entries.
14
+ *
15
+ * @kind component
16
+ * @returns A [`<Section>`](/ui/Section) containing the throws table, or `null` when there are none.
17
+ * @example <DocumentationThrows throws={throws} />
18
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationThrows/DocumentationThrows
19
+ */
20
+ export function DocumentationThrows({ throws }) {
21
+ const map = useTreeMap();
22
+ if (!throws?.length)
23
+ return null;
24
+ return (_jsx(Section, { children: _jsx(Scroll, { horizontal: true, children: _jsxs(Table, { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx(Cell, { header: true, width: "fit", children: "Throws" }), _jsx(Cell, { header: true, width: "xxnarrow", grow: true })] }) }), _jsx("tbody", { children: throws.map(({ type = DEFAULT_TYPE, description }) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(TreeLink, { name: type, nowrap: true }) }), _jsx("td", { children: description || getTreeElement(map, type)?.props.description })] }, `${type}-${description}`))) })] }) }) }));
25
+ }
@@ -0,0 +1,63 @@
1
+ import type { ReactNode } from "react";
2
+ import type { ImmutableArray } from "../../util/array.js";
3
+ import type { DocumentationThrow } from "../../util/tree.js";
4
+ import { Section } from "../block/Section.js";
5
+ import { Scroll } from "../style/Scroll.js";
6
+ import { Cell } from "../table/Cell.js";
7
+ import { Table } from "../table/Table.js";
8
+ import { getTreeElement, useTreeMap } from "../tree/TreeContext.js";
9
+ import { TreeLink } from "../tree/TreeLink.js";
10
+
11
+ const DEFAULT_TYPE = "unknown";
12
+
13
+ /**
14
+ * Props for `DocumentationThrows` — the `@throws` entries to render, one row each.
15
+ *
16
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationThrows/DocumentationThrowsProps
17
+ */
18
+ export interface DocumentationThrowsProps {
19
+ /** Throw entries to render — one row per documented thrown type. */
20
+ readonly throws?: ImmutableArray<DocumentationThrow> | undefined;
21
+ }
22
+
23
+ /**
24
+ * Render a documented symbol's `@throws` entries as a scrollable table — one row per thrown type.
25
+ * - Self-contained: pulls its own copy of the tree map from [`useTreeMap()`](/ui/useTreeMap) so the `Type` column can link each type to its documented page via [`TreeLink`](/ui/TreeLink) (exact-match only; compound or builtin types stay plain text).
26
+ * - A row with no hand-written description falls back to the referenced type's own `description`.
27
+ * - Renders nothing when there are no throw entries.
28
+ *
29
+ * @kind component
30
+ * @returns A [`<Section>`](/ui/Section) containing the throws table, or `null` when there are none.
31
+ * @example <DocumentationThrows throws={throws} />
32
+ * @see https://dhoulb.github.io/shelving/ui/docs/DocumentationThrows/DocumentationThrows
33
+ */
34
+ export function DocumentationThrows({ throws }: DocumentationThrowsProps): ReactNode {
35
+ const map = useTreeMap();
36
+ if (!throws?.length) return null;
37
+ return (
38
+ <Section>
39
+ <Scroll horizontal>
40
+ <Table>
41
+ <thead>
42
+ <tr>
43
+ <Cell header width="fit">
44
+ Throws
45
+ </Cell>
46
+ <Cell header width="xxnarrow" grow />
47
+ </tr>
48
+ </thead>
49
+ <tbody>
50
+ {throws.map(({ type = DEFAULT_TYPE, description }) => (
51
+ <tr key={`${type}-${description}`}>
52
+ <td>
53
+ <TreeLink name={type} nowrap />
54
+ </td>
55
+ <td>{description || getTreeElement(map, type)?.props.description}</td>
56
+ </tr>
57
+ ))}
58
+ </tbody>
59
+ </Table>
60
+ </Scroll>
61
+ </Section>
62
+ );
63
+ }
@@ -3,4 +3,8 @@ export * from "./DocumentationCard.js";
3
3
  export * from "./DocumentationHomePage.js";
4
4
  export * from "./DocumentationKind.js";
5
5
  export * from "./DocumentationPage.js";
6
+ export * from "./DocumentationParams.js";
7
+ export * from "./DocumentationReferences.js";
8
+ export * from "./DocumentationReturns.js";
6
9
  export * from "./DocumentationSignatures.js";
10
+ export * from "./DocumentationThrows.js";
package/ui/docs/index.js CHANGED
@@ -3,4 +3,8 @@ export * from "./DocumentationCard.js";
3
3
  export * from "./DocumentationHomePage.js";
4
4
  export * from "./DocumentationKind.js";
5
5
  export * from "./DocumentationPage.js";
6
+ export * from "./DocumentationParams.js";
7
+ export * from "./DocumentationReferences.js";
8
+ export * from "./DocumentationReturns.js";
6
9
  export * from "./DocumentationSignatures.js";
10
+ export * from "./DocumentationThrows.js";
package/ui/docs/index.ts CHANGED
@@ -3,4 +3,8 @@ export * from "./DocumentationCard.js";
3
3
  export * from "./DocumentationHomePage.js";
4
4
  export * from "./DocumentationKind.js";
5
5
  export * from "./DocumentationPage.js";
6
+ export * from "./DocumentationParams.js";
7
+ export * from "./DocumentationReferences.js";
8
+ export * from "./DocumentationReturns.js";
6
9
  export * from "./DocumentationSignatures.js";
10
+ export * from "./DocumentationThrows.js";