shelving 1.255.1 → 1.256.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/ui/block/Block.d.ts +2 -1
- package/ui/block/Block.js +2 -1
- package/ui/block/Block.module.css +11 -0
- package/ui/block/Block.tsx +10 -1
- package/ui/block/Panel.module.css +1 -0
- package/ui/block/Section.module.css +12 -0
- package/ui/docs/DocumentationApp.d.ts +7 -0
- package/ui/docs/DocumentationApp.js +14 -0
- package/ui/docs/DocumentationApp.tsx +26 -0
- package/ui/docs/DocumentationPage.js +9 -25
- package/ui/docs/DocumentationPage.tsx +16 -35
- package/ui/{tree/TreeIndexPage.d.ts → docs/DocumentationSearchPage.d.ts} +3 -7
- package/ui/{tree/TreeIndexPage.js → docs/DocumentationSearchPage.js} +11 -15
- package/ui/{tree/TreeIndexPage.tsx → docs/DocumentationSearchPage.tsx} +15 -20
- package/ui/docs/index.d.ts +2 -1
- package/ui/docs/index.js +2 -1
- package/ui/docs/index.ts +2 -1
- package/ui/inline/Code.module.css +1 -0
- package/ui/inline/Mark.module.css +1 -0
- package/ui/misc/Tag.module.css +1 -0
- package/ui/style/Gap.d.ts +2 -7
- package/ui/style/Gap.js +1 -1
- package/ui/style/Gap.module.css +49 -9
- package/ui/style/Gap.tsx +3 -9
- package/ui/style/Indent.module.css +10 -2
- package/ui/style/Padding.d.ts +2 -7
- package/ui/style/Padding.module.css +10 -2
- package/ui/style/Padding.tsx +2 -26
- package/ui/style/Space.module.css +10 -9
- package/ui/tree/TreeApp.d.ts +5 -3
- package/ui/tree/TreeApp.js +4 -6
- package/ui/tree/TreeApp.tsx +14 -11
- package/ui/tree/TreePage.js +3 -2
- package/ui/tree/TreePage.tsx +16 -13
- package/ui/tree/TreeSidebar.d.ts +3 -3
- package/ui/tree/TreeSidebar.js +2 -4
- package/ui/tree/TreeSidebar.tsx +4 -5
- package/ui/tree/index.d.ts +1 -1
- package/ui/tree/index.js +1 -1
- package/ui/tree/index.ts +1 -1
- package/ui/docs/DocumentationHomePage.d.ts +0 -14
- package/ui/docs/DocumentationHomePage.js +0 -23
- package/ui/docs/DocumentationHomePage.md +0 -34
- package/ui/docs/DocumentationHomePage.test.tsx +0 -35
- package/ui/docs/DocumentationHomePage.tsx +0 -45
package/package.json
CHANGED
package/ui/block/Block.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants } from "../style/Color.js";
|
|
3
3
|
import { type IndentVariants } from "../style/Indent.js";
|
|
4
|
+
import { type PaddingVariants } from "../style/Padding.js";
|
|
4
5
|
import { type SpaceVariants } from "../style/Space.js";
|
|
5
6
|
import { type TypographyVariants } from "../style/Typography.js";
|
|
6
7
|
import { type WidthVariants } from "../style/Width.js";
|
|
@@ -16,7 +17,7 @@ export type BlockElement = "div" | "section" | "header" | "footer" | "article" |
|
|
|
16
17
|
*
|
|
17
18
|
* @see https://shelving.cc/ui/BlockProps
|
|
18
19
|
*/
|
|
19
|
-
export interface BlockProps extends ColorVariants, IndentVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
20
|
+
export interface BlockProps extends ColorVariants, PaddingVariants, IndentVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
20
21
|
/**
|
|
21
22
|
* Element this `<Block>` renders as, e.g. "header" to output a "<header>"
|
|
22
23
|
* @default "div"
|
package/ui/block/Block.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { getColorClass } from "../style/Color.js";
|
|
3
3
|
import { getIndentClass } from "../style/Indent.js";
|
|
4
|
+
import { getPaddingClass } from "../style/Padding.js";
|
|
4
5
|
import { getSpaceClass } from "../style/Space.js";
|
|
5
6
|
import { getTypographyClass } from "../style/Typography.js";
|
|
6
7
|
import { getWidthClass } from "../style/Width.js";
|
|
@@ -19,7 +20,7 @@ const BLOCK_CLASS = getModuleClass(BLOCK_CSS, "block");
|
|
|
19
20
|
*/
|
|
20
21
|
export function getBlockClass(variants) {
|
|
21
22
|
return getClass(BLOCK_CLASS, //
|
|
22
|
-
getColorClass(variants), getIndentClass(variants), getSpaceClass(variants), getTypographyClass(variants), getWidthClass(variants));
|
|
23
|
+
getColorClass(variants), getIndentClass(variants), getPaddingClass(variants), getSpaceClass(variants), getTypographyClass(variants), getWidthClass(variants));
|
|
23
24
|
}
|
|
24
25
|
/**
|
|
25
26
|
* Plain `<div>` block with block-level spacing.
|
package/ui/block/Block.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants, getColorClass } from "../style/Color.js";
|
|
3
3
|
import { getIndentClass, type IndentVariants } from "../style/Indent.js";
|
|
4
|
+
import { getPaddingClass, type PaddingVariants } from "../style/Padding.js";
|
|
4
5
|
import { getSpaceClass, type SpaceVariants } from "../style/Space.js";
|
|
5
6
|
import { getTypographyClass, type TypographyVariants } from "../style/Typography.js";
|
|
6
7
|
import { getWidthClass, type WidthVariants } from "../style/Width.js";
|
|
@@ -22,7 +23,14 @@ export type BlockElement = "div" | "section" | "header" | "footer" | "article" |
|
|
|
22
23
|
*
|
|
23
24
|
* @see https://shelving.cc/ui/BlockProps
|
|
24
25
|
*/
|
|
25
|
-
export interface BlockProps
|
|
26
|
+
export interface BlockProps
|
|
27
|
+
extends ColorVariants,
|
|
28
|
+
PaddingVariants,
|
|
29
|
+
IndentVariants,
|
|
30
|
+
SpaceVariants,
|
|
31
|
+
TypographyVariants,
|
|
32
|
+
WidthVariants,
|
|
33
|
+
OptionalChildProps {
|
|
26
34
|
/**
|
|
27
35
|
* Element this `<Block>` renders as, e.g. "header" to output a "<header>"
|
|
28
36
|
* @default "div"
|
|
@@ -45,6 +53,7 @@ export function getBlockClass(variants: BlockProps): string {
|
|
|
45
53
|
BLOCK_CLASS, //
|
|
46
54
|
getColorClass(variants),
|
|
47
55
|
getIndentClass(variants),
|
|
56
|
+
getPaddingClass(variants),
|
|
48
57
|
getSpaceClass(variants),
|
|
49
58
|
getTypographyClass(variants),
|
|
50
59
|
getWidthClass(variants),
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
inline-size: 100%;
|
|
29
29
|
margin-inline: 0;
|
|
30
30
|
margin-block: 0;
|
|
31
|
+
padding-block: var(--panel-padding, var(--space-section));
|
|
31
32
|
padding-inline: var(--panel-indent, var(--space-normal));
|
|
32
33
|
border-top: var(--panel-border, var(--panel-stroke, var(--stroke-normal)) solid var(--tint-80));
|
|
33
34
|
border-bottom: var(--panel-border, var(--panel-stroke, var(--stroke-normal)) solid var(--tint-80));
|
|
@@ -18,3 +18,15 @@
|
|
|
18
18
|
margin-block: var(--section-space, var(--space-section));
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
@layer overrides {
|
|
23
|
+
.prose :where(section, article, aside, nav, header, footer, figure),
|
|
24
|
+
.section {
|
|
25
|
+
&:first-child {
|
|
26
|
+
margin-block-start: 0;
|
|
27
|
+
}
|
|
28
|
+
&:last-child {
|
|
29
|
+
margin-block-end: 0;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import { type TreeAppProps } from "../tree/TreeApp.js";
|
|
3
|
+
/**
|
|
4
|
+
* Documentation app.
|
|
5
|
+
* - Build upon `<TreeApp>` to include a `<DocumentationSearchPage>` at its `/search` URL.
|
|
6
|
+
*/
|
|
7
|
+
export declare function DocumentationApp({ tree, routes, sidebar, ...meta }: TreeAppProps): ReactElement;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Menu, MenuItem } from "../menu/Menu.js";
|
|
3
|
+
import { TreeApp } from "../tree/TreeApp.js";
|
|
4
|
+
import { TreeSidebar } from "../tree/TreeSidebar.js";
|
|
5
|
+
import { DocumentationSearchPage } from "./DocumentationSearchPage.js";
|
|
6
|
+
/**
|
|
7
|
+
* Documentation app.
|
|
8
|
+
* - Build upon `<TreeApp>` to include a `<DocumentationSearchPage>` at its `/search` URL.
|
|
9
|
+
*/
|
|
10
|
+
export function DocumentationApp({ tree, routes = {
|
|
11
|
+
"/search": DocumentationSearchPage,
|
|
12
|
+
}, sidebar = (_jsx(TreeSidebar, { tree: tree, children: _jsx(Menu, { children: _jsx(MenuItem, { href: "/search", children: "Search" }) }) })), ...meta }) {
|
|
13
|
+
return _jsx(TreeApp, { tree: tree, routes: routes, sidebar: sidebar, ...meta });
|
|
14
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import { Menu, MenuItem } from "../menu/Menu.js";
|
|
3
|
+
import { TreeApp, type TreeAppProps } from "../tree/TreeApp.js";
|
|
4
|
+
import { TreeSidebar } from "../tree/TreeSidebar.js";
|
|
5
|
+
import { DocumentationSearchPage } from "./DocumentationSearchPage.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Documentation app.
|
|
9
|
+
* - Build upon `<TreeApp>` to include a `<DocumentationSearchPage>` at its `/search` URL.
|
|
10
|
+
*/
|
|
11
|
+
export function DocumentationApp({
|
|
12
|
+
tree,
|
|
13
|
+
routes = {
|
|
14
|
+
"/search": DocumentationSearchPage,
|
|
15
|
+
},
|
|
16
|
+
sidebar = (
|
|
17
|
+
<TreeSidebar tree={tree}>
|
|
18
|
+
<Menu>
|
|
19
|
+
<MenuItem href="/search">Search</MenuItem>
|
|
20
|
+
</Menu>
|
|
21
|
+
</TreeSidebar>
|
|
22
|
+
),
|
|
23
|
+
...meta
|
|
24
|
+
}: TreeAppProps): ReactElement {
|
|
25
|
+
return <TreeApp tree={tree} routes={routes} sidebar={sidebar} {...meta} />;
|
|
26
|
+
}
|
|
@@ -21,7 +21,8 @@ import { DocumentationReturns } from "./DocumentationReturns.js";
|
|
|
21
21
|
import { DocumentationSignatures } from "./DocumentationSignatures.js";
|
|
22
22
|
import { DocumentationThrows } from "./DocumentationThrows.js";
|
|
23
23
|
/** Documentation `kind`s grouped into card sections, in display order — pluralised, sentence-case headings. Data members (properties) are not child elements — they render as the Properties table instead. */
|
|
24
|
-
const
|
|
24
|
+
const KINDS = {
|
|
25
|
+
module: "Modules",
|
|
25
26
|
component: "Components",
|
|
26
27
|
function: "Functions",
|
|
27
28
|
class: "Classes",
|
|
@@ -31,29 +32,6 @@ const KIND_SECTIONS = {
|
|
|
31
32
|
"static method": "Static methods",
|
|
32
33
|
method: "Methods",
|
|
33
34
|
};
|
|
34
|
-
/** Render a list of tree elements grouped into kind-based card sections, in `KIND_SECTIONS` order. */
|
|
35
|
-
function _renderSections(elements) {
|
|
36
|
-
return Object.entries(KIND_SECTIONS).map(([kind, label]) => {
|
|
37
|
-
const group = elements.filter(el => el.props.kind === kind);
|
|
38
|
-
return group.length ? (_jsxs(Section, { children: [_jsx(Heading, { children: label }), _jsx(TreeCards, { children: group })] }, kind)) : null;
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Children listing for a documentation page — this page's child symbols grouped into kind-based card sections.
|
|
43
|
-
*
|
|
44
|
-
* - Renders nothing when the page has no children (e.g. a leaf symbol).
|
|
45
|
-
* - Cross-tree search and kind filtering live on the index page (`TreeIndexPage`), not here.
|
|
46
|
-
*
|
|
47
|
-
* @param props The page's child elements.
|
|
48
|
-
* @returns The grouped card sections, or `null` when there are no children.
|
|
49
|
-
*/
|
|
50
|
-
function DocumentationChildren({ elements }) {
|
|
51
|
-
const childElements = Array.from(walkElements(elements));
|
|
52
|
-
// No children → nothing to list.
|
|
53
|
-
if (!childElements.length)
|
|
54
|
-
return null;
|
|
55
|
-
return _renderSections(childElements);
|
|
56
|
-
}
|
|
57
35
|
/**
|
|
58
36
|
* Page renderer for a `tree-documentation` element — the full detail page for a documented symbol.
|
|
59
37
|
* - Renders breadcrumbs, title (with kind + `readonly` tags), relational links (`member of`, `extends`, `implements`), signatures (one per overload), content, parameters, returns, throws, properties, referenced types, and examples.
|
|
@@ -69,5 +47,11 @@ function DocumentationChildren({ elements }) {
|
|
|
69
47
|
* @see https://shelving.cc/ui/DocumentationPage
|
|
70
48
|
*/
|
|
71
49
|
export function DocumentationPage({ title, name, kind = "unknown", description, content, signatures, params, returns, throws, properties, types, examples, children, ...props }) {
|
|
72
|
-
|
|
50
|
+
const elements = Array.from(walkElements(children));
|
|
51
|
+
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 })] }) }), _jsxs(Block, { indent: "normal", padding: "section", children: [signatures?.length || params?.length || returns?.length || throws?.length || properties?.length || types?.length ? (_jsxs(Section, { children: [_jsx(DocumentationSignatures, { signatures: signatures }), _jsx(DocumentationParams, { params: params }), _jsx(DocumentationReturns, { returns: returns }), _jsx(DocumentationThrows, { throws: throws }), _jsx(DocumentationProperties, { properties: properties }), _jsx(DocumentationReferences, { types: types })] })) : null, content && (_jsx(Section, { children: _jsx(Prose, { children: _jsx(TreeMarkup, { children: content }) }) })), examples?.length && (_jsxs(Section, { children: [_jsx(Heading, { children: "Examples" }), examples.map(({ description }) => (_jsx(Preformatted, { children: description }, description)))] })), elements.length
|
|
52
|
+
? Object.entries(KINDS).map(([kind, label]) => {
|
|
53
|
+
const group = elements.filter(el => el.props.kind === kind);
|
|
54
|
+
return group.length ? (_jsxs(Section, { children: [_jsx(Heading, { children: label }), _jsx(TreeCards, { children: group })] }, kind)) : null;
|
|
55
|
+
})
|
|
56
|
+
: null] })] }) }));
|
|
73
57
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import { walkElements } from "../../util/element.js";
|
|
3
|
-
import type { DocumentationElementProps, TreeElement
|
|
3
|
+
import type { DocumentationElementProps, TreeElement } from "../../util/tree.js";
|
|
4
4
|
import { Block } from "../block/Block.js";
|
|
5
5
|
import { Heading } from "../block/Heading.js";
|
|
6
6
|
import { Panel } from "../block/Panel.js";
|
|
@@ -23,7 +23,8 @@ import { DocumentationSignatures } from "./DocumentationSignatures.js";
|
|
|
23
23
|
import { DocumentationThrows } from "./DocumentationThrows.js";
|
|
24
24
|
|
|
25
25
|
/** Documentation `kind`s grouped into card sections, in display order — pluralised, sentence-case headings. Data members (properties) are not child elements — they render as the Properties table instead. */
|
|
26
|
-
const
|
|
26
|
+
const KINDS = {
|
|
27
|
+
module: "Modules",
|
|
27
28
|
component: "Components",
|
|
28
29
|
function: "Functions",
|
|
29
30
|
class: "Classes",
|
|
@@ -34,37 +35,6 @@ const KIND_SECTIONS = {
|
|
|
34
35
|
method: "Methods",
|
|
35
36
|
};
|
|
36
37
|
|
|
37
|
-
/** Render a list of tree elements grouped into kind-based card sections, in `KIND_SECTIONS` order. */
|
|
38
|
-
function _renderSections(elements: readonly TreeElement[]): ReactNode {
|
|
39
|
-
return Object.entries(KIND_SECTIONS).map(([kind, label]) => {
|
|
40
|
-
const group = elements.filter(el => (el.props as DocumentationElementProps).kind === kind);
|
|
41
|
-
return group.length ? (
|
|
42
|
-
<Section key={kind}>
|
|
43
|
-
<Heading>{label}</Heading>
|
|
44
|
-
<TreeCards>{group}</TreeCards>
|
|
45
|
-
</Section>
|
|
46
|
-
) : null;
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Children listing for a documentation page — this page's child symbols grouped into kind-based card sections.
|
|
52
|
-
*
|
|
53
|
-
* - Renders nothing when the page has no children (e.g. a leaf symbol).
|
|
54
|
-
* - Cross-tree search and kind filtering live on the index page (`TreeIndexPage`), not here.
|
|
55
|
-
*
|
|
56
|
-
* @param props The page's child elements.
|
|
57
|
-
* @returns The grouped card sections, or `null` when there are no children.
|
|
58
|
-
*/
|
|
59
|
-
function DocumentationChildren({ elements }: { readonly elements?: TreeElements }): ReactNode {
|
|
60
|
-
const childElements = Array.from(walkElements<TreeElement>(elements));
|
|
61
|
-
|
|
62
|
-
// No children → nothing to list.
|
|
63
|
-
if (!childElements.length) return null;
|
|
64
|
-
|
|
65
|
-
return _renderSections(childElements);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
38
|
/**
|
|
69
39
|
* Page renderer for a `tree-documentation` element — the full detail page for a documented symbol.
|
|
70
40
|
* - Renders breadcrumbs, title (with kind + `readonly` tags), relational links (`member of`, `extends`, `implements`), signatures (one per overload), content, parameters, returns, throws, properties, referenced types, and examples.
|
|
@@ -95,6 +65,7 @@ export function DocumentationPage({
|
|
|
95
65
|
children,
|
|
96
66
|
...props
|
|
97
67
|
}: DocumentationElementProps): ReactNode {
|
|
68
|
+
const elements = Array.from(walkElements<TreeElement>(children));
|
|
98
69
|
return (
|
|
99
70
|
<Page title={title ?? name} description={description}>
|
|
100
71
|
<Block color={getDocumentationKindColor(kind)}>
|
|
@@ -110,7 +81,7 @@ export function DocumentationPage({
|
|
|
110
81
|
<DocumentationButtons {...props} />
|
|
111
82
|
</Header>
|
|
112
83
|
</Panel>
|
|
113
|
-
<Block indent="normal">
|
|
84
|
+
<Block indent="normal" padding="section">
|
|
114
85
|
{signatures?.length || params?.length || returns?.length || throws?.length || properties?.length || types?.length ? (
|
|
115
86
|
<Section>
|
|
116
87
|
<DocumentationSignatures signatures={signatures} />
|
|
@@ -136,7 +107,17 @@ export function DocumentationPage({
|
|
|
136
107
|
))}
|
|
137
108
|
</Section>
|
|
138
109
|
)}
|
|
139
|
-
|
|
110
|
+
{elements.length
|
|
111
|
+
? Object.entries(KINDS).map(([kind, label]) => {
|
|
112
|
+
const group = elements.filter(el => (el.props as DocumentationElementProps).kind === kind);
|
|
113
|
+
return group.length ? (
|
|
114
|
+
<Section key={kind}>
|
|
115
|
+
<Heading>{label}</Heading>
|
|
116
|
+
<TreeCards>{group}</TreeCards>
|
|
117
|
+
</Section>
|
|
118
|
+
) : null;
|
|
119
|
+
})
|
|
120
|
+
: null}
|
|
140
121
|
</Block>
|
|
141
122
|
</Block>
|
|
142
123
|
</Page>
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
-
import type { AbsolutePath } from "../../util/path.js";
|
|
3
|
-
/** Canonical URL path of the `TreeIndexPage`, wired as a `<TreeApp>` fallback route. */
|
|
4
|
-
export declare const TREE_INDEX_PATH: AbsolutePath;
|
|
5
2
|
/**
|
|
6
3
|
* Page listing every element in the system in one flat, searchable view.
|
|
7
4
|
*
|
|
@@ -9,11 +6,10 @@ export declare const TREE_INDEX_PATH: AbsolutePath;
|
|
|
9
6
|
* - The kind checkboxes are multi-select — ticking several narrows to a `kind IN […]` filter; ticking none shows every kind.
|
|
10
7
|
* - An empty query lists everything (capped at 100); a non-empty query ranks with `searchTree` and caps at 20.
|
|
11
8
|
* - Reads the whole tree from the surrounding `<TreeProvider>` (the flattened map's root), so it works on every page.
|
|
12
|
-
* - Wired as a `<TreeApp>` fallback route at `TREE_INDEX_PATH` (`/all`) — it's not a node in the tree.
|
|
13
9
|
*
|
|
14
10
|
* @kind component
|
|
15
11
|
* @returns A `<Page>` with a search input, kind checkboxes, and a flat card listing of results.
|
|
16
|
-
* @example <Router routes={{
|
|
17
|
-
* @see https://shelving.cc/ui/
|
|
12
|
+
* @example <Router routes={{ search: DocumentationSearchPage }} />
|
|
13
|
+
* @see https://shelving.cc/ui/DocumentationSearchPage
|
|
18
14
|
*/
|
|
19
|
-
export declare function
|
|
15
|
+
export declare function DocumentationSearchPage(): ReactNode;
|
|
@@ -3,23 +3,20 @@ import { useMemo, useState } from "react";
|
|
|
3
3
|
import { toggleArrayItem } from "../../util/array.js";
|
|
4
4
|
import { searchTree } from "../../util/tree.js";
|
|
5
5
|
import { Block } from "../block/Block.js";
|
|
6
|
+
import { Panel } from "../block/Panel.js";
|
|
6
7
|
import { Header, Section } from "../block/Section.js";
|
|
7
8
|
import { Title } from "../block/Title.js";
|
|
8
|
-
import { DocumentationKind } from "../docs/DocumentationKind.js";
|
|
9
9
|
import { CheckboxInput } from "../form/CheckboxInput.js";
|
|
10
10
|
import { TextInput } from "../form/TextInput.js";
|
|
11
11
|
import { Page } from "../page/Page.js";
|
|
12
12
|
import { Row } from "../style/Flex.js";
|
|
13
|
-
import { TreeCards } from "
|
|
14
|
-
import { useTreeMap } from "
|
|
15
|
-
|
|
16
|
-
export const TREE_INDEX_PATH = "/all";
|
|
13
|
+
import { TreeCards } from "../tree/TreeCards.js";
|
|
14
|
+
import { useTreeMap } from "../tree/TreeContext.js";
|
|
15
|
+
import { DocumentationKind } from "./DocumentationKind.js";
|
|
17
16
|
/** Title shown for the index page. */
|
|
18
|
-
const
|
|
19
|
-
/** Description shown for the index page (page `<meta>` description). */
|
|
20
|
-
const INDEX_DESCRIPTION = "Search every documented element in the system.";
|
|
17
|
+
const TITLE = "Search...";
|
|
21
18
|
/** Kinds offered as filter chips, in display order — mirrors `DocumentationPage`'s sections. */
|
|
22
|
-
const
|
|
19
|
+
const KINDS = ["module", "component", "function", "class", "interface", "type", "constant", "method", "property"];
|
|
23
20
|
/** Cap on the flat listing when there's no query — keeps "show everything" sane. */
|
|
24
21
|
const INDEX_LIMIT = 100;
|
|
25
22
|
/**
|
|
@@ -29,14 +26,13 @@ const INDEX_LIMIT = 100;
|
|
|
29
26
|
* - The kind checkboxes are multi-select — ticking several narrows to a `kind IN […]` filter; ticking none shows every kind.
|
|
30
27
|
* - An empty query lists everything (capped at 100); a non-empty query ranks with `searchTree` and caps at 20.
|
|
31
28
|
* - Reads the whole tree from the surrounding `<TreeProvider>` (the flattened map's root), so it works on every page.
|
|
32
|
-
* - Wired as a `<TreeApp>` fallback route at `TREE_INDEX_PATH` (`/all`) — it's not a node in the tree.
|
|
33
29
|
*
|
|
34
30
|
* @kind component
|
|
35
31
|
* @returns A `<Page>` with a search input, kind checkboxes, and a flat card listing of results.
|
|
36
|
-
* @example <Router routes={{
|
|
37
|
-
* @see https://shelving.cc/ui/
|
|
32
|
+
* @example <Router routes={{ search: DocumentationSearchPage }} />
|
|
33
|
+
* @see https://shelving.cc/ui/DocumentationSearchPage
|
|
38
34
|
*/
|
|
39
|
-
export function
|
|
35
|
+
export function DocumentationSearchPage() {
|
|
40
36
|
const [query, setQuery] = useState("");
|
|
41
37
|
const [selected, setSelected] = useState([]);
|
|
42
38
|
const root = useTreeMap().get("/");
|
|
@@ -45,12 +41,12 @@ export function TreeIndexPage() {
|
|
|
45
41
|
if (!root)
|
|
46
42
|
return [];
|
|
47
43
|
const all = searchTree(root, "", { limit: Number.POSITIVE_INFINITY });
|
|
48
|
-
return
|
|
44
|
+
return KINDS.filter(kind => all.some(el => el.props.kind === kind));
|
|
49
45
|
}, [root]);
|
|
50
46
|
const trimmed = query.trim();
|
|
51
47
|
// Multiple kinds can be ticked at once — an array value decodes to a `kind IN […]` filter.
|
|
52
48
|
const filter = selected.length ? { kind: selected } : undefined;
|
|
53
49
|
// Each element's `key` is its unique canonical path (stamped by `flattenTree()`), so this flat cross-tree listing reconciles correctly.
|
|
54
50
|
const cards = root ? searchTree(root, trimmed, { limit: trimmed ? 20 : INDEX_LIMIT, filter }) : [];
|
|
55
|
-
return (
|
|
51
|
+
return (_jsxs(Page, { title: TITLE, children: [_jsxs(Panel, { children: [_jsx(Header, { children: _jsx(Title, { center: true, children: TITLE }) }), _jsxs(Section, { children: [_jsx(TextInput, { name: "search", title: "Search", placeholder: "Search\u2026", value: query, onValue: v => setQuery(v ?? "") }), !!kinds.length && (_jsx(Row, { left: true, wrap: true, children: kinds.map(kind => (_jsx(CheckboxInput, { name: kind, width: "fit", value: selected.includes(kind), onValue: () => setSelected(s => toggleArrayItem(s, kind)), children: _jsx(DocumentationKind, { kind: kind }) }, kind))) }))] })] }), _jsx(Block, { indent: "normal", padding: "section", children: _jsx(Section, { children: _jsx(TreeCards, { children: cards }) }) })] }));
|
|
56
52
|
}
|
|
@@ -1,31 +1,25 @@
|
|
|
1
1
|
import { type ReactNode, useMemo, useState } from "react";
|
|
2
2
|
import { type ImmutableArray, toggleArrayItem } from "../../util/array.js";
|
|
3
|
-
import type { AbsolutePath } from "../../util/path.js";
|
|
4
3
|
import type { Query } from "../../util/query.js";
|
|
5
4
|
import type { DocumentationElementProps } from "../../util/tree.js";
|
|
6
5
|
import { searchTree } from "../../util/tree.js";
|
|
7
6
|
import { Block } from "../block/Block.js";
|
|
7
|
+
import { Panel } from "../block/Panel.js";
|
|
8
8
|
import { Header, Section } from "../block/Section.js";
|
|
9
9
|
import { Title } from "../block/Title.js";
|
|
10
|
-
import { DocumentationKind } from "../docs/DocumentationKind.js";
|
|
11
10
|
import { CheckboxInput } from "../form/CheckboxInput.js";
|
|
12
11
|
import { TextInput } from "../form/TextInput.js";
|
|
13
12
|
import { Page } from "../page/Page.js";
|
|
14
13
|
import { Row } from "../style/Flex.js";
|
|
15
|
-
import { TreeCards } from "
|
|
16
|
-
import { useTreeMap } from "
|
|
17
|
-
|
|
18
|
-
/** Canonical URL path of the `TreeIndexPage`, wired as a `<TreeApp>` fallback route. */
|
|
19
|
-
export const TREE_INDEX_PATH = "/all" as AbsolutePath;
|
|
14
|
+
import { TreeCards } from "../tree/TreeCards.js";
|
|
15
|
+
import { useTreeMap } from "../tree/TreeContext.js";
|
|
16
|
+
import { DocumentationKind } from "./DocumentationKind.js";
|
|
20
17
|
|
|
21
18
|
/** Title shown for the index page. */
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
/** Description shown for the index page (page `<meta>` description). */
|
|
25
|
-
const INDEX_DESCRIPTION = "Search every documented element in the system.";
|
|
19
|
+
const TITLE = "Search...";
|
|
26
20
|
|
|
27
21
|
/** Kinds offered as filter chips, in display order — mirrors `DocumentationPage`'s sections. */
|
|
28
|
-
const
|
|
22
|
+
const KINDS = ["module", "component", "function", "class", "interface", "type", "constant", "method", "property"];
|
|
29
23
|
|
|
30
24
|
/** Cap on the flat listing when there's no query — keeps "show everything" sane. */
|
|
31
25
|
const INDEX_LIMIT = 100;
|
|
@@ -37,14 +31,13 @@ const INDEX_LIMIT = 100;
|
|
|
37
31
|
* - The kind checkboxes are multi-select — ticking several narrows to a `kind IN […]` filter; ticking none shows every kind.
|
|
38
32
|
* - An empty query lists everything (capped at 100); a non-empty query ranks with `searchTree` and caps at 20.
|
|
39
33
|
* - Reads the whole tree from the surrounding `<TreeProvider>` (the flattened map's root), so it works on every page.
|
|
40
|
-
* - Wired as a `<TreeApp>` fallback route at `TREE_INDEX_PATH` (`/all`) — it's not a node in the tree.
|
|
41
34
|
*
|
|
42
35
|
* @kind component
|
|
43
36
|
* @returns A `<Page>` with a search input, kind checkboxes, and a flat card listing of results.
|
|
44
|
-
* @example <Router routes={{
|
|
45
|
-
* @see https://shelving.cc/ui/
|
|
37
|
+
* @example <Router routes={{ search: DocumentationSearchPage }} />
|
|
38
|
+
* @see https://shelving.cc/ui/DocumentationSearchPage
|
|
46
39
|
*/
|
|
47
|
-
export function
|
|
40
|
+
export function DocumentationSearchPage(): ReactNode {
|
|
48
41
|
const [query, setQuery] = useState("");
|
|
49
42
|
const [selected, setSelected] = useState<ImmutableArray<string>>([]);
|
|
50
43
|
|
|
@@ -54,7 +47,7 @@ export function TreeIndexPage(): ReactNode {
|
|
|
54
47
|
const kinds = useMemo(() => {
|
|
55
48
|
if (!root) return [];
|
|
56
49
|
const all = searchTree(root, "", { limit: Number.POSITIVE_INFINITY });
|
|
57
|
-
return
|
|
50
|
+
return KINDS.filter(kind => all.some(el => (el.props as DocumentationElementProps).kind === kind));
|
|
58
51
|
}, [root]);
|
|
59
52
|
|
|
60
53
|
const trimmed = query.trim();
|
|
@@ -64,10 +57,10 @@ export function TreeIndexPage(): ReactNode {
|
|
|
64
57
|
const cards = root ? searchTree(root, trimmed, { limit: trimmed ? 20 : INDEX_LIMIT, filter }) : [];
|
|
65
58
|
|
|
66
59
|
return (
|
|
67
|
-
<Page title={
|
|
68
|
-
<
|
|
60
|
+
<Page title={TITLE}>
|
|
61
|
+
<Panel>
|
|
69
62
|
<Header>
|
|
70
|
-
<Title>{
|
|
63
|
+
<Title center>{TITLE}</Title>
|
|
71
64
|
</Header>
|
|
72
65
|
<Section>
|
|
73
66
|
<TextInput name="search" title="Search" placeholder="Search…" value={query} onValue={v => setQuery(v ?? "")} />
|
|
@@ -87,6 +80,8 @@ export function TreeIndexPage(): ReactNode {
|
|
|
87
80
|
</Row>
|
|
88
81
|
)}
|
|
89
82
|
</Section>
|
|
83
|
+
</Panel>
|
|
84
|
+
<Block indent="normal" padding="section">
|
|
90
85
|
<Section>
|
|
91
86
|
<TreeCards>{cards}</TreeCards>
|
|
92
87
|
</Section>
|
package/ui/docs/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
export * from "./DocumentationApp.js";
|
|
1
2
|
export * from "./DocumentationButtons.js";
|
|
2
3
|
export * from "./DocumentationCard.js";
|
|
3
4
|
export * from "./DocumentationDescription.js";
|
|
4
|
-
export * from "./DocumentationHomePage.js";
|
|
5
5
|
export * from "./DocumentationKind.js";
|
|
6
6
|
export * from "./DocumentationPage.js";
|
|
7
7
|
export * from "./DocumentationParams.js";
|
|
8
8
|
export * from "./DocumentationProperties.js";
|
|
9
9
|
export * from "./DocumentationReferences.js";
|
|
10
10
|
export * from "./DocumentationReturns.js";
|
|
11
|
+
export * from "./DocumentationSearchPage.js";
|
|
11
12
|
export * from "./DocumentationSignatures.js";
|
|
12
13
|
export * from "./DocumentationThrows.js";
|
|
13
14
|
export * from "./DocumentationType.js";
|
package/ui/docs/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
export * from "./DocumentationApp.js";
|
|
1
2
|
export * from "./DocumentationButtons.js";
|
|
2
3
|
export * from "./DocumentationCard.js";
|
|
3
4
|
export * from "./DocumentationDescription.js";
|
|
4
|
-
export * from "./DocumentationHomePage.js";
|
|
5
5
|
export * from "./DocumentationKind.js";
|
|
6
6
|
export * from "./DocumentationPage.js";
|
|
7
7
|
export * from "./DocumentationParams.js";
|
|
8
8
|
export * from "./DocumentationProperties.js";
|
|
9
9
|
export * from "./DocumentationReferences.js";
|
|
10
10
|
export * from "./DocumentationReturns.js";
|
|
11
|
+
export * from "./DocumentationSearchPage.js";
|
|
11
12
|
export * from "./DocumentationSignatures.js";
|
|
12
13
|
export * from "./DocumentationThrows.js";
|
|
13
14
|
export * from "./DocumentationType.js";
|
package/ui/docs/index.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
export * from "./DocumentationApp.js";
|
|
1
2
|
export * from "./DocumentationButtons.js";
|
|
2
3
|
export * from "./DocumentationCard.js";
|
|
3
4
|
export * from "./DocumentationDescription.js";
|
|
4
|
-
export * from "./DocumentationHomePage.js";
|
|
5
5
|
export * from "./DocumentationKind.js";
|
|
6
6
|
export * from "./DocumentationPage.js";
|
|
7
7
|
export * from "./DocumentationParams.js";
|
|
8
8
|
export * from "./DocumentationProperties.js";
|
|
9
9
|
export * from "./DocumentationReferences.js";
|
|
10
10
|
export * from "./DocumentationReturns.js";
|
|
11
|
+
export * from "./DocumentationSearchPage.js";
|
|
11
12
|
export * from "./DocumentationSignatures.js";
|
|
12
13
|
export * from "./DocumentationThrows.js";
|
|
13
14
|
export * from "./DocumentationType.js";
|
package/ui/misc/Tag.module.css
CHANGED
package/ui/style/Gap.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Allowed values for gap spacing for components that support `GapVariants`
|
|
3
|
-
*
|
|
4
|
-
* @see https://shelving.cc/ui/GapValue
|
|
5
|
-
*/
|
|
6
|
-
export type GapValue = "none" | "xxsmall" | "xsmall" | "small" | "normal" | "large" | "xlarge" | "xxlarge";
|
|
1
|
+
import type { SpaceValue } from "./Space.js";
|
|
7
2
|
/**
|
|
8
3
|
* Variant props for the gap between a component's children, e.g. `gap="large"`.
|
|
9
4
|
*
|
|
@@ -11,7 +6,7 @@ export type GapValue = "none" | "xxsmall" | "xsmall" | "small" | "normal" | "lar
|
|
|
11
6
|
*/
|
|
12
7
|
export interface GapVariants {
|
|
13
8
|
/** Gap between child elements. */
|
|
14
|
-
gap?:
|
|
9
|
+
gap?: SpaceValue | undefined;
|
|
15
10
|
}
|
|
16
11
|
/**
|
|
17
12
|
* Get the gap class for a component from its `gap` variant prop.
|
package/ui/style/Gap.js
CHANGED