@marianmeres/stuic 2.60.0 → 2.62.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/dist/actions/popover/popover.svelte.js +18 -4
- package/dist/actions/tooltip/tooltip.svelte.js +15 -11
- package/dist/components/AppShell/AppShellSimple.svelte +5 -2
- package/dist/components/AssetsPreview/AssetsPreview.svelte +15 -17
- package/dist/components/AssetsPreview/AssetsPreview.svelte.d.ts +2 -4
- package/dist/components/CommandMenu/CommandMenu.svelte +145 -147
- package/dist/components/CommandMenu/README.md +6 -0
- package/dist/components/DropdownMenu/README.md +2 -2
- package/dist/components/Input/FieldOptions.svelte +255 -252
- package/dist/components/Input/FieldOptions.svelte.d.ts +2 -2
- package/dist/components/Modal/Modal.svelte +37 -48
- package/dist/components/Modal/Modal.svelte.d.ts +3 -13
- package/dist/components/Modal/README.md +17 -6
- package/dist/components/ModalDialog/ModalDialog.svelte +50 -13
- package/dist/components/ModalDialog/ModalDialog.svelte.d.ts +9 -0
- package/dist/components/ModalDialog/README.md +27 -8
- package/dist/components/Notifications/Notifications.svelte +135 -96
- package/dist/components/Notifications/notifications-icons.js +4 -4
- package/dist/components/X/X.svelte +1 -1
- package/package.json +1 -1
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
classNotifContent,
|
|
98
98
|
classNotifButton,
|
|
99
99
|
classNotifButtonX,
|
|
100
|
-
buttonXStrokeWidth =
|
|
100
|
+
buttonXStrokeWidth = 3,
|
|
101
101
|
//
|
|
102
102
|
classProgress,
|
|
103
103
|
classProgressBar,
|
|
@@ -110,6 +110,8 @@
|
|
|
110
110
|
iconFns = {},
|
|
111
111
|
}: Props = $props();
|
|
112
112
|
|
|
113
|
+
let popoverEl: HTMLDivElement | null = $state(null);
|
|
114
|
+
|
|
113
115
|
let { x, y, xMobile, yMobile } = $derived.by(() => {
|
|
114
116
|
const x = X_POSITIONS.includes(posX) ? posX : DEFAULT.posX;
|
|
115
117
|
const xMobile = X_POSITIONS.includes(posXMobile) ? posXMobile : DEFAULT.posXMobile;
|
|
@@ -118,11 +120,6 @@
|
|
|
118
120
|
return { x, y, xMobile, yMobile };
|
|
119
121
|
});
|
|
120
122
|
|
|
121
|
-
const maybeComponent = (n: Notification): { Cmp: any; props: any } => {
|
|
122
|
-
// todo when needed
|
|
123
|
-
return { Cmp: null, props: null };
|
|
124
|
-
};
|
|
125
|
-
|
|
126
123
|
let _iconFns = $derived({ ...notificationsDefaultIcons, ...iconFns });
|
|
127
124
|
|
|
128
125
|
const maybeIcon = (n: Notification) => {
|
|
@@ -132,50 +129,51 @@
|
|
|
132
129
|
};
|
|
133
130
|
|
|
134
131
|
const _classWrapX = `
|
|
135
|
-
fixed z-50 flex flex-row inset-0
|
|
132
|
+
fixed z-50 flex flex-row inset-0
|
|
136
133
|
pointer-events-none bg-transparent`;
|
|
137
134
|
|
|
138
135
|
const _classWrapY = `
|
|
139
|
-
p-4 space-y-4
|
|
140
|
-
flex flex-col inset-0
|
|
136
|
+
p-4 space-y-4
|
|
137
|
+
flex flex-col inset-0
|
|
138
|
+
w-full sm:w-auto
|
|
141
139
|
pointer-events-none bg-transparent`;
|
|
142
140
|
|
|
143
141
|
const _classNotifBox = `
|
|
144
|
-
relative flex
|
|
145
|
-
pointer-events-auto
|
|
146
|
-
w-
|
|
147
|
-
rounded-lg
|
|
148
|
-
shadow-lg
|
|
149
|
-
border border-notif-border dark:border-notif-border-dark
|
|
150
|
-
bg-notif-bg text-notif-text
|
|
142
|
+
relative flex
|
|
143
|
+
pointer-events-auto
|
|
144
|
+
w-full sm:w-sm max-w-full sm:max-w-sm
|
|
145
|
+
rounded-lg
|
|
146
|
+
shadow-lg
|
|
147
|
+
border border-notif-border dark:border-notif-border-dark
|
|
148
|
+
bg-notif-bg text-notif-text
|
|
151
149
|
dark:bg-notif-bg-dark dark:text-notif-text-dark`;
|
|
152
150
|
|
|
153
151
|
const _classNotifCount = `
|
|
154
|
-
absolute -top-2 -right-2
|
|
155
|
-
w-auto h-auto
|
|
156
|
-
flex items-center justify-center
|
|
157
|
-
px-2 py-1 rounded-full
|
|
158
|
-
leading-none text-xs
|
|
152
|
+
absolute -top-2 -right-2
|
|
153
|
+
w-auto h-auto
|
|
154
|
+
flex items-center justify-center
|
|
155
|
+
px-2 py-1 rounded-full
|
|
156
|
+
leading-none text-xs
|
|
159
157
|
bg-neutral-950 text-neutral-50`;
|
|
160
158
|
|
|
161
159
|
const _classNotifIcon = `
|
|
162
|
-
flex items-center justify-center
|
|
163
|
-
pt-4 pr-0 pb-4 pl-4
|
|
160
|
+
flex items-center justify-center
|
|
161
|
+
pt-4 pr-0 pb-4 pl-4
|
|
164
162
|
text-neutral-200`;
|
|
165
163
|
|
|
166
164
|
const _classNotifContent = `
|
|
167
|
-
flex-1
|
|
168
|
-
flex flex-col justify-center
|
|
169
|
-
|
|
165
|
+
flex-1
|
|
166
|
+
flex flex-col justify-center
|
|
167
|
+
tracking-tight
|
|
170
168
|
pl-4 pr-1 py-3`;
|
|
171
169
|
|
|
172
170
|
const _classNotifButton = `
|
|
173
|
-
flex flex-col items-center justify-center
|
|
174
|
-
leading-none
|
|
175
|
-
px-3
|
|
176
|
-
hover:bg-neutral-950/10
|
|
177
|
-
focus-visible:bg-neutral-950/10 focus-visible:outline-none focus-visible:ring-0
|
|
178
|
-
group
|
|
171
|
+
flex flex-col items-center justify-center
|
|
172
|
+
leading-none
|
|
173
|
+
px-3
|
|
174
|
+
hover:bg-neutral-950/10
|
|
175
|
+
focus-visible:bg-neutral-950/10 focus-visible:outline-none focus-visible:ring-0
|
|
176
|
+
group
|
|
179
177
|
rounded-tr-md rounded-br-md`;
|
|
180
178
|
|
|
181
179
|
const _classNotifButtonX = `opacity-75 group-hover:opacity-100`;
|
|
@@ -202,11 +200,32 @@
|
|
|
202
200
|
`--color-notif-border-dark: var(--color-border-dark-${type}, var(--color-${theme}-700));`,
|
|
203
201
|
].join("");
|
|
204
202
|
};
|
|
203
|
+
|
|
204
|
+
// Manage popover visibility based on notifications
|
|
205
|
+
$effect(() => {
|
|
206
|
+
if (!popoverEl) return;
|
|
207
|
+
|
|
208
|
+
const hasNotifications = notifications.stack.length > 0;
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
if (hasNotifications && !popoverEl.matches(":popover-open")) {
|
|
212
|
+
popoverEl.showPopover();
|
|
213
|
+
} else if (!hasNotifications && popoverEl.matches(":popover-open")) {
|
|
214
|
+
popoverEl.hidePopover();
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
// Popover API not supported - element remains in DOM flow
|
|
218
|
+
}
|
|
219
|
+
});
|
|
205
220
|
</script>
|
|
206
221
|
|
|
207
|
-
|
|
222
|
+
<div
|
|
223
|
+
bind:this={popoverEl}
|
|
224
|
+
popover="manual"
|
|
225
|
+
class="stuic-notifs-popover"
|
|
226
|
+
aria-live="assertive"
|
|
227
|
+
>
|
|
208
228
|
<div
|
|
209
|
-
aria-live="assertive"
|
|
210
229
|
class={twMerge(
|
|
211
230
|
"stuic-notifs wrap-x",
|
|
212
231
|
_classWrapX,
|
|
@@ -217,75 +236,95 @@
|
|
|
217
236
|
>
|
|
218
237
|
<div class={twMerge("wrap-y", _classWrapY, YMAP_M[yMobile], YMAP[y], classWrapY)}>
|
|
219
238
|
{#each notifications.stack as n (n.id)}
|
|
220
|
-
{@const { Cmp, props } = maybeComponent(n)}
|
|
221
239
|
{@const iconHtml = maybeIcon(n)}
|
|
222
240
|
{@const showXButton = !noXButton || n.ttl > 1000}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
241
|
+
<div
|
|
242
|
+
class={twMerge("box", _classNotifBox, classNotifBox)}
|
|
243
|
+
transition:fade|global={{ duration }}
|
|
244
|
+
role="alert"
|
|
245
|
+
style={_buildTheme(n.type)}
|
|
246
|
+
>
|
|
247
|
+
{#if n.ttl && !noProgress}
|
|
248
|
+
<Progress
|
|
249
|
+
progress={100 - n._ttlProgress * 100}
|
|
250
|
+
class={twMerge(_classProgress, classProgress)}
|
|
251
|
+
classBar={twMerge(_classProgressBar, classProgressBar)}
|
|
252
|
+
styleBar="transition-duration: {notifications.options.disposeInterval}ms;"
|
|
253
|
+
/>
|
|
254
|
+
{/if}
|
|
255
|
+
|
|
256
|
+
{#if n.count > 1}
|
|
257
|
+
<div class={twMerge("count", _classNotifCount, classNotifCount)}>
|
|
258
|
+
{n.count}
|
|
259
|
+
</div>
|
|
260
|
+
{/if}
|
|
261
|
+
{#if !noIcons && iconHtml}
|
|
262
|
+
<div class={twMerge("icon", _classNotifIcon, classNotifIcon)}>
|
|
263
|
+
{@html iconHtml}
|
|
264
|
+
</div>
|
|
265
|
+
{/if}
|
|
266
|
+
|
|
226
267
|
<div
|
|
227
|
-
class={twMerge(
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
268
|
+
class={twMerge(
|
|
269
|
+
"content",
|
|
270
|
+
_classNotifContent,
|
|
271
|
+
classNotifContent,
|
|
272
|
+
!showXButton && "pr-4"
|
|
273
|
+
)}
|
|
231
274
|
>
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
{/if}
|
|
240
|
-
|
|
241
|
-
{#if n.count > 1}
|
|
242
|
-
<div class={twMerge("count", _classNotifCount, classNotifCount)}>
|
|
243
|
-
{n.count}
|
|
244
|
-
</div>
|
|
245
|
-
{/if}
|
|
246
|
-
{#if !noIcons && iconHtml}
|
|
247
|
-
<div class={twMerge("icon", _classNotifIcon, classNotifIcon)}>
|
|
248
|
-
{@html iconHtml}
|
|
249
|
-
</div>
|
|
250
|
-
{/if}
|
|
275
|
+
<Thc
|
|
276
|
+
thc={n.content}
|
|
277
|
+
forceAsHtml={n.forceAsHtml ?? forceAsHtml}
|
|
278
|
+
notification={n}
|
|
279
|
+
{notifications}
|
|
280
|
+
/>
|
|
281
|
+
</div>
|
|
251
282
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
283
|
+
{#if showXButton}
|
|
284
|
+
<button
|
|
285
|
+
type="button"
|
|
286
|
+
class={twMerge("button", _classNotifButton, classNotifButton)}
|
|
287
|
+
aria-label={ariaCloseLabel}
|
|
288
|
+
onclick={(e) => {
|
|
289
|
+
e.preventDefault();
|
|
290
|
+
e.stopPropagation();
|
|
291
|
+
e.stopImmediatePropagation();
|
|
292
|
+
notifications.removeById(n.id);
|
|
293
|
+
}}
|
|
259
294
|
>
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
notification={n}
|
|
264
|
-
{notifications}
|
|
295
|
+
<X
|
|
296
|
+
class={twMerge("x", _classNotifButtonX, classNotifButtonX)}
|
|
297
|
+
strokeWidth={buttonXStrokeWidth}
|
|
265
298
|
/>
|
|
266
|
-
</
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
<button
|
|
270
|
-
type="button"
|
|
271
|
-
class={twMerge("button", _classNotifButton, classNotifButton)}
|
|
272
|
-
aria-label={ariaCloseLabel}
|
|
273
|
-
onclick={(e) => {
|
|
274
|
-
e.preventDefault();
|
|
275
|
-
e.stopPropagation();
|
|
276
|
-
e.stopImmediatePropagation();
|
|
277
|
-
notifications.removeById(n.id);
|
|
278
|
-
}}
|
|
279
|
-
>
|
|
280
|
-
<X
|
|
281
|
-
class={twMerge("x", _classNotifButtonX, classNotifButtonX)}
|
|
282
|
-
strokeWidth={buttonXStrokeWidth}
|
|
283
|
-
/>
|
|
284
|
-
</button>
|
|
285
|
-
{/if}
|
|
286
|
-
</div>
|
|
287
|
-
{/if}
|
|
299
|
+
</button>
|
|
300
|
+
{/if}
|
|
301
|
+
</div>
|
|
288
302
|
{/each}
|
|
289
303
|
</div>
|
|
290
304
|
</div>
|
|
291
|
-
|
|
305
|
+
</div>
|
|
306
|
+
|
|
307
|
+
<style>
|
|
308
|
+
/* Override default popover positioning */
|
|
309
|
+
.stuic-notifs-popover {
|
|
310
|
+
/* Reset popover defaults */
|
|
311
|
+
position: fixed;
|
|
312
|
+
inset: 0;
|
|
313
|
+
margin: 0;
|
|
314
|
+
padding: 0;
|
|
315
|
+
border: none;
|
|
316
|
+
background: transparent;
|
|
317
|
+
max-width: none;
|
|
318
|
+
max-height: none;
|
|
319
|
+
width: 100%;
|
|
320
|
+
height: 100%;
|
|
321
|
+
overflow: visible;
|
|
322
|
+
pointer-events: none;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Transparent backdrop so content behind is clickable */
|
|
326
|
+
.stuic-notifs-popover::backdrop {
|
|
327
|
+
background: transparent;
|
|
328
|
+
pointer-events: none;
|
|
329
|
+
}
|
|
330
|
+
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { iconAlertWarning, iconAlertSuccess, iconAlertInfo, iconAlertError, } from "../../icons/index.js";
|
|
2
2
|
export const notificationsDefaultIcons = {
|
|
3
|
-
info: () => iconAlertInfo({}),
|
|
4
|
-
success: () => iconAlertSuccess({}),
|
|
5
|
-
warn: () => iconAlertWarning({}),
|
|
6
|
-
error: () => iconAlertError({}),
|
|
3
|
+
info: () => iconAlertInfo({ size: 29 }),
|
|
4
|
+
success: () => iconAlertSuccess({ size: 29 }),
|
|
5
|
+
warn: () => iconAlertWarning({ size: 29 }),
|
|
6
|
+
error: () => iconAlertError({ size: 29 }),
|
|
7
7
|
};
|