@lavalogic/scoria 0.40.10 → 0.40.12
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/Components/LoadingAnimation.svelte +39 -14
- package/dist/Components/LoadingModal.svelte +2 -18
- package/dist/Components/LoadingModalProps.d.ts +7 -0
- package/dist/Components/LoadingOverlay.svelte +2 -18
- package/dist/Components/LoadingOverlayProps.d.ts +7 -0
- package/dist/Helpers/loaderDefaults.svelte.d.ts +16 -0
- package/dist/Helpers/loaderDefaults.svelte.js +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
</script>
|
|
100
100
|
|
|
101
101
|
<script lang="ts">
|
|
102
|
+
import { loaderDefaults } from '../Helpers/loaderDefaults.svelte.js';
|
|
102
103
|
import type { LoadingAnimationProps } from './LoadingAnimationProps.js';
|
|
103
104
|
|
|
104
105
|
const {
|
|
@@ -114,7 +115,16 @@
|
|
|
114
115
|
// The word the box spells: the caller's first name, or the product name as a
|
|
115
116
|
// friendly fallback. Block capitals tumble cleanly and dodge lowercase
|
|
116
117
|
// descenders clipping the baseline on landing.
|
|
117
|
-
|
|
118
|
+
// Explicit `name` prop wins; otherwise fall back to the app-wide default
|
|
119
|
+
// (set by the host so internally-rendered loaders also show the user), then
|
|
120
|
+
// finally the product name.
|
|
121
|
+
const word = $derived(
|
|
122
|
+
(name.trim() || loaderDefaults.name.trim() || 'FloWMS').toUpperCase()
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// Caption text with any trailing dots/ellipsis stripped, since the pill
|
|
126
|
+
// appends its own animated "..." — avoids "moment……" style doubling.
|
|
127
|
+
const captionText = $derived(caption.replace(/[\s.…]+$/, ''));
|
|
118
128
|
|
|
119
129
|
// Per-letter render data: each letter is a stack of DEPTH layers (painted
|
|
120
130
|
// back-to-front) topped by the lit face, so it has genuine 3D thickness.
|
|
@@ -764,7 +774,7 @@
|
|
|
764
774
|
whose opacity cycles, so the pill width stays fixed as they animate. -->
|
|
765
775
|
{#if showText}
|
|
766
776
|
<div class="caption">
|
|
767
|
-
<span class="caption-label">{
|
|
777
|
+
<span class="caption-label">{captionText}</span><span
|
|
768
778
|
class="caption-dots"
|
|
769
779
|
aria-hidden="true"><span>.</span><span>.</span><span>.</span></span
|
|
770
780
|
>
|
|
@@ -786,17 +796,20 @@
|
|
|
786
796
|
--kraft-inner: #8a6b43;
|
|
787
797
|
--seam: rgba(0, 0, 0, 0.14);
|
|
788
798
|
--ink: #3c4045;
|
|
789
|
-
/*
|
|
790
|
-
--fill-1: #
|
|
791
|
-
--fill-2: #
|
|
792
|
-
--fill-3: #
|
|
793
|
-
--fill-4: #
|
|
794
|
-
--fill-5: #
|
|
799
|
+
/* subtle white confetti — shades of white/off-white */
|
|
800
|
+
--fill-1: #ffffff;
|
|
801
|
+
--fill-2: #eef1f4;
|
|
802
|
+
--fill-3: #f8fafb;
|
|
803
|
+
--fill-4: #e2e7ec;
|
|
804
|
+
--fill-5: #fbfcfd;
|
|
795
805
|
--hw: calc(var(--w) / 2);
|
|
796
806
|
--hd: calc(var(--d) / 2);
|
|
797
807
|
--hh: calc(var(--h) / 2);
|
|
798
808
|
--y-outer: calc(var(--hh) * -1 + 0.5px);
|
|
799
809
|
--y-inner: calc(var(--hh) * -1 + 1.5px);
|
|
810
|
+
/* Push the box (and its letters) down within the footprint so the caption
|
|
811
|
+
pill has clear headroom above the opened flaps. */
|
|
812
|
+
--stage-shift: 40px;
|
|
800
813
|
display: grid;
|
|
801
814
|
place-items: center;
|
|
802
815
|
position: relative;
|
|
@@ -806,6 +819,7 @@
|
|
|
806
819
|
.flowms-loader .scene {
|
|
807
820
|
width: var(--w);
|
|
808
821
|
height: var(--h);
|
|
822
|
+
translate: 0 var(--stage-shift);
|
|
809
823
|
perspective: 820px;
|
|
810
824
|
perspective-origin: 50% 40%;
|
|
811
825
|
transform-style: preserve-3d;
|
|
@@ -1021,7 +1035,7 @@
|
|
|
1021
1035
|
margin-top: -48px;
|
|
1022
1036
|
border-radius: 50%;
|
|
1023
1037
|
opacity: 0;
|
|
1024
|
-
background: radial-gradient(circle, rgba(
|
|
1038
|
+
background: radial-gradient(circle, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 35%, rgba(255, 255, 255, 0) 70%);
|
|
1025
1039
|
}
|
|
1026
1040
|
.flowms-loader .fill {
|
|
1027
1041
|
position: absolute;
|
|
@@ -1033,6 +1047,8 @@
|
|
|
1033
1047
|
margin-top: -6.5px;
|
|
1034
1048
|
border-radius: 3px;
|
|
1035
1049
|
opacity: 0;
|
|
1050
|
+
/* faint edge so the white pieces stay visible on light backgrounds */
|
|
1051
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
|
1036
1052
|
}
|
|
1037
1053
|
.flowms-loader .fill:nth-child(5n+1) {
|
|
1038
1054
|
background: var(--fill-1);
|
|
@@ -1064,7 +1080,7 @@
|
|
|
1064
1080
|
.flowms-loader .letterstage {
|
|
1065
1081
|
position: absolute;
|
|
1066
1082
|
left: 50%;
|
|
1067
|
-
top: 50
|
|
1083
|
+
top: calc(50% + var(--stage-shift)); /* track the shifted box */
|
|
1068
1084
|
width: var(--w);
|
|
1069
1085
|
height: var(--h);
|
|
1070
1086
|
transform: translate(-50%, -50%);
|
|
@@ -1097,21 +1113,30 @@
|
|
|
1097
1113
|
top: 0;
|
|
1098
1114
|
}
|
|
1099
1115
|
.flowms-loader {
|
|
1100
|
-
/* Caption pill: sits above the box and on top of every other layer.
|
|
1116
|
+
/* Caption pill: sits above the box and on top of every other layer. Its
|
|
1117
|
+
bottom edge is anchored just above the opened flaps, so longer messages
|
|
1118
|
+
wrap and grow UPWARD into the headroom rather than down over the box. */
|
|
1101
1119
|
}
|
|
1102
1120
|
.flowms-loader .caption {
|
|
1103
1121
|
position: absolute;
|
|
1104
1122
|
left: 50%;
|
|
1105
|
-
|
|
1123
|
+
bottom: calc(100% - 50px);
|
|
1106
1124
|
transform: translateX(-50%);
|
|
1107
|
-
|
|
1125
|
+
/* `width: max-content` opts out of the half-container shrink that
|
|
1126
|
+
`left: 50%` would otherwise impose, so the pill sizes to its text up
|
|
1127
|
+
to the max-width (then wraps). */
|
|
1128
|
+
width: max-content;
|
|
1129
|
+
max-width: min(380px, 90vw);
|
|
1130
|
+
white-space: normal;
|
|
1131
|
+
text-align: center;
|
|
1132
|
+
text-wrap: balance;
|
|
1108
1133
|
padding: 7px 16px;
|
|
1109
1134
|
border-radius: 999px;
|
|
1110
1135
|
background: rgba(255, 255, 255, 0.82);
|
|
1111
1136
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
1112
1137
|
-webkit-backdrop-filter: blur(3px);
|
|
1113
1138
|
backdrop-filter: blur(3px);
|
|
1114
|
-
font: 600 14px/1.
|
|
1139
|
+
font: 600 14px/1.3 system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
1115
1140
|
color: #44515a;
|
|
1116
1141
|
letter-spacing: 0.2px;
|
|
1117
1142
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import LoadingAnimation from './LoadingAnimation.svelte';
|
|
5
5
|
import type { LoadingModalProps } from './LoadingModalProps.js';
|
|
6
6
|
|
|
7
|
-
const { showModal, message, name }: LoadingModalProps = $props();
|
|
7
|
+
const { showModal, message, name, caption }: LoadingModalProps = $props();
|
|
8
8
|
|
|
9
9
|
let dialog: HTMLDialogElement | undefined = $state();
|
|
10
10
|
|
|
@@ -35,12 +35,9 @@
|
|
|
35
35
|
aria-live="polite"
|
|
36
36
|
>
|
|
37
37
|
<div class="modal-root">
|
|
38
|
-
{#if message}
|
|
39
|
-
<p>{message}</p>
|
|
40
|
-
{/if}
|
|
41
38
|
<LoadingAnimation
|
|
42
39
|
{name}
|
|
43
|
-
|
|
40
|
+
caption={message ?? caption}
|
|
44
41
|
/>
|
|
45
42
|
</div>
|
|
46
43
|
</dialog>
|
|
@@ -309,17 +306,4 @@ dialog .modal-root {
|
|
|
309
306
|
align-items: center;
|
|
310
307
|
background: rgba(0, 0, 0, 0);
|
|
311
308
|
position: relative;
|
|
312
|
-
}
|
|
313
|
-
dialog .modal-root p {
|
|
314
|
-
position: absolute;
|
|
315
|
-
left: 50%;
|
|
316
|
-
top: 50%;
|
|
317
|
-
z-index: 99999;
|
|
318
|
-
translate: -50% -80%;
|
|
319
|
-
user-select: none;
|
|
320
|
-
text-shadow: 0px 0px 3px #000000;
|
|
321
|
-
background-color: rgba(0, 0, 0, 0.4);
|
|
322
|
-
border-radius: 4px;
|
|
323
|
-
padding: 1rem;
|
|
324
|
-
color: #ffffff;
|
|
325
309
|
}</style>
|
|
@@ -19,4 +19,11 @@ export interface LoadingModalProps {
|
|
|
19
19
|
* erupts. When omitted the loader falls back to the product name.
|
|
20
20
|
*/
|
|
21
21
|
name?: string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Optional caption shown in the pill above the box (an animated `...` is
|
|
24
|
+
* appended automatically). Use this instead of {@link message} to keep the
|
|
25
|
+
* loader's own pill rather than rendering a separate message bar. Ignored
|
|
26
|
+
* when {@link message} is set. Defaults to `'Loading'`.
|
|
27
|
+
*/
|
|
28
|
+
caption?: string | undefined;
|
|
22
29
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import LoadingAnimation from './LoadingAnimation.svelte';
|
|
5
5
|
import type { LoadingOverlayProps } from './LoadingOverlayProps.js';
|
|
6
6
|
|
|
7
|
-
const { message, absolute, borderRadius, name }: LoadingOverlayProps =
|
|
7
|
+
const { message, absolute, borderRadius, name, caption }: LoadingOverlayProps =
|
|
8
8
|
$props();
|
|
9
9
|
</script>
|
|
10
10
|
|
|
@@ -17,12 +17,9 @@
|
|
|
17
17
|
? `border-radius: ${borderRadius};`
|
|
18
18
|
: undefined}
|
|
19
19
|
>
|
|
20
|
-
{#if message}
|
|
21
|
-
<p>{message}</p>
|
|
22
|
-
{/if}
|
|
23
20
|
<LoadingAnimation
|
|
24
21
|
{name}
|
|
25
|
-
|
|
22
|
+
caption={message ?? caption}
|
|
26
23
|
/>
|
|
27
24
|
</div>
|
|
28
25
|
|
|
@@ -42,19 +39,6 @@
|
|
|
42
39
|
flex-flow: column;
|
|
43
40
|
gap: 2rem;
|
|
44
41
|
}
|
|
45
|
-
.loading-overlay p {
|
|
46
|
-
position: absolute;
|
|
47
|
-
left: 50%;
|
|
48
|
-
top: 50%;
|
|
49
|
-
z-index: 99999;
|
|
50
|
-
translate: -50% -80%;
|
|
51
|
-
user-select: none;
|
|
52
|
-
text-shadow: 0px 0px 3px #000000;
|
|
53
|
-
background-color: rgba(0, 0, 0, 0.4);
|
|
54
|
-
border-radius: 4px;
|
|
55
|
-
padding: 1rem;
|
|
56
|
-
color: #ffffff;
|
|
57
|
-
}
|
|
58
42
|
.loading-overlay.absolute {
|
|
59
43
|
position: absolute;
|
|
60
44
|
}</style>
|
|
@@ -13,6 +13,13 @@ export interface LoadingOverlayProps {
|
|
|
13
13
|
* erupts. When omitted the loader falls back to the product name.
|
|
14
14
|
*/
|
|
15
15
|
name?: string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Optional caption shown in the pill above the box (an animated `...` is
|
|
18
|
+
* appended automatically). Use this instead of {@link message} to keep the
|
|
19
|
+
* loader's own pill rather than rendering a separate message bar. Ignored
|
|
20
|
+
* when {@link message} is set. Defaults to `'Loading'`.
|
|
21
|
+
*/
|
|
22
|
+
caption?: string | undefined;
|
|
16
23
|
/**
|
|
17
24
|
* When `true` the overlay uses `position: absolute` and fills its
|
|
18
25
|
* nearest positioned ancestor instead of the viewport. Use this
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global fallback configuration for all loaders.
|
|
3
|
+
*
|
|
4
|
+
* Loaders rendered *internally* by components like {@link Table},
|
|
5
|
+
* {@link DesktopModal} and {@link AppointmentCalendar} can't be handed a `name`
|
|
6
|
+
* prop at the call site. So the host app sets {@link loaderDefaults.name} once —
|
|
7
|
+
* typically in its root layout inside a browser `$effect` — and every loader
|
|
8
|
+
* (including those internal ones) spells that name. An explicit `name` prop on a
|
|
9
|
+
* specific loader still takes precedence.
|
|
10
|
+
*
|
|
11
|
+
* Only assign this on the client (inside an `$effect` / `onMount`). Assigning it
|
|
12
|
+
* during SSR would share one request's value with concurrent requests.
|
|
13
|
+
*/
|
|
14
|
+
export declare const loaderDefaults: {
|
|
15
|
+
name: string;
|
|
16
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global fallback configuration for all loaders.
|
|
3
|
+
*
|
|
4
|
+
* Loaders rendered *internally* by components like {@link Table},
|
|
5
|
+
* {@link DesktopModal} and {@link AppointmentCalendar} can't be handed a `name`
|
|
6
|
+
* prop at the call site. So the host app sets {@link loaderDefaults.name} once —
|
|
7
|
+
* typically in its root layout inside a browser `$effect` — and every loader
|
|
8
|
+
* (including those internal ones) spells that name. An explicit `name` prop on a
|
|
9
|
+
* specific loader still takes precedence.
|
|
10
|
+
*
|
|
11
|
+
* Only assign this on the client (inside an `$effect` / `onMount`). Assigning it
|
|
12
|
+
* during SSR would share one request's value with concurrent requests.
|
|
13
|
+
*/
|
|
14
|
+
export const loaderDefaults = $state({ name: '' });
|
package/dist/index.d.ts
CHANGED
|
@@ -64,6 +64,7 @@ export type { InfoAlertProps } from './Components/InfoAlertProps.js';
|
|
|
64
64
|
export type { InputProps } from './Components/InputProps.js';
|
|
65
65
|
export { default as LoadingAnimation } from './Components/LoadingAnimation.svelte';
|
|
66
66
|
export type { LoadingAnimationProps } from './Components/LoadingAnimationProps.js';
|
|
67
|
+
export { loaderDefaults } from './Helpers/loaderDefaults.svelte.js';
|
|
67
68
|
export { default as LoadingModal } from './Components/LoadingModal.svelte';
|
|
68
69
|
export type { LoadingModalProps } from './Components/LoadingModalProps.js';
|
|
69
70
|
export { default as LoadingOverlay } from './Components/LoadingOverlay.svelte';
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ export {} from './Components/IconProps.js';
|
|
|
40
40
|
export { icons } from './Components/Icons.js';
|
|
41
41
|
export { default as InfoAlert } from './Components/InfoAlert.svelte';
|
|
42
42
|
export { default as LoadingAnimation } from './Components/LoadingAnimation.svelte';
|
|
43
|
+
export { loaderDefaults } from './Helpers/loaderDefaults.svelte.js';
|
|
43
44
|
export { default as LoadingModal } from './Components/LoadingModal.svelte';
|
|
44
45
|
export { default as LoadingOverlay } from './Components/LoadingOverlay.svelte';
|
|
45
46
|
export { default as Modal } from './Components/Modal.svelte';
|