shelving 1.255.0 → 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.
Files changed (47) hide show
  1. package/package.json +1 -1
  2. package/ui/block/Block.d.ts +2 -1
  3. package/ui/block/Block.js +2 -1
  4. package/ui/block/Block.module.css +11 -0
  5. package/ui/block/Block.tsx +10 -1
  6. package/ui/block/Panel.module.css +1 -0
  7. package/ui/block/Section.module.css +12 -0
  8. package/ui/docs/DocumentationApp.d.ts +7 -0
  9. package/ui/docs/DocumentationApp.js +14 -0
  10. package/ui/docs/DocumentationApp.tsx +26 -0
  11. package/ui/docs/DocumentationPage.js +9 -25
  12. package/ui/docs/DocumentationPage.tsx +16 -35
  13. package/ui/{tree/TreeIndexPage.d.ts → docs/DocumentationSearchPage.d.ts} +3 -7
  14. package/ui/{tree/TreeIndexPage.js → docs/DocumentationSearchPage.js} +11 -15
  15. package/ui/{tree/TreeIndexPage.tsx → docs/DocumentationSearchPage.tsx} +15 -20
  16. package/ui/docs/index.d.ts +2 -1
  17. package/ui/docs/index.js +2 -1
  18. package/ui/docs/index.ts +2 -1
  19. package/ui/form/Form.module.css +1 -1
  20. package/ui/inline/Code.module.css +1 -0
  21. package/ui/inline/Mark.module.css +1 -0
  22. package/ui/misc/Tag.module.css +1 -0
  23. package/ui/style/Gap.d.ts +2 -7
  24. package/ui/style/Gap.js +1 -1
  25. package/ui/style/Gap.module.css +49 -9
  26. package/ui/style/Gap.tsx +3 -9
  27. package/ui/style/Indent.module.css +10 -2
  28. package/ui/style/Padding.d.ts +2 -7
  29. package/ui/style/Padding.module.css +10 -2
  30. package/ui/style/Padding.tsx +2 -26
  31. package/ui/style/Space.module.css +10 -9
  32. package/ui/tree/TreeApp.d.ts +5 -3
  33. package/ui/tree/TreeApp.js +4 -6
  34. package/ui/tree/TreeApp.tsx +14 -11
  35. package/ui/tree/TreePage.js +3 -2
  36. package/ui/tree/TreePage.tsx +16 -13
  37. package/ui/tree/TreeSidebar.d.ts +3 -3
  38. package/ui/tree/TreeSidebar.js +2 -4
  39. package/ui/tree/TreeSidebar.tsx +4 -5
  40. package/ui/tree/index.d.ts +1 -1
  41. package/ui/tree/index.js +1 -1
  42. package/ui/tree/index.ts +1 -1
  43. package/ui/docs/DocumentationHomePage.d.ts +0 -14
  44. package/ui/docs/DocumentationHomePage.js +0 -23
  45. package/ui/docs/DocumentationHomePage.md +0 -34
  46. package/ui/docs/DocumentationHomePage.test.tsx +0 -35
  47. package/ui/docs/DocumentationHomePage.tsx +0 -45
@@ -2,29 +2,69 @@
2
2
  @import "Space.module.css";
3
3
 
