@rettangoli/ui 1.6.0 → 1.6.1
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
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const VALID_DIALOG_SIZES = new Set(["sm", "md", "lg", "f"]);
|
|
2
2
|
const VALID_TOAST_SIZES = new Set(["sm", "md", "lg"]);
|
|
3
3
|
const VALID_TOAST_PHASES = new Set(["active", "exiting"]);
|
|
4
|
+
const VALID_TOAST_POSITIONS = new Set(["top", "bottom"]);
|
|
4
5
|
const VALID_COMPONENT_DIALOG_ROLES = new Set(["confirm", "cancel"]);
|
|
5
6
|
|
|
6
7
|
const DEFAULT_COMPONENT_DIALOG_BUTTONS = Object.freeze([
|
|
@@ -39,6 +40,10 @@ const normalizeToastPhase = (value, fallback = "active") => {
|
|
|
39
40
|
return VALID_TOAST_PHASES.has(value) ? value : fallback;
|
|
40
41
|
};
|
|
41
42
|
|
|
43
|
+
const normalizeToastPosition = (value, fallback = "top") => {
|
|
44
|
+
return VALID_TOAST_POSITIONS.has(value) ? value : fallback;
|
|
45
|
+
};
|
|
46
|
+
|
|
42
47
|
const normalizeComponentDialogActions = (value) => {
|
|
43
48
|
const sourceButtons = Array.isArray(value?.buttons) && value.buttons.length > 0
|
|
44
49
|
? value.buttons
|
|
@@ -223,6 +228,7 @@ export const addToast = ({ state }, options = {}) => {
|
|
|
223
228
|
id: `toast-${nextToastId}`,
|
|
224
229
|
message: options.message,
|
|
225
230
|
size: normalizeToastSize(options.size ?? options.s, "sm"),
|
|
231
|
+
position: normalizeToastPosition(options.position, "top"),
|
|
226
232
|
phase: "active",
|
|
227
233
|
};
|
|
228
234
|
|
|
@@ -277,6 +283,14 @@ export const selectViewData = ({ state }) => {
|
|
|
277
283
|
const isFormDialogOpen = state.isOpen && state.uiType === "formDialog";
|
|
278
284
|
const isComponentDialogOpen = state.isOpen && state.uiType === "componentDialog";
|
|
279
285
|
const componentDialogConfig = state.componentDialogConfig ?? createDefaultComponentDialogConfig();
|
|
286
|
+
const normalizedToasts = Array.isArray(state.toasts)
|
|
287
|
+
? state.toasts.map((toast) => ({
|
|
288
|
+
...toast,
|
|
289
|
+
size: normalizeToastSize(toast.size, "sm"),
|
|
290
|
+
position: normalizeToastPosition(toast.position, "top"),
|
|
291
|
+
phase: normalizeToastPhase(toast.phase, "active"),
|
|
292
|
+
}))
|
|
293
|
+
: [];
|
|
280
294
|
|
|
281
295
|
return {
|
|
282
296
|
isOpen: state.isOpen,
|
|
@@ -305,13 +319,9 @@ export const selectViewData = ({ state }) => {
|
|
|
305
319
|
actions: componentDialogConfig.actions ?? normalizeComponentDialogActions(),
|
|
306
320
|
key: componentDialogConfig.key ?? 0,
|
|
307
321
|
},
|
|
308
|
-
toasts:
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
size: normalizeToastSize(toast.size, "sm"),
|
|
312
|
-
phase: normalizeToastPhase(toast.phase, "active"),
|
|
313
|
-
}))
|
|
314
|
-
: [],
|
|
322
|
+
toasts: normalizedToasts,
|
|
323
|
+
topToasts: normalizedToasts.filter((toast) => toast.position === "top"),
|
|
324
|
+
bottomToasts: normalizedToasts.filter((toast) => toast.position === "bottom"),
|
|
315
325
|
isDialogOpen,
|
|
316
326
|
isFormDialogOpen,
|
|
317
327
|
isComponentDialogOpen,
|
|
@@ -38,34 +38,53 @@ styles:
|
|
|
38
38
|
max-width: calc(100vw - 2 * var(--spacing-lg))
|
|
39
39
|
opacity: 1
|
|
40
40
|
transform: translateY(0) scale(1)
|
|
41
|
-
animation: toast-in 220ms cubic-bezier(0.16, 1, 0.3, 1)
|
|
42
41
|
transition: opacity 180ms cubic-bezier(0.16, 1, 0.3, 1), transform 180ms cubic-bezier(0.16, 1, 0.3, 1)
|
|
43
42
|
will-change: opacity, transform
|
|
43
|
+
.toast-card-top:
|
|
44
|
+
animation: toast-in-top 220ms cubic-bezier(0.16, 1, 0.3, 1)
|
|
45
|
+
.toast-card-bottom:
|
|
46
|
+
animation: toast-in-bottom 220ms cubic-bezier(0.16, 1, 0.3, 1)
|
|
44
47
|
.toast-card-md:
|
|
45
48
|
width: 50vw
|
|
46
49
|
.toast-card-lg:
|
|
47
50
|
width: 80vw
|
|
48
|
-
.toast-card-exiting:
|
|
51
|
+
.toast-card-top.toast-card-exiting:
|
|
49
52
|
opacity: 0
|
|
50
53
|
transform: translateY(calc(var(--spacing-sm) * -0.5)) scale(0.98)
|
|
54
|
+
.toast-card-bottom.toast-card-exiting:
|
|
55
|
+
opacity: 0
|
|
56
|
+
transform: translateY(calc(var(--spacing-sm) * 0.5)) scale(0.98)
|
|
51
57
|
.toast-message:
|
|
52
58
|
overflow-wrap: anywhere
|
|
53
|
-
'@keyframes toast-in':
|
|
59
|
+
'@keyframes toast-in-top':
|
|
54
60
|
from:
|
|
55
61
|
opacity: 0
|
|
56
62
|
transform: translateY(calc(var(--spacing-sm) * -1)) scale(0.96)
|
|
57
63
|
to:
|
|
58
64
|
opacity: 1
|
|
59
65
|
transform: translateY(0) scale(1)
|
|
66
|
+
'@keyframes toast-in-bottom':
|
|
67
|
+
from:
|
|
68
|
+
opacity: 0
|
|
69
|
+
transform: translateY(var(--spacing-sm)) scale(0.96)
|
|
70
|
+
to:
|
|
71
|
+
opacity: 1
|
|
72
|
+
transform: translateY(0) scale(1)
|
|
60
73
|
'@media (prefers-reduced-motion: reduce)':
|
|
61
74
|
.toast-card:
|
|
62
75
|
animation: none
|
|
63
76
|
transition: none
|
|
64
77
|
template:
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- rtgl-
|
|
78
|
+
- $if topToasts.length > 0:
|
|
79
|
+
- rtgl-view class="toast-layer toast-layer-top" pos=fix edge=t z=2100 w=f ah=c g=sm ph=md pt=xl:
|
|
80
|
+
- $for toast, i in topToasts:
|
|
81
|
+
- 'rtgl-view class="toast-card toast-card-top toast-card-${toast.size} toast-card-${toast.phase}" key=toast-${toast.id} bgc=su bc=bo bw=xs br=md shadow=md ph=xl pv=lg':
|
|
82
|
+
- rtgl-text class=toast-message ta=c w=f: ${toast.message}
|
|
83
|
+
- $if bottomToasts.length > 0:
|
|
84
|
+
- rtgl-view class="toast-layer toast-layer-bottom" pos=fix edge=b z=2100 w=f ah=c g=sm ph=md pb=xl:
|
|
85
|
+
- $for toast, i in bottomToasts:
|
|
86
|
+
- 'rtgl-view class="toast-card toast-card-bottom toast-card-${toast.size} toast-card-${toast.phase}" key=toast-${toast.id} bgc=su bc=bo bw=xs br=md shadow=md ph=xl pv=lg':
|
|
87
|
+
- rtgl-text class=toast-message ta=c w=f: ${toast.message}
|
|
69
88
|
- rtgl-dialog#dialog ?open=${isDialogContainerOpen} s=${dialogSize}:
|
|
70
89
|
- $if isFormDialogOpen:
|
|
71
90
|
- rtgl-form#formDialog slot=content :form=${formDialogConfig.form} :defaultValues=${formDialogConfig.defaultValues} :context=${formDialogConfig.context} ?disabled=${formDialogConfig.disabled} key=form-dialog-${formDialogConfig.key}: null
|
|
@@ -163,11 +163,12 @@ const createGlobalUI = (globalUIElement) => {
|
|
|
163
163
|
},
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
|
-
* Shows a
|
|
166
|
+
* Shows a toast message that auto-dismisses after 3 seconds.
|
|
167
167
|
*
|
|
168
168
|
* @param {Object} options - Toast configuration options
|
|
169
169
|
* @param {string} options.message - The toast message (required)
|
|
170
170
|
* @param {('sm'|'md'|'lg')} [options.size] - Toast width preset matching dialog sizing (default: "sm")
|
|
171
|
+
* @param {('top'|'bottom')} [options.position] - Vertical viewport placement (default: "top")
|
|
171
172
|
* @returns {void}
|
|
172
173
|
* @throws {Error} If globalUIElement is not initialized
|
|
173
174
|
*/
|