shelving 1.262.0 → 1.263.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/react/createAPIContext.d.ts +5 -8
- package/react/createAPIContext.js +0 -2
- package/ui/form/Button.md +2 -0
- package/ui/form/Button.module.css +2 -0
- package/ui/inline/Code.module.css +1 -1
- package/ui/inline/Mark.module.css +2 -2
- package/ui/misc/Catcher.d.ts +10 -33
- package/ui/misc/Catcher.js +12 -18
- package/ui/misc/Catcher.tsx +15 -49
- package/ui/misc/Loader.d.ts +31 -0
- package/ui/misc/Loader.js +29 -0
- package/ui/misc/Loader.tsx +49 -0
- package/ui/misc/index.d.ts +1 -0
- package/ui/misc/index.js +1 -0
- package/ui/misc/index.tsx +1 -0
package/package.json
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { type ReactElement
|
|
1
|
+
import { type ReactElement } from "react";
|
|
2
2
|
import type { Endpoint } from "../api/endpoint/Endpoint.js";
|
|
3
3
|
import type { APIProvider } from "../api/provider/APIProvider.js";
|
|
4
4
|
import type { EndpointStore } from "../api/store/EndpointStore.js";
|
|
5
|
+
import type { ChildProps } from "../ui/index.js";
|
|
5
6
|
import type { Nullish } from "../util/null.js";
|
|
6
7
|
/**
|
|
7
|
-
* Bundle of hooks and a provider component returned by `createAPIContext()
|
|
8
|
+
* Bundle of hooks and a provider component returned by `createAPIContext()`
|
|
8
9
|
*
|
|
9
10
|
* @see https://shelving.cc/react/APIContext
|
|
10
11
|
*/
|
|
11
12
|
export interface APIContext<P, R> {
|
|
12
|
-
/**
|
|
13
|
+
/** React hook to return an `EndpointStore` for the specified endpoint/payload in the current `APIProvider` context. */
|
|
13
14
|
useAPI<PP extends P, RR extends R>(this: void, endpoint: Endpoint<PP, RR>, payload: PP): EndpointStore<PP, RR>;
|
|
14
15
|
useAPI<PP extends P, RR extends R>(this: void, endpoint: Nullish<Endpoint<PP, RR>>, payload: PP): EndpointStore<PP, RR> | undefined;
|
|
15
16
|
/** The `<APIContext>` wrapper to give your React components access to this API provider. */
|
|
16
|
-
readonly APIContext: (
|
|
17
|
-
children: ReactNode;
|
|
18
|
-
}) => ReactElement;
|
|
17
|
+
readonly APIContext: (props: ChildProps) => ReactElement;
|
|
19
18
|
}
|
|
20
19
|
/**
|
|
21
20
|
* Create an API context.
|
|
@@ -24,8 +23,6 @@ export interface APIContext<P, R> {
|
|
|
24
23
|
*
|
|
25
24
|
* @param provider `APIProvider` the created context resolves endpoint stores against.
|
|
26
25
|
*
|
|
27
|
-
* @todo Use and integreate our `EndpointCache` functionality and use it in this.
|
|
28
|
-
*
|
|
29
26
|
* @see https://shelving.cc/react/createAPIContext
|
|
30
27
|
*/
|
|
31
28
|
export declare function createAPIContext<P, R>(provider: APIProvider<P, R>): APIContext<P, R>;
|
|
@@ -11,8 +11,6 @@ import { useStore } from "./useStore.js";
|
|
|
11
11
|
*
|
|
12
12
|
* @param provider `APIProvider` the created context resolves endpoint stores against.
|
|
13
13
|
*
|
|
14
|
-
* @todo Use and integreate our `EndpointCache` functionality and use it in this.
|
|
15
|
-
*
|
|
16
14
|
* @see https://shelving.cc/react/createAPIContext
|
|
17
15
|
*/
|
|
18
16
|
export function createAPIContext(provider) {
|
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
|
}
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
.prose :is(code, kbd, samp, var):not(pre *) {
|
|
20
20
|
/* Box */
|
|
21
21
|
display: inline-block;
|
|
22
|
-
vertical-align: text-bottom;
|
|
23
22
|
padding-inline: var(--code-padding, var(--space-xxsmall));
|
|
24
23
|
border-radius: var(--code-radius, var(--radius-xxsmall));
|
|
24
|
+
vertical-align: baseline;
|
|
25
25
|
|
|
26
26
|
/* Style */
|
|
27
27
|
background: var(--code-background, var(--tint-90));
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
display: inline-block;
|
|
13
13
|
padding-inline: var(--mark-padding, var(--space-xxsmall));
|
|
14
14
|
border-radius: var(--mark-radius, var(--radius-xxsmall));
|
|
15
|
-
vertical-align:
|
|
15
|
+
vertical-align: baseline;
|
|
16
16
|
|
|
17
17
|
/* Style */
|
|
18
|
-
background
|
|
18
|
+
background: var(--mark-background, var(--tint-80));
|
|
19
19
|
color: var(--mark-color, var(--tint-00));
|
|
20
20
|
|
|
21
21
|
/* Text */
|
package/ui/misc/Catcher.d.ts
CHANGED
|
@@ -22,9 +22,9 @@ export declare function RetryButton({ children, ...props }: RetryButtonProps): R
|
|
|
22
22
|
/**
|
|
23
23
|
* Props for a component that renders a caught error `reason`.
|
|
24
24
|
*
|
|
25
|
-
* @see https://shelving.cc/ui/
|
|
25
|
+
* @see https://shelving.cc/ui/ErrorProps
|
|
26
26
|
*/
|
|
27
|
-
export interface
|
|
27
|
+
export interface ErrorProps {
|
|
28
28
|
reason: unknown;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
@@ -34,7 +34,7 @@ export interface ErrorComponentProps {
|
|
|
34
34
|
*/
|
|
35
35
|
export interface CatcherProps extends ChildProps {
|
|
36
36
|
/** Component to render an error (defaults to `<ErrorNotice />`) */
|
|
37
|
-
as: (props:
|
|
37
|
+
as: (props: ErrorProps) => ReactElement;
|
|
38
38
|
}
|
|
39
39
|
type CatcherState = {
|
|
40
40
|
/** The error that was caught. */
|
|
@@ -56,27 +56,6 @@ export declare class Catcher extends Component<CatcherProps, CatcherState> {
|
|
|
56
56
|
static getDerivedStateFromError(reason: unknown): CatcherState;
|
|
57
57
|
render(): ReactNode;
|
|
58
58
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Props for `<PageCatcher>` — the page `children` to guard.
|
|
61
|
-
*
|
|
62
|
-
* @see https://shelving.cc/ui/PageCatcherProps
|
|
63
|
-
*/
|
|
64
|
-
export interface PageCatcherProps extends ChildProps {
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Error boundary for a whole page that renders a full `<ErrorPage>` fallback on error.
|
|
68
|
-
*
|
|
69
|
-
* @kind component
|
|
70
|
-
* @see https://shelving.cc/ui/PageCatcher
|
|
71
|
-
*/
|
|
72
|
-
export declare function PageCatcher({ children }: PageCatcherProps): ReactElement;
|
|
73
|
-
/**
|
|
74
|
-
* Props for `<ErrorNotice>` — the caught error `reason`.
|
|
75
|
-
*
|
|
76
|
-
* @see https://shelving.cc/ui/ErrorNoticeProps
|
|
77
|
-
*/
|
|
78
|
-
export interface ErrorNoticeProps extends ErrorComponentProps {
|
|
79
|
-
}
|
|
80
59
|
/**
|
|
81
60
|
* Render a caught error as an inline `<Notice>` with a retry button.
|
|
82
61
|
*
|
|
@@ -85,21 +64,19 @@ export interface ErrorNoticeProps extends ErrorComponentProps {
|
|
|
85
64
|
* @kind component
|
|
86
65
|
* @see https://shelving.cc/ui/ErrorNotice
|
|
87
66
|
*/
|
|
88
|
-
export declare function ErrorNotice({ reason }:
|
|
67
|
+
export declare function ErrorNotice({ reason }: ErrorProps): ReactElement;
|
|
89
68
|
/**
|
|
90
|
-
*
|
|
69
|
+
* Error boundary for a whole page that renders a full `<ErrorPage>` fallback on error.
|
|
91
70
|
*
|
|
92
|
-
* @
|
|
71
|
+
* @kind component
|
|
72
|
+
* @see https://shelving.cc/ui/PageCatcher
|
|
93
73
|
*/
|
|
94
|
-
export
|
|
95
|
-
}
|
|
74
|
+
export declare function PageCatcher({ children }: ChildProps): ReactElement;
|
|
96
75
|
/**
|
|
97
|
-
* Render a caught error as a full-page `<Page>` with
|
|
98
|
-
*
|
|
99
|
-
* - 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>`.
|
|
100
77
|
*
|
|
101
78
|
* @kind component
|
|
102
79
|
* @see https://shelving.cc/ui/ErrorPage
|
|
103
80
|
*/
|
|
104
|
-
export declare function ErrorPage({ reason }:
|
|
81
|
+
export declare function ErrorPage({ reason }: ErrorProps): ReactElement;
|
|
105
82
|
export {};
|
package/ui/misc/Catcher.js
CHANGED
|
@@ -2,14 +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 {
|
|
6
|
-
import { Row } from "../block/Row.js";
|
|
7
|
-
import { Subheading } from "../block/Subheading.js";
|
|
5
|
+
import { Paragraph } from "../block/Paragraph.js";
|
|
8
6
|
import { Button } from "../form/Button.js";
|
|
9
7
|
import { CenteredLayout } from "../layout/CenteredLayout.js";
|
|
10
8
|
import { Notice } from "../notice/Notice.js";
|
|
11
9
|
import { Page } from "../page/Page.js";
|
|
12
|
-
import { Icon } from "./Icon.js";
|
|
13
10
|
const RetryContext = createContext(undefined);
|
|
14
11
|
RetryContext.displayName = "RetryContext";
|
|
15
12
|
const RETRY_CHILDREN = (_jsxs(_Fragment, { children: [_jsx(ArrowPathIcon, {}), "Retry"] }));
|
|
@@ -59,15 +56,6 @@ export class Catcher extends Component {
|
|
|
59
56
|
return (_jsx(RetryContext, { value: retry, children: _jsx(ErrorComponent, { reason: reason }) }));
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Error boundary for a whole page that renders a full `<ErrorPage>` fallback on error.
|
|
64
|
-
*
|
|
65
|
-
* @kind component
|
|
66
|
-
* @see https://shelving.cc/ui/PageCatcher
|
|
67
|
-
*/
|
|
68
|
-
export function PageCatcher({ children }) {
|
|
69
|
-
return _jsx(Catcher, { as: ErrorPage, children: children });
|
|
70
|
-
}
|
|
71
59
|
/**
|
|
72
60
|
* Render a caught error as an inline `<Notice>` with a retry button.
|
|
73
61
|
*
|
|
@@ -78,17 +66,23 @@ export function PageCatcher({ children }) {
|
|
|
78
66
|
*/
|
|
79
67
|
export function ErrorNotice({ reason }) {
|
|
80
68
|
const message = getMessage(reason) ?? "Unknown error";
|
|
81
|
-
return (_jsxs(Notice, { status: "error", children: [_jsx(
|
|
69
|
+
return (_jsxs(Notice, { status: "error", children: [_jsx(Paragraph, { children: message }), _jsx(RetryButton, { small: true })] }));
|
|
82
70
|
}
|
|
83
71
|
/**
|
|
84
|
-
*
|
|
72
|
+
* Error boundary for a whole page that renders a full `<ErrorPage>` fallback on error.
|
|
85
73
|
*
|
|
86
|
-
*
|
|
74
|
+
* @kind component
|
|
75
|
+
* @see https://shelving.cc/ui/PageCatcher
|
|
76
|
+
*/
|
|
77
|
+
export function PageCatcher({ children }) {
|
|
78
|
+
return _jsx(Catcher, { as: ErrorPage, children: children });
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Render a caught error as a full-page `<Page>` with a centered `<ErrorNotice>`.
|
|
87
82
|
*
|
|
88
83
|
* @kind component
|
|
89
84
|
* @see https://shelving.cc/ui/ErrorPage
|
|
90
85
|
*/
|
|
91
86
|
export function ErrorPage({ reason }) {
|
|
92
|
-
|
|
93
|
-
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 }) }) }));
|
|
94
88
|
}
|
package/ui/misc/Catcher.tsx
CHANGED
|
@@ -2,15 +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 {
|
|
6
|
-
import { Row } from "../block/Row.js";
|
|
7
|
-
import { Subheading } from "../block/Subheading.js";
|
|
5
|
+
import { Paragraph } from "../block/Paragraph.js";
|
|
8
6
|
import { Button, type ButtonVariants } from "../form/Button.js";
|
|
9
7
|
import { CenteredLayout } from "../layout/CenteredLayout.js";
|
|
10
8
|
import { Notice } from "../notice/Notice.js";
|
|
11
9
|
import { Page } from "../page/Page.js";
|
|
12
10
|
import type { ChildProps, OptionalChildProps } from "../util/props.js";
|
|
13
|
-
import { Icon } from "./Icon.js";
|
|
14
11
|
|
|
15
12
|
const RetryContext = createContext<Callback | undefined>(undefined);
|
|
16
13
|
RetryContext.displayName = "RetryContext";
|
|
@@ -51,9 +48,9 @@ export function RetryButton({ children = RETRY_CHILDREN, ...props }: RetryButton
|
|
|
51
48
|
/**
|
|
52
49
|
* Props for a component that renders a caught error `reason`.
|
|
53
50
|
*
|
|
54
|
-
* @see https://shelving.cc/ui/
|
|
51
|
+
* @see https://shelving.cc/ui/ErrorProps
|
|
55
52
|
*/
|
|
56
|
-
export interface
|
|
53
|
+
export interface ErrorProps {
|
|
57
54
|
reason: unknown;
|
|
58
55
|
}
|
|
59
56
|
|
|
@@ -64,7 +61,7 @@ export interface ErrorComponentProps {
|
|
|
64
61
|
*/
|
|
65
62
|
export interface CatcherProps extends ChildProps {
|
|
66
63
|
/** Component to render an error (defaults to `<ErrorNotice />`) */
|
|
67
|
-
as: (props:
|
|
64
|
+
as: (props: ErrorProps) => ReactElement;
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
type CatcherState = {
|
|
@@ -107,30 +104,6 @@ export class Catcher extends Component<CatcherProps, CatcherState> {
|
|
|
107
104
|
}
|
|
108
105
|
}
|
|
109
106
|
|
|
110
|
-
/**
|
|
111
|
-
* Props for `<PageCatcher>` — the page `children` to guard.
|
|
112
|
-
*
|
|
113
|
-
* @see https://shelving.cc/ui/PageCatcherProps
|
|
114
|
-
*/
|
|
115
|
-
export interface PageCatcherProps extends ChildProps {}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Error boundary for a whole page that renders a full `<ErrorPage>` fallback on error.
|
|
119
|
-
*
|
|
120
|
-
* @kind component
|
|
121
|
-
* @see https://shelving.cc/ui/PageCatcher
|
|
122
|
-
*/
|
|
123
|
-
export function PageCatcher({ children }: PageCatcherProps): ReactElement {
|
|
124
|
-
return <Catcher as={ErrorPage}>{children}</Catcher>;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Props for `<ErrorNotice>` — the caught error `reason`.
|
|
129
|
-
*
|
|
130
|
-
* @see https://shelving.cc/ui/ErrorNoticeProps
|
|
131
|
-
*/
|
|
132
|
-
export interface ErrorNoticeProps extends ErrorComponentProps {}
|
|
133
|
-
|
|
134
107
|
/**
|
|
135
108
|
* Render a caught error as an inline `<Notice>` with a retry button.
|
|
136
109
|
*
|
|
@@ -139,44 +112,37 @@ export interface ErrorNoticeProps extends ErrorComponentProps {}
|
|
|
139
112
|
* @kind component
|
|
140
113
|
* @see https://shelving.cc/ui/ErrorNotice
|
|
141
114
|
*/
|
|
142
|
-
export function ErrorNotice({ reason }:
|
|
115
|
+
export function ErrorNotice({ reason }: ErrorProps): ReactElement {
|
|
143
116
|
const message = getMessage(reason) ?? "Unknown error";
|
|
144
117
|
return (
|
|
145
118
|
<Notice status="error">
|
|
146
|
-
<
|
|
119
|
+
<Paragraph>{message}</Paragraph>
|
|
147
120
|
<RetryButton small />
|
|
148
121
|
</Notice>
|
|
149
122
|
);
|
|
150
123
|
}
|
|
151
124
|
|
|
152
125
|
/**
|
|
153
|
-
*
|
|
126
|
+
* Error boundary for a whole page that renders a full `<ErrorPage>` fallback on error.
|
|
154
127
|
*
|
|
155
|
-
* @
|
|
128
|
+
* @kind component
|
|
129
|
+
* @see https://shelving.cc/ui/PageCatcher
|
|
156
130
|
*/
|
|
157
|
-
export
|
|
131
|
+
export function PageCatcher({ children }: ChildProps): ReactElement {
|
|
132
|
+
return <Catcher as={ErrorPage}>{children}</Catcher>;
|
|
133
|
+
}
|
|
158
134
|
|
|
159
135
|
/**
|
|
160
|
-
* Render a caught error as a full-page `<Page>` with
|
|
161
|
-
*
|
|
162
|
-
* - 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>`.
|
|
163
137
|
*
|
|
164
138
|
* @kind component
|
|
165
139
|
* @see https://shelving.cc/ui/ErrorPage
|
|
166
140
|
*/
|
|
167
|
-
export function ErrorPage({ reason }:
|
|
168
|
-
const message = getMessage(reason) ?? "Unknown error";
|
|
141
|
+
export function ErrorPage({ reason }: ErrorProps): ReactElement {
|
|
169
142
|
return (
|
|
170
143
|
<Page title="Error">
|
|
171
144
|
<CenteredLayout>
|
|
172
|
-
<
|
|
173
|
-
<Subheading>
|
|
174
|
-
<Row left>
|
|
175
|
-
<Icon status="error" /> {message}
|
|
176
|
-
</Row>
|
|
177
|
-
</Subheading>
|
|
178
|
-
<RetryButton />
|
|
179
|
-
</Card>
|
|
145
|
+
<ErrorNotice reason={reason} />
|
|
180
146
|
</CenteredLayout>
|
|
181
147
|
</Page>
|
|
182
148
|
);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactElement, type ReactNode } from "react";
|
|
2
|
+
import type { ChildProps } from "../util/props.js";
|
|
3
|
+
/**
|
|
4
|
+
* Props for `<Loader>` and `<PageLoader>` — the `children` to load plus an optional `fallback` shown while they suspend.
|
|
5
|
+
*
|
|
6
|
+
* @see https://shelving.cc/ui/LoaderProps
|
|
7
|
+
*/
|
|
8
|
+
export interface LoaderProps extends ChildProps {
|
|
9
|
+
/** Element rendered while `children` suspend (defaults to `LOADING`). */
|
|
10
|
+
readonly fallback?: ReactNode | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Load a component.
|
|
14
|
+
*
|
|
15
|
+
* - Wrapped in `<Catcher>` so child components can throw errors.
|
|
16
|
+
* - Wrapped in `<Suspense>` so child components can throw promises.
|
|
17
|
+
*
|
|
18
|
+
* @kind component
|
|
19
|
+
* @see https://shelving.cc/ui/Loader
|
|
20
|
+
*/
|
|
21
|
+
export declare function Loader({ children, fallback }: LoaderProps): ReactElement;
|
|
22
|
+
/**
|
|
23
|
+
* Load a page.
|
|
24
|
+
*
|
|
25
|
+
* - Wrapped in `<PageCatcher>` so child components can throw errors.
|
|
26
|
+
* - Wrapped in `<Suspense>` so child components can throw promises.
|
|
27
|
+
*
|
|
28
|
+
* @kind component
|
|
29
|
+
* @see https://shelving.cc/ui/PageLoader
|
|
30
|
+
*/
|
|
31
|
+
export declare function PageLoader({ children, fallback }: LoaderProps): ReactElement;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
import { CenteredLayout } from "../layout/CenteredLayout.js";
|
|
4
|
+
import { Catcher, PageCatcher } from "./Catcher.js";
|
|
5
|
+
import { LOADING } from "./Loading.js";
|
|
6
|
+
/**
|
|
7
|
+
* Load a component.
|
|
8
|
+
*
|
|
9
|
+
* - Wrapped in `<Catcher>` so child components can throw errors.
|
|
10
|
+
* - Wrapped in `<Suspense>` so child components can throw promises.
|
|
11
|
+
*
|
|
12
|
+
* @kind component
|
|
13
|
+
* @see https://shelving.cc/ui/Loader
|
|
14
|
+
*/
|
|
15
|
+
export function Loader({ children, fallback = LOADING }) {
|
|
16
|
+
return (_jsx(Catcher, { children: _jsx(Suspense, { fallback: fallback, children: children }) }));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Load a page.
|
|
20
|
+
*
|
|
21
|
+
* - Wrapped in `<PageCatcher>` so child components can throw errors.
|
|
22
|
+
* - Wrapped in `<Suspense>` so child components can throw promises.
|
|
23
|
+
*
|
|
24
|
+
* @kind component
|
|
25
|
+
* @see https://shelving.cc/ui/PageLoader
|
|
26
|
+
*/
|
|
27
|
+
export function PageLoader({ children, fallback = _jsx(CenteredLayout, { children: LOADING }) }) {
|
|
28
|
+
return (_jsx(PageCatcher, { children: _jsx(Suspense, { fallback: fallback, children: children }) }));
|
|
29
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ReactElement, type ReactNode, Suspense } from "react";
|
|
2
|
+
import { CenteredLayout } from "../layout/CenteredLayout.js";
|
|
3
|
+
import type { ChildProps } from "../util/props.js";
|
|
4
|
+
import { Catcher, PageCatcher } from "./Catcher.js";
|
|
5
|
+
import { LOADING } from "./Loading.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Props for `<Loader>` and `<PageLoader>` — the `children` to load plus an optional `fallback` shown while they suspend.
|
|
9
|
+
*
|
|
10
|
+
* @see https://shelving.cc/ui/LoaderProps
|
|
11
|
+
*/
|
|
12
|
+
export interface LoaderProps extends ChildProps {
|
|
13
|
+
/** Element rendered while `children` suspend (defaults to `LOADING`). */
|
|
14
|
+
readonly fallback?: ReactNode | undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Load a component.
|
|
19
|
+
*
|
|
20
|
+
* - Wrapped in `<Catcher>` so child components can throw errors.
|
|
21
|
+
* - Wrapped in `<Suspense>` so child components can throw promises.
|
|
22
|
+
*
|
|
23
|
+
* @kind component
|
|
24
|
+
* @see https://shelving.cc/ui/Loader
|
|
25
|
+
*/
|
|
26
|
+
export function Loader({ children, fallback = LOADING }: LoaderProps): ReactElement {
|
|
27
|
+
return (
|
|
28
|
+
<Catcher>
|
|
29
|
+
<Suspense fallback={fallback}>{children}</Suspense>
|
|
30
|
+
</Catcher>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Load a page.
|
|
36
|
+
*
|
|
37
|
+
* - Wrapped in `<PageCatcher>` so child components can throw errors.
|
|
38
|
+
* - Wrapped in `<Suspense>` so child components can throw promises.
|
|
39
|
+
*
|
|
40
|
+
* @kind component
|
|
41
|
+
* @see https://shelving.cc/ui/PageLoader
|
|
42
|
+
*/
|
|
43
|
+
export function PageLoader({ children, fallback = <CenteredLayout>{LOADING}</CenteredLayout> }: LoaderProps): ReactElement {
|
|
44
|
+
return (
|
|
45
|
+
<PageCatcher>
|
|
46
|
+
<Suspense fallback={fallback}>{children}</Suspense>
|
|
47
|
+
</PageCatcher>
|
|
48
|
+
);
|
|
49
|
+
}
|
package/ui/misc/index.d.ts
CHANGED
package/ui/misc/index.js
CHANGED