4
4
  @layer variants {
5
- /* Gap variants — sets `gap` directly. Used by flex/grid layouts and by Lists/Definitions for the spacing between their items. */
6
- .none {
5
+ /* Named. */
6
+ .gap-none {
7
7
  gap: 0;
8
8
  }
9
- .xxsmall {
9
+ .gap-paragraph {
10
+ gap: var(--space-paragraph);
11
+ }
12
+ .gap-section {
13
+ gap: var(--space-section);
14
+ }
15
+
16
+ /* Scale. */
17
+ .gap-xxsmall {
10
18
  gap: var(--space-xxsmall);
11
19
  }
12
- .xsmall {
20
+ .gap-xsmall {
13
21
  gap: var(--space-xsmall);
14
22
  }
15
- .small {
23
+ .gap-small {
16
24
  gap: var(--space-small);
17
25
  }
18
- .normal {
26
+ .gap-normal {
19
27
  gap: var(--space-normal);
20
28
  }
21
- .large {
29
+ .gap-large {
22
30
  gap: var(--space-large);
23
31
  }
24
- .xlarge {
32
+ .gap-xlarge {
25
33
  gap: var(--space-xlarge);
26
34
  }
27
- .xxlarge {
35
+ .gap-xxlarge {
28
36
  gap: var(--space-xxlarge);
29
37
  }
38
+
39
+ /* Numeric. */
40
+ .gap-1x {
41
+ gap: calc(var(--space-normal) * 1);
42
+ }
43
+ .gap-2x {
44
+ gap: calc(var(--space-normal) * 2);
45
+ }
46
+ .gap-3x {
47
+ gap: calc(var(--space-normal) * 3);
48
+ }
49
+ .gap-4x {
50
+ gap: calc(var(--space-normal) * 4);
51
+ }
52
+ .gap-5x {
53
+ gap: calc(var(--space-normal) * 5);
54
+ }
55
+ .gap-6x {
56
+ gap: calc(var(--space-normal) * 6);
57
+ }
58
+ .gap-7x {
59
+ gap: calc(var(--space-normal) * 7);
60
+ }
61
+ .gap-8x {
62
+ gap: calc(var(--space-normal) * 8);
63
+ }
64
+ .gap-9x {
65
+ gap: calc(var(--space-normal) * 9);
66
+ }
67
+ .gap-10x {
68
+ gap: calc(var(--space-normal) * 10);
69
+ }
30
70
  }
package/ui/style/Gap.tsx CHANGED
@@ -1,12 +1,6 @@
1
1
  import { getModuleClass } from "../util/css.js";
2
2
  import GAP_CSS from "./Gap.module.css";
3
-
4
- /**
5
- * Allowed values for gap spacing for components that support `GapVariants`
6
- *
7
- * @see https://shelving.cc/ui/GapValue
8
- */
9
- export type GapValue = "none" | "xxsmall" | "xsmall" | "small" | "normal" | "large" | "xlarge" | "xxlarge";
3
+ import type { SpaceValue } from "./Space.js";
10
4
 
11
5
  /**
12
6
  * Variant props for the gap between a component's children, e.g. `gap="large"`.
@@ -15,7 +9,7 @@ export type GapValue = "none" | "xxsmall" | "xsmall" | "small" | "normal" | "lar
15
9
  */
16
10
  export interface GapVariants {
17
11
  /** Gap between child elements. */
18
- gap?: GapValue | undefined;
12
+ gap?: SpaceValue | undefined;
19
13
  }
20
14
 
21
15
  /**
@@ -27,5 +21,5 @@ export interface GapVariants {
27
21
  * @see https://shelving.cc/ui/getGapClass
28
22
  */
29
23
  export function getGapClass({ gap }: GapVariants): string | undefined {
30
- return gap && getModuleClass(GAP_CSS, gap);
24
+ return gap && getModuleClass(GAP_CSS, `gap-${gap}`);
31
25
  }
@@ -2,10 +2,18 @@
2
2
  @import "Space.module.css";
3
3
 
4
4
  @layer variants {
5
- /* Inline-padding ("indent") variants — left + right padding to keep content off the edges. */
5
+ /* Named. */
6
6
  .indent-none {
7
7
  padding-inline: 0;
8
8
  }
9
+ .indent-paragraph {
10
+ padding-inline: var(--space-paragraph);
11
+ }
12
+ .indent-section {
13
+ padding-inline: var(--space-section);
14
+ }
15
+
16
+ /* Scale. */
9
17
  .indent-xxsmall {
10
18
  padding-inline: var(--space-xxsmall);
11
19
  }
@@ -28,7 +36,7 @@
28
36
  padding-inline: var(--space-xxlarge);
29
37
  }
30
38
 
31
- /* Numeric inline-padding multiples of `--space-normal` (`1x` … `10x`). */
39
+ /* Numeric. */
32
40
  .indent-1x {
33
41
  padding-inline: calc(var(--space-normal) * 1);
34
42
  }
@@ -1,9 +1,4 @@
1
- /**
2
- * Allowed values for padding for components that support `PaddingVariants`
3
- *
4
- * @see https://shelving.cc/ui/PaddingVariant
5
- */
6
- export type PaddingVariant = "none" | "xxsmall" | "xsmall" | "small" | "normal" | "large" | "xlarge" | "xxlarge" | "1x" | "2x" | "3x" | "4x" | "5x" | "6x" | "7x" | "8x" | "9x" | "10x";
1
+ import type { SpaceValue } from "./Space.js";
7
2
  /**
8
3
  * Variant props for the block-padding (top + bottom) of a component, e.g. `padding="large"`.
9
4
  *
@@ -11,7 +6,7 @@ export type PaddingVariant = "none" | "xxsmall" | "xsmall" | "small" | "normal"
11
6
  */
12
7
  export interface PaddingVariants {
13
8
  /** Block-padding (top + bottom) of the element. */
14
- padding?: PaddingVariant | undefined;
9
+ padding?: SpaceValue | undefined;
15
10
  }
16
11
  /**
17
12
  * Get the block-padding class for a component from its `padding` variant prop.
@@ -2,10 +2,18 @@
2
2
  @import "Space.module.css";
3
3
 
4
4
  @layer variants {
5
- /* Block-padding variants. */
5
+ /* Named. */
6
6
  .padding-none {
7
7
  padding-block: 0;
8
8
  }
9
+ .padding-paragraph {
10
+ padding-block: var(--space-paragraph);
11
+ }
12
+ .padding-section {
13
+ padding-block: var(--space-section);
14
+ }
15
+
16
+ /* Scale. */
9
17
  .padding-xxsmall {
10
18
  padding-block: var(--space-xxsmall);
11
19
  }
@@ -28,7 +36,7 @@
28
36
  padding-block: var(--space-xxlarge);
29
37
  }
30
38
 
31
- /* Numeric block-padding multiples of `--space-normal` (`1x` … `10x`). */
39
+ /* Numeric. */
32
40
  .padding-1x {
33
41
  padding-block: calc(var(--space-normal) * 1);
34
42
  }
@@ -1,30 +1,6 @@
1
1
  import { getModuleClass } from "../util/css.js";
2
2
  import PADDING_CSS from "./Padding.module.css";
3
-
4
- /**
5
- * Allowed values for padding for components that support `PaddingVariants`
6
- *
7
- * @see https://shelving.cc/ui/PaddingVariant
8
- */
9
- export type PaddingVariant =
10
- | "none"
11
- | "xxsmall"
12
- | "xsmall"
13
- | "small"
14
- | "normal"
15
- | "large"
16
- | "xlarge"
17
- | "xxlarge"
18
- | "1x"
19
- | "2x"
20
- | "3x"
21
- | "4x"
22
- | "5x"
23
- | "6x"
24
- | "7x"
25
- | "8x"
26
- | "9x"
27
- | "10x";
3
+ import type { SpaceValue } from "./Space.js";
28
4
 
29
5
  /**
30
6
  * Variant props for the block-padding (top + bottom) of a component, e.g. `padding="large"`.
@@ -33,7 +9,7 @@ export type PaddingVariant =
33
9
  */
34
10
  export interface PaddingVariants {
35
11
  /** Block-padding (top + bottom) of the element. */
36
- padding?: PaddingVariant | undefined;
12
+ padding?: SpaceValue | undefined;
37
13
  }
38
14
 
39
15
  /**
@@ -18,10 +18,18 @@
18
18
  }
19
19
 
20
20
  @layer variants {
21
- /* Block-space variants — opt-in margin-block modifiers for any block-level component. */
21
+ /* Named. */
22
22
  .space-none {
23
23
  margin-block: 0;
24
24
  }
25
+ .space-paragraph {
26
+ margin-block: var(--space-paragraph);
27
+ }
28
+ .space-section {
29
+ margin-block: var(--space-section);
30
+ }
31
+
32
+ /* Scale. */
25
33
  .space-xxsmall {
26
34
  margin-block: var(--space-xxsmall);
27
35
  }
@@ -44,7 +52,7 @@
44
52
  margin-block: var(--space-xxlarge);
45
53
  }
46
54
 
47
- /* Numeric block-space multiples of `--space-normal` (`1x` … `10x`). */
55
+ /* Numeric. */
48
56
  .space-1x {
49
57
  margin-block: calc(var(--space-normal) * 1);
50
58
  }
@@ -75,11 +83,4 @@
75
83
  .space-10x {
76
84
  margin-block: calc(var(--space-normal) * 10);
77
85
  }
78
-
79
- .space-section {
80
- margin-block: var(--space-section);
81
- }
82
- .space-paragraph {
83
- margin-block: var(--space-paragraph);
84
- }
85
86
  }
@@ -11,8 +11,11 @@ export interface TreeAppProps extends PossibleMeta {
11
11
  /** The tree elements to display. */
12
12
  tree: TreeElement;
13
13
  /**
14
- * Additional routes.
14
+ * Override the sidebar for the tree app.
15
+ * @default <TreeSidebar />
15
16
  */
17
+ sidebar?: ReactElement | undefined;
18
+ /** Additional routes. */
16
19
  routes?: Routes | undefined;
17
20
  }
18
21
  /**
@@ -21,7 +24,6 @@ export interface TreeAppProps extends PossibleMeta {
21
24
  * - Wraps `<App>` with error catching and a sidebar layout.
22
25
  * - The sidebar shows a `<TreeSidebar>` (root as a home link + a menu of its children).
23
26
  * - `/` renders the root via `<TreePage>`; `/**` catches every deeper path and feeds the full sub-path into `<TreePage>`.
24
- * - URLs that don't match a tree element fall through to a `<Router>` carrying the built-in `<TreeIndexPage>` (`/all`) plus any extra `routes`.
25
27
  * - Element rendering uses the default mappings on `<TreePage>`, `<TreeMenu>`, `<TreeCards>`.
26
28
  * Override by wrapping with `<TreePageMapping>`, `<TreeMenuMapping>`, or `<TreeCardMapping>`.
27
29
  *
@@ -30,4 +32,4 @@ export interface TreeAppProps extends PossibleMeta {
30
32
  * @example <TreeApp tree={tree} title="Docs" />
31
33
  * @see https://shelving.cc/ui/TreeApp
32
34
  */
33
- export declare function TreeApp({ tree, routes: extraRoutes, ...meta }: TreeAppProps): ReactElement;
35
+ export declare function TreeApp({ tree, routes, sidebar, ...meta }: TreeAppProps): ReactElement;
@@ -2,8 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { App } from "../app/App.js";
3
3
  import { SidebarLayout } from "../layout/SidebarLayout.js";
4
4
  import { PageCatcher } from "../misc/Catcher.js";
5
+ import { Navigation } from "../router/Navigation.js";
5
6
  import { Router } from "../router/Router.js";
6
- import { TREE_INDEX_PATH, TreeIndexPage } from "./TreeIndexPage.js";
7
7
  import { TreeRouter } from "./TreeRouter.js";
8
8
  import { TreeSidebar } from "./TreeSidebar.js";
9
9
  /**
@@ -12,7 +12,6 @@ import { TreeSidebar } from "./TreeSidebar.js";
12
12
  * - Wraps `<App>` with error catching and a sidebar layout.
13
13
  * - The sidebar shows a `<TreeSidebar>` (root as a home link + a menu of its children).
14
14
  * - `/` renders the root via `<TreePage>`; `/**` catches every deeper path and feeds the full sub-path into `<TreePage>`.
15
- * - URLs that don't match a tree element fall through to a `<Router>` carrying the built-in `<TreeIndexPage>` (`/all`) plus any extra `routes`.
16
15
  * - Element rendering uses the default mappings on `<TreePage>`, `<TreeMenu>`, `<TreeCards>`.
17
16
  * Override by wrapping with `<TreePageMapping>`, `<TreeMenuMapping>`, or `<TreeCardMapping>`.
18
17
  *
@@ -21,8 +20,7 @@ import { TreeSidebar } from "./TreeSidebar.js";
21
20
  * @example <TreeApp tree={tree} title="Docs" />
22
21
  * @see https://shelving.cc/ui/TreeApp
23
22
  */
24
- export function TreeApp({ tree, routes: extraRoutes, ...meta }) {
25
- // URLs that don't resolve to a tree element fall through to this router: the built-in index page plus any extra routes.
26
- const fallback = _jsx(Router, { routes: { [TREE_INDEX_PATH]: TreeIndexPage, ...extraRoutes } });
27
- return (_jsx(App, { ...meta, children: _jsx(PageCatcher, { children: _jsx(SidebarLayout, { sidebar: _jsx(TreeSidebar, { tree: tree }), children: _jsx(TreeRouter, { tree: tree, fallback: fallback }) }) }) }));
23
+ export function TreeApp({ tree, routes, sidebar = _jsx(TreeSidebar, { tree: tree }), ...meta }) {
24
+ const fallback = routes && _jsx(Router, { routes: routes });
25
+ return (_jsx(App, { ...meta, children: _jsx(Navigation, { children: _jsx(PageCatcher, { children: _jsx(SidebarLayout, { sidebar: sidebar, children: _jsx(TreeRouter, { tree: tree, fallback: fallback }) }) }) }) }));
28
26
  }
@@ -3,10 +3,10 @@ import type { TreeElement } from "../../util/index.js";
3
3
  import { App } from "../app/App.js";
4
4
  import { SidebarLayout } from "../layout/SidebarLayout.js";
5
5
  import { PageCatcher } from "../misc/Catcher.js";
6
+ import { Navigation } from "../router/Navigation.js";
6
7
  import { Router } from "../router/Router.js";
7
8
  import type { Routes } from "../router/Routes.js";
8
9
  import type { PossibleMeta } from "../util/index.js";
9
- import { TREE_INDEX_PATH, TreeIndexPage } from "./TreeIndexPage.js";
10
10
  import { TreeRouter } from "./TreeRouter.js";
11
11
  import { TreeSidebar } from "./TreeSidebar.js";
12
12
 
@@ -19,8 +19,11 @@ export interface TreeAppProps extends PossibleMeta {
19
19
  /** The tree elements to display. */
20
20
  tree: TreeElement;
21
21
  /**
22
- * Additional routes.
22
+ * Override the sidebar for the tree app.
23
+ * @default <TreeSidebar />
23
24
  */
25
+ sidebar?: ReactElement | undefined;
26
+ /** Additional routes. */
24
27
  routes?: Routes | undefined;
25
28
  }
26
29
 
@@ -30,7 +33,6 @@ export interface TreeAppProps extends PossibleMeta {
30
33
  * - Wraps `<App>` with error catching and a sidebar layout.
31
34
  * - The sidebar shows a `<TreeSidebar>` (root as a home link + a menu of its children).
32
35
  * - `/` renders the root via `<TreePage>`; `/**` catches every deeper path and feeds the full sub-path into `<TreePage>`.
33
- * - URLs that don't match a tree element fall through to a `<Router>` carrying the built-in `<TreeIndexPage>` (`/all`) plus any extra `routes`.
34
36
  * - Element rendering uses the default mappings on `<TreePage>`, `<TreeMenu>`, `<TreeCards>`.
35
37
  * Override by wrapping with `<TreePageMapping>`, `<TreeMenuMapping>`, or `<TreeCardMapping>`.
36
38
  *
@@ -39,16 +41,17 @@ export interface TreeAppProps extends PossibleMeta {
39
41
  * @example <TreeApp tree={tree} title="Docs" />
40
42
  * @see https://shelving.cc/ui/TreeApp
41
43
  */
42
- export function TreeApp({ tree, routes: extraRoutes, ...meta }: TreeAppProps): ReactElement {
43
- // URLs that don't resolve to a tree element fall through to this router: the built-in index page plus any extra routes.
44
- const fallback = <Router routes={{ [TREE_INDEX_PATH]: TreeIndexPage, ...extraRoutes }} />;
44
+ export function TreeApp({ tree, routes, sidebar = <TreeSidebar tree={tree} />, ...meta }: TreeAppProps): ReactElement {
45
+ const fallback = routes && <Router routes={routes} />;
45
46
  return (
46
47
  <App {...meta}>
47
- <PageCatcher>
48
- <SidebarLayout sidebar={<TreeSidebar tree={tree} />}>
49
- <TreeRouter tree={tree} fallback={fallback} />
50
- </SidebarLayout>
51
- </PageCatcher>
48
+ <Navigation>
49
+ <PageCatcher>
50
+ <SidebarLayout sidebar={sidebar}>
51
+ <TreeRouter tree={tree} fallback={fallback} />
52
+ </SidebarLayout>
53
+ </PageCatcher>
54
+ </Navigation>
52
55
  </App>
53
56
  );
54
57
  }
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Block } from "../block/Block.js";
3
+ import { Panel } from "../block/Panel.js";
3
4
  import { Prose } from "../block/Prose.js";
4
- import { Header, Section } from "../block/Section.js";
5
+ import { Section } from "../block/Section.js";
5
6
  import { Title } from "../block/Title.js";
6
7
  import { Page } from "../page/Page.js";
7
8
  import { TreeCards } from "./TreeCards.js";
@@ -18,5 +19,5 @@ import { TreeMarkup } from "./TreeMarkup.js";
18
19
  * @see https://shelving.cc/ui/TreePage
19
20
  */
20
21
  export function TreePage({ title, name, description, content, children }) {
21
- return (_jsx(Page, { title: title ?? name, description: description, children: _jsxs(Block, { indent: "normal", children: [_jsx(Header, { children: _jsx(Title, { children: title ?? name }) }), _jsx(Section, { children: content && (_jsx(Prose, { children: _jsx(TreeMarkup, { children: content }) })) }), _jsx(Section, { children: _jsx(TreeCards, { children: children }) })] }) }));
22
+ return (_jsx(Page, { title: title ?? name, description: description, children: _jsxs(Block, { children: [_jsx(Panel, { children: _jsx(Title, { center: true, children: title ?? name }) }), _jsxs(Block, { indent: "normal", padding: "section", children: [content && (_jsx(Section, { children: _jsx(Prose, { children: _jsx(TreeMarkup, { children: content }) }) })), _jsx(Section, { children: _jsx(TreeCards, { children: children }) })] })] }) }));
22
23
  }
@@ -1,8 +1,9 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { TreeElementProps } from "../../util/tree.js";
3
3
  import { Block } from "../block/Block.js";
4
+ import { Panel } from "../block/Panel.js";
4
5
  import { Prose } from "../block/Prose.js";
5
- import { Header, Section } from "../block/Section.js";
6
+ import { Section } from "../block/Section.js";
6
7
  import { Title } from "../block/Title.js";
7
8
  import { Page } from "../page/Page.js";
8
9
  import { TreeCards } from "./TreeCards.js";
@@ -22,20 +23,22 @@ import { TreeMarkup } from "./TreeMarkup.js";
22
23
  export function TreePage({ title, name, description, content, children }: TreeElementProps): ReactNode {
23
24
  return (
24
25
  <Page title={title ?? name} description={description}>
25
- <Block indent="normal">
26
- <Header>
27
- <Title>{title ?? name}</Title>
28
- </Header>
29
- <Section>
26
+ <Block>
27
+ <Panel>
28
+ <Title center>{title ?? name}</Title>
29
+ </Panel>
30
+ <Block indent="normal" padding="section">
30
31
  {content && (
31
- <Prose>
32
- <TreeMarkup>{content}</TreeMarkup>
33
- </Prose>
32
+ <Section>
33
+ <Prose>
34
+ <TreeMarkup>{content}</TreeMarkup>
35
+ </Prose>
36
+ </Section>
34
37
  )}
35
- </Section>
36
- <Section>
37
- <TreeCards>{children}</TreeCards>
38
- </Section>
38
+ <Section>
39
+ <TreeCards>{children}</TreeCards>
40
+ </Section>
41
+ </Block>
39
42
  </Block>
40
43
  </Page>
41
44
  );
@@ -1,12 +1,13 @@
1
1
  import { type ReactNode } from "react";
2
2
  import type { AbsolutePath } from "../../util/path.js";
3
3
  import { type TreeElement } from "../../util/tree.js";
4
+ import type { OptionalChildProps } from "../util/index.js";
4
5
  /**
5
6
  * Props for the `TreeSidebar` component — the root tree element plus its URL path.
6
7
  *
7
8
  * @see https://shelving.cc/ui/TreeSidebarProps
8
9
  */
9
- export interface TreeSidebarProps {
10
+ export interface TreeSidebarProps extends OptionalChildProps {
10
11
  /** Root element of the tree. */
11
12
  readonly tree: TreeElement;
12
13
  /** URL path of the root — defaults to `/`. Children are rendered with `path + their.name`. */
@@ -15,7 +16,6 @@ export interface TreeSidebarProps {
15
16
  /**
16
17
  * Sidebar built from a tree element, in three sections separated by dividers.
17
18
  *
18
- * - **Top:** a "Home" link to the root and an "All elements" link to the `<TreeIndexPage>` (`/all`).
19
19
  * - **Middle:** a `<TextInput>` search-as-you-type filter.
20
20
  * - **Bottom:** the root's children as a `<TreeMenuMapper>` — swapped for a flat ranked list of results (capped at 20) while the search holds a query.
21
21
  *
@@ -26,4 +26,4 @@ export interface TreeSidebarProps {
26
26
  * @example <TreeSidebar tree={tree} />
27
27
  * @see https://shelving.cc/ui/TreeSidebar
28
28
  */
29
- export declare function TreeSidebar({ tree, path }: TreeSidebarProps): ReactNode;
29
+ export declare function TreeSidebar({ tree, path, children }: TreeSidebarProps): ReactNode;
@@ -5,12 +5,10 @@ import { flattenTree, searchTree } from "../../util/tree.js";
5
5
  import { Divider } from "../block/Divider.js";
6
6
  import { TextInput } from "../form/TextInput.js";
7
7
  import { Menu, MenuItem } from "../menu/Menu.js";
8
- import { TREE_INDEX_PATH } from "./TreeIndexPage.js";
9
8
  import { matchMenuElement, TreeMenuMapper } from "./TreeMenu.js";
10
9
  /**
11
10
  * Sidebar built from a tree element, in three sections separated by dividers.
12
11
  *
13
- * - **Top:** a "Home" link to the root and an "All elements" link to the `<TreeIndexPage>` (`/all`).
14
12
  * - **Middle:** a `<TextInput>` search-as-you-type filter.
15
13
  * - **Bottom:** the root's children as a `<TreeMenuMapper>` — swapped for a flat ranked list of results (capped at 20) while the search holds a query.
16
14
  *
@@ -21,11 +19,11 @@ import { matchMenuElement, TreeMenuMapper } from "./TreeMenu.js";
21
19
  * @example <TreeSidebar tree={tree} />
22
20
  * @see https://shelving.cc/ui/TreeSidebar
23
21
  */
24
- export function TreeSidebar({ tree, path = "/" }) {
22
+ export function TreeSidebar({ tree, path = "/", children }) {
25
23
  const [query, setQuery] = useState("");
26
24
  const trimmed = query.trim();
27
25
  // Flatten once so search results carry a canonical `path` (and a unique `key`) for their links (the sidebar sits outside the router's `<TreeProvider>`).
28
26
  const root = useMemo(() => flattenTree(tree).get("/") ?? tree, [tree]);
29
27
  const results = trimmed ? searchTree(root, trimmed, { limit: 20 }) : null;
30
- return (_jsxs(_Fragment, { children: [_jsxs(Menu, { children: [_jsx(MenuItem, { href: path, children: "Home" }), _jsx(MenuItem, { href: TREE_INDEX_PATH, children: "All elements" })] }), _jsx(Divider, {}), _jsx(TextInput, { name: "search", title: "Search", placeholder: "Search\u2026", value: query, onValue: v => setQuery(v ?? "") }), _jsx(Divider, {}), _jsx(Menu, { children: results ? (results.map(el => (_jsx(MenuItem, { href: el.props.path ?? path, children: el.props.title ?? el.props.name }, el.key)))) : (_jsx(TreeMenuMapper, { path: path, children: filterElements(tree.props.children, matchMenuElement) })) })] }));
28
+ return (_jsxs(_Fragment, { children: [_jsx(Menu, { children: _jsx(MenuItem, { href: path, children: "Home" }) }), children, _jsx(Divider, {}), _jsx(TextInput, { name: "search", title: "Search", placeholder: "Search\u2026", value: query, onValue: v => setQuery(v ?? "") }), _jsx(Divider, {}), _jsx(Menu, { children: results ? (results.map(el => (_jsx(MenuItem, { href: el.props.path ?? path, children: el.props.title ?? el.props.name }, el.key)))) : (_jsx(TreeMenuMapper, { path: path, children: filterElements(tree.props.children, matchMenuElement) })) })] }));
31
29
  }
@@ -5,7 +5,7 @@ import { flattenTree, searchTree, type TreeElement } from "../../util/tree.js";
5
5
  import { Divider } from "../block/Divider.js";
6
6
  import { TextInput } from "../form/TextInput.js";
7
7
  import { Menu, MenuItem } from "../menu/Menu.js";
8
- import { TREE_INDEX_PATH } from "./TreeIndexPage.js";
8
+ import type { OptionalChildProps } from "../util/index.js";
9
9
  import { matchMenuElement, TreeMenuMapper } from "./TreeMenu.js";
10
10
 
11
11
  /**
@@ -13,7 +13,7 @@ import { matchMenuElement, TreeMenuMapper } from "./TreeMenu.js";
13
13
  *
14
14
  * @see https://shelving.cc/ui/TreeSidebarProps
15
15
  */
16
- export interface TreeSidebarProps {
16
+ export interface TreeSidebarProps extends OptionalChildProps {
17
17
  /** Root element of the tree. */
18
18
  readonly tree: TreeElement;
19
19
  /** URL path of the root — defaults to `/`. Children are rendered with `path + their.name`. */
@@ -23,7 +23,6 @@ export interface TreeSidebarProps {
23
23
  /**
24
24
  * Sidebar built from a tree element, in three sections separated by dividers.
25
25
  *
26
- * - **Top:** a "Home" link to the root and an "All elements" link to the `<TreeIndexPage>` (`/all`).
27
26
  * - **Middle:** a `<TextInput>` search-as-you-type filter.
28
27
  * - **Bottom:** the root's children as a `<TreeMenuMapper>` — swapped for a flat ranked list of results (capped at 20) while the search holds a query.
29
28
  *
@@ -34,7 +33,7 @@ export interface TreeSidebarProps {
34
33
  * @example <TreeSidebar tree={tree} />
35
34
  * @see https://shelving.cc/ui/TreeSidebar
36
35
  */
37
- export function TreeSidebar({ tree, path = "/" as AbsolutePath }: TreeSidebarProps): ReactNode {
36
+ export function TreeSidebar({ tree, path = "/", children }: TreeSidebarProps): ReactNode {
38
37
  const [query, setQuery] = useState("");
39
38
  const trimmed = query.trim();
40
39
 
@@ -46,8 +45,8 @@ export function TreeSidebar({ tree, path = "/" as AbsolutePath }: TreeSidebarPro
46
45
  <>
47
46
  <Menu>
48
47
  <MenuItem href={path}>Home</MenuItem>
49
- <MenuItem href={TREE_INDEX_PATH}>All elements</MenuItem>
50
48
  </Menu>
49
+ {children}
51
50
  <Divider />
52
51
  <TextInput name="search" title="Search" placeholder="Search…" value={query} onValue={v => setQuery(v ?? "")} />
53
52
  <Divider />
@@ -1,10 +1,10 @@
1
+ export * from "../docs/DocumentationSearchPage.js";
1
2
  export * from "./TreeApp.js";
2
3
  export * from "./TreeBreadcrumbs.js";
3
4
  export * from "./TreeButton.js";
4
5
  export * from "./TreeCard.js";
5
6
  export * from "./TreeCards.js";
6
7
  export * from "./TreeContext.js";
7
- export * from "./TreeIndexPage.js";
8
8
  export * from "./TreeLink.js";
9
9
  export * from "./TreeMarkup.js";
10
10
  export * from "./TreeMenu.js";
package/ui/tree/index.js CHANGED
@@ -1,10 +1,10 @@
1
+ export * from "../docs/DocumentationSearchPage.js";
1
2
  export * from "./TreeApp.js";
2
3
  export * from "./TreeBreadcrumbs.js";
3
4
  export * from "./TreeButton.js";
4
5
  export * from "./TreeCard.js";
5
6
  export * from "./TreeCards.js";
6
7
  export * from "./TreeContext.js";
7
- export * from "./TreeIndexPage.js";
8
8
  export * from "./TreeLink.js";
9
9
  export * from "./TreeMarkup.js";
10
10
  export * from "./TreeMenu.js";
package/ui/tree/index.ts CHANGED
@@ -1,10 +1,10 @@
1
+ export * from "../docs/DocumentationSearchPage.js";
1
2
  export * from "./TreeApp.js";
2
3
  export * from "./TreeBreadcrumbs.js";
3
4
  export * from "./TreeButton.js";
4
5
  export * from "./TreeCard.js";
5
6
  export * from "./TreeCards.js";
6
7
  export * from "./TreeContext.js";
7
- export * from "./TreeIndexPage.js";
8
8
  export * from "./TreeLink.js";
9
9
  export * from "./TreeMarkup.js";
10
10
  export * from "./TreeMenu.js";
@@ -1,14 +0,0 @@
1
- import type { ReactNode } from "react";
2
- import type { TreeElementProps } from "../../util/tree.js";
3
- /**
4
- * Page renderer for the documentation site's home page — a bold coloured hero panel over the module listing.
5
- * - The whole page sits in a single `color="red"` `<Block>`, so the hero panel, prose, and child cards all pick up the red tint.
6
- * - The hero is a `padding="5x"` `<Panel>` with the package name centred as a `<Title>`.
7
- * - Below the hero it renders any absorbed prose content, then the root's children (the modules) as a stack of cards.
8
- *
9
- * @kind component
10
- * @returns A `<Page>` with a coloured hero panel followed by the module listing.
11
- * @example <DocumentationHomePage {...root.props} />
12
- * @see https://shelving.cc/ui/DocumentationHomePage
13
- */
14
- export declare function DocumentationHomePage({ title, name, description, content, children }: TreeElementProps): ReactNode;
@@ -1,23 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Block } from "../block/Block.js";
3
- import { Panel } from "../block/Panel.js";
4
- import { Prose } from "../block/Prose.js";
5
- import { Section } from "../block/Section.js";
6
- import { Title } from "../block/Title.js";
7
- import { Page } from "../page/Page.js";
8
- import { TreeCards } from "../tree/TreeCards.js";
9
- import { TreeMarkup } from "../tree/TreeMarkup.js";
10
- /**
11
- * Page renderer for the documentation site's home page — a bold coloured hero panel over the module listing.
12
- * - The whole page sits in a single `color="red"` `<Block>`, so the hero panel, prose, and child cards all pick up the red tint.
13
- * - The hero is a `padding="5x"` `<Panel>` with the package name centred as a `<Title>`.
14
- * - Below the hero it renders any absorbed prose content, then the root's children (the modules) as a stack of cards.
15
- *
16
- * @kind component
17
- * @returns A `<Page>` with a coloured hero panel followed by the module listing.
18
- * @example <DocumentationHomePage {...root.props} />
19
- * @see https://shelving.cc/ui/DocumentationHomePage
20
- */
21
- export function DocumentationHomePage({ title, name, description, content, children }) {
22
- return (_jsx(Page, { title: title ?? name, description: description, children: _jsxs(Block, { color: "red", children: [_jsx(Panel, { padding: "5x", children: _jsx(Title, { center: true, children: title ?? name }) }), _jsxs(Block, { indent: "normal", children: [content && (_jsx(Section, { children: _jsx(Prose, { children: _jsx(TreeMarkup, { children: content }) }) })), _jsx(Section, { children: _jsx(TreeCards, { children: children }) })] })] }) }));
23
- }