shelving 1.215.0 → 1.215.2

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.
@@ -6,7 +6,8 @@ import { FileExtractor } from "./FileExtractor.js";
6
6
  * - Extracts exported, public, non-`_`-prefixed declarations as `tree-documentation` children.
7
7
  * - Overloaded declarations sharing a name are merged into a single `tree-documentation` with multiple `signatures`.
8
8
  * - Top-of-file JSDoc comment becomes the file's `content`.
9
- * - Does not set `title` TS source files have no confident title source. The renderer falls back to `name`.
9
+ * - Sets `title` on every `tree-documentation` child `name()` for functions and methods, `name` for other kinds.
10
+ * - The file element itself has no `title` — a TS source file has no confident title source; renderers fall back to `name`.
10
11
  */
11
12
  export declare class TypescriptExtractor extends FileExtractor {
12
13
  extractProps(name: string, text: string): Partial<FileElementProps> & {
@@ -7,7 +7,8 @@ import { FileExtractor } from "./FileExtractor.js";
7
7
  * - Extracts exported, public, non-`_`-prefixed declarations as `tree-documentation` children.
8
8
  * - Overloaded declarations sharing a name are merged into a single `tree-documentation` with multiple `signatures`.
9
9
  * - Top-of-file JSDoc comment becomes the file's `content`.
10
- * - Does not set `title` TS source files have no confident title source. The renderer falls back to `name`.
10
+ * - Sets `title` on every `tree-documentation` child `name()` for functions and methods, `name` for other kinds.
11
+ * - The file element itself has no `title` — a TS source file has no confident title source; renderers fall back to `name`.
11
12
  */
12
13
  export class TypescriptExtractor extends FileExtractor {
13
14
  extractProps(name, text) {
@@ -22,8 +23,8 @@ export class TypescriptExtractor extends FileExtractor {
22
23
  const existing = byKey.get(element.key);
23
24
  byKey.set(element.key, existing ? _mergeOverloads(existing, element) : element);
24
25
  }
25
- // No `title` — TS source files don't have a confident title source (the filename isn't one).
26
- // The renderer falls back to `name` when displaying.
26
+ // The file element itself gets no `title` — a TS source file has no confident title source (the filename isn't one),
27
+ // so renderers fall back to `name`. The `tree-documentation` children each carry their own `title`.
27
28
  return { name, content, children: Array.from(byKey.values()) };
28
29
  }
29
30
  }
@@ -96,6 +97,8 @@ function _extractStatement(statement, source) {
96
97
  key: requireSlug(name),
97
98
  props: {
98
99
  name,
100
+ // Functions read as callable with `()`; other kinds use the bare name.
101
+ title: kind === "function" ? `${name}()` : name,
99
102
  kind,
100
103
  content: _buildJSDocContent(jsDoc?.description, jsDoc?.unhandled),
101
104
  signatures: signature ? [signature] : undefined,
@@ -230,7 +233,7 @@ function _getClassMembers(statement, source) {
230
233
  members.push({
231
234
  type: "tree-documentation",
232
235
  key,
233
- props: { name, content, kind: "method", signatures: [signature] },
236
+ props: { name, title: `${name}()`, content, kind: "method", signatures: [signature] },
234
237
  });
235
238
  }
236
239
  }
@@ -239,7 +242,7 @@ function _getClassMembers(statement, source) {
239
242
  members.push({
240
243
  type: "tree-documentation",
241
244
  key: requireSlug(name),
242
- props: { name, content, kind: "property", signatures: type ? [type] : undefined },
245
+ props: { name, title: name, content, kind: "property", signatures: type ? [type] : undefined },
243
246
  });
244
247
  }
245
248
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shelving",
3
- "version": "1.215.0",
3
+ "version": "1.215.2",
4
4
  "author": "Dave Houlbrooke <dave@shax.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -2,8 +2,8 @@ import type { ReactNode } from "react";
2
2
  import type { DirectoryElementProps } from "../../util/element.js";
3
3
  import { type AbsolutePath } from "../../util/path.js";
4
4
  interface DirectoryCardProps extends DirectoryElementProps {
5
- path?: AbsolutePath | undefined;
5
+ path: AbsolutePath;
6
6
  }
7
7
  /** Card renderer for a `tree-directory` element. */
8
- export declare function DirectoryCard({ path, title, name, content }: DirectoryCardProps): ReactNode;
8
+ export declare function DirectoryCard({ path, name, title, content }: DirectoryCardProps): ReactNode;
9
9
  export {};
@@ -5,7 +5,7 @@ import { Heading } from "../block/Heading.js";
5
5
  import { Prose } from "../block/Prose.js";
6
6
  import { Markup } from "../misc/Markup.js";
7
7
  /** Card renderer for a `tree-directory` element. */
8
- export function DirectoryCard({ path = "/", title, name, content }) {
8
+ export function DirectoryCard({ path, name, title, content }) {
9
9
  const href = joinPath(path, name);
10
10
  return (_jsxs(Card, { href: href, children: [_jsx(Heading, { level: "3", children: title ?? name }), content && (_jsx(Prose, { children: _jsx(Markup, { children: content }) }))] }));
11
11
  }
@@ -7,11 +7,11 @@ import { Prose } from "../block/Prose.js";
7
7
  import { Markup } from "../misc/Markup.js";
8
8
 
9
9
  interface DirectoryCardProps extends DirectoryElementProps {
10
- path?: AbsolutePath | undefined;
10
+ path: AbsolutePath;
11
11
  }
12
12
 
13
13
  /** Card renderer for a `tree-directory` element. */
14
- export function DirectoryCard({ path = "/", title, name, content }: DirectoryCardProps): ReactNode {
14
+ export function DirectoryCard({ path, name, title, content }: DirectoryCardProps): ReactNode {
15
15
  const href = joinPath(path, name);
16
16
  return (
17
17
  <Card href={href}>
@@ -1,9 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Prose } from "../block/Prose.js";
3
3
  import { Markup } from "../misc/Markup.js";
4
+ import { requireMeta } from "../misc/MetaContext.js";
4
5
  import { Page } from "../page/Page.js";
5
6
  import { TreeCards } from "../tree/TreeCards.js";
6
7
  /** Page renderer for a `tree-directory` element — shows title, content, and child cards. */
7
8
  export function DirectoryPage({ title, name, description, content, children }) {
8
- return (_jsxs(Page, { title: title ?? name, description: description, children: [content && (_jsx(Prose, { children: _jsx(Markup, { children: content }) })), _jsx(TreeCards, { children: children })] }));
9
+ const { url } = requireMeta();
10
+ const path = url?.pathname ?? "/";
11
+ return (_jsxs(Page, { title: title ?? name, description: description, children: [content && (_jsx(Prose, { children: _jsx(Markup, { children: content }) })), _jsx(TreeCards, { path: path, children: children })] }));
9
12
  }
@@ -2,11 +2,14 @@ import type { ReactNode } from "react";
2
2
  import type { DirectoryElementProps } from "../../util/element.js";
3
3
  import { Prose } from "../block/Prose.js";
4
4
  import { Markup } from "../misc/Markup.js";
5
+ import { requireMeta } from "../misc/MetaContext.js";
5
6
  import { Page } from "../page/Page.js";
6
7
  import { TreeCards } from "../tree/TreeCards.js";
7
8
 
8
9
  /** Page renderer for a `tree-directory` element — shows title, content, and child cards. */
9
10
  export function DirectoryPage({ title, name, description, content, children }: DirectoryElementProps): ReactNode {
11
+ const { url } = requireMeta();
12
+ const path = url?.pathname ?? "/";
10
13
  return (
11
14
  <Page title={title ?? name} description={description}>
12
15
  {content && (
@@ -14,7 +17,7 @@ export function DirectoryPage({ title, name, description, content, children }: D
14
17
  <Markup>{content}</Markup>
15
18
  </Prose>
16
19
  )}
17
- <TreeCards>{children}</TreeCards>
20
+ <TreeCards path={path}>{children}</TreeCards>
18
21
  </Page>
19
22
  );
20
23
  }
@@ -2,7 +2,7 @@ import type { ReactNode } from "react";
2
2
  import type { DocumentationElementProps } from "../../util/element.js";
3
3
  import { type AbsolutePath } from "../../util/path.js";
4
4
  interface DocumentationCardProps extends DocumentationElementProps {
5
- path?: AbsolutePath | undefined;
5
+ path: AbsolutePath;
6
6
  }
7
7
  /** Card renderer for a `tree-documentation` element. */
8
8
  export declare function DocumentationCard({ path, title, name, kind, content, signatures }: DocumentationCardProps): ReactNode;
@@ -9,7 +9,7 @@ import { Code } from "../inline/Code.js";
9
9
  import { Markup } from "../misc/Markup.js";
10
10
  import { DocumentationKind } from "./DocumentationKind.js";
11
11
  /** Card renderer for a `tree-documentation` element. */
12
- export function DocumentationCard({ path = "/", title, name, kind, content, signatures }) {
12
+ export function DocumentationCard({ path, title, name, kind, content, signatures }) {
13
13
  const href = joinPath(path, name);
14
14
  return (_jsxs(Card, { href: href, children: [_jsx(Heading, { level: "3", children: _jsxs(Flex, { left: true, children: [_jsx(Code, { children: title ?? name }), kind && _jsx(DocumentationKind, { kind: kind })] }) }), signatures?.map(sig => (_jsx(Preformatted, { children: sig }, sig))), content && (_jsx(Prose, { children: _jsx(Markup, { children: content }) }))] }));
15
15
  }
@@ -11,11 +11,11 @@ import { Markup } from "../misc/Markup.js";
11
11
  import { DocumentationKind } from "./DocumentationKind.js";
12
12
 
13
13
  interface DocumentationCardProps extends DocumentationElementProps {
14
- path?: AbsolutePath | undefined;
14
+ path: AbsolutePath;
15
15
  }
16
16
 
17
17
  /** Card renderer for a `tree-documentation` element. */
18
- export function DocumentationCard({ path = "/", title, name, kind, content, signatures }: DocumentationCardProps): ReactNode {
18
+ export function DocumentationCard({ path, title, name, kind, content, signatures }: DocumentationCardProps): ReactNode {
19
19
  const href = joinPath(path, name);
20
20
  return (
21
21
  <Card href={href}>
@@ -2,8 +2,8 @@ import type { ReactNode } from "react";
2
2
  import type { FileElementProps } from "../../util/element.js";
3
3
  import { type AbsolutePath } from "../../util/path.js";
4
4
  interface FileCardProps extends FileElementProps {
5
- path?: AbsolutePath | undefined;
5
+ path: AbsolutePath;
6
6
  }
7
7
  /** Card renderer for a `tree-file` element. */
8
- export declare function FileCard({ path, title, name, content }: FileCardProps): ReactNode;
8
+ export declare function FileCard({ path, name, title, content }: FileCardProps): ReactNode;
9
9
  export {};
@@ -5,7 +5,7 @@ import { Heading } from "../block/Heading.js";
5
5
  import { Prose } from "../block/Prose.js";
6
6
  import { Markup } from "../misc/Markup.js";
7
7
  /** Card renderer for a `tree-file` element. */
8
- export function FileCard({ path = "/", title, name, content }) {
8
+ export function FileCard({ path, name, title, content }) {
9
9
  const href = joinPath(path, name);
10
10
  return (_jsxs(Card, { href: href, children: [_jsx(Heading, { level: "3", children: title ?? name }), content && (_jsx(Prose, { children: _jsx(Markup, { children: content }) }))] }));
11
11
  }
@@ -7,11 +7,11 @@ import { Prose } from "../block/Prose.js";
7
7
  import { Markup } from "../misc/Markup.js";
8
8
 
9
9
  interface FileCardProps extends FileElementProps {
10
- path?: AbsolutePath | undefined;
10
+ path: AbsolutePath;
11
11
  }
12
12
 
13
13
  /** Card renderer for a `tree-file` element. */
14
- export function FileCard({ path = "/", title, name, content }: FileCardProps): ReactNode {
14
+ export function FileCard({ path, name, title, content }: FileCardProps): ReactNode {
15
15
  const href = joinPath(path, name);
16
16
  return (
17
17
  <Card href={href}>
@@ -7,6 +7,6 @@ import { TreeCards } from "../tree/TreeCards.js";
7
7
  /** Page renderer for a `tree-file` element — shows title, content, and child code symbols. */
8
8
  export function FilePage({ title, name, description, content, children }) {
9
9
  const { url } = requireMeta();
10
- const path = (url?.pathname ?? "/");
10
+ const path = url?.pathname ?? "/";
11
11
  return (_jsxs(Page, { title: title ?? name, description: description, children: [content && (_jsx(Prose, { children: _jsx(Markup, { children: content }) })), _jsx(TreeCards, { path: path, children: children })] }));
12
12
  }
@@ -1,6 +1,5 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { FileElementProps } from "../../util/element.js";
3
- import type { AbsolutePath } from "../../util/path.js";
4
3
  import { Prose } from "../block/Prose.js";
5
4
  import { Markup } from "../misc/Markup.js";
6
5
  import { requireMeta } from "../misc/MetaContext.js";
@@ -10,7 +9,7 @@ import { TreeCards } from "../tree/TreeCards.js";
10
9
  /** Page renderer for a `tree-file` element — shows title, content, and child code symbols. */
11
10
  export function FilePage({ title, name, description, content, children }: FileElementProps): ReactNode {
12
11
  const { url } = requireMeta();
13
- const path = (url?.pathname ?? "/") as AbsolutePath;
12
+ const path = url?.pathname ?? "/";
14
13
  return (
15
14
  <Page title={title ?? name} description={description}>
16
15
  {content && (
@@ -3,21 +3,21 @@ import { type TreeElements } from "../../util/element.js";
3
3
  import type { AbsolutePath } from "../../util/path.js";
4
4
  /** Extras threaded through `TreeCardMapper` to every card — currently just the parent URL path. */
5
5
  export interface TreeCardExtras {
6
- /** URL path of the parent element. Each card computes its own path as `path + mapped.key`. Defaults to `/`. */
7
- readonly path?: AbsolutePath | undefined;
6
+ /** URL path of the parent element. Each card computes its own path as `path + mapped.name`. Defaults to `/`. */
7
+ readonly path: AbsolutePath;
8
8
  }
9
9
  /** Mapping + Mapper pair for tree cards — wrap children in `<TreeCardMapping>` to override. */
10
10
  export declare const TreeCardMapping: import("react").FunctionComponent<import("../misc/Mapper.js").MappingProps<TreeCardExtras>>, TreeCardMapper: import("react").FunctionComponent<import("../misc/Mapper.js").MapperProps<TreeCardExtras>>;
11
11
  export interface TreeCardsProps {
12
12
  /** The children to render as cards. */
13
13
  readonly children?: TreeElements;
14
- /** URL path of the parent element. Each card appends its own key to compute its href. */
14
+ /** URL path of the parent element. Each card appends its own name to compute its href. */
15
15
  readonly path?: AbsolutePath | undefined;
16
16
  }
17
17
  /**
18
18
  * Render a list of tree elements as a stack of cards.
19
19
  * - Each element is dispatched via `<TreeCardMapper>` to its registered renderer.
20
- * - `path` is threaded through to each card so it can compute its href as `path + key`.
20
+ * - `path` is threaded through to each card so it can compute its href as `path + name`.
21
21
  * - To override the renderer for a specific element type, wrap in `<TreeCardMapping mapping={…}>`.
22
22
  */
23
- export declare function TreeCards({ children, path }: TreeCardsProps): ReactNode;
23
+ export declare function TreeCards({ path, children }: TreeCardsProps): ReactNode;
@@ -13,9 +13,9 @@ export const [TreeCardMapping, TreeCardMapper] = createMapper({
13
13
  /**
14
14
  * Render a list of tree elements as a stack of cards.
15
15
  * - Each element is dispatched via `<TreeCardMapper>` to its registered renderer.
16
- * - `path` is threaded through to each card so it can compute its href as `path + key`.
16
+ * - `path` is threaded through to each card so it can compute its href as `path + name`.
17
17
  * - To override the renderer for a specific element type, wrap in `<TreeCardMapping mapping={…}>`.
18
18
  */
19
- export function TreeCards({ children, path }) {
19
+ export function TreeCards({ path = "/", children }) {
20
20
  return _jsx(TreeCardMapper, { path: path, children: walkElements(children) });
21
21
  }
@@ -8,8 +8,8 @@ import { createMapper } from "../misc/Mapper.js";
8
8
 
9
9
  /** Extras threaded through `TreeCardMapper` to every card — currently just the parent URL path. */
10
10
  export interface TreeCardExtras {
11
- /** URL path of the parent element. Each card computes its own path as `path + mapped.key`. Defaults to `/`. */
12
- readonly path?: AbsolutePath | undefined;
11
+ /** URL path of the parent element. Each card computes its own path as `path + mapped.name`. Defaults to `/`. */
12
+ readonly path: AbsolutePath;
13
13
  }
14
14
 
15
15
  /** Mapping + Mapper pair for tree cards — wrap children in `<TreeCardMapping>` to override. */
@@ -22,16 +22,16 @@ export const [TreeCardMapping, TreeCardMapper] = createMapper<TreeCardExtras>({
22
22
  export interface TreeCardsProps {
23
23
  /** The children to render as cards. */
24
24
  readonly children?: TreeElements;
25
- /** URL path of the parent element. Each card appends its own key to compute its href. */
25
+ /** URL path of the parent element. Each card appends its own name to compute its href. */
26
26
  readonly path?: AbsolutePath | undefined;
27
27
  }
28
28
 
29
29
  /**
30
30
  * Render a list of tree elements as a stack of cards.
31
31
  * - Each element is dispatched via `<TreeCardMapper>` to its registered renderer.
32
- * - `path` is threaded through to each card so it can compute its href as `path + key`.
32
+ * - `path` is threaded through to each card so it can compute its href as `path + name`.
33
33
  * - To override the renderer for a specific element type, wrap in `<TreeCardMapping mapping={…}>`.
34
34
  */
35
- export function TreeCards({ children, path }: TreeCardsProps): ReactNode {
35
+ export function TreeCards({ path = "/", children }: TreeCardsProps): ReactNode {
36
36
  return <TreeCardMapper path={path}>{walkElements(children)}</TreeCardMapper>;
37
37
  }
@@ -9,7 +9,7 @@ export declare const MENU_QUERY: Query<{
9
9
  /** Extras threaded through `TreeMenuMapper` to every menu item — the parent's URL path. */
10
10
  interface TreeMenuExtras {
11
11
  /** URL path of the parent element. Each item appends its own `name` to compute its own path. Defaults to `/`. */
12
- readonly path?: AbsolutePath | undefined;
12
+ readonly path: AbsolutePath;
13
13
  }
14
14
  /**
15
15
  * Default menu item renderer for any `tree-*` element.
@@ -31,5 +31,5 @@ export interface TreeMenuProps {
31
31
  * - To customise renderers for specific types, wrap in `<TreeMenuMapping mapping={…}>`.
32
32
  * - Only directories and files appear — code symbols are kept off the navigation.
33
33
  */
34
- export declare function TreeMenu({ tree, path }: TreeMenuProps): ReactNode;
34
+ export declare function TreeMenu({ path, tree }: TreeMenuProps): ReactNode;
35
35
  export {};
@@ -27,6 +27,6 @@ export const [TreeMenuMapping, TreeMenuMapper] = createMapper({
27
27
  * - To customise renderers for specific types, wrap in `<TreeMenuMapping mapping={…}>`.
28
28
  * - Only directories and files appear — code symbols are kept off the navigation.
29
29
  */
30
- export function TreeMenu({ tree, path = "/" }) {
30
+ export function TreeMenu({ path = "/", tree }) {
31
31
  return (_jsx(Menu, { children: _jsx(TreeMenuMapper, { path: path, children: queryElements(tree.props.children, MENU_QUERY) }) }));
32
32
  }
@@ -12,7 +12,7 @@ export const MENU_QUERY: Query<{ type: string }> = { type: ["tree-directory", "t
12
12
  /** Extras threaded through `TreeMenuMapper` to every menu item — the parent's URL path. */
13
13
  interface TreeMenuExtras {
14
14
  /** URL path of the parent element. Each item appends its own `name` to compute its own path. Defaults to `/`. */
15
- readonly path?: AbsolutePath | undefined;
15
+ readonly path: AbsolutePath;
16
16
  }
17
17
 
18
18
  /**
@@ -54,7 +54,7 @@ export interface TreeMenuProps {
54
54
  * - To customise renderers for specific types, wrap in `<TreeMenuMapping mapping={…}>`.
55
55
  * - Only directories and files appear — code symbols are kept off the navigation.
56
56
  */
57
- export function TreeMenu({ tree, path = "/" }: TreeMenuProps): ReactNode {
57
+ export function TreeMenu({ path = "/", tree }: TreeMenuProps): ReactNode {
58
58
  return (
59
59
  <Menu>
60
60
  <TreeMenuMapper path={path}>{queryElements(tree.props.children, MENU_QUERY)}</TreeMenuMapper>