@r2digisolutions/components 0.9.5 → 0.9.7
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/atoms/Button/Button.svelte +1 -1
- package/dist/components/atoms/StepMark/StepMark.svelte +1 -2
- package/dist/components/molecules/FormActions/FormActions.svelte +23 -19
- package/dist/components/molecules/FormActions/FormActions.svelte.d.ts +2 -0
- package/dist/components/molecules/Stepper/Stepper.svelte +1 -1
- package/dist/components/molecules/TimePicker/TimePicker.svelte +32 -23
- package/package.json +1 -1
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
const variantClasses: Record<ButtonVariant, string> = {
|
|
42
42
|
primary:
|
|
43
|
-
'bg-brand-
|
|
43
|
+
'bg-brand-600 text-white hover:bg-brand-700 active:bg-brand-800 focus-visible:ring-brand-500 shadow-sm hover:shadow-md active:scale-[0.98]',
|
|
44
44
|
secondary:
|
|
45
45
|
'bg-surface-elevated text-primary border border-border hover:bg-surface-overlay hover:border-border-strong focus-visible:ring-brand-500 shadow-sm active:scale-[0.98]',
|
|
46
46
|
ghost:
|
|
@@ -26,8 +26,7 @@
|
|
|
26
26
|
'inline-flex shrink-0 items-center justify-center rounded-full font-semibold tabular-nums transition-colors',
|
|
27
27
|
dims,
|
|
28
28
|
state === 'complete' && 'bg-brand-500 text-white',
|
|
29
|
-
state === 'current' &&
|
|
30
|
-
'bg-brand-500/15 text-brand-700 ring-2 ring-brand-500/40 dark:text-brand-300',
|
|
29
|
+
state === 'current' && 'bg-brand-500 text-white',
|
|
31
30
|
state === 'upcoming' && 'bg-surface-overlay text-muted ring-1 ring-border'
|
|
32
31
|
]}
|
|
33
32
|
aria-current={state === 'current' ? 'step' : undefined}
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
fullWidth?: boolean;
|
|
19
19
|
align?: 'start' | 'end' | 'between';
|
|
20
20
|
showCancel?: boolean;
|
|
21
|
+
/** Hide the primary submit control (e.g. file-upload step that auto-advances). */
|
|
22
|
+
showSubmit?: boolean;
|
|
21
23
|
/**
|
|
22
24
|
* plain = bare row
|
|
23
25
|
* bar = bordered footer chrome inside a card
|
|
@@ -44,6 +46,7 @@
|
|
|
44
46
|
fullWidth = true,
|
|
45
47
|
align = 'end',
|
|
46
48
|
showCancel = true,
|
|
49
|
+
showSubmit = true,
|
|
47
50
|
variant = 'bar',
|
|
48
51
|
size = 'md',
|
|
49
52
|
hint = '',
|
|
@@ -69,12 +72,11 @@
|
|
|
69
72
|
|
|
70
73
|
<div
|
|
71
74
|
class={[
|
|
72
|
-
'
|
|
75
|
+
'gap-3 sm:flex-row sm:items-center flex w-full flex-col',
|
|
73
76
|
alignClasses[align],
|
|
74
|
-
variant === 'bar' &&
|
|
75
|
-
'rounded-b-2xl border-t border-border bg-surface/50 px-4 py-3 sm:px-5',
|
|
77
|
+
variant === 'bar' && 'rounded-b-2xl border-border bg-surface/50 px-4 py-3 sm:px-5 border-t',
|
|
76
78
|
variant === 'sticky' &&
|
|
77
|
-
'
|
|
79
|
+
'border-border bg-surface-elevated/95 px-4 py-3 backdrop-blur-md dark:shadow-black/30 sm:px-5 shrink-0 border-t shadow-[0_-8px_24px_rgb(0,0,0,0.06)]',
|
|
78
80
|
variant === 'plain' && 'gap-2',
|
|
79
81
|
className
|
|
80
82
|
]}
|
|
@@ -82,7 +84,7 @@
|
|
|
82
84
|
aria-label="Form actions"
|
|
83
85
|
>
|
|
84
86
|
{#if hint || extra || dangerLabel}
|
|
85
|
-
<div class="
|
|
87
|
+
<div class="min-w-0 gap-2 flex flex-1 flex-wrap items-center">
|
|
86
88
|
{#if dangerLabel}
|
|
87
89
|
<Button
|
|
88
90
|
type="button"
|
|
@@ -103,13 +105,13 @@
|
|
|
103
105
|
{/if}
|
|
104
106
|
</div>
|
|
105
107
|
{:else if align === 'between'}
|
|
106
|
-
<div class="hidden flex-1
|
|
108
|
+
<div class="sm:block hidden flex-1" aria-hidden="true"></div>
|
|
107
109
|
{/if}
|
|
108
110
|
|
|
109
111
|
<div
|
|
110
112
|
class={[
|
|
111
|
-
'flex items-center
|
|
112
|
-
fullWidth && 'w-
|
|
113
|
+
'gap-2 flex items-center',
|
|
114
|
+
fullWidth && 'sm:w-auto sm:flex-row w-full flex-col-reverse'
|
|
113
115
|
]}
|
|
114
116
|
>
|
|
115
117
|
{#if showCancel}
|
|
@@ -118,21 +120,23 @@
|
|
|
118
120
|
variant="secondary"
|
|
119
121
|
{size}
|
|
120
122
|
disabled={busy}
|
|
121
|
-
class={fullWidth ? 'w-
|
|
123
|
+
class={fullWidth ? 'sm:w-auto w-full' : ''}
|
|
122
124
|
onclick={() => oncancel?.()}
|
|
123
125
|
>
|
|
124
126
|
{resolvedCancelLabel}
|
|
125
127
|
</Button>
|
|
126
128
|
{/if}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
129
|
+
{#if showSubmit}
|
|
130
|
+
<Button
|
|
131
|
+
type="submit"
|
|
132
|
+
{size}
|
|
133
|
+
loading={resolvedLoading}
|
|
134
|
+
disabled={busy || submitDisabled}
|
|
135
|
+
class={fullWidth ? 'sm:w-auto w-full' : ''}
|
|
136
|
+
onclick={() => onsubmit?.()}
|
|
137
|
+
>
|
|
138
|
+
{resolvedSubmitLabel}
|
|
139
|
+
</Button>
|
|
140
|
+
{/if}
|
|
137
141
|
</div>
|
|
138
142
|
</div>
|
|
@@ -13,6 +13,8 @@ interface FormActionsProps {
|
|
|
13
13
|
fullWidth?: boolean;
|
|
14
14
|
align?: 'start' | 'end' | 'between';
|
|
15
15
|
showCancel?: boolean;
|
|
16
|
+
/** Hide the primary submit control (e.g. file-upload step that auto-advances). */
|
|
17
|
+
showSubmit?: boolean;
|
|
16
18
|
/**
|
|
17
19
|
* plain = bare row
|
|
18
20
|
* bar = bordered footer chrome inside a card
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
variant === 'dots' ? circleSize.dot : circleSize.box,
|
|
104
104
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500/30 focus-visible:ring-offset-2 focus-visible:ring-offset-surface',
|
|
105
105
|
state === 'complete' && 'border-brand-500 bg-brand-500 text-white',
|
|
106
|
-
state === 'current' && 'border-brand-500 bg-
|
|
106
|
+
state === 'current' && 'border-brand-500 bg-brand-500 text-white',
|
|
107
107
|
state === 'error' && 'border-red-500 bg-red-50 text-red-600 dark:bg-red-950/40 dark:text-red-400',
|
|
108
108
|
state === 'upcoming' && 'border-border bg-surface-elevated text-muted'
|
|
109
109
|
];
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
const viewTop = vv?.offsetTop ?? 0;
|
|
113
113
|
const gap = 8;
|
|
114
114
|
const pad = 8;
|
|
115
|
-
const estimated = { panelW:
|
|
115
|
+
const estimated = { panelW: 208, panelH: 280 };
|
|
116
116
|
const canMeasure = opts.measure !== false && !!panelEl?.matches(':popover-open');
|
|
117
117
|
const panelW = Math.min(
|
|
118
118
|
canMeasure && panelEl?.offsetWidth ? panelEl.offsetWidth : estimated.panelW,
|
|
@@ -139,13 +139,12 @@
|
|
|
139
139
|
if (panelEl) {
|
|
140
140
|
const s = panelEl.style;
|
|
141
141
|
s.setProperty('margin', '0');
|
|
142
|
-
s.
|
|
142
|
+
s.removeProperty('inset');
|
|
143
143
|
s.setProperty('top', `${Math.round(top)}px`);
|
|
144
144
|
s.setProperty('left', `${Math.round(left)}px`);
|
|
145
145
|
s.setProperty('right', 'auto');
|
|
146
146
|
s.setProperty('bottom', 'auto');
|
|
147
|
-
s.setProperty('width', '
|
|
148
|
-
s.setProperty('min-width', `${Math.round(Math.min(panelW, trigger.width))}px`);
|
|
147
|
+
s.setProperty('width', '13rem');
|
|
149
148
|
s.setProperty('visibility', placed ? 'visible' : 'hidden');
|
|
150
149
|
}
|
|
151
150
|
}
|
|
@@ -263,16 +262,16 @@
|
|
|
263
262
|
});
|
|
264
263
|
</script>
|
|
265
264
|
|
|
266
|
-
<div class={['w-full
|
|
265
|
+
<div class={['w-full max-w-[16rem] min-w-[12rem]', className]}>
|
|
267
266
|
{#if label}
|
|
268
|
-
<span class="mb-1.5
|
|
267
|
+
<span class="mb-1.5 text-sm font-medium text-primary block">{label}</span>
|
|
269
268
|
{/if}
|
|
270
269
|
|
|
271
270
|
<div
|
|
272
271
|
bind:this={triggerEl}
|
|
273
272
|
class={[
|
|
274
|
-
'
|
|
275
|
-
open && 'border-brand-500 ring-
|
|
273
|
+
'h-10 rounded-xl border-border bg-surface-elevated flex w-full items-center overflow-hidden border transition-colors',
|
|
274
|
+
open && 'border-brand-500 ring-brand-500/20 ring-2',
|
|
276
275
|
disabled && 'opacity-60'
|
|
277
276
|
]}
|
|
278
277
|
>
|
|
@@ -285,13 +284,13 @@
|
|
|
285
284
|
aria-haspopup="dialog"
|
|
286
285
|
aria-controls={panelId}
|
|
287
286
|
class={[
|
|
288
|
-
'
|
|
287
|
+
'min-w-0 gap-2 px-3.5 text-sm flex h-full flex-1 items-center text-left',
|
|
289
288
|
'hover:bg-surface-overlay focus-visible:outline-none',
|
|
290
289
|
disabled && 'cursor-not-allowed'
|
|
291
290
|
]}
|
|
292
291
|
>
|
|
293
292
|
<svg
|
|
294
|
-
class="h-4 w-4 shrink-0
|
|
293
|
+
class="h-4 w-4 text-muted shrink-0"
|
|
295
294
|
viewBox="0 0 24 24"
|
|
296
295
|
fill="none"
|
|
297
296
|
stroke="currentColor"
|
|
@@ -312,10 +311,16 @@
|
|
|
312
311
|
<button
|
|
313
312
|
type="button"
|
|
314
313
|
onclick={clear}
|
|
315
|
-
class="
|
|
314
|
+
class="px-3 text-muted hover:bg-surface-overlay hover:text-primary h-full"
|
|
316
315
|
aria-label="Clear"
|
|
317
316
|
>
|
|
318
|
-
<svg
|
|
317
|
+
<svg
|
|
318
|
+
class="h-3.5 w-3.5"
|
|
319
|
+
viewBox="0 0 24 24"
|
|
320
|
+
fill="none"
|
|
321
|
+
stroke="currentColor"
|
|
322
|
+
stroke-width="2"
|
|
323
|
+
>
|
|
319
324
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
|
320
325
|
</svg>
|
|
321
326
|
</button>
|
|
@@ -332,18 +337,18 @@
|
|
|
332
337
|
onbeforetoggle={handleBeforeToggle}
|
|
333
338
|
ontoggle={handleToggle}
|
|
334
339
|
data-placed={placed ? true : undefined}
|
|
335
|
-
class="timepicker-popover m-0
|
|
340
|
+
class="timepicker-popover m-0 w-52 rounded-2xl border-border bg-surface-elevated shadow-xl overflow-hidden border outline-none"
|
|
336
341
|
>
|
|
337
|
-
<div class="grid grid-cols-2 divide-x
|
|
342
|
+
<div class="divide-border grid grid-cols-2 divide-x">
|
|
338
343
|
<div class="flex flex-col">
|
|
339
344
|
<span
|
|
340
|
-
class="border-
|
|
345
|
+
class="border-border px-3 py-2 font-medium tracking-wide text-muted border-b text-center text-[11px] uppercase"
|
|
341
346
|
>
|
|
342
347
|
Hour
|
|
343
348
|
</span>
|
|
344
349
|
<div
|
|
345
350
|
bind:this={hourListEl}
|
|
346
|
-
class="max-h-52 overflow-y-auto
|
|
351
|
+
class="max-h-52 p-1.5 overflow-y-auto"
|
|
347
352
|
role="listbox"
|
|
348
353
|
aria-label="Hours"
|
|
349
354
|
>
|
|
@@ -356,8 +361,8 @@
|
|
|
356
361
|
aria-selected={selectedH === h}
|
|
357
362
|
onclick={() => pickHour(h)}
|
|
358
363
|
class={[
|
|
359
|
-
'
|
|
360
|
-
'focus-visible:
|
|
364
|
+
'rounded-lg px-2 py-1.5 text-sm w-full transition-colors',
|
|
365
|
+
'focus-visible:ring-brand-500/30 focus-visible:ring-2 focus-visible:outline-none',
|
|
361
366
|
disabledHour && 'cursor-not-allowed opacity-30',
|
|
362
367
|
selectedH === h
|
|
363
368
|
? 'bg-brand-500 font-semibold text-white'
|
|
@@ -371,13 +376,13 @@
|
|
|
371
376
|
</div>
|
|
372
377
|
<div class="flex flex-col">
|
|
373
378
|
<span
|
|
374
|
-
class="border-
|
|
379
|
+
class="border-border px-3 py-2 font-medium tracking-wide text-muted border-b text-center text-[11px] uppercase"
|
|
375
380
|
>
|
|
376
381
|
Min
|
|
377
382
|
</span>
|
|
378
383
|
<div
|
|
379
384
|
bind:this={minuteListEl}
|
|
380
|
-
class="max-h-52 overflow-y-auto
|
|
385
|
+
class="max-h-52 p-1.5 overflow-y-auto"
|
|
381
386
|
role="listbox"
|
|
382
387
|
aria-label="Minutes"
|
|
383
388
|
>
|
|
@@ -390,8 +395,8 @@
|
|
|
390
395
|
aria-selected={selectedM === m}
|
|
391
396
|
onclick={() => pickMinute(m)}
|
|
392
397
|
class={[
|
|
393
|
-
'
|
|
394
|
-
'focus-visible:
|
|
398
|
+
'rounded-lg px-2 py-1.5 text-sm w-full transition-colors',
|
|
399
|
+
'focus-visible:ring-brand-500/30 focus-visible:ring-2 focus-visible:outline-none',
|
|
395
400
|
disabledMin && 'cursor-not-allowed opacity-30',
|
|
396
401
|
selectedM === m
|
|
397
402
|
? 'bg-brand-500 font-semibold text-white'
|
|
@@ -412,8 +417,12 @@
|
|
|
412
417
|
.timepicker-popover {
|
|
413
418
|
position: fixed;
|
|
414
419
|
inset: unset;
|
|
420
|
+
top: auto;
|
|
421
|
+
right: auto;
|
|
422
|
+
bottom: auto;
|
|
423
|
+
left: auto;
|
|
415
424
|
margin: 0;
|
|
416
|
-
width:
|
|
425
|
+
width: 13rem;
|
|
417
426
|
height: max-content;
|
|
418
427
|
}
|
|
419
428
|
|