kitzo 1.1.6 → 2.0.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/README.md +86 -7
- package/dist/kitzo.esm.js +0 -1
- package/dist/kitzo.umd.js +0 -1
- package/dist/react.d.ts +20 -0
- package/dist/react.esm.js +446 -0
- package/package.json +18 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/kitzo)
|
|
4
4
|
|
|
5
|
-
### A lightweight
|
|
5
|
+
### A lightweight library of Vanilla js and React js
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
##### [Vanilla js](#quick-usage-overview-vanilla-js)
|
|
8
8
|
|
|
9
9
|
- Copy on click
|
|
10
10
|
- Tooltip on mouseover
|
|
@@ -12,6 +12,10 @@ Current features
|
|
|
12
12
|
- Debounce function
|
|
13
13
|
- Hover clip-path effect
|
|
14
14
|
|
|
15
|
+
##### [React js](#react)
|
|
16
|
+
|
|
17
|
+
- React Toast notifications
|
|
18
|
+
|
|
15
19
|
#### Install
|
|
16
20
|
|
|
17
21
|
```bash
|
|
@@ -21,17 +25,16 @@ npm i kitzo
|
|
|
21
25
|
or
|
|
22
26
|
|
|
23
27
|
```javascript
|
|
24
|
-
<script src="https://cdn.jsdelivr.net/npm/kitzo@
|
|
28
|
+
<script src="https://cdn.jsdelivr.net/npm/kitzo@2.0.0/dist/kitzo.umd.min.js"></script>
|
|
25
29
|
```
|
|
26
30
|
|
|
27
31
|
> Attach this script tag in the html head tag and you are good to go.
|
|
28
32
|
|
|
29
33
|
---
|
|
30
34
|
|
|
31
|
-
#### Quick usage overview
|
|
32
|
-
|
|
35
|
+
#### Quick usage overview: Vanilla js
|
|
33
36
|
|
|
34
|
-
| [API](#apis)
|
|
37
|
+
| [API](#vanilla-apis) |
|
|
35
38
|
| ----------------------------------- |
|
|
36
39
|
| [`kitzo.copy()`](#copy-api) |
|
|
37
40
|
| [`kitzo.tooltip()`](#tooltip-api) |
|
|
@@ -39,7 +42,8 @@ or
|
|
|
39
42
|
| [`kitzo.debounce()`](#debounce-api) |
|
|
40
43
|
| [`kitzo.clippath()`](#clippath-api) |
|
|
41
44
|
|
|
42
|
-
#### APIs
|
|
45
|
+
#### Vanilla APIs
|
|
46
|
+
|
|
43
47
|
```javascript
|
|
44
48
|
// NPM usage
|
|
45
49
|
import kitzo from 'kitzo';
|
|
@@ -122,3 +126,78 @@ kitzo.clippath(selectors | element | NodeList, {
|
|
|
122
126
|
style: object,
|
|
123
127
|
});
|
|
124
128
|
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## React
|
|
133
|
+
|
|
134
|
+
#### Install
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npm i kitzo
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### React APIs
|
|
141
|
+
|
|
142
|
+
```jsx
|
|
143
|
+
import { ToastContainer, toast, ... } from 'kitzo/react';
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
##### Toast API:
|
|
147
|
+
|
|
148
|
+
```jsx
|
|
149
|
+
import { toast } from 'kitzo/react';
|
|
150
|
+
|
|
151
|
+
toast.success('toast message', {});
|
|
152
|
+
toast.error('toast message', {});
|
|
153
|
+
toast.promise(
|
|
154
|
+
promise(),
|
|
155
|
+
{
|
|
156
|
+
loading: 'Saving...',
|
|
157
|
+
success: 'Saved',
|
|
158
|
+
error: 'Error occured',
|
|
159
|
+
},
|
|
160
|
+
{ duration: 2000 }
|
|
161
|
+
);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
##### Toast API Usage
|
|
165
|
+
|
|
166
|
+
```jsx
|
|
167
|
+
import { ToastContainer, toast } from 'kitzo/react';
|
|
168
|
+
|
|
169
|
+
function App() {
|
|
170
|
+
function fakePromise() {
|
|
171
|
+
return new Promise((resolved, rejected) => {
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
Math.random() > 0.5 ? resolved('resolved') : rejected('rejected');
|
|
174
|
+
}, 2000)
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<div>
|
|
180
|
+
<button onClick={() => toast.success('✅ Success toast message')}>Succes</button>
|
|
181
|
+
<button onClick={() => toast.error('❌ Error toast message')}>Error</button>
|
|
182
|
+
<button
|
|
183
|
+
onClick={() => {
|
|
184
|
+
toast.promise(
|
|
185
|
+
fakePromise(),
|
|
186
|
+
{
|
|
187
|
+
loading: 'Saving data...',
|
|
188
|
+
success: 'Data saved',
|
|
189
|
+
error: 'Failed saving data',
|
|
190
|
+
},
|
|
191
|
+
{ duration: 2500 }
|
|
192
|
+
);
|
|
193
|
+
}}
|
|
194
|
+
>
|
|
195
|
+
Promise
|
|
196
|
+
</button>
|
|
197
|
+
|
|
198
|
+
{/* Toast container must needed */}
|
|
199
|
+
<ToastContainer position="top-center" />
|
|
200
|
+
</div>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
```
|
package/dist/kitzo.esm.js
CHANGED
|
@@ -215,7 +215,6 @@ function ripple(element, config = {}) {
|
|
|
215
215
|
btn.setAttribute('data-kitzo-ripple', true);
|
|
216
216
|
rippleConfigMap.set(btn, config);
|
|
217
217
|
const { position, overflow } = window.getComputedStyle(btn);
|
|
218
|
-
console.log(position, overflow);
|
|
219
218
|
if (position === 'static') {
|
|
220
219
|
btn.style.position = 'relative';
|
|
221
220
|
}
|
package/dist/kitzo.umd.js
CHANGED
|
@@ -221,7 +221,6 @@
|
|
|
221
221
|
btn.setAttribute('data-kitzo-ripple', true);
|
|
222
222
|
rippleConfigMap.set(btn, config);
|
|
223
223
|
const { position, overflow } = window.getComputedStyle(btn);
|
|
224
|
-
console.log(position, overflow);
|
|
225
224
|
if (position === 'static') {
|
|
226
225
|
btn.style.position = 'relative';
|
|
227
226
|
}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface ToastOptions {
|
|
2
|
+
duration?: number;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface ToastAPI {
|
|
6
|
+
success(text?: string, options?: ToastOptions): void;
|
|
7
|
+
error(text?: string, options?: ToastOptions): void;
|
|
8
|
+
promise<T>(
|
|
9
|
+
callback: Promise<T>,
|
|
10
|
+
msgs?: {
|
|
11
|
+
loading?: string;
|
|
12
|
+
success?: string | ((res: T) => string);
|
|
13
|
+
error?: string | ((err: Error) => string);
|
|
14
|
+
},
|
|
15
|
+
options?: ToastOptions
|
|
16
|
+
): Promise<T>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export declare const toast: ToastAPI;
|
|
20
|
+
export declare function ToastContainer(props: { position?: string }): JSX.Element;
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import { useRef, useLayoutEffect, useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const listeners = new Set();
|
|
4
|
+
let isStyleAdded = false;
|
|
5
|
+
function toastStyles() {
|
|
6
|
+
return `@layer base {
|
|
7
|
+
.toast-content,
|
|
8
|
+
.toast-content-bottom {
|
|
9
|
+
font-size: 0.925rem;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.toast-content,
|
|
14
|
+
.toast-content-bottom {
|
|
15
|
+
pointer-events: all;
|
|
16
|
+
padding-inline: 0.625rem 0.825rem;
|
|
17
|
+
padding-block: 0.625rem;
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
gap: 0.5rem;
|
|
21
|
+
background-color: white;
|
|
22
|
+
border-radius: 0.5525rem;
|
|
23
|
+
box-shadow: 0 2px 8px -3px rgba(0, 0, 0, 0.3);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.toast-content {
|
|
27
|
+
animation: slide-in 230ms forwards;
|
|
28
|
+
}
|
|
29
|
+
.toast-content.exit {
|
|
30
|
+
animation: slide-out 110ms forwards;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.toast-content-bottom {
|
|
34
|
+
animation: bottom-slide-in 230ms forwards;
|
|
35
|
+
}
|
|
36
|
+
.toast-content-bottom.exit {
|
|
37
|
+
animation: bottom-slide-out 110ms forwards;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@keyframes slide-in {
|
|
41
|
+
from {
|
|
42
|
+
opacity: 0;
|
|
43
|
+
translate: 0 -100%;
|
|
44
|
+
scale: 0.7;
|
|
45
|
+
}
|
|
46
|
+
to {
|
|
47
|
+
opacity: 1;
|
|
48
|
+
translate: 0 0;
|
|
49
|
+
scale: 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@keyframes slide-out {
|
|
54
|
+
from {
|
|
55
|
+
opacity: 1;
|
|
56
|
+
translate: 0 0;
|
|
57
|
+
scale: 1;
|
|
58
|
+
}
|
|
59
|
+
to {
|
|
60
|
+
opacity: 0;
|
|
61
|
+
translate: 0 -100%;
|
|
62
|
+
scale: 0.7;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@keyframes bottom-slide-in {
|
|
67
|
+
from {
|
|
68
|
+
opacity: 0;
|
|
69
|
+
translate: 0 100%;
|
|
70
|
+
scale: 0.7;
|
|
71
|
+
}
|
|
72
|
+
to {
|
|
73
|
+
opacity: 1;
|
|
74
|
+
translate: 0 0;
|
|
75
|
+
scale: 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes bottom-slide-out {
|
|
80
|
+
from {
|
|
81
|
+
opacity: 1;
|
|
82
|
+
translate: 0 0;
|
|
83
|
+
scale: 1;
|
|
84
|
+
}
|
|
85
|
+
to {
|
|
86
|
+
opacity: 0;
|
|
87
|
+
translate: 0 100%;
|
|
88
|
+
scale: 0.7;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.svg-container {
|
|
93
|
+
display: grid;
|
|
94
|
+
place-items: center;
|
|
95
|
+
border-radius: 10rem;
|
|
96
|
+
background-color: #61d345;
|
|
97
|
+
color: white;
|
|
98
|
+
height: 20px;
|
|
99
|
+
width: 20px;
|
|
100
|
+
position: relative;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
|
|
103
|
+
scale: 1.1;
|
|
104
|
+
animation: svg-container-animation 400ms ease-in-out forwards;
|
|
105
|
+
|
|
106
|
+
svg {
|
|
107
|
+
width: 14px;
|
|
108
|
+
height: 14px;
|
|
109
|
+
stroke-width: 4px;
|
|
110
|
+
display: inline-block;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.svg-container.success {
|
|
115
|
+
background-color: #61d345;
|
|
116
|
+
}
|
|
117
|
+
.svg-container.error {
|
|
118
|
+
background-color: #ff4b4b;
|
|
119
|
+
|
|
120
|
+
svg {
|
|
121
|
+
scale: 0;
|
|
122
|
+
animation: error-svg-zoom-in 170ms 130ms forwards;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.svg-container.success::before {
|
|
127
|
+
content: '';
|
|
128
|
+
position: absolute;
|
|
129
|
+
inset: 0;
|
|
130
|
+
z-index: 5;
|
|
131
|
+
border-radius: 10rem;
|
|
132
|
+
background-color: #61d345;
|
|
133
|
+
animation: success-container-before-animation 250ms 150ms forwards;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@keyframes svg-container-animation {
|
|
137
|
+
0% {
|
|
138
|
+
scale: 1;
|
|
139
|
+
}
|
|
140
|
+
50% {
|
|
141
|
+
scale: 1.15;
|
|
142
|
+
}
|
|
143
|
+
100% {
|
|
144
|
+
scale: 1;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@keyframes success-container-before-animation {
|
|
149
|
+
from {
|
|
150
|
+
translate: 0 0;
|
|
151
|
+
}
|
|
152
|
+
to {
|
|
153
|
+
translate: 100% -50%;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@keyframes error-svg-zoom-in {
|
|
158
|
+
from {
|
|
159
|
+
scale: 0;
|
|
160
|
+
}
|
|
161
|
+
to {
|
|
162
|
+
scale: 1;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.promise-svg-container {
|
|
167
|
+
width: 20px;
|
|
168
|
+
height: 20px;
|
|
169
|
+
display: grid;
|
|
170
|
+
place-items: center;
|
|
171
|
+
color: #474747;
|
|
172
|
+
|
|
173
|
+
svg {
|
|
174
|
+
width: 14px;
|
|
175
|
+
height: 14px;
|
|
176
|
+
stroke-width: 3px;
|
|
177
|
+
display: inline-block;
|
|
178
|
+
animation: rotate-infinity 1000ms infinite linear;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@keyframes rotate-infinity {
|
|
183
|
+
to {
|
|
184
|
+
rotate: 360deg;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
`;
|
|
188
|
+
}
|
|
189
|
+
function addToast(toast) {
|
|
190
|
+
listeners.forEach(callback => {
|
|
191
|
+
callback(toast);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function subscribe(callback) {
|
|
195
|
+
if (!isStyleAdded) {
|
|
196
|
+
const styleTag = document.createElement('style');
|
|
197
|
+
styleTag.textContent = toastStyles();
|
|
198
|
+
document.head.appendChild(styleTag);
|
|
199
|
+
isStyleAdded = true;
|
|
200
|
+
}
|
|
201
|
+
listeners.add(callback);
|
|
202
|
+
return () => listeners.delete(callback);
|
|
203
|
+
}
|
|
204
|
+
function success(text = 'Toast success', options = {}) {
|
|
205
|
+
const id = Date.now();
|
|
206
|
+
options = Object.assign({
|
|
207
|
+
duration: 2000,
|
|
208
|
+
id
|
|
209
|
+
}, options);
|
|
210
|
+
addToast({
|
|
211
|
+
type: 'success',
|
|
212
|
+
text,
|
|
213
|
+
options
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function error(text = 'Toast denied', options = {}) {
|
|
217
|
+
const id = Date.now();
|
|
218
|
+
options = Object.assign({
|
|
219
|
+
duration: 2000,
|
|
220
|
+
id
|
|
221
|
+
}, options);
|
|
222
|
+
addToast({
|
|
223
|
+
type: 'error',
|
|
224
|
+
text,
|
|
225
|
+
options
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
function promise(callback, msgs = {}, options = {}) {
|
|
229
|
+
const id = Date.now();
|
|
230
|
+
options = Object.assign({
|
|
231
|
+
duration: 2000,
|
|
232
|
+
id
|
|
233
|
+
}, options);
|
|
234
|
+
msgs = Object.assign({
|
|
235
|
+
loading: 'Saving...',
|
|
236
|
+
success: 'Success',
|
|
237
|
+
error: 'Something went wrong'
|
|
238
|
+
}, msgs);
|
|
239
|
+
addToast({
|
|
240
|
+
type: 'loading',
|
|
241
|
+
text: msgs.loading,
|
|
242
|
+
options: {
|
|
243
|
+
...options,
|
|
244
|
+
duration: Infinity,
|
|
245
|
+
id
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
callback.then(res => {
|
|
249
|
+
const successMsg = typeof msgs.success === 'function' ? msgs.success(res) : msgs.success;
|
|
250
|
+
addToast({
|
|
251
|
+
type: 'success',
|
|
252
|
+
text: successMsg,
|
|
253
|
+
options
|
|
254
|
+
});
|
|
255
|
+
return res;
|
|
256
|
+
}).catch(err => {
|
|
257
|
+
const normalizedError = err instanceof Error ? err : new Error(String(err));
|
|
258
|
+
const errorMsg = typeof msgs.error === 'function' ? msgs.error(normalizedError) : msgs.error;
|
|
259
|
+
addToast({
|
|
260
|
+
type: 'error',
|
|
261
|
+
text: errorMsg,
|
|
262
|
+
options
|
|
263
|
+
});
|
|
264
|
+
return Promise.reject(normalizedError);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function SuccessSvg() {
|
|
269
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
270
|
+
className: "svg-container success"
|
|
271
|
+
}, /*#__PURE__*/React.createElement("svg", {
|
|
272
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
273
|
+
width: "24",
|
|
274
|
+
height: "24",
|
|
275
|
+
viewBox: "0 0 24 24",
|
|
276
|
+
fill: "none",
|
|
277
|
+
stroke: "currentColor",
|
|
278
|
+
strokeWidth: "2",
|
|
279
|
+
strokeLinecap: "round",
|
|
280
|
+
strokeLinejoin: "round"
|
|
281
|
+
}, /*#__PURE__*/React.createElement("path", {
|
|
282
|
+
d: "M20 6 9 17l-5-5"
|
|
283
|
+
})));
|
|
284
|
+
}
|
|
285
|
+
function ErrorSvg() {
|
|
286
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
287
|
+
className: "svg-container error"
|
|
288
|
+
}, /*#__PURE__*/React.createElement("svg", {
|
|
289
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
290
|
+
width: "24",
|
|
291
|
+
height: "24",
|
|
292
|
+
viewBox: "0 0 24 24",
|
|
293
|
+
fill: "none",
|
|
294
|
+
stroke: "currentColor",
|
|
295
|
+
strokeWidth: "2",
|
|
296
|
+
strokeLinecap: "round",
|
|
297
|
+
strokeLinejoin: "round"
|
|
298
|
+
}, /*#__PURE__*/React.createElement("path", {
|
|
299
|
+
d: "M18 6 6 18"
|
|
300
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
301
|
+
d: "m6 6 12 12"
|
|
302
|
+
})));
|
|
303
|
+
}
|
|
304
|
+
function LoadingSvg() {
|
|
305
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
306
|
+
className: "promise-svg-container"
|
|
307
|
+
}, /*#__PURE__*/React.createElement("svg", {
|
|
308
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
309
|
+
width: "24",
|
|
310
|
+
height: "24",
|
|
311
|
+
viewBox: "0 0 24 24",
|
|
312
|
+
fill: "none",
|
|
313
|
+
stroke: "currentColor",
|
|
314
|
+
strokeWidth: "2",
|
|
315
|
+
strokeLinecap: "round",
|
|
316
|
+
strokeLinejoin: "round"
|
|
317
|
+
}, /*#__PURE__*/React.createElement("path", {
|
|
318
|
+
d: "M21 12a9 9 0 1 1-6.219-8.56"
|
|
319
|
+
})));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const GAP = 10;
|
|
323
|
+
function Toast({
|
|
324
|
+
toast,
|
|
325
|
+
setToasts,
|
|
326
|
+
position
|
|
327
|
+
}) {
|
|
328
|
+
const ref = useRef(null);
|
|
329
|
+
useLayoutEffect(() => {
|
|
330
|
+
if (!ref.current) return;
|
|
331
|
+
const h = ref.current.getBoundingClientRect().height;
|
|
332
|
+
setToasts(prev => prev.map(t => t.options.id === toast.id ? t : {
|
|
333
|
+
...t,
|
|
334
|
+
offset: t.offset + h + GAP
|
|
335
|
+
}));
|
|
336
|
+
}, [setToasts, toast.id]);
|
|
337
|
+
if (position.includes('bottom')) {
|
|
338
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
339
|
+
ref: ref,
|
|
340
|
+
className: "toast",
|
|
341
|
+
style: {
|
|
342
|
+
transform: `translateY(-${toast.offset}px)`,
|
|
343
|
+
...getToastPosition(position)
|
|
344
|
+
}
|
|
345
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
346
|
+
className: `toast-content-bottom ${toast.leaving ? 'exit' : ''}`
|
|
347
|
+
}, toast.type === 'loading' && /*#__PURE__*/React.createElement(LoadingSvg, null), toast.type === 'success' && /*#__PURE__*/React.createElement(SuccessSvg, null), toast.type === 'error' && /*#__PURE__*/React.createElement(ErrorSvg, null), /*#__PURE__*/React.createElement("span", null, toast.text)));
|
|
348
|
+
}
|
|
349
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
350
|
+
ref: ref,
|
|
351
|
+
className: "toast",
|
|
352
|
+
style: {
|
|
353
|
+
transform: `translateY(${toast.offset}px)`,
|
|
354
|
+
...getToastPosition(position)
|
|
355
|
+
}
|
|
356
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
357
|
+
className: `toast-content ${toast.leaving ? 'exit' : ''}`
|
|
358
|
+
}, toast.type === 'loading' && /*#__PURE__*/React.createElement(LoadingSvg, null), toast.type === 'success' && /*#__PURE__*/React.createElement(SuccessSvg, null), toast.type === 'error' && /*#__PURE__*/React.createElement(ErrorSvg, null), /*#__PURE__*/React.createElement("span", null, toast.text)));
|
|
359
|
+
}
|
|
360
|
+
function getToastPosition(position) {
|
|
361
|
+
const isLeft = position.includes('left');
|
|
362
|
+
const isRight = position.includes('right');
|
|
363
|
+
const styles = {
|
|
364
|
+
position: 'absolute',
|
|
365
|
+
width: 'calc(100% - 2rem)',
|
|
366
|
+
pointerEvents: 'none',
|
|
367
|
+
transition: 'transform 230ms',
|
|
368
|
+
display: 'flex'
|
|
369
|
+
};
|
|
370
|
+
if (position.includes('top')) {
|
|
371
|
+
styles.top = '1rem';
|
|
372
|
+
styles.justifyContent = isLeft ? 'flex-start' : isRight ? 'flex-end' : 'center';
|
|
373
|
+
}
|
|
374
|
+
if (position.includes('bottom')) {
|
|
375
|
+
styles.bottom = '1rem';
|
|
376
|
+
styles.justifyContent = isLeft ? 'flex-start' : isRight ? 'flex-end' : 'center';
|
|
377
|
+
}
|
|
378
|
+
return styles;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const EXIT_ANIM_MS = 300;
|
|
382
|
+
function ToastContainer(props) {
|
|
383
|
+
props = Object.assign({
|
|
384
|
+
position: 'top-center'
|
|
385
|
+
}, props);
|
|
386
|
+
const {
|
|
387
|
+
position
|
|
388
|
+
} = props;
|
|
389
|
+
const [toasts, setToasts] = useState([]);
|
|
390
|
+
useEffect(() => {
|
|
391
|
+
const unsub = subscribe(toast => {
|
|
392
|
+
const duration = toast.options.duration;
|
|
393
|
+
const id = toast.options.id;
|
|
394
|
+
setToasts(prev => {
|
|
395
|
+
const exists = prev.some(t => t.options.id === id);
|
|
396
|
+
if (exists) {
|
|
397
|
+
return prev.map(t => t.options.id === id ? {
|
|
398
|
+
...t,
|
|
399
|
+
...toast
|
|
400
|
+
} : t);
|
|
401
|
+
}
|
|
402
|
+
return [{
|
|
403
|
+
id,
|
|
404
|
+
...toast,
|
|
405
|
+
offset: 0,
|
|
406
|
+
leaving: false
|
|
407
|
+
}, ...prev];
|
|
408
|
+
});
|
|
409
|
+
if (toast.type !== 'loading') {
|
|
410
|
+
setTimeout(() => {
|
|
411
|
+
setToasts(prev => prev.map(t => t.options.id === id ? {
|
|
412
|
+
...t,
|
|
413
|
+
leaving: true
|
|
414
|
+
} : t));
|
|
415
|
+
}, Math.max(0, duration - EXIT_ANIM_MS));
|
|
416
|
+
setTimeout(() => {
|
|
417
|
+
setToasts(prev => prev.filter(t => t.options.id !== id));
|
|
418
|
+
}, duration);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
return () => unsub();
|
|
422
|
+
}, []);
|
|
423
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
424
|
+
style: {
|
|
425
|
+
position: 'fixed',
|
|
426
|
+
inset: 0,
|
|
427
|
+
zIndex: 100000000,
|
|
428
|
+
pointerEvents: 'none',
|
|
429
|
+
fontFamily: 'inherit',
|
|
430
|
+
padding: '1rem'
|
|
431
|
+
}
|
|
432
|
+
}, toasts.map(t => /*#__PURE__*/React.createElement(Toast, {
|
|
433
|
+
key: t.options.id,
|
|
434
|
+
toast: t,
|
|
435
|
+
setToasts: setToasts,
|
|
436
|
+
position: position
|
|
437
|
+
})));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const toast = {
|
|
441
|
+
success,
|
|
442
|
+
error,
|
|
443
|
+
promise
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
export { ToastContainer, toast };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kitzo",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A lightweight JavaScript UI micro-library.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/kitzo.umd.js",
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
"import": "./dist/kitzo.esm.js",
|
|
10
10
|
"require": "./dist/kitzo.umd.js",
|
|
11
11
|
"types": "./dist/kitzo.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./react": {
|
|
14
|
+
"import": "./dist/react.esm.js",
|
|
15
|
+
"types": "./dist/react.d.ts"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"files": [
|
|
@@ -27,6 +31,7 @@
|
|
|
27
31
|
"modular",
|
|
28
32
|
"ui",
|
|
29
33
|
"javascript",
|
|
34
|
+
"react",
|
|
30
35
|
"kitzo"
|
|
31
36
|
],
|
|
32
37
|
"author": "Riyad",
|
|
@@ -37,7 +42,19 @@
|
|
|
37
42
|
},
|
|
38
43
|
"homepage": "https://github.com/riyad-96/kitzo#readme",
|
|
39
44
|
"devDependencies": {
|
|
45
|
+
"@rollup/plugin-commonjs": "^28.0.6",
|
|
46
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
47
|
+
"@babel/core": "^7.28.4",
|
|
48
|
+
"@babel/preset-react": "^7.27.1",
|
|
49
|
+
"@rollup/plugin-babel": "^6.0.4",
|
|
50
|
+
"@vitejs/plugin-react": "^5.0.4",
|
|
51
|
+
"react": "^19.1.1",
|
|
52
|
+
"react-dom": "^19.1.1",
|
|
40
53
|
"rollup": "^4.46.2",
|
|
41
54
|
"vite": "^7.0.4"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"react": ">=17",
|
|
58
|
+
"react-dom": ">=17"
|
|
42
59
|
}
|
|
43
60
|
}
|