shelving 1.262.1 → 1.264.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/form/Button.md +2 -0
- package/ui/form/Button.module.css +2 -0
- package/ui/form/SubmitButton.js +2 -2
- package/ui/form/SubmitButton.tsx +2 -2
- package/ui/misc/Catcher.d.ts +1 -3
- package/ui/misc/Catcher.js +2 -9
- package/ui/misc/Catcher.tsx +2 -16
- package/ui/misc/Icon.module.css +3 -1
- package/ui/misc/Loading.d.ts +10 -14
- package/ui/misc/Loading.js +14 -7
- package/ui/misc/Loading.md +24 -5
- package/ui/misc/Loading.module.css +3 -10
- package/ui/misc/Loading.tsx +16 -25
- package/ui/notice/Message.d.ts +0 -7
- package/ui/notice/Message.js +0 -8
- package/ui/notice/Message.tsx +0 -9
package/package.json
CHANGED
package/ui/form/Button.md
CHANGED
|
@@ -60,6 +60,8 @@ import { getButtonClass } from "shelving/ui";
|
|
|
60
60
|
| `--button-radius` | Corner radius | `var(--radius-xsmall)` (8px) |
|
|
61
61
|
| `--button-padding` | Inner padding | `var(--space-small)` (12px) |
|
|
62
62
|
| `--button-small-padding` | Inner padding when `small` | `var(--space-xxsmall)` (4px) |
|
|
63
|
+
| `--button-gap` | Gap between icon and label | `var(--space-small)` (12px) |
|
|
64
|
+
| `--button-small-gap` | Gap between icon and label when `small` | `var(--space-xxsmall)` (4px) |
|
|
63
65
|
| `--button-space` | Outer block margin | `var(--space-small)` (12px) |
|
|
64
66
|
| `--button-font` | Font family | `var(--font-body)` |
|
|
65
67
|
| `--button-weight` | Font weight | `var(--weight-strong)` (700) |
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
/* Content */
|
|
29
29
|
overflow: hidden;
|
|
30
30
|
word-break: normal;
|
|
31
|
+
gap: var(--button-gap, var(--space-small));
|
|
31
32
|
justify-content: center;
|
|
32
33
|
align-items: center;
|
|
33
34
|
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
|
|
62
63
|
/* Variants */
|
|
63
64
|
&.small {
|
|
65
|
+
gap: var(--button-small-gap, var(--space-xxsmall));
|
|
64
66
|
padding-block: var(--button-small-padding, var(--space-xxsmall));
|
|
65
67
|
padding-inline: var(--button-small-padding, var(--space-xxsmall));
|
|
66
68
|
}
|
package/ui/form/SubmitButton.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ArrowRightIcon } from "@heroicons/react/24/solid";
|
|
3
3
|
import { useStore } from "../../react/useStore.js";
|
|
4
|
-
import {
|
|
4
|
+
import { LOADING } from "../misc/Loading.js";
|
|
5
5
|
import { getButtonClass } from "./Button.js";
|
|
6
6
|
import { requireForm } from "./FormContext.js";
|
|
7
7
|
/**
|
|
@@ -15,6 +15,6 @@ import { requireForm } from "./FormContext.js";
|
|
|
15
15
|
export function SubmitButton({ children = SUBMIT_CHILDREN, strong = true, color = "primary", full = true, ...variants }) {
|
|
16
16
|
const form = requireForm();
|
|
17
17
|
const busy = useStore(form.busy).value;
|
|
18
|
-
return (_jsx("button", { type: "submit", disabled: busy, className: getButtonClass({ strong, color, full, ...variants }), children: busy ?
|
|
18
|
+
return (_jsx("button", { type: "submit", disabled: busy, className: getButtonClass({ strong, color, full, ...variants }), children: busy ? LOADING : children }));
|
|
19
19
|
}
|
|
20
20
|
const SUBMIT_CHILDREN = (_jsxs(_Fragment, { children: ["Save", _jsx(ArrowRightIcon, {})] }));
|
package/ui/form/SubmitButton.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ArrowRightIcon } from "@heroicons/react/24/solid";
|
|
2
2
|
import type { ReactElement } from "react";
|
|
3
3
|
import { useStore } from "../../react/useStore.js";
|
|
4
|
-
import {
|
|
4
|
+
import { LOADING } from "../misc/Loading.js";
|
|
5
5
|
import type { OptionalChildProps } from "../util/props.js";
|
|
6
6
|
import { type ButtonVariants, getButtonClass } from "./Button.js";
|
|
7
7
|
import { requireForm } from "./FormContext.js";
|
|
@@ -25,7 +25,7 @@ export function SubmitButton({
|
|
|
25
25
|
const busy = useStore(form.busy).value;
|
|
26
26
|
return (
|
|
27
27
|
<button type="submit" disabled={busy} className={getButtonClass({ strong, color, full, ...variants })}>
|
|
28
|
-
{busy ?
|
|
28
|
+
{busy ? LOADING : children}
|
|
29
29
|
</button>
|
|
30
30
|
);
|
|
31
31
|
}
|
package/ui/misc/Catcher.d.ts
CHANGED
|
@@ -73,9 +73,7 @@ export declare function ErrorNotice({ reason }: ErrorProps): ReactElement;
|
|
|
73
73
|
*/
|
|
74
74
|
export declare function PageCatcher({ children }: ChildProps): ReactElement;
|
|
75
75
|
/**
|
|
76
|
-
* Render a caught error as a full-page `<Page>` with
|
|
77
|
-
*
|
|
78
|
-
* - Uses `getMessage()` to extract a human-readable message, falling back to `"Unknown error"`.
|
|
76
|
+
* Render a caught error as a full-page `<Page>` with a centered `<ErrorNotice>`.
|
|
79
77
|
*
|
|
80
78
|
* @kind component
|
|
81
79
|
* @see https://shelving.cc/ui/ErrorPage
|
package/ui/misc/Catcher.js
CHANGED
|
@@ -2,15 +2,11 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { ArrowPathIcon } from "@heroicons/react/24/solid";
|
|
3
3
|
import { Component, createContext, use } from "react";
|
|
4
4
|
import { getMessage } from "../../util/error.js";
|
|
5
|
-
import { Card } from "../block/Card.js";
|
|
6
5
|
import { Paragraph } from "../block/Paragraph.js";
|
|
7
|
-
import { Row } from "../block/Row.js";
|
|
8
|
-
import { Subheading } from "../block/Subheading.js";
|
|
9
6
|
import { Button } from "../form/Button.js";
|
|
10
7
|
import { CenteredLayout } from "../layout/CenteredLayout.js";
|
|
11
8
|
import { Notice } from "../notice/Notice.js";
|
|
12
9
|
import { Page } from "../page/Page.js";
|
|
13
|
-
import { Icon } from "./Icon.js";
|
|
14
10
|
const RetryContext = createContext(undefined);
|
|
15
11
|
RetryContext.displayName = "RetryContext";
|
|
16
12
|
const RETRY_CHILDREN = (_jsxs(_Fragment, { children: [_jsx(ArrowPathIcon, {}), "Retry"] }));
|
|
@@ -82,14 +78,11 @@ export function PageCatcher({ children }) {
|
|
|
82
78
|
return _jsx(Catcher, { as: ErrorPage, children: children });
|
|
83
79
|
}
|
|
84
80
|
/**
|
|
85
|
-
* Render a caught error as a full-page `<Page>` with
|
|
86
|
-
*
|
|
87
|
-
* - Uses `getMessage()` to extract a human-readable message, falling back to `"Unknown error"`.
|
|
81
|
+
* Render a caught error as a full-page `<Page>` with a centered `<ErrorNotice>`.
|
|
88
82
|
*
|
|
89
83
|
* @kind component
|
|
90
84
|
* @see https://shelving.cc/ui/ErrorPage
|
|
91
85
|
*/
|
|
92
86
|
export function ErrorPage({ reason }) {
|
|
93
|
-
|
|
94
|
-
return (_jsx(Page, { title: "Error", children: _jsx(CenteredLayout, { children: _jsxs(Card, { status: "error", children: [_jsx(Subheading, { children: _jsxs(Row, { left: true, children: [_jsx(Icon, { status: "error" }), " ", message] }) }), _jsx(RetryButton, {})] }) }) }));
|
|
87
|
+
return (_jsx(Page, { title: "Error", children: _jsx(CenteredLayout, { children: _jsx(ErrorNotice, { reason: reason }) }) }));
|
|
95
88
|
}
|
package/ui/misc/Catcher.tsx
CHANGED
|
@@ -2,16 +2,12 @@ import { ArrowPathIcon } from "@heroicons/react/24/solid";
|
|
|
2
2
|
import { Component, createContext, type ReactElement, type ReactNode, use } from "react";
|
|
3
3
|
import { getMessage } from "../../util/error.js";
|
|
4
4
|
import type { Callback } from "../../util/function.js";
|
|
5
|
-
import { Card } from "../block/Card.js";
|
|
6
5
|
import { Paragraph } from "../block/Paragraph.js";
|
|
7
|
-
import { Row } from "../block/Row.js";
|
|
8
|
-
import { Subheading } from "../block/Subheading.js";
|
|
9
6
|
import { Button, type ButtonVariants } from "../form/Button.js";
|
|
10
7
|
import { CenteredLayout } from "../layout/CenteredLayout.js";
|
|
11
8
|
import { Notice } from "../notice/Notice.js";
|
|
12
9
|
import { Page } from "../page/Page.js";
|
|
13
10
|
import type { ChildProps, OptionalChildProps } from "../util/props.js";
|
|
14
|
-
import { Icon } from "./Icon.js";
|
|
15
11
|
|
|
16
12
|
const RetryContext = createContext<Callback | undefined>(undefined);
|
|
17
13
|
RetryContext.displayName = "RetryContext";
|
|
@@ -137,26 +133,16 @@ export function PageCatcher({ children }: ChildProps): ReactElement {
|
|
|
137
133
|
}
|
|
138
134
|
|
|
139
135
|
/**
|
|
140
|
-
* Render a caught error as a full-page `<Page>` with
|
|
141
|
-
*
|
|
142
|
-
* - Uses `getMessage()` to extract a human-readable message, falling back to `"Unknown error"`.
|
|
136
|
+
* Render a caught error as a full-page `<Page>` with a centered `<ErrorNotice>`.
|
|
143
137
|
*
|
|
144
138
|
* @kind component
|
|
145
139
|
* @see https://shelving.cc/ui/ErrorPage
|
|
146
140
|
*/
|
|
147
141
|
export function ErrorPage({ reason }: ErrorProps): ReactElement {
|
|
148
|
-
const message = getMessage(reason) ?? "Unknown error";
|
|
149
142
|
return (
|
|
150
143
|
<Page title="Error">
|
|
151
144
|
<CenteredLayout>
|
|
152
|
-
<
|
|
153
|
-
<Subheading>
|
|
154
|
-
<Row left>
|
|
155
|
-
<Icon status="error" /> {message}
|
|
156
|
-
</Row>
|
|
157
|
-
</Subheading>
|
|
158
|
-
<RetryButton />
|
|
159
|
-
</Card>
|
|
145
|
+
<ErrorNotice reason={reason} />
|
|
160
146
|
</CenteredLayout>
|
|
161
147
|
</Page>
|
|
162
148
|
);
|
package/ui/misc/Icon.module.css
CHANGED
package/ui/misc/Loading.d.ts
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
|
-
declare const _componentProps: unique symbol;
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
3
|
+
* Animated loading spinner shaped like a Heroicon — a faint track plus a rotating indicator arc.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
readonly [_componentProps]?: never;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Animated spinner SVG used as a loading indicator.
|
|
13
|
-
*
|
|
14
|
-
* - Self-contained inline SVG with a rotating indicator arc; inherits its colour and size from the surrounding text.
|
|
5
|
+
* - Self-contained inline SVG; the spin is driven by an inline SMIL `<animateTransform>`.
|
|
6
|
+
* - The track and indicator paint from scaled steps of the current tint ladder (`--tint-70` / `--tint-80`), so their colour follows whatever tint `<Icon>` (or an ancestor) sets.
|
|
7
|
+
* - Takes only `className` like the Heroicons, so it slots straight into `<Icon icon={Loading} />` to pick up icon sizing, colour, and centring.
|
|
15
8
|
*
|
|
16
9
|
* @kind component
|
|
17
10
|
* @see https://shelving.cc/ui/Loading
|
|
18
11
|
*/
|
|
19
|
-
export declare function Loading(
|
|
12
|
+
export declare function Loading({ className }: {
|
|
13
|
+
className?: string | undefined;
|
|
14
|
+
}): ReactElement;
|
|
20
15
|
/**
|
|
21
|
-
* Shared
|
|
16
|
+
* Shared loading spinner element with a stable `key`, ready to drop into `Suspense` fallbacks and lists.
|
|
17
|
+
*
|
|
18
|
+
* - A `<Loading>` rendered through `<Icon>`, so it picks up icon sizing, colour, and centring.
|
|
22
19
|
*
|
|
23
20
|
* @see https://shelving.cc/ui/LOADING
|
|
24
21
|
*/
|
|
25
22
|
export declare const LOADING: import("react").JSX.Element;
|
|
26
|
-
export {};
|
package/ui/misc/Loading.js
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { getModuleClass } from "../util/css.js";
|
|
3
|
-
import
|
|
3
|
+
import { Icon } from "./Icon.js";
|
|
4
|
+
import LOADING_CSS from "./Loading.module.css";
|
|
5
|
+
const LOADING_TRACK_CLASS = getModuleClass(LOADING_CSS, "track");
|
|
6
|
+
const LOADING_INDICATOR_CLASS = getModuleClass(LOADING_CSS, "indicator");
|
|
4
7
|
/**
|
|
5
|
-
* Animated spinner
|
|
8
|
+
* Animated loading spinner shaped like a Heroicon — a faint track plus a rotating indicator arc.
|
|
6
9
|
*
|
|
7
|
-
* - Self-contained inline SVG
|
|
10
|
+
* - Self-contained inline SVG; the spin is driven by an inline SMIL `<animateTransform>`.
|
|
11
|
+
* - The track and indicator paint from scaled steps of the current tint ladder (`--tint-70` / `--tint-80`), so their colour follows whatever tint `<Icon>` (or an ancestor) sets.
|
|
12
|
+
* - Takes only `className` like the Heroicons, so it slots straight into `<Icon icon={Loading} />` to pick up icon sizing, colour, and centring.
|
|
8
13
|
*
|
|
9
14
|
* @kind component
|
|
10
15
|
* @see https://shelving.cc/ui/Loading
|
|
11
16
|
*/
|
|
12
|
-
export function Loading() {
|
|
13
|
-
return (_jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", className:
|
|
17
|
+
export function Loading({ className }) {
|
|
18
|
+
return (_jsxs("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", className: className, "data-slot": "icon", children: [_jsx("title", { children: "Loading..." }), _jsx("circle", { className: LOADING_TRACK_CLASS, cx: "12", cy: "12", r: "9", pathLength: "100" }), _jsxs("g", { children: [_jsx("animateTransform", { attributeName: "transform", attributeType: "xml", type: "rotate", from: "0 12 12", to: "360 12 12", dur: "0.5s", repeatCount: "indefinite" }), _jsx("circle", { className: LOADING_INDICATOR_CLASS, cx: "12", cy: "12", r: "9", pathLength: "100" })] })] }));
|
|
14
19
|
}
|
|
15
20
|
/**
|
|
16
|
-
* Shared
|
|
21
|
+
* Shared loading spinner element with a stable `key`, ready to drop into `Suspense` fallbacks and lists.
|
|
22
|
+
*
|
|
23
|
+
* - A `<Loading>` rendered through `<Icon>`, so it picks up icon sizing, colour, and centring.
|
|
17
24
|
*
|
|
18
25
|
* @see https://shelving.cc/ui/LOADING
|
|
19
26
|
*/
|
|
20
|
-
export const LOADING = _jsx(
|
|
27
|
+
export const LOADING = _jsx(Icon, { icon: Loading }, "loading");
|
package/ui/misc/Loading.md
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
# Loading
|
|
2
2
|
|
|
3
|
-
An animated SVG spinner
|
|
3
|
+
An animated SVG spinner shaped like a Heroicon — a faint full track plus a rotating indicator arc. It takes only `className`, so it behaves like any other icon and is meant to be styled by `<Icon>`.
|
|
4
4
|
|
|
5
5
|
**Things to know:**
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
7
|
+
- The track and indicator paint from scaled steps of the current tint ladder (`--tint-70` / `--tint-80`), so the faint track and brighter indicator both follow whatever tint `<Icon>` (or an ancestor) sets, correctly shaded.
|
|
8
|
+
- The spin is driven by an inline SMIL `<animateTransform>`, so it needs no CSS to animate.
|
|
9
|
+
- Feed it to `<Icon>` to size, colour, and centre it: `<Icon icon={Loading} size="large" status="loading" />`. `<Icon status="loading">` already uses it automatically.
|
|
10
|
+
- `LOADING` is a pre-keyed `<Icon icon={Loading} />` element with a stable `key` — drop it straight into `Suspense` fallbacks and lists to avoid unnecessary reconciliation overhead.
|
|
9
11
|
|
|
10
12
|
## Usage
|
|
11
13
|
|
|
12
14
|
```tsx
|
|
13
|
-
import {
|
|
15
|
+
import { Icon, LOADING, Loading } from "shelving/ui";
|
|
14
16
|
|
|
15
|
-
<
|
|
17
|
+
// Styled through <Icon>, like any other icon.
|
|
18
|
+
<Icon icon={Loading} size="large" />
|
|
19
|
+
|
|
20
|
+
// <Icon status="loading"> uses it for you.
|
|
21
|
+
<Icon status="loading" />
|
|
16
22
|
|
|
17
23
|
// Pre-keyed constant for fallbacks and lists.
|
|
18
24
|
<Suspense fallback={LOADING}>
|
|
@@ -21,3 +27,16 @@ import { Loading, LOADING } from "shelving/ui";
|
|
|
21
27
|
|
|
22
28
|
{busy ? LOADING : children}
|
|
23
29
|
```
|
|
30
|
+
|
|
31
|
+
## Styling
|
|
32
|
+
|
|
33
|
+
Size, centring, and overall colour come from wrapping it in `<Icon>` — its `--icon-color` / `--icon-size` hooks and `color` / `status` / `size` / `tint` variants drive the spinner (see the `Icon` Styling section). On top of that, the two arcs expose their own hooks:
|
|
34
|
+
|
|
35
|
+
| Variable | Styles | Default |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `--loading-track` | Track (background arc) stroke | `var(--tint-70)` |
|
|
38
|
+
| `--loading-indicator` | Indicator (moving arc) stroke | `var(--tint-80)` |
|
|
39
|
+
| `--loading-stroke-width` | Stroke width of both arcs | `2.5` |
|
|
40
|
+
| `--loading-length` | `stroke-dasharray` of the indicator arc | `28 100` |
|
|
41
|
+
|
|
42
|
+
**Global tokens it reads** — the tint-ladder steps `--tint-70` / `--tint-80` for the arc strokes (rebound by the `color` / `status` / `tint` variants on the wrapping `<Icon>`).
|
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
@import "../style/layers.css";
|
|
2
|
-
@import "../style/Typography.module.css";
|
|
3
2
|
@import "../style/Tint.module.css";
|
|
4
3
|
|
|
5
4
|
@layer components {
|
|
6
|
-
.spinner {
|
|
7
|
-
inline-size: var(--loading-size, var(--size-icon));
|
|
8
|
-
block-size: var(--loading-size, var(--size-icon));
|
|
9
|
-
flex: none;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
5
|
.track {
|
|
13
6
|
fill: none;
|
|
14
|
-
stroke: var(--loading-
|
|
7
|
+
stroke: var(--loading-track, var(--tint-70));
|
|
15
8
|
stroke-width: var(--loading-stroke-width, 2.5);
|
|
16
9
|
}
|
|
17
10
|
|
|
18
11
|
.indicator {
|
|
19
12
|
fill: none;
|
|
20
|
-
stroke: var(--loading-
|
|
13
|
+
stroke: var(--loading-indicator, var(--tint-80));
|
|
21
14
|
stroke-width: var(--loading-stroke-width, 2.5);
|
|
22
15
|
stroke-linecap: round;
|
|
23
|
-
stroke-dasharray: var(--loading-
|
|
16
|
+
stroke-dasharray: var(--loading-length, 28 100);
|
|
24
17
|
}
|
|
25
18
|
}
|
package/ui/misc/Loading.tsx
CHANGED
|
@@ -1,37 +1,26 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { getModuleClass } from "../util/css.js";
|
|
3
|
-
import
|
|
3
|
+
import { Icon } from "./Icon.js";
|
|
4
|
+
import LOADING_CSS from "./Loading.module.css";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const LOADING_TRACK_CLASS = getModuleClass(LOADING_CSS, "track");
|
|
7
|
+
const LOADING_INDICATOR_CLASS = getModuleClass(LOADING_CSS, "indicator");
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
|
-
*
|
|
10
|
+
* Animated loading spinner shaped like a Heroicon — a faint track plus a rotating indicator arc.
|
|
9
11
|
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
readonly [_componentProps]?: never;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Animated spinner SVG used as a loading indicator.
|
|
18
|
-
*
|
|
19
|
-
* - Self-contained inline SVG with a rotating indicator arc; inherits its colour and size from the surrounding text.
|
|
12
|
+
* - Self-contained inline SVG; the spin is driven by an inline SMIL `<animateTransform>`.
|
|
13
|
+
* - The track and indicator paint from scaled steps of the current tint ladder (`--tint-70` / `--tint-80`), so their colour follows whatever tint `<Icon>` (or an ancestor) sets.
|
|
14
|
+
* - Takes only `className` like the Heroicons, so it slots straight into `<Icon icon={Loading} />` to pick up icon sizing, colour, and centring.
|
|
20
15
|
*
|
|
21
16
|
* @kind component
|
|
22
17
|
* @see https://shelving.cc/ui/Loading
|
|
23
18
|
*/
|
|
24
|
-
export function Loading(): ReactElement {
|
|
19
|
+
export function Loading({ className }: { className?: string | undefined }): ReactElement {
|
|
25
20
|
return (
|
|
26
|
-
<svg
|
|
27
|
-
aria-hidden="true"
|
|
28
|
-
viewBox="0 0 24 24"
|
|
29
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
30
|
-
className={getModuleClass(styles, "spinner")}
|
|
31
|
-
data-slot="icon"
|
|
32
|
-
>
|
|
21
|
+
<svg aria-hidden="true" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" className={className} data-slot="icon">
|
|
33
22
|
<title>Loading...</title>
|
|
34
|
-
<circle className={
|
|
23
|
+
<circle className={LOADING_TRACK_CLASS} cx="12" cy="12" r="9" pathLength="100" />
|
|
35
24
|
<g>
|
|
36
25
|
<animateTransform
|
|
37
26
|
attributeName="transform"
|
|
@@ -42,15 +31,17 @@ export function Loading(): ReactElement {
|
|
|
42
31
|
dur="0.5s"
|
|
43
32
|
repeatCount="indefinite"
|
|
44
33
|
/>
|
|
45
|
-
<circle className={
|
|
34
|
+
<circle className={LOADING_INDICATOR_CLASS} cx="12" cy="12" r="9" pathLength="100" />
|
|
46
35
|
</g>
|
|
47
36
|
</svg>
|
|
48
37
|
);
|
|
49
38
|
}
|
|
50
39
|
|
|
51
40
|
/**
|
|
52
|
-
* Shared
|
|
41
|
+
* Shared loading spinner element with a stable `key`, ready to drop into `Suspense` fallbacks and lists.
|
|
42
|
+
*
|
|
43
|
+
* - A `<Loading>` rendered through `<Icon>`, so it picks up icon sizing, colour, and centring.
|
|
53
44
|
*
|
|
54
45
|
* @see https://shelving.cc/ui/LOADING
|
|
55
46
|
*/
|
|
56
|
-
export const LOADING = <Loading key="loading" />;
|
|
47
|
+
export const LOADING = <Icon icon={Loading} key="loading" />;
|
package/ui/notice/Message.d.ts
CHANGED
|
@@ -17,10 +17,3 @@ export interface MessageProps extends BlockVariants, StatusVariants, ChildProps
|
|
|
17
17
|
* @see https://shelving.cc/ui/Message
|
|
18
18
|
*/
|
|
19
19
|
export declare function Message({ children, ...props }: MessageProps): import("react").JSX.Element;
|
|
20
|
-
/**
|
|
21
|
-
* Shared loading `<Message>` element containing the `<Loading>` spinner.
|
|
22
|
-
*
|
|
23
|
-
* @example return isLoading ? LOADING_MESSAGE : <Message>{text}</Message>;
|
|
24
|
-
* @see https://shelving.cc/ui/LOADING_MESSAGE
|
|
25
|
-
*/
|
|
26
|
-
export declare const LOADING_MESSAGE: import("react").JSX.Element;
|
package/ui/notice/Message.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { LOADING } from "../misc/Loading.js";
|
|
3
2
|
import { getBlockClass } from "../style/Block.js";
|
|
4
3
|
import { getStatusClass } from "../style/Status.js";
|
|
5
4
|
import { getClass, getModuleClass } from "../util/css.js";
|
|
@@ -18,10 +17,3 @@ export function Message({ children, ...props }) {
|
|
|
18
17
|
return (_jsx("p", { role: status === "error" || status === "danger" ? "alert" : "status", className: getClass(MESSAGE_CLASS, //
|
|
19
18
|
getBlockClass(props), getStatusClass(props)), children: children }));
|
|
20
19
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Shared loading `<Message>` element containing the `<Loading>` spinner.
|
|
23
|
-
*
|
|
24
|
-
* @example return isLoading ? LOADING_MESSAGE : <Message>{text}</Message>;
|
|
25
|
-
* @see https://shelving.cc/ui/LOADING_MESSAGE
|
|
26
|
-
*/
|
|
27
|
-
export const LOADING_MESSAGE = _jsx(Message, { status: "loading", children: LOADING });
|
package/ui/notice/Message.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { LOADING } from "../misc/Loading.js";
|
|
2
1
|
import { type BlockVariants, getBlockClass } from "../style/Block.js";
|
|
3
2
|
import { getStatusClass, type StatusVariants } from "../style/Status.js";
|
|
4
3
|
import { getClass, getModuleClass } from "../util/css.js";
|
|
@@ -37,11 +36,3 @@ export function Message({ children, ...props }: MessageProps) {
|
|
|
37
36
|
</p>
|
|
38
37
|
);
|
|
39
38
|
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Shared loading `<Message>` element containing the `<Loading>` spinner.
|
|
43
|
-
*
|
|
44
|
-
* @example return isLoading ? LOADING_MESSAGE : <Message>{text}</Message>;
|
|
45
|
-
* @see https://shelving.cc/ui/LOADING_MESSAGE
|
|
46
|
-
*/
|
|
47
|
-
export const LOADING_MESSAGE = <Message status="loading">{LOADING}</Message>;
|