shelving 1.236.2 → 1.237.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/extract/IndexExtractor.js +9 -2
- package/extract/MergingExtractor.d.ts +3 -1
- package/extract/MergingExtractor.js +41 -3
- package/extract/TypescriptExtractor.d.ts +1 -0
- package/extract/TypescriptExtractor.js +12 -2
- package/package.json +1 -1
- package/ui/README.md +19 -274
- package/ui/app/App.d.ts +1 -0
- package/ui/app/App.js +1 -0
- package/ui/app/App.md +58 -0
- package/ui/app/App.tsx +1 -0
- package/ui/block/Card.d.ts +1 -0
- package/ui/block/Card.js +1 -0
- package/ui/block/Card.md +85 -0
- package/ui/block/Card.tsx +1 -0
- package/ui/block/Heading.d.ts +1 -0
- package/ui/block/Heading.js +1 -0
- package/ui/block/Heading.md +70 -0
- package/ui/block/Heading.tsx +1 -0
- package/ui/block/List.d.ts +1 -0
- package/ui/block/List.js +1 -0
- package/ui/block/List.md +51 -0
- package/ui/block/List.tsx +1 -0
- package/ui/block/Panel.d.ts +1 -0
- package/ui/block/Panel.js +1 -0
- package/ui/block/Panel.md +50 -0
- package/ui/block/Panel.tsx +1 -0
- package/ui/block/Paragraph.d.ts +1 -0
- package/ui/block/Paragraph.js +1 -0
- package/ui/block/Paragraph.md +48 -0
- package/ui/block/Paragraph.tsx +1 -0
- package/ui/block/Prose.d.ts +1 -0
- package/ui/block/Prose.js +1 -0
- package/ui/block/Prose.md +49 -0
- package/ui/block/Prose.tsx +1 -0
- package/ui/block/Section.d.ts +6 -0
- package/ui/block/Section.js +6 -0
- package/ui/block/Section.md +56 -0
- package/ui/block/Section.tsx +6 -0
- package/ui/block/Subheading.d.ts +1 -0
- package/ui/block/Subheading.js +1 -0
- package/ui/block/Subheading.md +58 -0
- package/ui/block/Subheading.tsx +1 -0
- package/ui/block/Table.d.ts +1 -0
- package/ui/block/Table.js +1 -0
- package/ui/block/Table.md +54 -0
- package/ui/block/Table.tsx +1 -0
- package/ui/block/Title.d.ts +1 -0
- package/ui/block/Title.js +1 -0
- package/ui/block/Title.md +57 -0
- package/ui/block/Title.tsx +1 -0
- package/ui/dialog/Dialog.d.ts +1 -0
- package/ui/dialog/Dialog.js +1 -0
- package/ui/dialog/Dialog.md +73 -0
- package/ui/dialog/Dialog.tsx +1 -0
- package/ui/dialog/Modal.d.ts +1 -0
- package/ui/dialog/Modal.js +1 -0
- package/ui/dialog/Modal.md +40 -0
- package/ui/dialog/Modal.tsx +1 -0
- package/ui/docs/DocumentationButtons.d.ts +2 -0
- package/ui/docs/DocumentationButtons.js +2 -0
- package/ui/docs/DocumentationButtons.md +38 -0
- package/ui/docs/DocumentationButtons.tsx +2 -0
- package/ui/docs/DocumentationCard.d.ts +1 -0
- package/ui/docs/DocumentationCard.js +1 -0
- package/ui/docs/DocumentationCard.md +35 -0
- package/ui/docs/DocumentationCard.tsx +1 -0
- package/ui/docs/DocumentationKind.d.ts +1 -1
- package/ui/docs/DocumentationKind.js +9 -4
- package/ui/docs/DocumentationKind.tsx +10 -5
- package/ui/docs/DocumentationPage.d.ts +1 -0
- package/ui/docs/DocumentationPage.js +2 -0
- package/ui/docs/DocumentationPage.md +46 -0
- package/ui/docs/DocumentationPage.tsx +2 -0
- package/ui/form/Button.d.ts +1 -0
- package/ui/form/Button.js +1 -0
- package/ui/form/Button.md +88 -0
- package/ui/form/Button.tsx +1 -0
- package/ui/form/Field.d.ts +6 -1
- package/ui/form/Field.js +6 -1
- package/ui/form/Field.md +59 -0
- package/ui/form/Field.tsx +6 -1
- package/ui/form/Form.d.ts +1 -0
- package/ui/form/Form.md +118 -0
- package/ui/form/Form.tsx +1 -0
- package/ui/form/FormStore.md +47 -0
- package/ui/form/SchemaInput.d.ts +1 -0
- package/ui/form/SchemaInput.md +64 -0
- package/ui/form/SchemaInput.tsx +1 -0
- package/ui/inline/Code.d.ts +1 -0
- package/ui/inline/Code.js +1 -0
- package/ui/inline/Code.md +58 -0
- package/ui/inline/Code.tsx +1 -0
- package/ui/inline/Link.d.ts +1 -0
- package/ui/inline/Link.js +1 -0
- package/ui/inline/Link.md +47 -0
- package/ui/inline/Link.tsx +1 -0
- package/ui/inline/Mark.d.ts +1 -0
- package/ui/inline/Mark.js +1 -0
- package/ui/inline/Mark.md +40 -0
- package/ui/inline/Mark.tsx +1 -0
- package/ui/inline/Strong.d.ts +1 -0
- package/ui/inline/Strong.js +1 -0
- package/ui/inline/Strong.md +34 -0
- package/ui/inline/Strong.tsx +1 -0
- package/ui/layout/CenteredLayout.d.ts +1 -0
- package/ui/layout/CenteredLayout.js +1 -0
- package/ui/layout/CenteredLayout.md +38 -0
- package/ui/layout/CenteredLayout.tsx +1 -0
- package/ui/layout/SidebarLayout.d.ts +1 -0
- package/ui/layout/SidebarLayout.js +1 -0
- package/ui/layout/SidebarLayout.md +65 -0
- package/ui/layout/SidebarLayout.tsx +1 -0
- package/ui/menu/Menu.d.ts +2 -0
- package/ui/menu/Menu.js +2 -0
- package/ui/menu/Menu.md +51 -0
- package/ui/menu/Menu.tsx +2 -0
- package/ui/menu/MenuItem.md +54 -0
- package/ui/misc/Catcher.d.ts +1 -0
- package/ui/misc/Catcher.js +1 -0
- package/ui/misc/Catcher.md +41 -0
- package/ui/misc/Catcher.tsx +1 -0
- package/ui/misc/Loading.d.ts +1 -0
- package/ui/misc/Loading.js +1 -0
- package/ui/misc/Loading.md +28 -0
- package/ui/misc/Loading.tsx +1 -0
- package/ui/misc/Mapper.md +40 -0
- package/ui/misc/Markup.d.ts +1 -0
- package/ui/misc/Markup.js +1 -0
- package/ui/misc/Markup.md +34 -0
- package/ui/misc/Markup.tsx +1 -0
- package/ui/misc/StatusIcon.d.ts +1 -0
- package/ui/misc/StatusIcon.js +1 -0
- package/ui/misc/StatusIcon.md +25 -0
- package/ui/misc/StatusIcon.tsx +1 -0
- package/ui/misc/Tag.d.ts +1 -0
- package/ui/misc/Tag.js +1 -0
- package/ui/misc/Tag.md +47 -0
- package/ui/misc/Tag.tsx +1 -0
- package/ui/notice/Notice.d.ts +1 -0
- package/ui/notice/Notice.js +1 -0
- package/ui/notice/Notice.md +53 -0
- package/ui/notice/Notice.tsx +1 -0
- package/ui/notice/Notices.d.ts +1 -0
- package/ui/notice/Notices.js +1 -0
- package/ui/notice/Notices.md +59 -0
- package/ui/notice/Notices.tsx +1 -0
- package/ui/page/HTML.d.ts +1 -0
- package/ui/page/HTML.js +1 -0
- package/ui/page/HTML.md +36 -0
- package/ui/page/HTML.tsx +1 -0
- package/ui/page/Head.d.ts +1 -0
- package/ui/page/Head.js +1 -0
- package/ui/page/Head.md +26 -0
- package/ui/page/Head.tsx +1 -0
- package/ui/page/Page.d.ts +1 -0
- package/ui/page/Page.js +1 -0
- package/ui/page/Page.md +42 -0
- package/ui/page/Page.tsx +1 -0
- package/ui/router/Navigation.d.ts +1 -0
- package/ui/router/Navigation.js +1 -0
- package/ui/router/Navigation.md +41 -0
- package/ui/router/Navigation.tsx +1 -0
- package/ui/router/NavigationStore.md +34 -0
- package/ui/router/Router.d.ts +1 -0
- package/ui/router/Router.js +1 -0
- package/ui/router/Router.md +143 -0
- package/ui/router/Router.tsx +1 -0
- package/ui/style/TINT_CLASS.md +55 -0
- package/ui/transition/CollapseTransition.d.ts +1 -0
- package/ui/transition/CollapseTransition.js +1 -0
- package/ui/transition/CollapseTransition.md +34 -0
- package/ui/transition/CollapseTransition.tsx +1 -0
- package/ui/transition/FadeTransition.d.ts +1 -0
- package/ui/transition/FadeTransition.js +1 -0
- package/ui/transition/FadeTransition.md +36 -0
- package/ui/transition/FadeTransition.tsx +1 -0
- package/ui/transition/HorizontalTransition.d.ts +1 -0
- package/ui/transition/HorizontalTransition.js +1 -0
- package/ui/transition/HorizontalTransition.md +44 -0
- package/ui/transition/HorizontalTransition.tsx +1 -0
- package/ui/transition/Transition.d.ts +1 -0
- package/ui/transition/Transition.js +1 -0
- package/ui/transition/Transition.md +70 -0
- package/ui/transition/Transition.tsx +1 -0
- package/ui/transition/VerticalTransition.d.ts +1 -0
- package/ui/transition/VerticalTransition.js +1 -0
- package/ui/transition/VerticalTransition.md +34 -0
- package/ui/transition/VerticalTransition.tsx +1 -0
- package/ui/tree/TreeApp.d.ts +1 -0
- package/ui/tree/TreeApp.js +1 -0
- package/ui/tree/TreeApp.md +59 -0
- package/ui/tree/TreeApp.tsx +1 -0
- package/ui/tree/TreeMenu.d.ts +1 -0
- package/ui/tree/TreeMenu.js +1 -0
- package/ui/tree/TreeMenu.md +35 -0
- package/ui/tree/TreeMenu.tsx +1 -0
- package/ui/tree/TreeSidebar.d.ts +1 -0
- package/ui/tree/TreeSidebar.js +1 -0
- package/ui/tree/TreeSidebar.md +24 -0
- package/ui/tree/TreeSidebar.tsx +1 -0
- package/ui/util/getClass.md +55 -0
- package/ui/util/notify.md +50 -0
- package/ui/util/requireContext.md +24 -0
- package/ui/app/README.md +0 -32
- package/ui/block/README.md +0 -144
- package/ui/dialog/README.md +0 -80
- package/ui/docs/README.md +0 -71
- package/ui/form/README.md +0 -165
- package/ui/inline/README.md +0 -86
- package/ui/layout/README.md +0 -71
- package/ui/menu/README.md +0 -33
- package/ui/misc/README.md +0 -121
- package/ui/notice/README.md +0 -94
- package/ui/page/README.md +0 -56
- package/ui/router/README.md +0 -186
- package/ui/transition/README.md +0 -80
- package/ui/tree/README.md +0 -78
- package/ui/util/README.md +0 -153
package/ui/page/HTML.tsx
CHANGED
|
@@ -14,6 +14,7 @@ export interface HTMLProps extends PossibleMeta, ChildProps {}
|
|
|
14
14
|
* Render the full `<html>` document shell wrapping `<head>` and `<body>`.
|
|
15
15
|
* - Emits the literal `<head>` with `<base>` and other shell-level metadata; per-page hoistable elements (title, meta, links, stylesheets, scripts) come from `<Head>` inside `<Page>` and are hoisted into this `<head>` by React 19.
|
|
16
16
|
*
|
|
17
|
+
* @kind component
|
|
17
18
|
* @param children The document body content.
|
|
18
19
|
* @param meta Initial meta (language/root/app) merged with the surrounding `<Meta>` context.
|
|
19
20
|
* @returns The `<html>` document element.
|
package/ui/page/Head.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { type ReactElement } from "react";
|
|
|
5
5
|
* - Does not render `<base>` (not hoistable — that lives in `<Head>` in the `<HTML>` shell component).
|
|
6
6
|
* - Updates `window.history` to match the page URL.
|
|
7
7
|
*
|
|
8
|
+
* @kind component
|
|
8
9
|
* @returns The hoistable head elements derived from the current `<Meta>` context.
|
|
9
10
|
* @example <Page title="Settings"><Head />…</Page>
|
|
10
11
|
* @see https://dhoulb.github.io/shelving/ui/page/Head/Head
|
package/ui/page/Head.js
CHANGED
|
@@ -11,6 +11,7 @@ const R_HTTP_EQUIV = /^[A-Z][a-zA-Z0-9]*(-[A-Z][a-zA-Z0-9]*)*$/;
|
|
|
11
11
|
* - Does not render `<base>` (not hoistable — that lives in `<Head>` in the `<HTML>` shell component).
|
|
12
12
|
* - Updates `window.history` to match the page URL.
|
|
13
13
|
*
|
|
14
|
+
* @kind component
|
|
14
15
|
* @returns The hoistable head elements derived from the current `<Meta>` context.
|
|
15
16
|
* @example <Page title="Settings"><Head />…</Page>
|
|
16
17
|
* @see https://dhoulb.github.io/shelving/ui/page/Head/Head
|
package/ui/page/Head.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Head
|
|
2
|
+
|
|
3
|
+
Low-level emitter of hoistable head metadata from the current `Meta` context. It outputs `<title>`, `<meta>`, `<link>`, stylesheet, module, and script elements inline, and React 19 hoists each one into the document `<head>`. It also syncs `window.history` to the page URL.
|
|
4
|
+
|
|
5
|
+
**Things to know:**
|
|
6
|
+
|
|
7
|
+
- [`Page`](/ui/Page) renders `<Head>` automatically — you rarely need it directly.
|
|
8
|
+
- It does not render `<base>`, which is not hoistable; that lives in the [`HTML`](/ui/HTML) shell.
|
|
9
|
+
- The composed title combines the page `title` with the app name from context.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Page, Head } from "shelving/ui";
|
|
15
|
+
|
|
16
|
+
// <Page> already renders <Head> for you; render it directly only for custom shells.
|
|
17
|
+
<Page title="Settings">
|
|
18
|
+
<Head/>
|
|
19
|
+
…
|
|
20
|
+
</Page>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## See also
|
|
24
|
+
|
|
25
|
+
- [`Page`](/ui/Page) — renders `Head` and supplies the per-page meta it reads
|
|
26
|
+
- [`HTML`](/ui/HTML) — owns the literal `<head>` and the non-hoistable `<base>`
|
package/ui/page/Head.tsx
CHANGED
|
@@ -13,6 +13,7 @@ const R_HTTP_EQUIV = /^[A-Z][a-zA-Z0-9]*(-[A-Z][a-zA-Z0-9]*)*$/;
|
|
|
13
13
|
* - Does not render `<base>` (not hoistable — that lives in `<Head>` in the `<HTML>` shell component).
|
|
14
14
|
* - Updates `window.history` to match the page URL.
|
|
15
15
|
*
|
|
16
|
+
* @kind component
|
|
16
17
|
* @returns The hoistable head elements derived from the current `<Meta>` context.
|
|
17
18
|
* @example <Page title="Settings"><Head />…</Page>
|
|
18
19
|
* @see https://dhoulb.github.io/shelving/ui/page/Head/Head
|
package/ui/page/Page.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface PageProps extends PossibleMeta, ChildProps {
|
|
|
13
13
|
* - Sets the document title and other head metadata via `<Head>`, which emits hoistable tags inline; React 19 hoists each one into the document `<head>`. `<base>` is not emitted here — it lives in the `<HTML>` shell's `<Head>`.
|
|
14
14
|
* - Also updates `window.history` to match the page URL.
|
|
15
15
|
*
|
|
16
|
+
* @kind component
|
|
16
17
|
* @param children The page content.
|
|
17
18
|
* @param meta Per-page meta (title, description, etc.) merged with the surrounding `<Meta>` context.
|
|
18
19
|
* @returns The page element with its meta applied.
|
package/ui/page/Page.js
CHANGED
|
@@ -6,6 +6,7 @@ import { Head } from "./Head.js";
|
|
|
6
6
|
* - Sets the document title and other head metadata via `<Head>`, which emits hoistable tags inline; React 19 hoists each one into the document `<head>`. `<base>` is not emitted here — it lives in the `<HTML>` shell's `<Head>`.
|
|
7
7
|
* - Also updates `window.history` to match the page URL.
|
|
8
8
|
*
|
|
9
|
+
* @kind component
|
|
9
10
|
* @param children The page content.
|
|
10
11
|
* @param meta Per-page meta (title, description, etc.) merged with the surrounding `<Meta>` context.
|
|
11
12
|
* @returns The page element with its meta applied.
|
package/ui/page/Page.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Page
|
|
2
|
+
|
|
3
|
+
Wraps one page (or screen) inside an app, applying its per-page metadata. It merges `PossibleMeta` props into context and emits hoistable head tags (title, description, meta, links, stylesheets, scripts) that React 19 lifts into the document `<head>`. It also updates `window.history` to match the page URL.
|
|
4
|
+
|
|
5
|
+
**Things to know:**
|
|
6
|
+
|
|
7
|
+
- Accepts `PossibleMeta` props (`app`, `root`, `url`, `title`, `description`, `language`, `tags`, `links`, `stylesheets`, `modules`, `scripts`) and merges them with the surrounding `Meta` context.
|
|
8
|
+
- The page title is composed with the app name from context — `title="User profile"` under `app="My App"` renders `"User profile - My App"`.
|
|
9
|
+
- It renders [`Head`](/ui/Head) inline; React 19 hoists each `<title>`, `<meta>`, `<link>`, and `<script>` into `<head>`, so no portal is needed. `<base>` is the exception — that lives in [`HTML`](/ui/HTML).
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Page, Section } from "shelving/ui";
|
|
15
|
+
|
|
16
|
+
function UserPage({ id }: { id: string }) {
|
|
17
|
+
return (
|
|
18
|
+
<Page title="User profile" url={`/users/${id}`} description="View user details.">
|
|
19
|
+
<Section>…</Section>
|
|
20
|
+
</Page>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Layouts go inside `<Page>`:
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { Page, CenteredLayout } from "shelving/ui";
|
|
29
|
+
|
|
30
|
+
<Page title="Sign in">
|
|
31
|
+
<CenteredLayout>
|
|
32
|
+
<LoginForm/>
|
|
33
|
+
</CenteredLayout>
|
|
34
|
+
</Page>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## See also
|
|
38
|
+
|
|
39
|
+
- [`HTML`](/ui/HTML) — the document shell that sits above pages
|
|
40
|
+
- [`Head`](/ui/Head) — the hoistable-tag emitter that `Page` renders
|
|
41
|
+
- [`SidebarLayout`](/ui/SidebarLayout) / [`CenteredLayout`](/ui/CenteredLayout) — layouts that live inside a page
|
|
42
|
+
- [`Router`](/ui/Router) — matches URLs to the pages it renders
|
package/ui/page/Page.tsx
CHANGED
|
@@ -16,6 +16,7 @@ export interface PageProps extends PossibleMeta, ChildProps {}
|
|
|
16
16
|
* - Sets the document title and other head metadata via `<Head>`, which emits hoistable tags inline; React 19 hoists each one into the document `<head>`. `<base>` is not emitted here — it lives in the `<HTML>` shell's `<Head>`.
|
|
17
17
|
* - Also updates `window.history` to match the page URL.
|
|
18
18
|
*
|
|
19
|
+
* @kind component
|
|
19
20
|
* @param children The page content.
|
|
20
21
|
* @param meta Per-page meta (title, description, etc.) merged with the surrounding `<Meta>` context.
|
|
21
22
|
* @returns The page element with its meta applied.
|
|
@@ -19,6 +19,7 @@ export interface NavigationProps extends PossibleMeta, OptionalChildProps {
|
|
|
19
19
|
*
|
|
20
20
|
* TODO: switch click/popstate handling to the browser Navigation API when broadly supported.
|
|
21
21
|
*
|
|
22
|
+
* @kind component
|
|
22
23
|
* @param children The app subtree to provide navigation to.
|
|
23
24
|
* @param meta Initial meta (url/base) merged with the surrounding `<Meta>` context.
|
|
24
25
|
* @returns The navigation provider wrapping `children`.
|
package/ui/router/Navigation.js
CHANGED
|
@@ -16,6 +16,7 @@ import { NavigationStore } from "./NavigationStore.js";
|
|
|
16
16
|
*
|
|
17
17
|
* TODO: switch click/popstate handling to the browser Navigation API when broadly supported.
|
|
18
18
|
*
|
|
19
|
+
* @kind component
|
|
19
20
|
* @param children The app subtree to provide navigation to.
|
|
20
21
|
* @param meta Initial meta (url/base) merged with the surrounding `<Meta>` context.
|
|
21
22
|
* @returns The navigation provider wrapping `children`.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Navigation
|
|
2
|
+
|
|
3
|
+
The top-level navigation provider for a client-side app. It owns a single [`NavigationStore`](/ui/NavigationStore), publishes the live URL into the `<Meta>` context so descendant [`Router`](/ui/Router)s re-render on navigation, and wires up browser history. Use exactly one `<Navigation>` per app — nested routers all share its single store.
|
|
4
|
+
|
|
5
|
+
**Things to know:**
|
|
6
|
+
|
|
7
|
+
- Same-origin anchor clicks are intercepted automatically and turned into `forward()` calls. Add a `download` attribute to an anchor to opt out.
|
|
8
|
+
- It listens for `popstate` so the store stays in sync with browser back/forward.
|
|
9
|
+
- It initialises the store from the surrounding `<Meta>` url/base, so set those on an ancestor [`HTML`](/ui/HTML) / [`Page`](/ui/Page).
|
|
10
|
+
- [`Router`](/ui/Router) works with no `<Navigation>` at all (SSR, static rendering, tests) — `<Navigation>` is only what makes the URL *live* on the client.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import { HTML, Navigation, Router } from "shelving/ui";
|
|
16
|
+
|
|
17
|
+
<HTML url={initialUrl} root="https://example.com/">
|
|
18
|
+
<Navigation>
|
|
19
|
+
<Router routes={ROUTES}/>
|
|
20
|
+
</Navigation>
|
|
21
|
+
</HTML>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Imperative navigation
|
|
25
|
+
|
|
26
|
+
Read the navigation store from anywhere in the tree with `requireNavigation()` for imperative URL changes:
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { requireNavigation } from "shelving/ui";
|
|
30
|
+
|
|
31
|
+
const nav = requireNavigation();
|
|
32
|
+
nav.forward("/users/123"); // push a new history entry
|
|
33
|
+
nav.redirect("/login"); // replace the current history entry
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## See also
|
|
37
|
+
|
|
38
|
+
- [`Router`](/ui/Router) — matches the URL `<Navigation>` publishes and renders the page
|
|
39
|
+
- [`NavigationStore`](/ui/NavigationStore) — the store `<Navigation>` owns and `requireNavigation()` returns
|
|
40
|
+
- [`HTML`](/ui/HTML) / [`Page`](/ui/Page) — supply the initial url/base meta
|
|
41
|
+
- [`HorizontalTransition`](/ui/HorizontalTransition) — animate the route changes `<Navigation>` triggers
|
package/ui/router/Navigation.tsx
CHANGED
|
@@ -25,6 +25,7 @@ export interface NavigationProps extends PossibleMeta, OptionalChildProps {}
|
|
|
25
25
|
*
|
|
26
26
|
* TODO: switch click/popstate handling to the browser Navigation API when broadly supported.
|
|
27
27
|
*
|
|
28
|
+
* @kind component
|
|
28
29
|
* @param children The app subtree to provide navigation to.
|
|
29
30
|
* @param meta Initial meta (url/base) merged with the surrounding `<Meta>` context.
|
|
30
31
|
* @returns The navigation provider wrapping `children`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# NavigationStore
|
|
2
|
+
|
|
3
|
+
The store holding the current navigation URL and driving browser history. It extends `URLStore` — the current location is its `value` — and is owned by [`Navigation`](/ui/Navigation). Reach for it via [`requireNavigation()`](/ui/Navigation) rather than constructing your own.
|
|
4
|
+
|
|
5
|
+
**Things to know:**
|
|
6
|
+
|
|
7
|
+
- `forward()` pushes a new browser history entry; `redirect()` replaces the current one. Both resolve the destination against the store's `base`.
|
|
8
|
+
- It is a [`store`](/store) `URLStore`, so components can subscribe to it for re-renders.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { requireNavigation } from "shelving/ui";
|
|
14
|
+
|
|
15
|
+
function LogoutButton() {
|
|
16
|
+
const nav = requireNavigation();
|
|
17
|
+
return <Button onClick={() => nav.redirect("/login")}>Log out</Button>;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Constructed directly only when wiring navigation by hand (e.g. tests):
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { NavigationStore } from "shelving/ui";
|
|
25
|
+
|
|
26
|
+
const nav = new NavigationStore("/");
|
|
27
|
+
nav.forward("/home");
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## See also
|
|
31
|
+
|
|
32
|
+
- [`Navigation`](/ui/Navigation) — owns the store and exposes it via `requireNavigation()`
|
|
33
|
+
- [`Router`](/ui/Router) — renders the page for whatever URL the store holds
|
|
34
|
+
- [`store`](/store) — the `URLStore` base and subscription model
|
package/ui/router/Router.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export interface RouterProps extends PossibleMeta {
|
|
|
23
23
|
* - Route `{placeholders}` are passed as props to function/component route values along with merged URL `?query` params. They are not published into context — descendants of a `ReactElement`-valued route can't see them automatically.
|
|
24
24
|
* - Returns `null` when there's no URL in context or the URL is outside the base.
|
|
25
25
|
*
|
|
26
|
+
* @kind component
|
|
26
27
|
* @param routes The route table to match the current URL against.
|
|
27
28
|
* @param fallback Element to render when nothing matches; explicit `null` renders nothing instead of throwing.
|
|
28
29
|
* @param meta Optional meta (url/base) overrides for this router scope.
|
package/ui/router/Router.js
CHANGED
|
@@ -12,6 +12,7 @@ import { MetaContext, requireMetaURL } from "../misc/MetaContext.js";
|
|
|
12
12
|
* - Route `{placeholders}` are passed as props to function/component route values along with merged URL `?query` params. They are not published into context — descendants of a `ReactElement`-valued route can't see them automatically.
|
|
13
13
|
* - Returns `null` when there's no URL in context or the URL is outside the base.
|
|
14
14
|
*
|
|
15
|
+
* @kind component
|
|
15
16
|
* @param routes The route table to match the current URL against.
|
|
16
17
|
* @param fallback Element to render when nothing matches; explicit `null` renders nothing instead of throwing.
|
|
17
18
|
* @param meta Optional meta (url/base) overrides for this router scope.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Router
|
|
2
|
+
|
|
3
|
+
A pure URL matcher: it reads the current URL from the surrounding `<Meta>` context, matches it against a `routes` table, and renders the matched element. It has no client requirements, so it works for SSR, static rendering, and tests with no [`Navigation`](/ui/Navigation) at all — wrap it in [`Navigation`](/ui/Navigation) on the client to get live URL updates.
|
|
4
|
+
|
|
5
|
+
**Things to know:**
|
|
6
|
+
|
|
7
|
+
- Route keys are `AbsolutePath` strings starting with `/`. Placeholders (`{id}`, `:id`, `[id]`, `${id}`, `{{id}}`) are passed to function/component route values as props, merged with URL `?query` params (placeholders win on conflict).
|
|
8
|
+
- `<Router>` accepts `PossibleMeta` props (`url`, `base`, etc.) to override the surrounding context — this is how nested routers scope themselves.
|
|
9
|
+
- With a `base` set, the path used for matching is the URL after `matchURLPrefix` strips the base prefix; URLs outside the base render as `null`.
|
|
10
|
+
- Pass `fallback` to control no-match behaviour. An explicit `null` renders nothing; leaving it `undefined` throws a `NotFoundError`.
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
### Basic setup
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { HTML, Navigation, Router } from "shelving/ui";
|
|
18
|
+
|
|
19
|
+
<HTML url={initialUrl} root="https://example.com/">
|
|
20
|
+
<Navigation>
|
|
21
|
+
<Router routes={{
|
|
22
|
+
"/": HomePage,
|
|
23
|
+
"/users/{id}": UserPage,
|
|
24
|
+
"/about": AboutPage,
|
|
25
|
+
}}/>
|
|
26
|
+
</Navigation>
|
|
27
|
+
</HTML>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Route value types
|
|
31
|
+
|
|
32
|
+
| Value | Behaviour |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Component | Rendered as `<Component {...params}/>` with merged placeholder + query props. |
|
|
35
|
+
| `AbsolutePath` string | Redirects to that path (placeholders resolved against the source). |
|
|
36
|
+
| `ReactElement` | Rendered as-is — use for layout wrapping or composing inner routers. |
|
|
37
|
+
| `null` / `false` | Skipped, as if the route were absent — lets a route be conditionally disabled. |
|
|
38
|
+
|
|
39
|
+
### Placeholder syntax
|
|
40
|
+
|
|
41
|
+
All forms produce the same matched value — pick whichever reads best:
|
|
42
|
+
|
|
43
|
+
| Form | Single segment | Catchall (one+ segments, also matches empty) |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| Anonymous | `*` (named `"0"`) | `**` / `***` (named `"0"`) |
|
|
46
|
+
| Colon | `:name` | `:name*` / `:name**` |
|
|
47
|
+
| Single brace | `{name}` | `{...name}` / `{name*}` |
|
|
48
|
+
| Square bracket | `[name]` | `[...name]` / `[name*]` |
|
|
49
|
+
| Dollar brace | `${name}` | `${...name}` / `${name*}` |
|
|
50
|
+
| Double brace | `{{name}}` | `{{...name}}` / `{{name*}}` |
|
|
51
|
+
|
|
52
|
+
Modifier chars are tolerant: one-or-more stars and three-or-more dots are all equivalent, so `{path*}`, `{path**}`, `{...path}`, and `{....path}` behave the same. Catchall placeholders allow empty values, so a trailing catchall matches the trailing-slash-absent variant — `/files/{...path}` matches `/files`, `/files/`, and `/files/a/b/c`.
|
|
53
|
+
|
|
54
|
+
### Layout wrapping
|
|
55
|
+
|
|
56
|
+
Put layout JSX as the route value with another `<Router>` inside. Since `<Router>` reads its URL from `<Meta>`, the inner router sees the same URL.
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
const SIDEBARRED_ROUTES = {
|
|
60
|
+
"/users": <UsersPage/>,
|
|
61
|
+
"/users/{id}": <UserPage/>,
|
|
62
|
+
"/settings": <SettingsPage/>,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
<Router routes={{
|
|
66
|
+
"/": <HomePage/>,
|
|
67
|
+
"/{...path}": (
|
|
68
|
+
<SidebarLayout sidebar={<Nav/>}>
|
|
69
|
+
<Router routes={SIDEBARRED_ROUTES}/>
|
|
70
|
+
</SidebarLayout>
|
|
71
|
+
),
|
|
72
|
+
}}/>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Section / microsite pattern
|
|
76
|
+
|
|
77
|
+
A self-contained "section" — its own URL prefix and routes — composes via a catchall plus a function route value that hands the captured sub-path to a nested router as its `url`.
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
const USER_ROUTES = {
|
|
81
|
+
"/": UsersPage,
|
|
82
|
+
"/{id}": UserPage,
|
|
83
|
+
"/{id}/edit": UserEditPage,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export function UserRouter({ path = "/" }: { path?: AbsolutePath }) {
|
|
87
|
+
return <Router routes={USER_ROUTES} url={path}/>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// At the call site — the top-level router stays a flat list of section prefixes:
|
|
91
|
+
<Router routes={{
|
|
92
|
+
"/": <HomePage/>,
|
|
93
|
+
"/users/{...path}": ({ path }) => <UserRouter path={path}/>,
|
|
94
|
+
"/blog/{...path}": ({ path }) => <BlogRouter path={path}/>,
|
|
95
|
+
}}/>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The outer router captures everything under `/users` into `path`; the inner router treats it as its starting URL, so its `"/"` matches the bare `/users` and `/{id}` matches `/users/123`.
|
|
99
|
+
|
|
100
|
+
### Stacking layouts and sections
|
|
101
|
+
|
|
102
|
+
The two patterns compose — wrap a group of routes in a layout, then route further inside, handing off to section routers via the catchall:
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
const SIDEBARRED_ROUTES = {
|
|
106
|
+
"/": <Dashboard/>,
|
|
107
|
+
"/users/{...path}": ({ path }) => <UserRouter path={path}/>,
|
|
108
|
+
"/blog/{...path}": ({ path }) => <BlogRouter path={path}/>,
|
|
109
|
+
"/settings": <SettingsPage/>,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
<Router routes={{
|
|
113
|
+
"/login": <LoginPage/>, // no sidebar
|
|
114
|
+
"/{...path}": ( // everything else wrapped
|
|
115
|
+
<SidebarLayout sidebar={<Nav/>}>
|
|
116
|
+
<Router routes={SIDEBARRED_ROUTES}/>
|
|
117
|
+
</SidebarLayout>
|
|
118
|
+
),
|
|
119
|
+
}}/>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### SSR / static rendering
|
|
123
|
+
|
|
124
|
+
`<Router>` re-renders when context changes and needs no client. For static rendering set `url` and `root` on the outer wrapper and skip `<Navigation>`:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
renderToString(
|
|
128
|
+
<HTML url={path} root="https://example.com/">
|
|
129
|
+
<Router routes={ROUTES}/>
|
|
130
|
+
</HTML>
|
|
131
|
+
);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Base paths
|
|
135
|
+
|
|
136
|
+
`root="https://example.com/app/"` is supported — the base path prefix is stripped from the URL before matching, and URLs that fall outside the base render as `null`.
|
|
137
|
+
|
|
138
|
+
## See also
|
|
139
|
+
|
|
140
|
+
- [`Navigation`](/ui/Navigation) — publishes a live URL into `<Meta>` for client-side routing
|
|
141
|
+
- [`HTML`](/ui/HTML) / [`Page`](/ui/Page) — supply the `<Meta>` URL the router reads
|
|
142
|
+
- [`SidebarLayout`](/ui/SidebarLayout) / [`CenteredLayout`](/ui/CenteredLayout) — wrap route groups in a shared layout
|
|
143
|
+
- [`HorizontalTransition`](/ui/HorizontalTransition) — animate route changes
|
package/ui/router/Router.tsx
CHANGED
|
@@ -31,6 +31,7 @@ export interface RouterProps extends PossibleMeta {
|
|
|
31
31
|
* - Route `{placeholders}` are passed as props to function/component route values along with merged URL `?query` params. They are not published into context — descendants of a `ReactElement`-valued route can't see them automatically.
|
|
32
32
|
* - Returns `null` when there's no URL in context or the URL is outside the base.
|
|
33
33
|
*
|
|
34
|
+
* @kind component
|
|
34
35
|
* @param routes The route table to match the current URL against.
|
|
35
36
|
* @param fallback Element to render when nothing matches; explicit `null` renders nothing instead of throwing.
|
|
36
37
|
* @param meta Optional meta (url/base) overrides for this router scope.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# TINT_CLASS
|
|
2
|
+
|
|
3
|
+
All colour in the library flows from a single anchor variable, **`--tint-50`**, defined in `Tint.module.css`. From that one hue a 21-step ladder — `--tint-00`, `--tint-05`, … `--tint-95`, `--tint-100` — is computed with `color-mix()` in OKLCH: `--tint-00` is black, `--tint-50` is the anchor hue itself, `--tint-100` is white, and every step in between mixes the anchor toward one extreme or the other.
|
|
4
|
+
|
|
5
|
+
The anchor defaults to `--color-gray`, so the default ladder is a neutral grey ramp — grey is just the colour you get when nothing moves the anchor. The page baseline paints from the extremes: `body { color: var(--tint-00); background: var(--tint-100); }`.
|
|
6
|
+
|
|
7
|
+
## The recompute trick
|
|
8
|
+
|
|
9
|
+
The ladder is computed at `:root` and *recomputed* under `TINT_CLASS` (the `.tint` class). That recomputation is the whole trick: move the anchor at any scope, apply `TINT_CLASS`, and all 21 shades rebuild from the new hue at that scope. Colour and status classes are exactly that — they only move the anchor:
|
|
10
|
+
|
|
11
|
+
```css
|
|
12
|
+
/* Color.module.css — a colour variant just moves the anchor. */
|
|
13
|
+
.red {
|
|
14
|
+
--tint-50: var(--color-red);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/* Status.module.css — a status maps a semantic name onto a palette colour. */
|
|
18
|
+
.success {
|
|
19
|
+
--tint-50: var(--color-success);
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
[`getColorClass`](/ui/getColorClass) and [`getStatusClass`](/ui/getStatusClass) compose `TINT_CLASS` automatically, so `<Card color="red">` is: move the anchor to red, rebuild the ladder, and let the card paint from the same steps it always paints from. Descendants inherit the rebuilt ladder, which is why a [`Tag`](/ui/Tag) or [`Preformatted`](/ui/Preformatted) nested in a red card tints to match it.
|
|
24
|
+
|
|
25
|
+
## How components paint from the ladder
|
|
26
|
+
|
|
27
|
+
Components paint from the ladder by convention:
|
|
28
|
+
|
|
29
|
+
| Step | Used for |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `--tint-00` | Body text, headings — maximum contrast |
|
|
32
|
+
| `--tint-50` | The hue itself — accents, labels, `Tag` backgrounds, `strong` button backgrounds |
|
|
33
|
+
| `--tint-80` | Borders |
|
|
34
|
+
| `--tint-90` | Surfaces — [`Card`](/ui/Card), `Preformatted`, [`Button`](/ui/Button) backgrounds |
|
|
35
|
+
| `--tint-95` | Hover state of those surfaces |
|
|
36
|
+
| `--tint-100` | The page background; text on `--tint-50` backgrounds |
|
|
37
|
+
|
|
38
|
+
Pairings follow contrast: long text reads at `00`-on-`90` or `00`-on-`100`; short labels read at `100`-on-`50`.
|
|
39
|
+
|
|
40
|
+
## Theming
|
|
41
|
+
|
|
42
|
+
A theme is a CSS file of custom-property overrides at `:root`, imported after the base styles. Work from broadest to narrowest:
|
|
43
|
+
|
|
44
|
+
1. **Move a palette colour.** Overriding `--color-gray` moves the default anchor, retinting every neutral ladder in the app — the broadest possible change. Overriding `--color-red`, `--color-primary`, etc. re-aims every variant and status that maps to it.
|
|
45
|
+
2. **Retint one component family.** Set its tint hook: `--card-tint: var(--color-purple)` makes all cards (and their nested content) purple-tinted, with text, border, surface, and hover shades all derived for free.
|
|
46
|
+
3. **Override one property.** Per-property hooks are the scalpel: `--button-radius: 999px`, `--card-border: none`, `--tag-case: none`.
|
|
47
|
+
|
|
48
|
+
**Don't override individual ladder steps (`--tint-90`, etc.) at `:root`.** The ladder is *recomputed* from the anchor inside every `TINT_CLASS` scope — which includes every component that accepts `color=` or `status=` — so a step override at `:root` only reaches untinted regions and produces inconsistent surfaces. Move the anchor (option 1 or 2) instead, and the steps follow.
|
|
49
|
+
|
|
50
|
+
## See also
|
|
51
|
+
|
|
52
|
+
- [`getColorClass`](/ui/getColorClass) — moves the anchor to a named palette colour and composes `TINT_CLASS`.
|
|
53
|
+
- [`getStatusClass`](/ui/getStatusClass) — moves the anchor via a semantic status name.
|
|
54
|
+
- [`Card`](/ui/Card) — a painting component whose Styling section shows the per-component tint hook in practice.
|
|
55
|
+
- [`ui`](/ui) — the styling system overview: design tokens, cascade layers, and styling props.
|
|
@@ -11,6 +11,7 @@ export interface CollapseTransitionProps extends TransitionProps {
|
|
|
11
11
|
/**
|
|
12
12
|
* Transition that collapses its children in and out by animating their size.
|
|
13
13
|
*
|
|
14
|
+
* @kind component
|
|
14
15
|
* @param props Shared transition variant props plus `children`.
|
|
15
16
|
* @returns A `<Transition>` element configured with the `collapse` class.
|
|
16
17
|
* @example <CollapseTransition>{visible && <Panel />}</CollapseTransition>
|
|
@@ -4,6 +4,7 @@ import { Transition } from "./Transition.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Transition that collapses its children in and out by animating their size.
|
|
6
6
|
*
|
|
7
|
+
* @kind component
|
|
7
8
|
* @param props Shared transition variant props plus `children`.
|
|
8
9
|
* @returns A `<Transition>` element configured with the `collapse` class.
|
|
9
10
|
* @example <CollapseTransition>{visible && <Panel />}</CollapseTransition>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# CollapseTransition
|
|
2
|
+
|
|
3
|
+
A [`Transition`](/ui/Transition) preset that collapses its children in and out by animating their size, clipping the overflow during the animation.
|
|
4
|
+
|
|
5
|
+
**Things to know:**
|
|
6
|
+
|
|
7
|
+
- Uses the `collapse` transition class — there is no direction-aware variant, so forward and back animate identically.
|
|
8
|
+
- Pass `overlay` to raise the transition group above surrounding content during the animation (`z-index: 100`).
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { CollapseTransition } from "shelving/ui";
|
|
14
|
+
|
|
15
|
+
function Details({ open }: { open: boolean }) {
|
|
16
|
+
return open ? (
|
|
17
|
+
<CollapseTransition>
|
|
18
|
+
<Panel>…</Panel>
|
|
19
|
+
</CollapseTransition>
|
|
20
|
+
) : null;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Styling
|
|
25
|
+
|
|
26
|
+
This preset exposes no own `--collapse-transition-*` hooks. Its `CollapseTransition.css` only sets `overflow: hidden` on `::view-transition-image-pair(.collapse)` so the collapsing content is clipped.
|
|
27
|
+
|
|
28
|
+
**Global tokens it reads** — none.
|
|
29
|
+
|
|
30
|
+
## See also
|
|
31
|
+
|
|
32
|
+
- [`Transition`](/ui/Transition) — the base wrapper and `overlay` variant
|
|
33
|
+
- [`FadeTransition`](/ui/FadeTransition) — opacity-based alternative
|
|
34
|
+
- [`VerticalTransition`](/ui/VerticalTransition) / [`HorizontalTransition`](/ui/HorizontalTransition) — direction-aware slides
|
|
@@ -12,6 +12,7 @@ export interface CollapseTransitionProps extends TransitionProps {}
|
|
|
12
12
|
/**
|
|
13
13
|
* Transition that collapses its children in and out by animating their size.
|
|
14
14
|
*
|
|
15
|
+
* @kind component
|
|
15
16
|
* @param props Shared transition variant props plus `children`.
|
|
16
17
|
* @returns A `<Transition>` element configured with the `collapse` class.
|
|
17
18
|
* @example <CollapseTransition>{visible && <Panel />}</CollapseTransition>
|
|
@@ -10,6 +10,7 @@ export interface FadeTransitionProps extends TransitionProps {
|
|
|
10
10
|
/**
|
|
11
11
|
* Transition that fades its children in and out by animating their opacity.
|
|
12
12
|
*
|
|
13
|
+
* @kind component
|
|
13
14
|
* @param props Shared transition variant props plus `children`.
|
|
14
15
|
* @returns A `<Transition>` element configured with the `fade` class.
|
|
15
16
|
* @example <FadeTransition>{visible && <Toast />}</FadeTransition>
|
|
@@ -3,6 +3,7 @@ import { Transition } from "./Transition.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Transition that fades its children in and out by animating their opacity.
|
|
5
5
|
*
|
|
6
|
+
* @kind component
|
|
6
7
|
* @param props Shared transition variant props plus `children`.
|
|
7
8
|
* @returns A `<Transition>` element configured with the `fade` class.
|
|
8
9
|
* @example <FadeTransition>{visible && <Toast />}</FadeTransition>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# FadeTransition
|
|
2
|
+
|
|
3
|
+
A [`Transition`](/ui/Transition) preset that fades its children in and out by animating opacity. Wrap any content that should animate when it mounts or unmounts.
|
|
4
|
+
|
|
5
|
+
**Things to know:**
|
|
6
|
+
|
|
7
|
+
- Uses the `fade` transition class — there is no direction-aware variant, so forward and back animate identically.
|
|
8
|
+
- Pass `overlay` to raise the transition group above surrounding content during the animation (`z-index: 100`).
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { FadeTransition } from "shelving/ui";
|
|
14
|
+
|
|
15
|
+
function Panel({ visible }: { visible: boolean }) {
|
|
16
|
+
return visible ? (
|
|
17
|
+
<FadeTransition>
|
|
18
|
+
<div className="panel">…</div>
|
|
19
|
+
</FadeTransition>
|
|
20
|
+
) : null;
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Styling
|
|
25
|
+
|
|
26
|
+
| Variable | Styles | Default |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `--fade-transition-duration` | Duration of the fade-in and fade-out keyframes | `var(--duration-fast)` |
|
|
29
|
+
|
|
30
|
+
**Global tokens it reads** — `--duration-fast`.
|
|
31
|
+
|
|
32
|
+
## See also
|
|
33
|
+
|
|
34
|
+
- [`Transition`](/ui/Transition) — the base wrapper and `overlay` variant
|
|
35
|
+
- [`CollapseTransition`](/ui/CollapseTransition) — size-based alternative
|
|
36
|
+
- [`VerticalTransition`](/ui/VerticalTransition) / [`HorizontalTransition`](/ui/HorizontalTransition) — direction-aware slides
|
|
@@ -11,6 +11,7 @@ export interface FadeTransitionProps extends TransitionProps {}
|
|
|
11
11
|
/**
|
|
12
12
|
* Transition that fades its children in and out by animating their opacity.
|
|
13
13
|
*
|
|
14
|
+
* @kind component
|
|
14
15
|
* @param props Shared transition variant props plus `children`.
|
|
15
16
|
* @returns A `<Transition>` element configured with the `fade` class.
|
|
16
17
|
* @example <FadeTransition>{visible && <Toast />}</FadeTransition>
|
|
@@ -11,6 +11,7 @@ export interface HorizontalTransitionProps extends TransitionProps {
|
|
|
11
11
|
/**
|
|
12
12
|
* Transition that slides its children horizontally — right when moving forward, left when moving back.
|
|
13
13
|
*
|
|
14
|
+
* @kind component
|
|
14
15
|
* @param props Shared transition variant props plus `children`.
|
|
15
16
|
* @returns A `<Transition>` element configured with the horizontal slide classes.
|
|
16
17
|
* @example <HorizontalTransition>{currentStep}</HorizontalTransition>
|
|
@@ -4,6 +4,7 @@ import { Transition } from "./Transition.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Transition that slides its children horizontally — right when moving forward, left when moving back.
|
|
6
6
|
*
|
|
7
|
+
* @kind component
|
|
7
8
|
* @param props Shared transition variant props plus `children`.
|
|
8
9
|
* @returns A `<Transition>` element configured with the horizontal slide classes.
|
|
9
10
|
* @example <HorizontalTransition>{currentStep}</HorizontalTransition>
|