@beautinique/frontend-components 1.0.4 → 1.0.6
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/README.md +67 -25
- package/dist/index.cjs +17 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/toast/ToastContainer.d.cts +5 -3
- package/dist/toast/ToastContainer.d.cts.map +1 -1
- package/dist/toast/ToastContainer.d.ts +5 -3
- package/dist/toast/ToastContainer.d.ts.map +1 -1
- package/dist/toast/index.cjs +155 -184
- package/dist/toast/index.cjs.map +1 -1
- package/dist/toast/index.d.cts +2 -3
- package/dist/toast/index.d.cts.map +1 -1
- package/dist/toast/index.d.ts +2 -3
- package/dist/toast/index.d.ts.map +1 -1
- package/dist/toast/index.js +155 -179
- package/dist/toast/index.js.map +1 -1
- package/dist/toast/toaster.d.cts +62 -3
- package/dist/toast/toaster.d.cts.map +1 -1
- package/dist/toast/toaster.d.ts +62 -3
- package/dist/toast/toaster.d.ts.map +1 -1
- package/dist/toast/types.d.cts +8 -8
- package/dist/toast/types.d.cts.map +1 -1
- package/dist/toast/types.d.ts +8 -8
- package/dist/toast/types.d.ts.map +1 -1
- package/dist/toast/uploads.d.cts +21 -30
- package/dist/toast/uploads.d.cts.map +1 -1
- package/dist/toast/uploads.d.ts +21 -30
- package/dist/toast/uploads.d.ts.map +1 -1
- package/package.json +3 -5
- package/dist/toast/toast.store.d.cts +0 -4
- package/dist/toast/toast.store.d.cts.map +0 -1
- package/dist/toast/toast.store.d.ts +0 -4
- package/dist/toast/toast.store.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -8,10 +8,10 @@ The components are styled with Tailwind classes and with the tokens (colours, sh
|
|
|
8
8
|
## Installation
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
npm install @beautinique/frontend-components @beautinique/frontend-styles @iconify/react
|
|
11
|
+
npm install @beautinique/frontend-components @beautinique/frontend-stores @beautinique/frontend-styles @iconify/react
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
Peer dependencies: `react`, `react-dom`, `@iconify/react`, `@beautinique/frontend-styles
|
|
14
|
+
Peer dependencies: `react`, `react-dom`, `@iconify/react`, `@beautinique/frontend-styles` and [`@beautinique/frontend-stores`](../stores/README.md) (the toasts are kept in a store that the app makes with it, see [Toasts](#toasts); that needs `zustand` in the app).
|
|
15
15
|
|
|
16
16
|
## Setup (once per app)
|
|
17
17
|
|
|
@@ -32,28 +32,36 @@ generated and the components come out unstyled. (The playground has a page that
|
|
|
32
32
|
Components that most screens use live in `/ui` (and, later, `/layout`). Components that few screens
|
|
33
33
|
use have a path of their own, so an app only bundles what it imports.
|
|
34
34
|
|
|
35
|
-
| Import path | What it gives
|
|
36
|
-
| --------------------------------------------- |
|
|
37
|
-
| `@beautinique/frontend-components` |
|
|
38
|
-
| `@beautinique/frontend-components/ui` | `Button`, `Tooltip`
|
|
39
|
-
| `@beautinique/frontend-components/toast` | `ToastContainer`, `
|
|
40
|
-
| `@beautinique/frontend-components/source.css` | The `@source` line of the setup above
|
|
35
|
+
| Import path | What it gives |
|
|
36
|
+
| --------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
37
|
+
| `@beautinique/frontend-components` | Everything `/ui` and `/toast` give (the very same values), and the types (`IButton`, ...) |
|
|
38
|
+
| `@beautinique/frontend-components/ui` | `Button`, `Tooltip` |
|
|
39
|
+
| `@beautinique/frontend-components/toast` | `ToastContainer`, `createToaster`, and the helpers and types of toasts |
|
|
40
|
+
| `@beautinique/frontend-components/source.css` | The `@source` line of the setup above |
|
|
41
|
+
|
|
42
|
+
`Button` can be imported from the root or from `/ui`, it is the same component either way:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { Button } from '@beautinique/frontend-components'; // or
|
|
46
|
+
import { Button } from '@beautinique/frontend-components/ui';
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The root only re-exports, it does not copy: an app that imports only `Button` from the root bundles the
|
|
50
|
+
same as with `/ui` (the bundler leaves out what is not used).
|
|
41
51
|
|
|
42
52
|
```tsx
|
|
43
|
-
import { Button, Tooltip } from '@beautinique/frontend-components
|
|
44
|
-
|
|
53
|
+
import { Button, Tooltip } from '@beautinique/frontend-components';
|
|
54
|
+
|
|
55
|
+
import { toaster } from '@/utils/toaster'; // made in the app, see Toasts
|
|
45
56
|
|
|
46
57
|
const App = () => (
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/>
|
|
55
|
-
</Tooltip>
|
|
56
|
-
</>
|
|
58
|
+
<Tooltip title="Save" description="Ctrl + S">
|
|
59
|
+
<Button
|
|
60
|
+
pattern="primary"
|
|
61
|
+
content="Save"
|
|
62
|
+
buttonProps={{ onClick: () => toaster.success({ title: 'Saved' }) }}
|
|
63
|
+
/>
|
|
64
|
+
</Tooltip>
|
|
57
65
|
);
|
|
58
66
|
```
|
|
59
67
|
|
|
@@ -104,6 +112,38 @@ const hint = (
|
|
|
104
112
|
|
|
105
113
|
### Toasts
|
|
106
114
|
|
|
115
|
+
The toasts are kept in a store that **the app makes**, once, with the toasts of this package, and gives to the two things that need it: the `ToastContainer` that draws them, and `createToaster` that shows them. The package holds no store of its own, and exports none.
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
// src/stores/toast.store.ts
|
|
119
|
+
import type { TToast } from '@beautinique/frontend-components';
|
|
120
|
+
import { createToastStore } from '@beautinique/frontend-stores';
|
|
121
|
+
|
|
122
|
+
export const useToastStore = createToastStore<TToast>();
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
// src/utils/toaster.ts - the toaster and the helpers, for the rest of the app to import
|
|
127
|
+
import { createToaster } from '@beautinique/frontend-components';
|
|
128
|
+
|
|
129
|
+
import { useToastStore } from '@/stores/toast.store';
|
|
130
|
+
|
|
131
|
+
export const {
|
|
132
|
+
toaster,
|
|
133
|
+
withProgressToast,
|
|
134
|
+
withUploadsToast,
|
|
135
|
+
runUploadsInToast,
|
|
136
|
+
createUploadsToast,
|
|
137
|
+
} = createToaster(useToastStore);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
// once, near the root of the app
|
|
142
|
+
import { ToastContainer } from '@beautinique/frontend-components';
|
|
143
|
+
|
|
144
|
+
<ToastContainer store={useToastStore} />;
|
|
145
|
+
```
|
|
146
|
+
|
|
107
147
|
`toaster` works from anywhere (an API client, a store), not only from components:
|
|
108
148
|
|
|
109
149
|
```tsx
|
|
@@ -116,18 +156,19 @@ toaster.custom({ type: 'custom', children: <p>Any React content</p> });
|
|
|
116
156
|
```
|
|
117
157
|
|
|
118
158
|
Toasts that follow uploads (`withProgressToast` for one request, `createUploadsToast`,
|
|
119
|
-
`withUploadsToast` and `runUploadsInToast` for several) are described in `src/toast/uploads.ts`.
|
|
159
|
+
`withUploadsToast` and `runUploadsInToast` for several) come out of `createToaster` too, and are described in `src/toast/uploads.ts`.
|
|
120
160
|
`runUploadsInToast` shows one toast for the uploads of several fields: the overall progress on the
|
|
121
161
|
left and a row (waiting, uploading, done or failed) for each field that has files.
|
|
122
162
|
|
|
163
|
+
**The store has to be one.** The container and `createToaster` must be given the same store: a toast added to a store that no container draws is never shown. Make it once (a module of the app, imported from there) and the two cannot differ. `createToaster` is also checked by the compiler: it takes a store of this package's `TToast`, nothing else.
|
|
164
|
+
|
|
123
165
|
The icons of the toasts are bundled, so a toast shows its icon without a network.
|
|
124
166
|
|
|
125
167
|
## Rules for the code of this package
|
|
126
168
|
|
|
127
|
-
- **
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
through it would never reach the `ToastContainer`.
|
|
169
|
+
- **The package holds no state.** The toast store is made by the app (`createToastStore` of `@beautinique/frontend-stores`, with this package's `TToast`) and given in, to the `ToastContainer` as a prop and to `createToaster`. Nothing here makes a store or exports one, so the package can never be the cause of two of them. The root only re-exports `/ui` and `/toast` (`tsup.config.ts` keeps them external, and `built-files.test.ts` checks the built files after `npm run build`).
|
|
170
|
+
- **The root has what most screens use** (`/ui`, later `/layout`, and `/toast`). A component that few
|
|
171
|
+
screens use gets a path of its own and is not in the root.
|
|
131
172
|
- **A component's own css lives next to the component** and is imported by it, not by the styles
|
|
132
173
|
package. It uses the variables of the styles package (`var(--smoke-eerie)`, ...) and does not
|
|
133
174
|
import them again: importing them a second time, after the app's own css, would undo the app's
|
|
@@ -138,6 +179,7 @@ The icons of the toasts are bundled, so a toast shows its icon without a network
|
|
|
138
179
|
|
|
139
180
|
```bash
|
|
140
181
|
npm run build # dist (needed by the playground and by the type check of the playground)
|
|
182
|
+
# `@beautinique/frontend-stores` has to be built first (`npm run build` at the root of the repo does it in order)
|
|
141
183
|
npm run playground # http://localhost:4200 - the components, in a real browser
|
|
142
184
|
npm test
|
|
143
185
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var toast = require('@beautinique/frontend-components/toast');
|
|
4
|
+
var ui = require('@beautinique/frontend-components/ui');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.keys(toast).forEach(function (k) {
|
|
9
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () { return toast[k]; }
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
Object.keys(ui).forEach(function (k) {
|
|
15
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return ui[k]; }
|
|
18
|
+
});
|
|
19
|
+
});
|
|
3
20
|
//# sourceMappingURL=index.cjs.map
|
|
4
21
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs","sourcesContent":[]}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,kBAAkB,CAAC;AACjC,mBAAmB,sBAAsB,CAAC;AAC1C,cAAc,eAAe,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,kBAAkB,CAAC;AACjC,mBAAmB,sBAAsB,CAAC;AAC1C,cAAc,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { IClassName } from '../types/component.js';
|
|
2
|
-
import type { TToastItem } from './types.js';
|
|
3
|
-
export declare const Toaster: import("react").MemoExoticComponent<(props: TToastItem & IClassName
|
|
4
|
-
|
|
2
|
+
import type { IToastContainer, TToastItem } from './types.js';
|
|
3
|
+
export declare const Toaster: import("react").MemoExoticComponent<(props: TToastItem & IClassName & {
|
|
4
|
+
onRemove?: (id: string) => void;
|
|
5
|
+
}) => import("react").JSX.Element | null>;
|
|
6
|
+
export declare const ToastContainer: ({ store: useToastStore }: IToastContainer) => import("react").JSX.Element | null;
|
|
5
7
|
//# sourceMappingURL=ToastContainer.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastContainer.d.cts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"ToastContainer.d.cts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EACV,eAAe,EAGf,UAAU,EAEX,MAAM,YAAY,CAAC;AA4UpB,eAAO,MAAM,OAAO,8CAzJQ,UAAU,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,wCAyJjD,CAAC;AAEzC,eAAO,MAAM,cAAc,GAAI,0BAA0B,eAAe,uCAavE,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { IClassName } from '../types/component.js';
|
|
2
|
-
import type { TToastItem } from './types.js';
|
|
3
|
-
export declare const Toaster: import("react").MemoExoticComponent<(props: TToastItem & IClassName
|
|
4
|
-
|
|
2
|
+
import type { IToastContainer, TToastItem } from './types.js';
|
|
3
|
+
export declare const Toaster: import("react").MemoExoticComponent<(props: TToastItem & IClassName & {
|
|
4
|
+
onRemove?: (id: string) => void;
|
|
5
|
+
}) => import("react").JSX.Element | null>;
|
|
6
|
+
export declare const ToastContainer: ({ store: useToastStore }: IToastContainer) => import("react").JSX.Element | null;
|
|
5
7
|
//# sourceMappingURL=ToastContainer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastContainer.d.ts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"ToastContainer.d.ts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EACV,eAAe,EAGf,UAAU,EAEX,MAAM,YAAY,CAAC;AA4UpB,eAAO,MAAM,OAAO,8CAzJQ,UAAU,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,wCAyJjD,CAAC;AAEzC,eAAO,MAAM,cAAc,GAAI,0BAA0B,eAAe,uCAavE,CAAC"}
|
package/dist/toast/index.cjs
CHANGED
|
@@ -1,58 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var nanoid = require('nanoid');
|
|
4
|
-
var zustand = require('zustand');
|
|
5
3
|
var react$1 = require('@iconify/react');
|
|
6
4
|
var react = require('react');
|
|
7
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
6
|
|
|
9
7
|
var __defProp = Object.defineProperty;
|
|
10
8
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
11
|
-
|
|
12
|
-
// src/lib/constants.ts
|
|
13
|
-
var TOAST_TYPES = [
|
|
14
|
-
"success",
|
|
15
|
-
"error",
|
|
16
|
-
"warning",
|
|
17
|
-
"progress",
|
|
18
|
-
"uploads",
|
|
19
|
-
"loading",
|
|
20
|
-
"default",
|
|
21
|
-
"custom"
|
|
22
|
-
];
|
|
23
|
-
var TOAST_TYPE = Object.fromEntries(TOAST_TYPES.map((type) => [type, type]));
|
|
24
|
-
|
|
25
|
-
// src/toast/toast.store.ts
|
|
26
|
-
var useToastStore = zustand.create((set) => ({
|
|
27
|
-
toasts: [],
|
|
28
|
-
add: /* @__PURE__ */ __name((toast) => {
|
|
29
|
-
const id = nanoid.nanoid();
|
|
30
|
-
set((state) => ({ toasts: [...state.toasts, { ...toast, id }] }));
|
|
31
|
-
return id;
|
|
32
|
-
}, "add"),
|
|
33
|
-
update: {
|
|
34
|
-
progress: /* @__PURE__ */ __name((id, progress) => {
|
|
35
|
-
set((state) => ({
|
|
36
|
-
toasts: state.toasts.map((toast) => toast.id === id ? { ...toast, progress } : toast)
|
|
37
|
-
}));
|
|
38
|
-
}, "progress"),
|
|
39
|
-
uploadItem: /* @__PURE__ */ __name((id, itemId, patch) => {
|
|
40
|
-
set((state) => ({
|
|
41
|
-
toasts: state.toasts.map(
|
|
42
|
-
(toast) => toast.id === id && toast.type === TOAST_TYPE.uploads ? {
|
|
43
|
-
...toast,
|
|
44
|
-
items: toast.items.map(
|
|
45
|
-
(item) => item.id === itemId ? { ...item, ...patch } : item
|
|
46
|
-
)
|
|
47
|
-
} : toast
|
|
48
|
-
)
|
|
49
|
-
}));
|
|
50
|
-
}, "uploadItem")
|
|
51
|
-
},
|
|
52
|
-
remove: /* @__PURE__ */ __name((id) => {
|
|
53
|
-
set((state) => ({ toasts: state.toasts.filter((t) => t.id !== id) }));
|
|
54
|
-
}, "remove")
|
|
55
|
-
}));
|
|
56
9
|
var TOAST_ICON_SETS = [
|
|
57
10
|
{
|
|
58
11
|
prefix: "solar",
|
|
@@ -114,6 +67,19 @@ var TOAST_ICON_NAMES = TOAST_ICON_SETS.flatMap(
|
|
|
114
67
|
({ prefix, icons }) => Object.keys(icons).map((name) => `${prefix}:${name}`)
|
|
115
68
|
);
|
|
116
69
|
|
|
70
|
+
// src/lib/constants.ts
|
|
71
|
+
var TOAST_TYPES = [
|
|
72
|
+
"success",
|
|
73
|
+
"error",
|
|
74
|
+
"warning",
|
|
75
|
+
"progress",
|
|
76
|
+
"uploads",
|
|
77
|
+
"loading",
|
|
78
|
+
"default",
|
|
79
|
+
"custom"
|
|
80
|
+
];
|
|
81
|
+
var TOAST_TYPE = Object.fromEntries(TOAST_TYPES.map((type) => [type, type]));
|
|
82
|
+
|
|
117
83
|
// src/lib/button.ts
|
|
118
84
|
var PATTERN_CSS = {
|
|
119
85
|
primary: "text-white bg-sky-blue-burst shadow-primary-btn hover:shadow-primary-btn-hover",
|
|
@@ -151,52 +117,6 @@ var Button = /* @__PURE__ */ __name(({
|
|
|
151
117
|
)
|
|
152
118
|
), "Button");
|
|
153
119
|
|
|
154
|
-
// src/toast/toaster.ts
|
|
155
|
-
var { add, update, remove } = useToastStore.getState();
|
|
156
|
-
var toaster = {
|
|
157
|
-
success: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.success }), "success"),
|
|
158
|
-
error: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.error }), "error"),
|
|
159
|
-
warning: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.warning }), "warning"),
|
|
160
|
-
default: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.default }), "default"),
|
|
161
|
-
loading: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.loading }), "loading"),
|
|
162
|
-
custom: /* @__PURE__ */ __name((data) => add(data), "custom"),
|
|
163
|
-
progress: {
|
|
164
|
-
start: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.progress }), "start"),
|
|
165
|
-
update: /* @__PURE__ */ __name((toastId, progress) => {
|
|
166
|
-
update.progress(toastId, progress);
|
|
167
|
-
}, "update"),
|
|
168
|
-
end: /* @__PURE__ */ __name((toastId) => {
|
|
169
|
-
remove(toastId);
|
|
170
|
-
}, "end")
|
|
171
|
-
},
|
|
172
|
-
uploads: {
|
|
173
|
-
start: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.uploads }), "start"),
|
|
174
|
-
update: /* @__PURE__ */ __name((toastId, itemId, patch) => {
|
|
175
|
-
update.uploadItem(toastId, itemId, patch);
|
|
176
|
-
}, "update")
|
|
177
|
-
},
|
|
178
|
-
remove: /* @__PURE__ */ __name((toastId) => {
|
|
179
|
-
remove(toastId);
|
|
180
|
-
}, "remove")
|
|
181
|
-
};
|
|
182
|
-
var withProgressToast = /* @__PURE__ */ __name(async ({
|
|
183
|
-
title,
|
|
184
|
-
description,
|
|
185
|
-
request
|
|
186
|
-
}) => {
|
|
187
|
-
const toastId = toaster.progress.start({ title, description, progress: 0 });
|
|
188
|
-
try {
|
|
189
|
-
const response = await request((event) => {
|
|
190
|
-
if (!event.total) return;
|
|
191
|
-
toaster.progress.update(toastId, Math.round(event.loaded * 100 / event.total));
|
|
192
|
-
});
|
|
193
|
-
toaster.progress.update(toastId, 100);
|
|
194
|
-
return response;
|
|
195
|
-
} finally {
|
|
196
|
-
toaster.progress.end(toastId);
|
|
197
|
-
}
|
|
198
|
-
}, "withProgressToast");
|
|
199
|
-
|
|
200
120
|
// src/toast/uploads.ts
|
|
201
121
|
var sum = /* @__PURE__ */ __name((numbers) => numbers.reduce((total, value) => total + value, 0), "sum");
|
|
202
122
|
var isUploadItemSettled = /* @__PURE__ */ __name(({ status }) => status === "success" || status === "error", "isUploadItemSettled");
|
|
@@ -246,92 +166,95 @@ var getUploadsSummary = /* @__PURE__ */ __name((items) => {
|
|
|
246
166
|
};
|
|
247
167
|
}, "getUploadsSummary");
|
|
248
168
|
var getFormDataFiles = /* @__PURE__ */ __name((data, key = "files") => data.getAll(key).filter((value) => value instanceof File), "getFormDataFiles");
|
|
249
|
-
var
|
|
250
|
-
|
|
251
|
-
description,
|
|
252
|
-
items
|
|
253
|
-
}) => {
|
|
254
|
-
if (items.length === 0) return void 0;
|
|
255
|
-
const statuses = new Map(items.map(({ id }) => [id, "pending"]));
|
|
256
|
-
const toastId = toaster.uploads.start({
|
|
169
|
+
var createUploadsHelpers = /* @__PURE__ */ __name((toaster) => {
|
|
170
|
+
const createUploadsToast = /* @__PURE__ */ __name(({
|
|
257
171
|
title,
|
|
258
172
|
description,
|
|
259
|
-
items
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
173
|
+
items
|
|
174
|
+
}) => {
|
|
175
|
+
if (items.length === 0) return void 0;
|
|
176
|
+
const statuses = new Map(items.map(({ id }) => [id, "pending"]));
|
|
177
|
+
const toastId = toaster.uploads.start({
|
|
178
|
+
title,
|
|
179
|
+
description,
|
|
180
|
+
items: items.map(({ id, label, files }) => {
|
|
181
|
+
const fileSizes = files.map(({ size }) => size);
|
|
182
|
+
return { id, label, status: "pending", loaded: 0, total: sum(fileSizes), fileSizes };
|
|
183
|
+
})
|
|
184
|
+
});
|
|
185
|
+
const patch = /* @__PURE__ */ __name((id, changes) => {
|
|
186
|
+
if (changes.status) statuses.set(id, changes.status);
|
|
187
|
+
toaster.uploads.update(toastId, id, changes);
|
|
188
|
+
}, "patch");
|
|
189
|
+
return {
|
|
190
|
+
item: /* @__PURE__ */ __name((id) => ({
|
|
191
|
+
run: /* @__PURE__ */ __name(async (request) => {
|
|
192
|
+
patch(id, { status: "uploading" });
|
|
193
|
+
try {
|
|
194
|
+
const result = await request((event) => {
|
|
195
|
+
if (!event.total) return;
|
|
196
|
+
patch(id, { loaded: event.loaded, total: event.total });
|
|
197
|
+
});
|
|
198
|
+
patch(id, { status: "success" });
|
|
199
|
+
return result;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
patch(id, { status: "error" });
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
}, "run")
|
|
205
|
+
}), "item"),
|
|
206
|
+
end: /* @__PURE__ */ __name(() => {
|
|
207
|
+
for (const [id, status] of statuses) {
|
|
208
|
+
if (status === "pending" || status === "uploading") patch(id, { status: "error" });
|
|
282
209
|
}
|
|
283
|
-
}, "
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (status === "pending" || status === "uploading") patch(id, { status: "error" });
|
|
288
|
-
}
|
|
289
|
-
}, "end")
|
|
290
|
-
};
|
|
291
|
-
}, "createUploadsToast");
|
|
292
|
-
var withUploadsToast = /* @__PURE__ */ __name(async ({
|
|
293
|
-
title,
|
|
294
|
-
description,
|
|
295
|
-
files,
|
|
296
|
-
request
|
|
297
|
-
}) => {
|
|
298
|
-
const group = createUploadsToast({
|
|
210
|
+
}, "end")
|
|
211
|
+
};
|
|
212
|
+
}, "createUploadsToast");
|
|
213
|
+
const withUploadsToast = /* @__PURE__ */ __name(async ({
|
|
299
214
|
title,
|
|
300
215
|
description,
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
})
|
|
316
|
-
const
|
|
216
|
+
files,
|
|
217
|
+
request
|
|
218
|
+
}) => {
|
|
219
|
+
const group = createUploadsToast({
|
|
220
|
+
title,
|
|
221
|
+
description,
|
|
222
|
+
items: files.length > 0 ? [{ id: "files", label: description ?? title, files }] : []
|
|
223
|
+
});
|
|
224
|
+
if (!group) return request(() => void 0);
|
|
225
|
+
try {
|
|
226
|
+
return await group.item("files").run(request);
|
|
227
|
+
} finally {
|
|
228
|
+
group.end();
|
|
229
|
+
}
|
|
230
|
+
}, "withUploadsToast");
|
|
231
|
+
const runUploadsInToast = /* @__PURE__ */ __name(async ({
|
|
317
232
|
title,
|
|
318
233
|
description,
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
(
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
234
|
+
uploads,
|
|
235
|
+
run
|
|
236
|
+
}) => {
|
|
237
|
+
const group = createUploadsToast({
|
|
238
|
+
title,
|
|
239
|
+
description,
|
|
240
|
+
items: uploads.filter(({ files }) => files.length > 0)
|
|
241
|
+
});
|
|
242
|
+
const settled = await Promise.allSettled(uploads.map(({ id }) => run(id, group?.item(id))));
|
|
243
|
+
group?.end();
|
|
244
|
+
const results = {};
|
|
245
|
+
settled.forEach((result, index) => {
|
|
246
|
+
if (result.status === "fulfilled") results[uploads[index].id] = result.value;
|
|
247
|
+
});
|
|
248
|
+
const failure = settled.find(
|
|
249
|
+
(result) => result.status === "rejected"
|
|
250
|
+
);
|
|
251
|
+
if (failure) {
|
|
252
|
+
throw failure.reason instanceof Error ? failure.reason : new Error("Upload failed");
|
|
253
|
+
}
|
|
254
|
+
return results;
|
|
255
|
+
}, "runUploadsInToast");
|
|
256
|
+
return { createUploadsToast, withUploadsToast, runUploadsInToast };
|
|
257
|
+
}, "createUploadsHelpers");
|
|
335
258
|
registerToastIcons();
|
|
336
259
|
var CircularProgress = /* @__PURE__ */ __name(({ progress, ...props }) => {
|
|
337
260
|
const radius = 10;
|
|
@@ -478,9 +401,9 @@ var ToasterItem = /* @__PURE__ */ __name((props) => {
|
|
|
478
401
|
buttonProps,
|
|
479
402
|
isClosable = true,
|
|
480
403
|
autoClose = true,
|
|
481
|
-
closeTimer = 5e3
|
|
404
|
+
closeTimer = 5e3,
|
|
405
|
+
onRemove
|
|
482
406
|
} = props;
|
|
483
|
-
const remove2 = useToastStore((s) => s.remove);
|
|
484
407
|
const [visible, setVisible] = react.useState(false);
|
|
485
408
|
const [mounted, setMounted] = react.useState(true);
|
|
486
409
|
const timeoutRef = react.useRef(null);
|
|
@@ -502,9 +425,9 @@ var ToasterItem = /* @__PURE__ */ __name((props) => {
|
|
|
502
425
|
setVisible(false);
|
|
503
426
|
timeoutRef.current = setTimeout(() => {
|
|
504
427
|
setMounted(false);
|
|
505
|
-
|
|
428
|
+
onRemove?.(props.id);
|
|
506
429
|
}, 300);
|
|
507
|
-
}, [
|
|
430
|
+
}, [onRemove, props.id]);
|
|
508
431
|
react.useEffect(() => {
|
|
509
432
|
const enterTimer = setTimeout(() => {
|
|
510
433
|
setVisible(true);
|
|
@@ -590,25 +513,73 @@ var ToasterItem = /* @__PURE__ */ __name((props) => {
|
|
|
590
513
|
);
|
|
591
514
|
}, "ToasterItem");
|
|
592
515
|
var Toaster = react.memo(ToasterItem);
|
|
593
|
-
var ToastContainer = /* @__PURE__ */ __name(() => {
|
|
516
|
+
var ToastContainer = /* @__PURE__ */ __name(({ store: useToastStore }) => {
|
|
594
517
|
const toasts = useToastStore((s) => s.toasts);
|
|
518
|
+
const remove = useToastStore((s) => s.remove);
|
|
595
519
|
if (toasts.length === 0) return null;
|
|
596
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "base:max-w-sm fixed right-2 bottom-2 z-999 flex w-full max-w-xs flex-col gap-2 sm:max-w-md md:right-4 md:bottom-4 md:max-w-lg lg:right-8 lg:bottom-8 lg:max-w-xl", children: toasts.map((toast) => /* @__PURE__ */ jsxRuntime.jsx(Toaster, { ...toast, id: toast.id }, toast.id)) });
|
|
520
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "base:max-w-sm fixed right-2 bottom-2 z-999 flex w-full max-w-xs flex-col gap-2 sm:max-w-md md:right-4 md:bottom-4 md:max-w-lg lg:right-8 lg:bottom-8 lg:max-w-xl", children: toasts.map((toast) => /* @__PURE__ */ jsxRuntime.jsx(Toaster, { ...toast, id: toast.id, onRemove: remove }, toast.id)) });
|
|
597
521
|
}, "ToastContainer");
|
|
598
522
|
|
|
523
|
+
// src/toast/toaster.ts
|
|
524
|
+
var createToasterApi = /* @__PURE__ */ __name((store) => {
|
|
525
|
+
const { add, update, remove } = store.getState();
|
|
526
|
+
return {
|
|
527
|
+
success: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.success }), "success"),
|
|
528
|
+
error: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.error }), "error"),
|
|
529
|
+
warning: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.warning }), "warning"),
|
|
530
|
+
default: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.default }), "default"),
|
|
531
|
+
loading: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.loading }), "loading"),
|
|
532
|
+
custom: /* @__PURE__ */ __name((data) => add(data), "custom"),
|
|
533
|
+
progress: {
|
|
534
|
+
start: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.progress }), "start"),
|
|
535
|
+
update: /* @__PURE__ */ __name((toastId, progress) => {
|
|
536
|
+
update.progress(toastId, progress);
|
|
537
|
+
}, "update"),
|
|
538
|
+
end: /* @__PURE__ */ __name((toastId) => {
|
|
539
|
+
remove(toastId);
|
|
540
|
+
}, "end")
|
|
541
|
+
},
|
|
542
|
+
uploads: {
|
|
543
|
+
start: /* @__PURE__ */ __name((data) => add({ ...data, type: TOAST_TYPE.uploads }), "start"),
|
|
544
|
+
update: /* @__PURE__ */ __name((toastId, itemId, patch) => {
|
|
545
|
+
update.uploadItem(toastId, itemId, patch);
|
|
546
|
+
}, "update")
|
|
547
|
+
},
|
|
548
|
+
remove: /* @__PURE__ */ __name((toastId) => {
|
|
549
|
+
remove(toastId);
|
|
550
|
+
}, "remove")
|
|
551
|
+
};
|
|
552
|
+
}, "createToasterApi");
|
|
553
|
+
var createToaster = /* @__PURE__ */ __name((store) => {
|
|
554
|
+
const toaster = createToasterApi(store);
|
|
555
|
+
const withProgressToast = /* @__PURE__ */ __name(async ({
|
|
556
|
+
title,
|
|
557
|
+
description,
|
|
558
|
+
request
|
|
559
|
+
}) => {
|
|
560
|
+
const toastId = toaster.progress.start({ title, description, progress: 0 });
|
|
561
|
+
try {
|
|
562
|
+
const response = await request((event) => {
|
|
563
|
+
if (!event.total) return;
|
|
564
|
+
toaster.progress.update(toastId, Math.round(event.loaded * 100 / event.total));
|
|
565
|
+
});
|
|
566
|
+
toaster.progress.update(toastId, 100);
|
|
567
|
+
return response;
|
|
568
|
+
} finally {
|
|
569
|
+
toaster.progress.end(toastId);
|
|
570
|
+
}
|
|
571
|
+
}, "withProgressToast");
|
|
572
|
+
return { toaster, withProgressToast, ...createUploadsHelpers(toaster) };
|
|
573
|
+
}, "createToaster");
|
|
574
|
+
|
|
599
575
|
exports.TOAST_ICON_NAMES = TOAST_ICON_NAMES;
|
|
600
576
|
exports.ToastContainer = ToastContainer;
|
|
601
577
|
exports.Toaster = Toaster;
|
|
602
|
-
exports.
|
|
578
|
+
exports.createToaster = createToaster;
|
|
603
579
|
exports.getFormDataFiles = getFormDataFiles;
|
|
604
580
|
exports.getUploadItemFilesDone = getUploadItemFilesDone;
|
|
605
581
|
exports.getUploadItemPercent = getUploadItemPercent;
|
|
606
582
|
exports.getUploadsSummary = getUploadsSummary;
|
|
607
583
|
exports.isUploadItemSettled = isUploadItemSettled;
|
|
608
|
-
exports.runUploadsInToast = runUploadsInToast;
|
|
609
|
-
exports.toaster = toaster;
|
|
610
|
-
exports.useToastStore = useToastStore;
|
|
611
|
-
exports.withProgressToast = withProgressToast;
|
|
612
|
-
exports.withUploadsToast = withUploadsToast;
|
|
613
584
|
//# sourceMappingURL=index.cjs.map
|
|
614
585
|
//# sourceMappingURL=index.cjs.map
|