@marianmeres/stuic 3.25.0 → 3.26.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.
|
@@ -72,6 +72,12 @@
|
|
|
72
72
|
/** Custom class for active item */
|
|
73
73
|
classItemActive?: string;
|
|
74
74
|
|
|
75
|
+
/** Show prev/next arrow buttons overlaid on left/right edges */
|
|
76
|
+
arrows?: boolean;
|
|
77
|
+
|
|
78
|
+
/** Custom class for arrow buttons */
|
|
79
|
+
classArrow?: string;
|
|
80
|
+
|
|
75
81
|
/** Skip all default styling */
|
|
76
82
|
unstyled?: boolean;
|
|
77
83
|
|
|
@@ -90,6 +96,11 @@
|
|
|
90
96
|
import { ItemCollection } from "@marianmeres/item-collection";
|
|
91
97
|
import { twMerge } from "../../utils/tw-merge.js";
|
|
92
98
|
import Thc from "../Thc/Thc.svelte";
|
|
99
|
+
import Button from "../Button/Button.svelte";
|
|
100
|
+
import {
|
|
101
|
+
iconArrowLeft as iconPrevious,
|
|
102
|
+
iconArrowRight as iconNext,
|
|
103
|
+
} from "../../icons/index.js";
|
|
93
104
|
|
|
94
105
|
let {
|
|
95
106
|
items,
|
|
@@ -111,6 +122,8 @@
|
|
|
111
122
|
classTrack,
|
|
112
123
|
classItem,
|
|
113
124
|
classItemActive,
|
|
125
|
+
arrows = false,
|
|
126
|
+
classArrow,
|
|
114
127
|
unstyled = false,
|
|
115
128
|
el = $bindable(),
|
|
116
129
|
onActiveChange,
|
|
@@ -367,5 +380,47 @@
|
|
|
367
380
|
</div>
|
|
368
381
|
{/each}
|
|
369
382
|
</div>
|
|
383
|
+
|
|
384
|
+
{#if arrows && coll.size > 1}
|
|
385
|
+
<div
|
|
386
|
+
class="absolute inset-0 flex items-center justify-between pointer-events-none"
|
|
387
|
+
>
|
|
388
|
+
<Button
|
|
389
|
+
class={twMerge(
|
|
390
|
+
"stuic-carousel-arrow pointer-events-auto p-0! ml-4",
|
|
391
|
+
classArrow
|
|
392
|
+
)}
|
|
393
|
+
onclick={() => {
|
|
394
|
+
coll.setActivePrevious();
|
|
395
|
+
scrollActiveIntoView();
|
|
396
|
+
}}
|
|
397
|
+
type="button"
|
|
398
|
+
disabled={!loop && coll.activeIndex === 0}
|
|
399
|
+
aspect1
|
|
400
|
+
variant="soft"
|
|
401
|
+
roundedFull
|
|
402
|
+
>
|
|
403
|
+
{@html iconPrevious({ size: 24 })}
|
|
404
|
+
</Button>
|
|
405
|
+
|
|
406
|
+
<Button
|
|
407
|
+
class={twMerge(
|
|
408
|
+
"stuic-carousel-arrow pointer-events-auto p-0! mr-4",
|
|
409
|
+
classArrow
|
|
410
|
+
)}
|
|
411
|
+
onclick={() => {
|
|
412
|
+
coll.setActiveNext();
|
|
413
|
+
scrollActiveIntoView();
|
|
414
|
+
}}
|
|
415
|
+
type="button"
|
|
416
|
+
disabled={!loop && coll.activeIndex === coll.size - 1}
|
|
417
|
+
aspect1
|
|
418
|
+
variant="soft"
|
|
419
|
+
roundedFull
|
|
420
|
+
>
|
|
421
|
+
{@html iconNext({ size: 24 })}
|
|
422
|
+
</Button>
|
|
423
|
+
</div>
|
|
424
|
+
{/if}
|
|
370
425
|
</div>
|
|
371
426
|
{/if}
|
|
@@ -51,6 +51,10 @@ export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "children">
|
|
|
51
51
|
classItem?: string;
|
|
52
52
|
/** Custom class for active item */
|
|
53
53
|
classItemActive?: string;
|
|
54
|
+
/** Show prev/next arrow buttons overlaid on left/right edges */
|
|
55
|
+
arrows?: boolean;
|
|
56
|
+
/** Custom class for arrow buttons */
|
|
57
|
+
classArrow?: string;
|
|
54
58
|
/** Skip all default styling */
|
|
55
59
|
unstyled?: boolean;
|
|
56
60
|
/** Bindable element reference */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validatePhoneNumber } from "../../Input/phone-validation.js";
|
|
1
2
|
// ====================================================================
|
|
2
3
|
// Default price formatter
|
|
3
4
|
// ====================================================================
|
|
@@ -28,6 +29,9 @@ export function validateCustomerForm(data, t) {
|
|
|
28
29
|
const emailError = validateEmail(data.email, t);
|
|
29
30
|
if (emailError)
|
|
30
31
|
errors.push({ field: "email", message: emailError });
|
|
32
|
+
const phoneError = validatePhoneNumber(data.phone);
|
|
33
|
+
if (phoneError)
|
|
34
|
+
errors.push({ field: "phone", message: phoneError });
|
|
31
35
|
return errors;
|
|
32
36
|
}
|
|
33
37
|
// ====================================================================
|
|
@@ -52,6 +56,9 @@ export function validateAddress(address, prefix, t) {
|
|
|
52
56
|
});
|
|
53
57
|
}
|
|
54
58
|
}
|
|
59
|
+
const phoneError = validatePhoneNumber(address.phone);
|
|
60
|
+
if (phoneError)
|
|
61
|
+
errors.push({ field: `${prefix}.phone`, message: phoneError });
|
|
55
62
|
return errors;
|
|
56
63
|
}
|
|
57
64
|
// ====================================================================
|
|
@@ -201,12 +201,12 @@
|
|
|
201
201
|
localNumber = _localNumber;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
// Compose full value from parts
|
|
204
|
+
// Compose full value from parts (strip only formatting chars, keep letters so they fail validation)
|
|
205
205
|
function composeValue(): string {
|
|
206
|
-
const
|
|
207
|
-
if (!
|
|
208
|
-
if (selectedCountry) return `+${selectedCountry.dialCode}${
|
|
209
|
-
return
|
|
206
|
+
const cleaned = _localNumber.replace(/[\s\-().\/]/g, "");
|
|
207
|
+
if (!cleaned) return "";
|
|
208
|
+
if (selectedCountry) return `+${selectedCountry.dialCode}${cleaned}`;
|
|
209
|
+
return cleaned;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
// Sync internal -> external value
|