shelving 1.254.1 → 1.255.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/README.md +1 -1
- package/ui/block/Block.d.ts +2 -1
- package/ui/block/Block.js +2 -1
- package/ui/block/Block.module.css +1 -0
- package/ui/block/Block.tsx +3 -1
- package/ui/block/Panel.d.ts +2 -1
- package/ui/block/Panel.js +2 -1
- package/ui/block/Panel.md +4 -2
- package/ui/block/Panel.module.css +7 -1
- package/ui/block/Panel.tsx +3 -1
- package/ui/block/Section.d.ts +2 -1
- package/ui/block/Section.js +2 -1
- package/ui/block/Section.md +3 -4
- package/ui/block/Section.module.css +3 -7
- package/ui/block/Section.tsx +3 -1
- package/ui/docs/DocumentationHomePage.js +1 -1
- package/ui/docs/DocumentationHomePage.tsx +10 -8
- package/ui/docs/DocumentationPage.js +1 -1
- package/ui/docs/DocumentationPage.tsx +28 -26
- package/ui/form/Form.d.ts +2 -1
- package/ui/form/Form.js +4 -3
- package/ui/form/Form.md +1 -1
- package/ui/form/Form.module.css +1 -0
- package/ui/form/Form.tsx +5 -3
- package/ui/style/Indent.d.ts +24 -0
- package/ui/style/Indent.js +13 -0
- package/ui/style/Indent.module.css +62 -0
- package/ui/style/Indent.tsx +49 -0
- package/ui/style/getSpaceClass.md +2 -2
- package/ui/style/index.d.ts +1 -0
- package/ui/style/index.js +1 -0
- package/ui/style/index.tsx +1 -0
- package/ui/tree/TreeIndexPage.js +2 -1
- package/ui/tree/TreeIndexPage.tsx +27 -24
- package/ui/tree/TreePage.js +2 -1
- package/ui/tree/TreePage.tsx +16 -13
package/package.json
CHANGED
package/ui/README.md
CHANGED
|
@@ -25,7 +25,7 @@ The styling system lives in `style/` and has four moving parts: design tokens, t
|
|
|
25
25
|
|
|
26
26
|
**Cascade layers.** Styles are ordered by `@layer`, lowest to highest priority: `defaults` (`:root` tokens, the tint ladder, body baseline) → `components` (the bulk of the CSS: `.card`, `.button`, …) → `variants` (cross-cutting opt-in modifiers, which always beat components) → `overrides` (top-priority structural fixes like `:first-child` / `:last-child` margin collapses). Unlayered rules beat all layered rules, so a theme should set tokens at `:root` or wrap its rules in `@layer`.
|
|
27
27
|
|
|
28
|
-
**Styling props.** The cross-cutting visual options are props, each backed by a helper in `style/` that maps the prop to a class. Colour and status move the tint anchor — `getColorClass()` and `getStatusClass()`; font size, weight, family, and case, plus text alignment, tint, and wrapping, all come from `getTypographyClass()`; spacing, padding, and gap from `getSpaceClass()`, `getPaddingClass()`, and `getGapClass()`; width constraints from `getWidthClass()`; flex layout from `getFlexClass()`; and opt-in scrolling from `getScrollClass()`. Each helper's page lists its exact prop values and what they set. A component opts into the props it wants by extending the matching `*Props` interfaces and composing the `getXxxClass(props)` calls.
|
|
28
|
+
**Styling props.** The cross-cutting visual options are props, each backed by a helper in `style/` that maps the prop to a class. Colour and status move the tint anchor — `getColorClass()` and `getStatusClass()`; font size, weight, family, and case, plus text alignment, tint, and wrapping, all come from `getTypographyClass()`; spacing, block-padding, inline-padding ("indent"), and gap from `getSpaceClass()`, `getPaddingClass()`, `getIndentClass()`, and `getGapClass()`; width constraints from `getWidthClass()`; flex layout from `getFlexClass()`; and opt-in scrolling from `getScrollClass()`. Each helper's page lists its exact prop values and what they set. A component opts into the props it wants by extending the matching `*Props` interfaces and composing the `getXxxClass(props)` calls.
|
|
29
29
|
|
|
30
30
|
Each painting component also exposes its own theme hooks — a single tint hook (`--card-tint`) to recolour the whole component, plus per-property hooks (`--card-background`, `--card-radius`, …) for surgical overrides. Those are documented in each component's own **Styling** section (see `<Card>` for the precedent).
|
|
31
31
|
|
package/ui/block/Block.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants } from "../style/Color.js";
|
|
3
|
+
import { type IndentVariants } from "../style/Indent.js";
|
|
3
4
|
import { type SpaceVariants } from "../style/Space.js";
|
|
4
5
|
import { type TypographyVariants } from "../style/Typography.js";
|
|
5
6
|
import { type WidthVariants } from "../style/Width.js";
|
|
@@ -15,7 +16,7 @@ export type BlockElement = "div" | "section" | "header" | "footer" | "article" |
|
|
|
15
16
|
*
|
|
16
17
|
* @see https://shelving.cc/ui/BlockProps
|
|
17
18
|
*/
|
|
18
|
-
export interface BlockProps extends ColorVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
19
|
+
export interface BlockProps extends ColorVariants, IndentVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
19
20
|
/**
|
|
20
21
|
* Element this `<Block>` renders as, e.g. "header" to output a "<header>"
|
|
21
22
|
* @default "div"
|
package/ui/block/Block.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { getColorClass } from "../style/Color.js";
|
|
3
|
+
import { getIndentClass } from "../style/Indent.js";
|
|
3
4
|
import { getSpaceClass } from "../style/Space.js";
|
|
4
5
|
import { getTypographyClass } from "../style/Typography.js";
|
|
5
6
|
import { getWidthClass } from "../style/Width.js";
|
|
@@ -18,7 +19,7 @@ const BLOCK_CLASS = getModuleClass(BLOCK_CSS, "block");
|
|
|
18
19
|
*/
|
|
19
20
|
export function getBlockClass(variants) {
|
|
20
21
|
return getClass(BLOCK_CLASS, //
|
|
21
|
-
getColorClass(variants), getSpaceClass(variants), getTypographyClass(variants), getWidthClass(variants));
|
|
22
|
+
getColorClass(variants), getIndentClass(variants), getSpaceClass(variants), getTypographyClass(variants), getWidthClass(variants));
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
25
|
* Plain `<div>` block with block-level spacing.
|
package/ui/block/Block.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants, getColorClass } from "../style/Color.js";
|
|
3
|
+
import { getIndentClass, type IndentVariants } from "../style/Indent.js";
|
|
3
4
|
import { getSpaceClass, type SpaceVariants } from "../style/Space.js";
|
|
4
5
|
import { getTypographyClass, type TypographyVariants } from "../style/Typography.js";
|
|
5
6
|
import { getWidthClass, type WidthVariants } from "../style/Width.js";
|
|
@@ -21,7 +22,7 @@ export type BlockElement = "div" | "section" | "header" | "footer" | "article" |
|
|
|
21
22
|
*
|
|
22
23
|
* @see https://shelving.cc/ui/BlockProps
|
|
23
24
|
*/
|
|
24
|
-
export interface BlockProps extends ColorVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
25
|
+
export interface BlockProps extends ColorVariants, IndentVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
25
26
|
/**
|
|
26
27
|
* Element this `<Block>` renders as, e.g. "header" to output a "<header>"
|
|
27
28
|
* @default "div"
|
|
@@ -43,6 +44,7 @@ export function getBlockClass(variants: BlockProps): string {
|
|
|
43
44
|
return getClass(
|
|
44
45
|
BLOCK_CLASS, //
|
|
45
46
|
getColorClass(variants),
|
|
47
|
+
getIndentClass(variants),
|
|
46
48
|
getSpaceClass(variants),
|
|
47
49
|
getTypographyClass(variants),
|
|
48
50
|
getWidthClass(variants),
|
package/ui/block/Panel.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants } from "../style/Color.js";
|
|
3
|
+
import { type IndentVariants } from "../style/Indent.js";
|
|
3
4
|
import { type PaddingVariants } from "../style/Padding.js";
|
|
4
5
|
import { type StatusVariants } from "../style/Status.js";
|
|
5
6
|
import { type TypographyVariants } from "../style/Typography.js";
|
|
@@ -10,7 +11,7 @@ import type { BlockElement } from "./Block.js";
|
|
|
10
11
|
*
|
|
11
12
|
* @see https://shelving.cc/ui/PanelProps
|
|
12
13
|
*/
|
|
13
|
-
export interface PanelProps extends ColorVariants, PaddingVariants, StatusVariants, TypographyVariants, OptionalChildProps {
|
|
14
|
+
export interface PanelProps extends ColorVariants, IndentVariants, PaddingVariants, StatusVariants, TypographyVariants, OptionalChildProps {
|
|
14
15
|
/**
|
|
15
16
|
* Element this `<Panel>` renders as, e.g. "header" to output a "<header>"
|
|
16
17
|
* @default "section"
|
package/ui/block/Panel.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { getColorClass } from "../style/Color.js";
|
|
3
|
+
import { getIndentClass } from "../style/Indent.js";
|
|
3
4
|
import { getPaddingClass } from "../style/Padding.js";
|
|
4
5
|
import { getStatusClass } from "../style/Status.js";
|
|
5
6
|
import { getTypographyClass } from "../style/Typography.js";
|
|
@@ -21,5 +22,5 @@ const PANEL_CLASS = getModuleClass(PANEL_CSS, "panel");
|
|
|
21
22
|
*/
|
|
22
23
|
export function Panel({ as: Element = "section", children, ...props }) {
|
|
23
24
|
return (_jsx(Element, { className: getClass(PANEL_CLASS, //
|
|
24
|
-
getStatusClass(props), getColorClass(props), getPaddingClass(props), getTypographyClass(props)), children: children }));
|
|
25
|
+
getStatusClass(props), getColorClass(props), getIndentClass(props), getPaddingClass(props), getTypographyClass(props)), children: children }));
|
|
25
26
|
}
|
package/ui/block/Panel.md
CHANGED
|
@@ -5,7 +5,8 @@ A full-width vertical region that paints the current surface colour. Use panels
|
|
|
5
5
|
**Things to know:**
|
|
6
6
|
|
|
7
7
|
- A panel always spans the full width of its container. To constrain the content inside, compose a `<Block>` `width="narrow"` (or `width="wide"`) within it.
|
|
8
|
-
- Block margin is always zero so panels stack flush; control the vertical breathing room with the `padding` variant (`<Panel padding="large">`, `<Panel padding="none">`).
|
|
8
|
+
- Block margin is always zero so panels stack flush; control the vertical breathing room with the `padding` variant (`<Panel padding="large">`, `<Panel padding="none">`).
|
|
9
|
+
- Inline padding ("indent") keeps content off the edges by default. Override it per-property with `--panel-indent`, or change it with the shared `indent` variant (`<Panel indent="large">`, `<Panel indent="none">`).
|
|
9
10
|
- `color=` / `status=` move the tint anchor for the whole panel scope, so the surface, border, and text re-derive together and cascade into nested content.
|
|
10
11
|
- The top and bottom borders are dropped on the first and last panel so the page doesn't gain stray edge lines.
|
|
11
12
|
|
|
@@ -39,5 +40,6 @@ import { Panel, Block, Title, Paragraph } from "shelving/ui";
|
|
|
39
40
|
| `--panel-color` | Text colour | `var(--tint-00)` |
|
|
40
41
|
| `--panel-border` | Top/bottom border shorthand | `var(--panel-stroke) solid var(--tint-80)` |
|
|
41
42
|
| `--panel-stroke` | Border thickness | `var(--stroke-normal)` (2px) |
|
|
43
|
+
| `--panel-indent` | Inline padding (left + right) keeping content off the edges | `var(--space-normal)` (16px) |
|
|
42
44
|
|
|
43
|
-
**Global tokens it reads:** the tint-ladder steps `--tint-00` / `--tint-80` / `--tint-90`, plus `--stroke-normal`. Vertical padding comes from the shared `padding` variant.
|
|
45
|
+
**Global tokens it reads:** the tint-ladder steps `--tint-00` / `--tint-80` / `--tint-90`, plus `--stroke-normal` and `--space-normal`. Vertical padding comes from the shared `padding` variant; inline padding from the shared `indent` variant.
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
@import "../style/Typography.module.css";
|
|
4
4
|
@import "../style/Status.module.css";
|
|
5
5
|
@import "../style/Color.module.css";
|
|
6
|
+
@import "../style/Indent.module.css";
|
|
6
7
|
@import "../style/Padding.module.css";
|
|
8
|
+
@import "../style/Space.module.css";
|
|
7
9
|
|
|
8
10
|
/*
|
|
9
11
|
* Full-width vertical region that paints the current surface. Panels always have zero block-space
|
|
10
12
|
* (they butt up against each other vertically to create stacked page sections). Vertical breathing
|
|
11
13
|
* room comes from the shared `padding` variant (`.large`, `.xxlarge`, etc. from `style/Padding`);
|
|
12
14
|
* with no `padding` the block padding is zero and the inner `<Section>` margins provide the spacing.
|
|
13
|
-
*
|
|
15
|
+
* Inline padding ("indent") keeps content off the edges by default (`--panel-indent`); override it
|
|
16
|
+
* with the shared `indent` variant. For narrower content inside a wide panel, compose a
|
|
17
|
+
* `<Block narrow>` (or `<Block wide>`) inside it.
|
|
14
18
|
*/
|
|
15
19
|
@layer components {
|
|
16
20
|
.panel {
|
|
@@ -20,9 +24,11 @@
|
|
|
20
24
|
/* Box */
|
|
21
25
|
position: relative;
|
|
22
26
|
display: flow-root;
|
|
27
|
+
box-sizing: border-box;
|
|
23
28
|
inline-size: 100%;
|
|
24
29
|
margin-inline: 0;
|
|
25
30
|
margin-block: 0;
|
|
31
|
+
padding-inline: var(--panel-indent, var(--space-normal));
|
|
26
32
|
border-top: var(--panel-border, var(--panel-stroke, var(--stroke-normal)) solid var(--tint-80));
|
|
27
33
|
border-bottom: var(--panel-border, var(--panel-stroke, var(--stroke-normal)) solid var(--tint-80));
|
|
28
34
|
|
package/ui/block/Panel.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants, getColorClass } from "../style/Color.js";
|
|
3
|
+
import { getIndentClass, type IndentVariants } from "../style/Indent.js";
|
|
3
4
|
import { getPaddingClass, type PaddingVariants } from "../style/Padding.js";
|
|
4
5
|
import { getStatusClass, type StatusVariants } from "../style/Status.js";
|
|
5
6
|
import { getTypographyClass, type TypographyVariants } from "../style/Typography.js";
|
|
@@ -15,7 +16,7 @@ const PANEL_CLASS = getModuleClass(PANEL_CSS, "panel");
|
|
|
15
16
|
*
|
|
16
17
|
* @see https://shelving.cc/ui/PanelProps
|
|
17
18
|
*/
|
|
18
|
-
export interface PanelProps extends ColorVariants, PaddingVariants, StatusVariants, TypographyVariants, OptionalChildProps {
|
|
19
|
+
export interface PanelProps extends ColorVariants, IndentVariants, PaddingVariants, StatusVariants, TypographyVariants, OptionalChildProps {
|
|
19
20
|
/**
|
|
20
21
|
* Element this `<Panel>` renders as, e.g. "header" to output a "<header>"
|
|
21
22
|
* @default "section"
|
|
@@ -43,6 +44,7 @@ export function Panel({ as: Element = "section", children, ...props }: PanelProp
|
|
|
43
44
|
PANEL_CLASS, //
|
|
44
45
|
getStatusClass(props),
|
|
45
46
|
getColorClass(props),
|
|
47
|
+
getIndentClass(props),
|
|
46
48
|
getPaddingClass(props),
|
|
47
49
|
getTypographyClass(props),
|
|
48
50
|
)}
|
package/ui/block/Section.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants } from "../style/Color.js";
|
|
3
|
+
import { type IndentVariants } from "../style/Indent.js";
|
|
3
4
|
import { type SpaceVariants } from "../style/Space.js";
|
|
4
5
|
import { type TypographyVariants } from "../style/Typography.js";
|
|
5
6
|
import { type WidthVariants } from "../style/Width.js";
|
|
@@ -10,7 +11,7 @@ import type { BlockElement } from "./Block.js";
|
|
|
10
11
|
*
|
|
11
12
|
* @see https://shelving.cc/ui/SectionProps
|
|
12
13
|
*/
|
|
13
|
-
export interface SectionProps extends ColorVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
14
|
+
export interface SectionProps extends ColorVariants, IndentVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
14
15
|
/**
|
|
15
16
|
* Element this `<Section>` renders as, e.g. "header" to output a "<header>"
|
|
16
17
|
* @default "section"
|
package/ui/block/Section.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { getColorClass } from "../style/Color.js";
|
|
3
|
+
import { getIndentClass } from "../style/Indent.js";
|
|
3
4
|
import { getSpaceClass } from "../style/Space.js";
|
|
4
5
|
import { getTypographyClass } from "../style/Typography.js";
|
|
5
6
|
import { getWidthClass } from "../style/Width.js";
|
|
@@ -18,7 +19,7 @@ const SECTION_CLASS = getModuleClass(SECTION_CSS, "section");
|
|
|
18
19
|
*/
|
|
19
20
|
export function getSectionClass(variants) {
|
|
20
21
|
return getClass(SECTION_CLASS, //
|
|
21
|
-
getColorClass(variants), getSpaceClass(variants), getTypographyClass(variants), getWidthClass(variants));
|
|
22
|
+
getColorClass(variants), getIndentClass(variants), getSpaceClass(variants), getTypographyClass(variants), getWidthClass(variants));
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
25
|
* `<section>` block with section-level spacing.
|
package/ui/block/Section.md
CHANGED
|
@@ -5,8 +5,8 @@ A landmark content region — renders a `<section>` with block-level spacing and
|
|
|
5
5
|
**Things to know:**
|
|
6
6
|
|
|
7
7
|
- Pick the component whose HTML element matches the semantic meaning rather than reaching for a generic `<Block>`. `<Section>` is a `<section>`, `<Figure>` a `<figure>`, and so on.
|
|
8
|
-
- Every section centres its content and caps the line length so
|
|
9
|
-
- Sections default to the `--width-normal` content width, so most of the time you set no width at all. Pass `width="narrow"` / `"wide"` / `"full"` (or `"fit"`) to change that, and the usual `color` / `space` / typography variants to retint and
|
|
8
|
+
- Every section centres its content and caps the line length, but it adds **no inline padding of its own**, so its content can run to the edge of its container. Keep content off the edges by placing the section inside something that already pads — a `<Panel>`, a `<Block indent="normal">`, or a layout that pads its scroll area — or by giving the section its own `indent` variant (`<Section indent="normal">`).
|
|
9
|
+
- Sections default to the `--width-normal` content width, so most of the time you set no width at all. Pass `width="narrow"` / `"wide"` / `"full"` (or `"fit"`) to change that, and the usual `color` / `space` / `indent` / typography variants to retint, respace, and inset.
|
|
10
10
|
- Pair `Figure` with `<Caption>` for a `<figure>` / `<figcaption>` pair.
|
|
11
11
|
|
|
12
12
|
## Usage
|
|
@@ -43,7 +43,6 @@ import { Header, Nav, Footer } from "shelving/ui";
|
|
|
43
43
|
| Variable | Styles | Default |
|
|
44
44
|
|---|---|---|
|
|
45
45
|
| `--section-width` | Content width | `var(--width-normal)` (55rem) |
|
|
46
|
-
| `--section-indent` | Inline gutter kept on each side so text doesn't touch the edges | `var(--space-normal)` (16px) |
|
|
47
46
|
| `--section-space` | Outer block margin (top + bottom) | `var(--space-section)` (2rem) |
|
|
48
47
|
|
|
49
|
-
**Global tokens it reads:** `--space-
|
|
48
|
+
**Global tokens it reads:** `--space-section` and `--width-normal` (the default content width). The `width` variant (`narrow` / `normal` / `wide` / `full` / `fit`) and the `indent` variant (inline padding, via `getIndentClass()`) come from the shared `shelving/ui` styling system.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
@import "../style/layers.css";
|
|
2
2
|
@import "../style/Color.module.css";
|
|
3
|
+
@import "../style/Indent.module.css";
|
|
3
4
|
@import "../style/Typography.module.css";
|
|
4
5
|
@import "../style/Space.module.css";
|
|
5
6
|
@import "../style/Width.module.css";
|
|
@@ -10,15 +11,10 @@
|
|
|
10
11
|
/* Box */
|
|
11
12
|
position: relative;
|
|
12
13
|
display: block;
|
|
13
|
-
box-sizing: border-box;
|
|
14
|
-
max-inline-size:
|
|
14
|
+
box-sizing: border-box; /* Keep the `indent` variant's inline padding inside the width. */
|
|
15
|
+
max-inline-size: 100%;
|
|
15
16
|
inline-size: var(--section-width, var(--width-normal)); /* Default to the normal content width; override with the `width` variant. */
|
|
16
17
|
margin-inline: auto;
|
|
17
18
|
margin-block: var(--section-space, var(--space-section));
|
|
18
|
-
|
|
19
|
-
.prose :where(section, article, aside, nav, header, footer, figure),
|
|
20
|
-
.section {
|
|
21
|
-
max-inline-size: 100%; /* Nested sections can touch the side again */
|
|
22
|
-
}
|
|
23
19
|
}
|
|
24
20
|
}
|
package/ui/block/Section.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { type ColorVariants, getColorClass } from "../style/Color.js";
|
|
3
|
+
import { getIndentClass, type IndentVariants } from "../style/Indent.js";
|
|
3
4
|
import { getSpaceClass, type SpaceVariants } from "../style/Space.js";
|
|
4
5
|
import { getTypographyClass, type TypographyVariants } from "../style/Typography.js";
|
|
5
6
|
import { getWidthClass, type WidthVariants } from "../style/Width.js";
|
|
@@ -15,7 +16,7 @@ const SECTION_CLASS = getModuleClass(SECTION_CSS, "section");
|
|
|
15
16
|
*
|
|
16
17
|
* @see https://shelving.cc/ui/SectionProps
|
|
17
18
|
*/
|
|
18
|
-
export interface SectionProps extends ColorVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
19
|
+
export interface SectionProps extends ColorVariants, IndentVariants, SpaceVariants, TypographyVariants, WidthVariants, OptionalChildProps {
|
|
19
20
|
/**
|
|
20
21
|
* Element this `<Section>` renders as, e.g. "header" to output a "<header>"
|
|
21
22
|
* @default "section"
|
|
@@ -37,6 +38,7 @@ export function getSectionClass(variants: SectionProps): string {
|
|
|
37
38
|
return getClass(
|
|
38
39
|
SECTION_CLASS, //
|
|
39
40
|
getColorClass(variants),
|
|
41
|
+
getIndentClass(variants),
|
|
40
42
|
getSpaceClass(variants),
|
|
41
43
|
getTypographyClass(variants),
|
|
42
44
|
getWidthClass(variants),
|
|
@@ -19,5 +19,5 @@ import { TreeMarkup } from "../tree/TreeMarkup.js";
|
|
|
19
19
|
* @see https://shelving.cc/ui/DocumentationHomePage
|
|
20
20
|
*/
|
|
21
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 }) }), content && (_jsx(Section, { children: _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, { 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
23
|
}
|
|
@@ -27,16 +27,18 @@ export function DocumentationHomePage({ title, name, description, content, child
|
|
|
27
27
|
<Panel padding="5x">
|
|
28
28
|
<Title center>{title ?? name}</Title>
|
|
29
29
|
</Panel>
|
|
30
|
-
|
|
30
|
+
<Block indent="normal">
|
|
31
|
+
{content && (
|
|
32
|
+
<Section>
|
|
33
|
+
<Prose>
|
|
34
|
+
<TreeMarkup>{content}</TreeMarkup>
|
|
35
|
+
</Prose>
|
|
36
|
+
</Section>
|
|
37
|
+
)}
|
|
31
38
|
<Section>
|
|
32
|
-
<
|
|
33
|
-
<TreeMarkup>{content}</TreeMarkup>
|
|
34
|
-
</Prose>
|
|
39
|
+
<TreeCards>{children}</TreeCards>
|
|
35
40
|
</Section>
|
|
36
|
-
|
|
37
|
-
<Section>
|
|
38
|
-
<TreeCards>{children}</TreeCards>
|
|
39
|
-
</Section>
|
|
41
|
+
</Block>
|
|
40
42
|
</Block>
|
|
41
43
|
</Page>
|
|
42
44
|
);
|
|
@@ -69,5 +69,5 @@ function DocumentationChildren({ elements }) {
|
|
|
69
69
|
* @see https://shelving.cc/ui/DocumentationPage
|
|
70
70
|
*/
|
|
71
71
|
export function DocumentationPage({ title, name, kind = "unknown", description, content, signatures, params, returns, throws, properties, types, examples, children, ...props }) {
|
|
72
|
-
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 || 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)))] })), _jsx(DocumentationChildren, { elements: children })] }) }));
|
|
72
|
+
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", 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)))] })), _jsx(DocumentationChildren, { elements: children })] })] }) }));
|
|
73
73
|
}
|
|
@@ -110,32 +110,34 @@ export function DocumentationPage({
|
|
|
110
110
|
<DocumentationButtons {...props} />
|
|
111
111
|
</Header>
|
|
112
112
|
</Panel>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
<
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
113
|
+
<Block indent="normal">
|
|
114
|
+
{signatures?.length || params?.length || returns?.length || throws?.length || properties?.length || types?.length ? (
|
|
115
|
+
<Section>
|
|
116
|
+
<DocumentationSignatures signatures={signatures} />
|
|
117
|
+
<DocumentationParams params={params} />
|
|
118
|
+
<DocumentationReturns returns={returns} />
|
|
119
|
+
<DocumentationThrows throws={throws} />
|
|
120
|
+
<DocumentationProperties properties={properties} />
|
|
121
|
+
<DocumentationReferences types={types} />
|
|
122
|
+
</Section>
|
|
123
|
+
) : null}
|
|
124
|
+
{content && (
|
|
125
|
+
<Section>
|
|
126
|
+
<Prose>
|
|
127
|
+
<TreeMarkup>{content}</TreeMarkup>
|
|
128
|
+
</Prose>
|
|
129
|
+
</Section>
|
|
130
|
+
)}
|
|
131
|
+
{examples?.length && (
|
|
132
|
+
<Section>
|
|
133
|
+
<Heading>Examples</Heading>
|
|
134
|
+
{examples.map(({ description }) => (
|
|
135
|
+
<Preformatted key={description}>{description}</Preformatted>
|
|
136
|
+
))}
|
|
137
|
+
</Section>
|
|
138
|
+
)}
|
|
139
|
+
<DocumentationChildren elements={children} />
|
|
140
|
+
</Block>
|
|
139
141
|
</Block>
|
|
140
142
|
</Page>
|
|
141
143
|
);
|
package/ui/form/Form.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { DataSchema } from "../../schema/DataSchema.js";
|
|
|
3
3
|
import type { Data, PartialData } from "../../util/data.js";
|
|
4
4
|
import type { ImmutableDictionary } from "../../util/dictionary.js";
|
|
5
5
|
import type { Arguments } from "../../util/function.js";
|
|
6
|
+
import { type IndentVariants } from "../style/Indent.js";
|
|
6
7
|
import { type NoticeCallback } from "../util/notice.js";
|
|
7
8
|
import type { OptionalChildProps } from "../util/props.js";
|
|
8
9
|
import { FormStore } from "./FormStore.js";
|
|
@@ -19,7 +20,7 @@ export type FormCallback<T extends Data> = (data: T, event: SubmitEvent<HTMLForm
|
|
|
19
20
|
*
|
|
20
21
|
* @see https://shelving.cc/ui/FormProps
|
|
21
22
|
*/
|
|
22
|
-
export interface FormProps<T extends Data> extends OptionalChildProps {
|
|
23
|
+
export interface FormProps<T extends Data> extends IndentVariants, OptionalChildProps {
|
|
23
24
|
/** Schema for the form. */
|
|
24
25
|
schema: DataSchema<T>;
|
|
25
26
|
/** Initial data for the form. */
|
package/ui/form/Form.js
CHANGED
|
@@ -2,7 +2,8 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { useInstance } from "../../react/useInstance.js";
|
|
3
3
|
import { useStore } from "../../react/useStore.js";
|
|
4
4
|
import { isAsync } from "../../util/async.js";
|
|
5
|
-
import {
|
|
5
|
+
import { getIndentClass } from "../style/Indent.js";
|
|
6
|
+
import { getClass, getModuleClass } from "../util/css.js";
|
|
6
7
|
import { notifySuccess, notifyThrown } from "../util/notice.js";
|
|
7
8
|
import FORM_CSS from "./Form.module.css";
|
|
8
9
|
import { FormContext } from "./FormContext.js";
|
|
@@ -11,7 +12,7 @@ import { FormFooter } from "./FormFooter.js";
|
|
|
11
12
|
import { FormStore } from "./FormStore.js";
|
|
12
13
|
const FORM_CLASS = getModuleClass(FORM_CSS, "form");
|
|
13
14
|
const FORM_FIELDSET_CLASS = getModuleClass(FORM_CSS, "fieldset");
|
|
14
|
-
export function Form({ schema, data: initialData, onSubmit, submit, messages, children = (_jsxs(_Fragment, { children: [_jsx(FormFields, {}), _jsx(FormFooter, { submit: submit })] })), }) {
|
|
15
|
+
export function Form({ schema, data: initialData, onSubmit, submit, messages, children = (_jsxs(_Fragment, { children: [_jsx(FormFields, {}), _jsx(FormFooter, { submit: submit })] })), ...props }) {
|
|
15
16
|
// Create a form store instance and subscribe to changes in it.
|
|
16
17
|
const store = useStore(useInstance(FormStore, schema, initialData, messages));
|
|
17
18
|
const busy = useStore(store.busy).value;
|
|
@@ -26,7 +27,7 @@ export function Form({ schema, data: initialData, onSubmit, submit, messages, ch
|
|
|
26
27
|
// Close the parent dialog on successful submit.
|
|
27
28
|
if (result)
|
|
28
29
|
dialog?.close();
|
|
29
|
-
}, className: FORM_CLASS, noValidate: true, children: _jsx("fieldset", { className: FORM_FIELDSET_CLASS, disabled: busy, children: _jsx(FormContext, { value: store, children: children }) }) }, store.key));
|
|
30
|
+
}, className: getClass(FORM_CLASS, getIndentClass(props)), noValidate: true, children: _jsx("fieldset", { className: FORM_FIELDSET_CLASS, disabled: busy, children: _jsx(FormContext, { value: store, children: children }) }) }, store.key));
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Run a form submit callback and publish success/error notices based on its return or thrown value.
|
package/ui/form/Form.md
CHANGED
|
@@ -105,4 +105,4 @@ When an `onSubmit` callback returns a non-empty `ReactNode`, `Form` dispatches i
|
|
|
105
105
|
|---|---|---|
|
|
106
106
|
| `--form-space` | Outer block margin (top + bottom) | `var(--space-paragraph)` (16px) |
|
|
107
107
|
|
|
108
|
-
**Global tokens it reads:** `--space-paragraph`.
|
|
108
|
+
**Global tokens it reads:** `--space-paragraph`. The `indent` variant (inline padding, via `getIndentClass()`) comes from the shared `shelving/ui` styling system — set `<Form indent="normal">` to inset the form's content from the edges.
|
package/ui/form/Form.module.css
CHANGED
package/ui/form/Form.tsx
CHANGED
|
@@ -6,7 +6,8 @@ import { isAsync } from "../../util/async.js";
|
|
|
6
6
|
import type { Data, PartialData } from "../../util/data.js";
|
|
7
7
|
import type { ImmutableDictionary } from "../../util/dictionary.js";
|
|
8
8
|
import type { Arguments } from "../../util/function.js";
|
|
9
|
-
import {
|
|
9
|
+
import { getIndentClass, type IndentVariants } from "../style/Indent.js";
|
|
10
|
+
import { getClass, getModuleClass } from "../util/css.js";
|
|
10
11
|
import { type NoticeCallback, notifySuccess, notifyThrown } from "../util/notice.js";
|
|
11
12
|
import type { OptionalChildProps } from "../util/props.js";
|
|
12
13
|
import FORM_CSS from "./Form.module.css";
|
|
@@ -35,7 +36,7 @@ export type FormCallback<T extends Data> = (
|
|
|
35
36
|
*
|
|
36
37
|
* @see https://shelving.cc/ui/FormProps
|
|
37
38
|
*/
|
|
38
|
-
export interface FormProps<T extends Data> extends OptionalChildProps {
|
|
39
|
+
export interface FormProps<T extends Data> extends IndentVariants, OptionalChildProps {
|
|
39
40
|
/** Schema for the form. */
|
|
40
41
|
schema: DataSchema<T>;
|
|
41
42
|
/** Initial data for the form. */
|
|
@@ -71,6 +72,7 @@ export function Form({
|
|
|
71
72
|
<FormFooter submit={submit} />
|
|
72
73
|
</>
|
|
73
74
|
),
|
|
75
|
+
...props
|
|
74
76
|
}: FormProps<Data>): ReactElement {
|
|
75
77
|
// Create a form store instance and subscribe to changes in it.
|
|
76
78
|
const store = useStore(useInstance(FormStore, schema, initialData, messages));
|
|
@@ -94,7 +96,7 @@ export function Form({
|
|
|
94
96
|
// Close the parent dialog on successful submit.
|
|
95
97
|
if (result) dialog?.close();
|
|
96
98
|
}}
|
|
97
|
-
className={FORM_CLASS}
|
|
99
|
+
className={getClass(FORM_CLASS, getIndentClass(props))}
|
|
98
100
|
noValidate={true}
|
|
99
101
|
>
|
|
100
102
|
<fieldset className={FORM_FIELDSET_CLASS} disabled={busy}>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allowed values for inline-padding ("indent") for components that support `IndentVariants`
|
|
3
|
+
*
|
|
4
|
+
* @see https://shelving.cc/ui/IndentVariant
|
|
5
|
+
*/
|
|
6
|
+
export type IndentVariant = "none" | "xxsmall" | "xsmall" | "small" | "normal" | "large" | "xlarge" | "xxlarge" | "1x" | "2x" | "3x" | "4x" | "5x" | "6x" | "7x" | "8x" | "9x" | "10x";
|
|
7
|
+
/**
|
|
8
|
+
* Variant props for the inline-padding ("indent", left + right) of a component, e.g. `indent="normal"`.
|
|
9
|
+
*
|
|
10
|
+
* @see https://shelving.cc/ui/IndentVariants
|
|
11
|
+
*/
|
|
12
|
+
export interface IndentVariants {
|
|
13
|
+
/** Inline-padding (left + right) of the element, keeping its content off the edges. */
|
|
14
|
+
indent?: IndentVariant | undefined;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the inline-padding ("indent") class for a component from its `indent` variant prop.
|
|
18
|
+
*
|
|
19
|
+
* @param variants
|
|
20
|
+
* @returns The indent class string, or `undefined` when no `indent` is set.
|
|
21
|
+
* @example getIndentClass({ indent: "normal" }) // "indent-normal"
|
|
22
|
+
* @see https://shelving.cc/ui/getIndentClass
|
|
23
|
+
*/
|
|
24
|
+
export declare function getIndentClass({ indent }: IndentVariants): string | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getModuleClass } from "../util/css.js";
|
|
2
|
+
import INDENT_CSS from "./Indent.module.css";
|
|
3
|
+
/**
|
|
4
|
+
* Get the inline-padding ("indent") class for a component from its `indent` variant prop.
|
|
5
|
+
*
|
|
6
|
+
* @param variants
|
|
7
|
+
* @returns The indent class string, or `undefined` when no `indent` is set.
|
|
8
|
+
* @example getIndentClass({ indent: "normal" }) // "indent-normal"
|
|
9
|
+
* @see https://shelving.cc/ui/getIndentClass
|
|
10
|
+
*/
|
|
11
|
+
export function getIndentClass({ indent }) {
|
|
12
|
+
return indent && getModuleClass(INDENT_CSS, `indent-${indent}`);
|
|
13
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
@import "layers.css";
|
|
2
|
+
@import "Space.module.css";
|
|
3
|
+
|
|
4
|
+
@layer variants {
|
|
5
|
+
/* Inline-padding ("indent") variants — left + right padding to keep content off the edges. */
|
|
6
|
+
.indent-none {
|
|
7
|
+
padding-inline: 0;
|
|
8
|
+
}
|
|
9
|
+
.indent-xxsmall {
|
|
10
|
+
padding-inline: var(--space-xxsmall);
|
|
11
|
+
}
|
|
12
|
+
.indent-xsmall {
|
|
13
|
+
padding-inline: var(--space-xsmall);
|
|
14
|
+
}
|
|
15
|
+
.indent-small {
|
|
16
|
+
padding-inline: var(--space-small);
|
|
17
|
+
}
|
|
18
|
+
.indent-normal {
|
|
19
|
+
padding-inline: var(--space-normal);
|
|
20
|
+
}
|
|
21
|
+
.indent-large {
|
|
22
|
+
padding-inline: var(--space-large);
|
|
23
|
+
}
|
|
24
|
+
.indent-xlarge {
|
|
25
|
+
padding-inline: var(--space-xlarge);
|
|
26
|
+
}
|
|
27
|
+
.indent-xxlarge {
|
|
28
|
+
padding-inline: var(--space-xxlarge);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Numeric inline-padding multiples of `--space-normal` (`1x` … `10x`). */
|
|
32
|
+
.indent-1x {
|
|
33
|
+
padding-inline: calc(var(--space-normal) * 1);
|
|
34
|
+
}
|
|
35
|
+
.indent-2x {
|
|
36
|
+
padding-inline: calc(var(--space-normal) * 2);
|
|
37
|
+
}
|
|
38
|
+
.indent-3x {
|
|
39
|
+
padding-inline: calc(var(--space-normal) * 3);
|
|
40
|
+
}
|
|
41
|
+
.indent-4x {
|
|
42
|
+
padding-inline: calc(var(--space-normal) * 4);
|
|
43
|
+
}
|
|
44
|
+
.indent-5x {
|
|
45
|
+
padding-inline: calc(var(--space-normal) * 5);
|
|
46
|
+
}
|
|
47
|
+
.indent-6x {
|
|
48
|
+
padding-inline: calc(var(--space-normal) * 6);
|
|
49
|
+
}
|
|
50
|
+
.indent-7x {
|
|
51
|
+
padding-inline: calc(var(--space-normal) * 7);
|
|
52
|
+
}
|
|
53
|
+
.indent-8x {
|
|
54
|
+
padding-inline: calc(var(--space-normal) * 8);
|
|
55
|
+
}
|
|
56
|
+
.indent-9x {
|
|
57
|
+
padding-inline: calc(var(--space-normal) * 9);
|
|
58
|
+
}
|
|
59
|
+
.indent-10x {
|
|
60
|
+
padding-inline: calc(var(--space-normal) * 10);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getModuleClass } from "../util/css.js";
|
|
2
|
+
import INDENT_CSS from "./Indent.module.css";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Allowed values for inline-padding ("indent") for components that support `IndentVariants`
|
|
6
|
+
*
|
|
7
|
+
* @see https://shelving.cc/ui/IndentVariant
|
|
8
|
+
*/
|
|
9
|
+
export type IndentVariant =
|
|
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";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Variant props for the inline-padding ("indent", left + right) of a component, e.g. `indent="normal"`.
|
|
31
|
+
*
|
|
32
|
+
* @see https://shelving.cc/ui/IndentVariants
|
|
33
|
+
*/
|
|
34
|
+
export interface IndentVariants {
|
|
35
|
+
/** Inline-padding (left + right) of the element, keeping its content off the edges. */
|
|
36
|
+
indent?: IndentVariant | undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the inline-padding ("indent") class for a component from its `indent` variant prop.
|
|
41
|
+
*
|
|
42
|
+
* @param variants
|
|
43
|
+
* @returns The indent class string, or `undefined` when no `indent` is set.
|
|
44
|
+
* @example getIndentClass({ indent: "normal" }) // "indent-normal"
|
|
45
|
+
* @see https://shelving.cc/ui/getIndentClass
|
|
46
|
+
*/
|
|
47
|
+
export function getIndentClass({ indent }: IndentVariants): string | undefined {
|
|
48
|
+
return indent && getModuleClass(INDENT_CSS, `indent-${indent}`);
|
|
49
|
+
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The `space` variant prop sets a block-level element's `margin-block` (top + bottom) from the spacing scale — `<Section space="large">`, `<Paragraph space="none">`. It's an **override** for one-off spacing; for an app-wide change, retune the spacing variables below in a theme file.
|
|
4
4
|
|
|
5
|
-
`getSpaceClass({ space })` maps the prop to a margin class (e.g. `space="large"` → `large`). The same scale also backs `getPaddingClass()` and `getGapClass()`, so all
|
|
5
|
+
`getSpaceClass({ space })` maps the prop to a margin class (e.g. `space="large"` → `large`). The same scale also backs `getPaddingClass()` (block padding), `getIndentClass()` (inline padding), and `getGapClass()`, so they all move together when you change `--space-normal`.
|
|
6
6
|
|
|
7
|
-
Alongside the named scale, `space` and `
|
|
7
|
+
Alongside the named scale, `space`, `padding`, and `indent` also accept numeric multiples of `--space-normal` — `1x` … `10x` (e.g. `padding="5x"` → `calc(var(--space-normal) * 5)`) — for larger one-off blocks like hero panels.
|
|
8
8
|
|
|
9
9
|
## Theme variables
|
|
10
10
|
|
package/ui/style/index.d.ts
CHANGED
package/ui/style/index.js
CHANGED
package/ui/style/index.tsx
CHANGED
package/ui/tree/TreeIndexPage.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
3
|
import { toggleArrayItem } from "../../util/array.js";
|
|
4
4
|
import { searchTree } from "../../util/tree.js";
|
|
5
|
+
import { Block } from "../block/Block.js";
|
|
5
6
|
import { Header, Section } from "../block/Section.js";
|
|
6
7
|
import { Title } from "../block/Title.js";
|
|
7
8
|
import { DocumentationKind } from "../docs/DocumentationKind.js";
|
|
@@ -51,5 +52,5 @@ export function TreeIndexPage() {
|
|
|
51
52
|
const filter = selected.length ? { kind: selected } : undefined;
|
|
52
53
|
// Each element's `key` is its unique canonical path (stamped by `flattenTree()`), so this flat cross-tree listing reconciles correctly.
|
|
53
54
|
const cards = root ? searchTree(root, trimmed, { limit: trimmed ? 20 : INDEX_LIMIT, filter }) : [];
|
|
54
|
-
return (
|
|
55
|
+
return (_jsx(Page, { title: INDEX_TITLE, description: INDEX_DESCRIPTION, children: _jsxs(Block, { indent: "normal", children: [_jsx(Header, { children: _jsx(Title, { children: INDEX_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(Section, { children: _jsx(TreeCards, { children: cards }) })] }) }));
|
|
55
56
|
}
|
|
@@ -4,6 +4,7 @@ import type { AbsolutePath } from "../../util/path.js";
|
|
|
4
4
|
import type { Query } from "../../util/query.js";
|
|
5
5
|
import type { DocumentationElementProps } from "../../util/tree.js";
|
|
6
6
|
import { searchTree } from "../../util/tree.js";
|
|
7
|
+
import { Block } from "../block/Block.js";
|
|
7
8
|
import { Header, Section } from "../block/Section.js";
|
|
8
9
|
import { Title } from "../block/Title.js";
|
|
9
10
|
import { DocumentationKind } from "../docs/DocumentationKind.js";
|
|
@@ -64,30 +65,32 @@ export function TreeIndexPage(): ReactNode {
|
|
|
64
65
|
|
|
65
66
|
return (
|
|
66
67
|
<Page title={INDEX_TITLE} description={INDEX_DESCRIPTION}>
|
|
67
|
-
<
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
|
|
68
|
+
<Block indent="normal">
|
|
69
|
+
<Header>
|
|
70
|
+
<Title>{INDEX_TITLE}</Title>
|
|
71
|
+
</Header>
|
|
72
|
+
<Section>
|
|
73
|
+
<TextInput name="search" title="Search" placeholder="Search…" value={query} onValue={v => setQuery(v ?? "")} />
|
|
74
|
+
{!!kinds.length && (
|
|
75
|
+
<Row left wrap>
|
|
76
|
+
{kinds.map(kind => (
|
|
77
|
+
<CheckboxInput
|
|
78
|
+
key={kind}
|
|
79
|
+
name={kind}
|
|
80
|
+
width="fit"
|
|
81
|
+
value={selected.includes(kind)}
|
|
82
|
+
onValue={() => setSelected(s => toggleArrayItem(s, kind))}
|
|
83
|
+
>
|
|
84
|
+
<DocumentationKind kind={kind} />
|
|
85
|
+
</CheckboxInput>
|
|
86
|
+
))}
|
|
87
|
+
</Row>
|
|
88
|
+
)}
|
|
89
|
+
</Section>
|
|
90
|
+
<Section>
|
|
91
|
+
<TreeCards>{cards}</TreeCards>
|
|
92
|
+
</Section>
|
|
93
|
+
</Block>
|
|
91
94
|
</Page>
|
|
92
95
|
);
|
|
93
96
|
}
|
package/ui/tree/TreePage.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Block } from "../block/Block.js";
|
|
2
3
|
import { Prose } from "../block/Prose.js";
|
|
3
4
|
import { Header, Section } from "../block/Section.js";
|
|
4
5
|
import { Title } from "../block/Title.js";
|
|
@@ -17,5 +18,5 @@ import { TreeMarkup } from "./TreeMarkup.js";
|
|
|
17
18
|
* @see https://shelving.cc/ui/TreePage
|
|
18
19
|
*/
|
|
19
20
|
export function TreePage({ title, name, description, content, children }) {
|
|
20
|
-
return (
|
|
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 }) })] }) }));
|
|
21
22
|
}
|
package/ui/tree/TreePage.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { TreeElementProps } from "../../util/tree.js";
|
|
3
|
+
import { Block } from "../block/Block.js";
|
|
3
4
|
import { Prose } from "../block/Prose.js";
|
|
4
5
|
import { Header, Section } from "../block/Section.js";
|
|
5
6
|
import { Title } from "../block/Title.js";
|
|
@@ -21,19 +22,21 @@ import { TreeMarkup } from "./TreeMarkup.js";
|
|
|
21
22
|
export function TreePage({ title, name, description, content, children }: TreeElementProps): ReactNode {
|
|
22
23
|
return (
|
|
23
24
|
<Page title={title ?? name} description={description}>
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
25
|
+
<Block indent="normal">
|
|
26
|
+
<Header>
|
|
27
|
+
<Title>{title ?? name}</Title>
|
|
28
|
+
</Header>
|
|
29
|
+
<Section>
|
|
30
|
+
{content && (
|
|
31
|
+
<Prose>
|
|
32
|
+
<TreeMarkup>{content}</TreeMarkup>
|
|
33
|
+
</Prose>
|
|
34
|
+
)}
|
|
35
|
+
</Section>
|
|
36
|
+
<Section>
|
|
37
|
+
<TreeCards>{children}</TreeCards>
|
|
38
|
+
</Section>
|
|
39
|
+
</Block>
|
|
37
40
|
</Page>
|
|
38
41
|
);
|
|
39
42
|
}
|