@marianmeres/stuic 3.115.0 → 3.116.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/API.md +297 -304
- package/dist/actions/dim-behind/index.css +4 -1
- package/dist/actions/focus-trap.js +3 -1
- package/dist/components/Accordion/README.md +17 -17
- package/dist/components/Accordion/index.css +4 -2
- package/dist/components/AssetsPreview/README.md +7 -7
- package/dist/components/AssetsPreview/_internal/assets-preview-types.d.ts +1 -2
- package/dist/components/AssetsPreview/_internal/assets-preview-utils.d.ts +1 -1
- package/dist/components/AssetsPreview/_internal/assets-preview-utils.js +9 -3
- package/dist/components/Avatar/Avatar.svelte +1 -3
- package/dist/components/Avatar/README.md +33 -27
- package/dist/components/Book/Book.svelte +6 -1
- package/dist/components/Book/README.md +22 -20
- package/dist/components/Book/index.css +4 -2
- package/dist/components/Button/README.md +17 -17
- package/dist/components/Card/Card.svelte +25 -8
- package/dist/components/Card/README.md +52 -56
- package/dist/components/Card/index.css +2 -1
- package/dist/components/Carousel/Carousel.svelte +1 -3
- package/dist/components/Carousel/README.md +28 -28
- package/dist/components/Cart/Cart.svelte +2 -1
- package/dist/components/Cart/README.md +25 -25
- package/dist/components/Checkout/CheckoutGuestOrLoginForm.svelte +8 -3
- package/dist/components/Checkout/CheckoutShippingStep.svelte +1 -2
- package/dist/components/Checkout/README.md +143 -130
- package/dist/components/CronInput/CronInput.svelte +64 -60
- package/dist/components/CronInput/README.md +46 -46
- package/dist/components/DataTable/DataTable.svelte +5 -1
- package/dist/components/DataTable/README.md +78 -63
- package/dist/components/DropdownMenu/DropdownMenu.svelte +6 -2
- package/dist/components/DropdownMenu/README.md +33 -27
- package/dist/components/EmailVerifyForm/EmailVerifyForm.svelte +2 -9
- package/dist/components/EmailVerifyForm/README.md +30 -30
- package/dist/components/Header/Header.svelte +161 -165
- package/dist/components/Header/README.md +7 -7
- package/dist/components/IconSwap/README.md +20 -15
- package/dist/components/IconSwap/index.css +2 -1
- package/dist/components/ImageCycler/ImageCycler.svelte +19 -5
- package/dist/components/ImageCycler/ImageCycler.svelte.d.ts +14 -10
- package/dist/components/ImageCycler/README.md +15 -15
- package/dist/components/ImageCycler/index.css +26 -20
- package/dist/components/Input/FieldFile.svelte +1 -3
- package/dist/components/Input/FieldInput.svelte +1 -3
- package/dist/components/Input/FieldKeyValues.svelte +2 -6
- package/dist/components/Input/FieldObject.svelte +2 -1
- package/dist/components/Input/README.md +11 -11
- package/dist/components/KbdShortcut/index.css +2 -1
- package/dist/components/LoginForm/LoginForm.svelte +1 -7
- package/dist/components/LoginForm/README.md +46 -46
- package/dist/components/ModalDialog/index.css +2 -1
- package/dist/components/Notifications/index.css +24 -6
- package/dist/components/OtpInput/OtpInput.svelte +0 -0
- package/dist/components/OtpInput/README.md +15 -19
- package/dist/components/OtpInput/index.css +1 -4
- package/dist/components/OtpInput/index.d.ts +1 -1
- package/dist/components/OtpInput/index.js +1 -1
- package/dist/components/Pill/README.md +41 -40
- package/dist/components/Pill/index.css +3 -6
- package/dist/components/PricingTable/README.md +86 -86
- package/dist/components/PricingTable/index.css +20 -35
- package/dist/components/RegisterForm/README.md +60 -60
- package/dist/components/RegisterForm/RegisterForm.svelte +1 -7
- package/dist/components/Separator/README.md +7 -7
- package/dist/components/TabbedMenu/index.css +6 -3
- package/dist/components/Tree/README.md +67 -67
- package/dist/components/UserAvatarMenu/UserAvatarMenu.svelte +1 -5
- package/dist/components/WithSidePanel/index.css +4 -4
- package/dist/index.css +12 -8
- package/dist/utils/design-tokens.d.ts +1 -1
- package/dist/utils/design-tokens.js +1 -1
- package/docs/architecture.md +7 -7
- package/docs/component-testing/00-overview-and-roadmap.md +19 -19
- package/docs/component-testing/01-framework-setup.md +6 -6
- package/docs/component-testing/02-test-conventions.md +6 -5
- package/docs/component-testing/03-component-coverage-roadmap.md +27 -27
- package/docs/component-testing/04-hard-cases-and-e2e.md +8 -8
- package/docs/component-testing/05-ci.md +3 -3
- package/docs/component-testing/PROGRESS.md +30 -26
- package/docs/component-testing/README.md +8 -8
- package/docs/conventions.md +25 -25
- package/docs/domains/components.md +386 -385
- package/docs/domains/theming.md +24 -24
- package/docs/domains/utils.md +22 -25
- package/docs/testing.md +2 -2
- package/docs/upgrading.md +32 -28
- package/package.json +2 -1
|
@@ -17,8 +17,12 @@
|
|
|
17
17
|
minWait?: number;
|
|
18
18
|
transitionDuration?: number;
|
|
19
19
|
onclick?: (image: ImageCyclerImage, index: number) => void;
|
|
20
|
-
title?: Snippet<
|
|
21
|
-
|
|
20
|
+
title?: Snippet<
|
|
21
|
+
[{ image: ImageCyclerImage; index: number; onclick: (() => void) | undefined }]
|
|
22
|
+
>;
|
|
23
|
+
description?: Snippet<
|
|
24
|
+
[{ image: ImageCyclerImage; index: number; onclick: (() => void) | undefined }]
|
|
25
|
+
>;
|
|
22
26
|
unstyled?: boolean;
|
|
23
27
|
class?: string;
|
|
24
28
|
el?: HTMLElement;
|
|
@@ -47,7 +51,9 @@
|
|
|
47
51
|
|
|
48
52
|
let _class = $derived(unstyled ? classProp : twMerge("stuic-image-cycler", classProp));
|
|
49
53
|
|
|
50
|
-
let _onclick = $derived(
|
|
54
|
+
let _onclick = $derived(
|
|
55
|
+
onclick ? () => onclick(images[currentIndex], currentIndex) : undefined
|
|
56
|
+
);
|
|
51
57
|
|
|
52
58
|
$effect(() => {
|
|
53
59
|
const idx = currentIndex;
|
|
@@ -87,10 +93,18 @@
|
|
|
87
93
|
out:fade={{ duration: transitionDuration }}
|
|
88
94
|
>
|
|
89
95
|
{#if title}
|
|
90
|
-
{@render title({
|
|
96
|
+
{@render title({
|
|
97
|
+
image: images[currentIndex],
|
|
98
|
+
index: currentIndex,
|
|
99
|
+
onclick: _onclick,
|
|
100
|
+
})}
|
|
91
101
|
{/if}
|
|
92
102
|
{#if description}
|
|
93
|
-
{@render description({
|
|
103
|
+
{@render description({
|
|
104
|
+
image: images[currentIndex],
|
|
105
|
+
index: currentIndex,
|
|
106
|
+
onclick: _onclick,
|
|
107
|
+
})}
|
|
94
108
|
{/if}
|
|
95
109
|
</div>
|
|
96
110
|
{/key}
|
|
@@ -13,16 +13,20 @@ export interface Props {
|
|
|
13
13
|
minWait?: number;
|
|
14
14
|
transitionDuration?: number;
|
|
15
15
|
onclick?: (image: ImageCyclerImage, index: number) => void;
|
|
16
|
-
title?: Snippet<[
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
title?: Snippet<[
|
|
17
|
+
{
|
|
18
|
+
image: ImageCyclerImage;
|
|
19
|
+
index: number;
|
|
20
|
+
onclick: (() => void) | undefined;
|
|
21
|
+
}
|
|
22
|
+
]>;
|
|
23
|
+
description?: Snippet<[
|
|
24
|
+
{
|
|
25
|
+
image: ImageCyclerImage;
|
|
26
|
+
index: number;
|
|
27
|
+
onclick: (() => void) | undefined;
|
|
28
|
+
}
|
|
29
|
+
]>;
|
|
26
30
|
unstyled?: boolean;
|
|
27
31
|
class?: string;
|
|
28
32
|
el?: HTMLElement;
|
|
@@ -4,18 +4,18 @@ Auto-cycling background-image carousel with fade transitions. Preloads the next
|
|
|
4
4
|
|
|
5
5
|
## Props
|
|
6
6
|
|
|
7
|
-
| Prop | Type
|
|
8
|
-
| -------------------- |
|
|
9
|
-
| `images` | `ImageCyclerImage[]`
|
|
10
|
-
| `fit` | `"cover" \| "contain" \| "fill"`
|
|
11
|
-
| `minWait` | `number`
|
|
12
|
-
| `transitionDuration` | `number`
|
|
13
|
-
| `onclick` | `(image, index) => void`
|
|
14
|
-
| `title` | `Snippet<[{ image, index, onclick }]>`
|
|
15
|
-
| `description` | `Snippet<[{ image, index, onclick }]>`
|
|
16
|
-
| `unstyled` | `boolean`
|
|
17
|
-
| `class` | `string`
|
|
18
|
-
| `el` | `HTMLElement`
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| -------------------- | -------------------------------------- | --------- | ------------------------------------------------------------ |
|
|
9
|
+
| `images` | `ImageCyclerImage[]` | required | Images to cycle through. |
|
|
10
|
+
| `fit` | `"cover" \| "contain" \| "fill"` | `"cover"` | Background-size mode. Set via `data-fit` on the image layer. |
|
|
11
|
+
| `minWait` | `number` | `3000` | Minimum wait (ms) on each image before advancing. |
|
|
12
|
+
| `transitionDuration` | `number` | `500` | Fade duration in ms (for both the image and the meta layer). |
|
|
13
|
+
| `onclick` | `(image, index) => void` | - | Click handler. The snippets receive a forwarded version. |
|
|
14
|
+
| `title` | `Snippet<[{ image, index, onclick }]>` | - | Title overlay snippet. |
|
|
15
|
+
| `description` | `Snippet<[{ image, index, onclick }]>` | - | Description overlay snippet. |
|
|
16
|
+
| `unstyled` | `boolean` | `false` | Skip default styling. |
|
|
17
|
+
| `class` | `string` | - | Additional CSS classes. |
|
|
18
|
+
| `el` | `HTMLElement` | - | Bindable root element. |
|
|
19
19
|
|
|
20
20
|
## `ImageCyclerImage`
|
|
21
21
|
|
|
@@ -71,9 +71,9 @@ interface ImageCyclerImage {
|
|
|
71
71
|
|
|
72
72
|
## CSS Variables
|
|
73
73
|
|
|
74
|
-
| Variable
|
|
75
|
-
|
|
|
76
|
-
| `--stuic-image-cycler-transition-duration`
|
|
74
|
+
| Variable | Default | Description |
|
|
75
|
+
| ------------------------------------------ | ------- | ---------------------------------------------------------------------------------------- |
|
|
76
|
+
| `--stuic-image-cycler-transition-duration` | `500ms` | (informational; the active transition duration comes from the `transitionDuration` prop) |
|
|
77
77
|
|
|
78
78
|
## Notes
|
|
79
79
|
|
|
@@ -1,28 +1,34 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
|
|
2
|
+
--stuic-image-cycler-transition-duration: 500ms;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
@layer components {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
.stuic-image-cycler {
|
|
7
|
+
position: relative;
|
|
8
|
+
width: 100%;
|
|
9
|
+
height: 100%;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
.stuic-image-cycler-bg {
|
|
14
|
+
position: absolute;
|
|
15
|
+
inset: 0;
|
|
16
|
+
background-position: center;
|
|
17
|
+
background-repeat: no-repeat;
|
|
18
|
+
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
.stuic-image-cycler-bg[data-fit="cover"] {
|
|
21
|
+
background-size: cover;
|
|
22
|
+
}
|
|
23
|
+
.stuic-image-cycler-bg[data-fit="contain"] {
|
|
24
|
+
background-size: contain;
|
|
25
|
+
}
|
|
26
|
+
.stuic-image-cycler-bg[data-fit="fill"] {
|
|
27
|
+
background-size: 100% 100%;
|
|
28
|
+
}
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
.stuic-image-cycler-meta {
|
|
31
|
+
position: absolute;
|
|
32
|
+
inset: 0;
|
|
33
|
+
}
|
|
28
34
|
}
|
|
@@ -8,9 +8,7 @@
|
|
|
8
8
|
type SnippetWithId = Snippet<[{ id: string }]>;
|
|
9
9
|
|
|
10
10
|
export interface Props
|
|
11
|
-
extends HTMLInputAttributes,
|
|
12
|
-
InputWrapClassProps,
|
|
13
|
-
Record<string, any> {
|
|
11
|
+
extends HTMLInputAttributes, InputWrapClassProps, Record<string, any> {
|
|
14
12
|
input?: HTMLInputElement;
|
|
15
13
|
files?: FileList;
|
|
16
14
|
multiple?: boolean;
|
|
@@ -9,9 +9,7 @@
|
|
|
9
9
|
type SnippetWithId = Snippet<[{ id: string }]>;
|
|
10
10
|
|
|
11
11
|
export interface Props
|
|
12
|
-
extends HTMLInputAttributes,
|
|
13
|
-
InputWrapClassProps,
|
|
14
|
-
Record<string, any> {
|
|
12
|
+
extends HTMLInputAttributes, InputWrapClassProps, Record<string, any> {
|
|
15
13
|
input?: HTMLInputElement;
|
|
16
14
|
value?: string | number;
|
|
17
15
|
label?: SnippetWithId | THC;
|
|
@@ -445,13 +445,9 @@
|
|
|
445
445
|
<span
|
|
446
446
|
class={twMerge(
|
|
447
447
|
"pointer-events-none absolute top-1.5 right-1.5",
|
|
448
|
-
st === "valid"
|
|
449
|
-
? "opacity-40"
|
|
450
|
-
: "text-amber-500 opacity-80"
|
|
448
|
+
st === "valid" ? "opacity-40" : "text-amber-500 opacity-80"
|
|
451
449
|
)}
|
|
452
|
-
title={st === "valid"
|
|
453
|
-
? t("json_detected")
|
|
454
|
-
: t("invalid_json_syntax")}
|
|
450
|
+
title={st === "valid" ? t("json_detected") : t("invalid_json_syntax")}
|
|
455
451
|
aria-hidden="true"
|
|
456
452
|
>
|
|
457
453
|
{@html st === "valid"
|
|
@@ -354,7 +354,8 @@
|
|
|
354
354
|
{value}
|
|
355
355
|
bind:this={hiddenInputEl}
|
|
356
356
|
use:validateAction={() => {
|
|
357
|
-
const customOpts =
|
|
357
|
+
const customOpts =
|
|
358
|
+
typeof validateProp === "object" && validateProp ? validateProp : {};
|
|
358
359
|
const userValidator = customOpts.customValidator;
|
|
359
360
|
return {
|
|
360
361
|
enabled: validateProp !== false,
|
|
@@ -52,17 +52,17 @@ A comprehensive form input system with multiple field components, validation sup
|
|
|
52
52
|
|
|
53
53
|
Every `Field*` component that uses the shared label/input/description scaffolding accepts **the same 9 class props**, exported as the `InputWrapClassProps` interface from `@marianmeres/stuic`. Each Field extends that interface in its own `Props`, so the shape stays in sync and new wrapper targets are added in one place.
|
|
54
54
|
|
|
55
|
-
| Prop
|
|
56
|
-
|
|
|
57
|
-
| `classLabel`
|
|
58
|
-
| `classLabelBox`
|
|
59
|
-
| `classInputBox`
|
|
60
|
-
| `classInputBoxWrap`
|
|
61
|
-
| `classInputBoxWrapInvalid`
|
|
62
|
-
| `classDescBox`
|
|
63
|
-
| `classDescBoxToggle`
|
|
64
|
-
| `classBelowBox`
|
|
65
|
-
| `classValidationBox`
|
|
55
|
+
| Prop | Target |
|
|
56
|
+
| -------------------------- | ---------------------------------------------------------- |
|
|
57
|
+
| `classLabel` | `<label>` element |
|
|
58
|
+
| `classLabelBox` | Wrapper around the label area |
|
|
59
|
+
| `classInputBox` | Wrapper around the whole input area |
|
|
60
|
+
| `classInputBoxWrap` | Inner input wrap (sibling to description/validation/below) |
|
|
61
|
+
| `classInputBoxWrapInvalid` | Added to `classInputBoxWrap` when validation fails |
|
|
62
|
+
| `classDescBox` | Description/help text box |
|
|
63
|
+
| `classDescBoxToggle` | Collapsible description's toggle button |
|
|
64
|
+
| `classBelowBox` | "Below" slot (rendered under the description) |
|
|
65
|
+
| `classValidationBox` | Validation message box |
|
|
66
66
|
|
|
67
67
|
Component-specific targets (e.g. `classInput` for the inner `<input>`/`<select>`/`<textarea>`, `classFileList` on `FieldFile`, `classOption`/`classOptgroup` on `FieldOptions`, `classPrefixTrigger` on `FieldPhoneNumber`, etc.) live on the component itself alongside these shared props.
|
|
68
68
|
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
/* Box model */
|
|
38
38
|
padding: var(--stuic-kbd-padding-y) var(--stuic-kbd-padding-x);
|
|
39
39
|
border-radius: var(--stuic-kbd-radius, var(--stuic-radius));
|
|
40
|
-
border: var(--stuic-kbd-border-width, var(--stuic-border-width)) solid
|
|
40
|
+
border: var(--stuic-kbd-border-width, var(--stuic-border-width)) solid
|
|
41
|
+
var(--stuic-kbd-border-color);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
/* Symbol styling (⌘, ⇧, ⌥, ⌃, ⊞) */
|
|
@@ -247,13 +247,7 @@
|
|
|
247
247
|
}
|
|
248
248
|
</script>
|
|
249
249
|
|
|
250
|
-
<form
|
|
251
|
-
bind:this={formEl}
|
|
252
|
-
class={_class}
|
|
253
|
-
use:onSubmitValidityCheck
|
|
254
|
-
novalidate
|
|
255
|
-
{...rest}
|
|
256
|
-
>
|
|
250
|
+
<form bind:this={formEl} class={_class} use:onSubmitValidityCheck novalidate {...rest}>
|
|
257
251
|
<!-- General error alert -->
|
|
258
252
|
<DismissibleMessage message={error} intent="destructive" />
|
|
259
253
|
|
|
@@ -6,47 +6,47 @@ Standalone login form with email/password fields, optional social/OAuth buttons,
|
|
|
6
6
|
|
|
7
7
|
## Exports
|
|
8
8
|
|
|
9
|
-
| Export | Kind | Description
|
|
10
|
-
| -------------------------- | --------- |
|
|
11
|
-
| `LoginForm` | component | Form component
|
|
12
|
-
| `LoginFormModal` | component | Modal-wrapped form with optional trigger snippet
|
|
13
|
-
| `LoginFormProps` | type | Props for `LoginForm`
|
|
14
|
-
| `LoginFormModalProps` | type | Props for `LoginFormModal`
|
|
15
|
-
| `LoginFormData` | type | `{ email, password, rememberMe }`
|
|
16
|
-
| `LoginFormValidationError` | type | `{ field, message }`
|
|
17
|
-
| `createEmptyLoginFormData` | function | Factory for an empty `LoginFormData`
|
|
18
|
-
| `validateLoginForm` | function | `(data, t) => LoginFormValidationError[]`
|
|
9
|
+
| Export | Kind | Description |
|
|
10
|
+
| -------------------------- | --------- | ------------------------------------------------ |
|
|
11
|
+
| `LoginForm` | component | Form component |
|
|
12
|
+
| `LoginFormModal` | component | Modal-wrapped form with optional trigger snippet |
|
|
13
|
+
| `LoginFormProps` | type | Props for `LoginForm` |
|
|
14
|
+
| `LoginFormModalProps` | type | Props for `LoginFormModal` |
|
|
15
|
+
| `LoginFormData` | type | `{ email, password, rememberMe }` |
|
|
16
|
+
| `LoginFormValidationError` | type | `{ field, message }` |
|
|
17
|
+
| `createEmptyLoginFormData` | function | Factory for an empty `LoginFormData` |
|
|
18
|
+
| `validateLoginForm` | function | `(data, t) => LoginFormValidationError[]` |
|
|
19
19
|
|
|
20
20
|
## LoginForm — Props
|
|
21
21
|
|
|
22
|
-
| Prop
|
|
23
|
-
|
|
|
24
|
-
| `formData`
|
|
25
|
-
| `onSubmit`
|
|
26
|
-
| `isSubmitting`
|
|
27
|
-
| `errors`
|
|
28
|
-
| `error`
|
|
29
|
-
| `onForgotPassword`
|
|
30
|
-
| `showRememberMe`
|
|
31
|
-
| `submitLabel`
|
|
32
|
-
| `submittingLabel`
|
|
33
|
-
| `submitButton`
|
|
34
|
-
| `socialLogins`
|
|
35
|
-
| `socialDividerLabel`
|
|
36
|
-
| `footer`
|
|
37
|
-
| `notifications`
|
|
38
|
-
| `t`
|
|
39
|
-
| `unstyled` / `class`
|
|
40
|
-
| `el`
|
|
22
|
+
| Prop | Type | Default | Description |
|
|
23
|
+
| -------------------- | --------------------------------------- | -------- | -------------------------------------------------------------------------------- |
|
|
24
|
+
| `formData` | `LoginFormData` | empty | Bindable form data. |
|
|
25
|
+
| `onSubmit` | `(data: LoginFormData) => void` | required | Called when client-side validation passes. |
|
|
26
|
+
| `isSubmitting` | `boolean` | `false` | Disables the CTA during submission. |
|
|
27
|
+
| `errors` | `LoginFormValidationError[]` | `[]` | Field-specific server errors (merged with internal validation). |
|
|
28
|
+
| `error` | `string` | - | General error rendered as a `DismissibleMessage` above the form. |
|
|
29
|
+
| `onForgotPassword` | `() => void` | - | Click handler for the "Forgot password?" link. Link is hidden when undefined. |
|
|
30
|
+
| `showRememberMe` | `boolean` | `true` | Render the remember-me checkbox. |
|
|
31
|
+
| `submitLabel` | `string` | i18n | Override the CTA label. |
|
|
32
|
+
| `submittingLabel` | `string` | i18n | Override the CTA label while submitting. |
|
|
33
|
+
| `submitButton` | `Snippet<[{ isSubmitting, disabled }]>` | - | Override the entire CTA section. |
|
|
34
|
+
| `socialLogins` | `Snippet` | - | Social/OAuth buttons rendered below the form. A divider is shown above when set. |
|
|
35
|
+
| `socialDividerLabel` | `string \| false` | i18n | Override (or hide with `false`) the divider above social buttons. |
|
|
36
|
+
| `footer` | `Snippet` | - | Content below the form (e.g., sign-up links). |
|
|
37
|
+
| `notifications` | `NotificationsStack` | - | When set, general errors are also pushed via `notifications.error()`. |
|
|
38
|
+
| `t` | `TranslateFn` | English | i18n function. |
|
|
39
|
+
| `unstyled` / `class` | - | - | Standard styling escape hatches. |
|
|
40
|
+
| `el` | `HTMLFormElement` | - | Bindable form element. |
|
|
41
41
|
|
|
42
42
|
### Imperative methods
|
|
43
43
|
|
|
44
44
|
`bind:this` exposes:
|
|
45
45
|
|
|
46
|
-
| Method
|
|
47
|
-
|
|
|
48
|
-
| `validate()`
|
|
49
|
-
| `scrollToFirstError(opts?)`
|
|
46
|
+
| Method | Returns | Purpose |
|
|
47
|
+
| --------------------------- | --------- | ------------------------------------------------------------------- |
|
|
48
|
+
| `validate()` | `boolean` | Forces every inner field's validator to run. `true` if all valid. |
|
|
49
|
+
| `scrollToFirstError(opts?)` | `boolean` | Scrolls + focuses the first invalid field. Call after `validate()`. |
|
|
50
50
|
|
|
51
51
|
These are essential for pristine-form errors (server errors set via the `errors` prop won't render until the user touches each field). See [`docs/domains/components.md#imperative-validate-api`](../../../docs/domains/components.md#imperative-validate-api) for the full pattern.
|
|
52
52
|
|
|
@@ -54,17 +54,17 @@ These are essential for pristine-form errors (server errors set via the `errors`
|
|
|
54
54
|
|
|
55
55
|
Inherits all `LoginForm` props, plus:
|
|
56
56
|
|
|
57
|
-
| Prop | Type
|
|
58
|
-
| --------------------- |
|
|
59
|
-
| `title` | `string`
|
|
60
|
-
| `visible` | `boolean`
|
|
61
|
-
| `trigger` | `Snippet<[{ open }]>`
|
|
62
|
-
| `classModal` | `string`
|
|
63
|
-
| `classInner` | `string`
|
|
64
|
-
| `classForm` | `string`
|
|
65
|
-
| `noXClose` | `boolean`
|
|
66
|
-
| `onClose` | `() => false \| void`
|
|
67
|
-
| `noClickOutsideClose` | `boolean`
|
|
57
|
+
| Prop | Type | Default | Description |
|
|
58
|
+
| --------------------- | --------------------- | ----------------- | ----------------------------------------------------------------------- |
|
|
59
|
+
| `title` | `string` | `"Log In"` (i18n) | Modal title. |
|
|
60
|
+
| `visible` | `boolean` | `false` | Bindable modal visibility. |
|
|
61
|
+
| `trigger` | `Snippet<[{ open }]>` | - | Optional trigger element rendered outside the modal. |
|
|
62
|
+
| `classModal` | `string` | - | Class for the Modal box. |
|
|
63
|
+
| `classInner` | `string` | - | Class for the Modal inner width container. |
|
|
64
|
+
| `classForm` | `string` | - | Class forwarded to the inner `LoginForm`. |
|
|
65
|
+
| `noXClose` | `boolean` | `false` | Hide the close (X) button. |
|
|
66
|
+
| `onClose` | `() => false \| void` | - | Pre-close hook. Return `false` to prevent close. |
|
|
67
|
+
| `noClickOutsideClose` | `boolean` | `true` | Disable backdrop-click close (default-on to protect typed credentials). |
|
|
68
68
|
|
|
69
69
|
**Methods:** `open(openerOrEvent?)`, `close()` — exposed via `bind:this`.
|
|
70
70
|
|
|
@@ -137,8 +137,8 @@ Prefix: `--stuic-login-form-*`
|
|
|
137
137
|
| `--stuic-login-form-gap-row` | Gap inside multi-column rows |
|
|
138
138
|
| `--stuic-login-form-forgot-margin-y` | Forgot-password link vertical margin |
|
|
139
139
|
| `--stuic-login-form-forgot-margin-x` | Forgot-password link horizontal margin |
|
|
140
|
-
| `--stuic-login-form-social-margin-top` | Margin above social buttons block
|
|
141
|
-
| `--stuic-login-form-social-gap` | Gap between social buttons
|
|
140
|
+
| `--stuic-login-form-social-margin-top` | Margin above social buttons block |
|
|
141
|
+
| `--stuic-login-form-social-gap` | Gap between social buttons |
|
|
142
142
|
| `--stuic-login-form-social-divider-color` | Divider text color |
|
|
143
143
|
| `--stuic-login-form-social-divider-font-size` | Divider text size |
|
|
144
144
|
| `--stuic-login-form-social-divider-margin-bottom` | Divider bottom margin |
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
============================================================================ */
|
|
43
43
|
|
|
44
44
|
.stuic-modal-dialog[open]::backdrop {
|
|
45
|
-
animation: stuic-modal-dialog-fadeIn
|
|
45
|
+
animation: stuic-modal-dialog-fadeIn
|
|
46
|
+
var(--stuic-modal-dialog-transition, var(--stuic-transition)) ease-out;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
@keyframes stuic-modal-dialog-fadeIn {
|
|
@@ -152,8 +152,14 @@
|
|
|
152
152
|
align-items: center;
|
|
153
153
|
justify-content: center;
|
|
154
154
|
padding: 0 calc(var(--spacing) * 3);
|
|
155
|
-
border-top-right-radius: var(
|
|
156
|
-
|
|
155
|
+
border-top-right-radius: var(
|
|
156
|
+
--stuic-notification-radius,
|
|
157
|
+
var(--stuic-radius-container)
|
|
158
|
+
);
|
|
159
|
+
border-bottom-right-radius: var(
|
|
160
|
+
--stuic-notification-radius,
|
|
161
|
+
var(--stuic-radius-container)
|
|
162
|
+
);
|
|
157
163
|
color: var(--_text);
|
|
158
164
|
opacity: 0.75;
|
|
159
165
|
transition: opacity var(--stuic-notification-transition, var(--stuic-transition));
|
|
@@ -198,8 +204,14 @@
|
|
|
198
204
|
position: absolute;
|
|
199
205
|
inset: 0;
|
|
200
206
|
background: transparent;
|
|
201
|
-
border-bottom-left-radius: var(
|
|
202
|
-
|
|
207
|
+
border-bottom-left-radius: var(
|
|
208
|
+
--stuic-notification-radius,
|
|
209
|
+
var(--stuic-radius-container)
|
|
210
|
+
);
|
|
211
|
+
border-bottom-right-radius: var(
|
|
212
|
+
--stuic-notification-radius,
|
|
213
|
+
var(--stuic-radius-container)
|
|
214
|
+
);
|
|
203
215
|
overflow: hidden;
|
|
204
216
|
pointer-events: none;
|
|
205
217
|
}
|
|
@@ -208,7 +220,13 @@
|
|
|
208
220
|
width: 100%;
|
|
209
221
|
height: 100%;
|
|
210
222
|
/* background: rgb(255 255 255 / 0.5); */
|
|
211
|
-
border-bottom-left-radius: var(
|
|
212
|
-
|
|
223
|
+
border-bottom-left-radius: var(
|
|
224
|
+
--stuic-notification-radius,
|
|
225
|
+
var(--stuic-radius-container)
|
|
226
|
+
);
|
|
227
|
+
border-bottom-right-radius: var(
|
|
228
|
+
--stuic-notification-radius,
|
|
229
|
+
var(--stuic-radius-container)
|
|
230
|
+
);
|
|
213
231
|
}
|
|
214
232
|
}
|
|
Binary file
|
|
@@ -11,29 +11,25 @@ Generic N-slot one-time-code input. 6 digits by default, configurable. Building
|
|
|
11
11
|
let code = $state("");
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
|
-
<OtpInput
|
|
15
|
-
bind:value={code}
|
|
16
|
-
length={6}
|
|
17
|
-
onComplete={(c) => console.log("Got code:", c)}
|
|
18
|
-
/>
|
|
14
|
+
<OtpInput bind:value={code} length={6} onComplete={(c) => console.log("Got code:", c)} />
|
|
19
15
|
```
|
|
20
16
|
|
|
21
17
|
## Props
|
|
22
18
|
|
|
23
|
-
| Prop | Type
|
|
24
|
-
| -------------- |
|
|
25
|
-
| `value` | `string`
|
|
26
|
-
| `length` | `number`
|
|
27
|
-
| `onComplete` | `(code: string) => void`
|
|
28
|
-
| `oninput` | `(value: string) => void`
|
|
29
|
-
| `error` | `boolean`
|
|
30
|
-
| `disabled` | `boolean`
|
|
31
|
-
| `autoFocus` | `boolean`
|
|
32
|
-
| `mode` | `"numeric" \| "alphanumeric"`
|
|
33
|
-
| `autocomplete` | `string`
|
|
34
|
-
| `unstyled` | `boolean`
|
|
35
|
-
| `class` | `string`
|
|
36
|
-
| `el` | `HTMLDivElement`
|
|
19
|
+
| Prop | Type | Default | Description |
|
|
20
|
+
| -------------- | ----------------------------- | ----------------- | ---------------------------------------------------- |
|
|
21
|
+
| `value` | `string` | `""` | Bindable concatenated value |
|
|
22
|
+
| `length` | `number` | `6` | Number of slots |
|
|
23
|
+
| `onComplete` | `(code: string) => void` | — | Fired when all slots are filled |
|
|
24
|
+
| `oninput` | `(value: string) => void` | — | Fired on every change |
|
|
25
|
+
| `error` | `boolean` | `false` | Renders error styling + `aria-invalid` |
|
|
26
|
+
| `disabled` | `boolean` | `false` | Disables all slots |
|
|
27
|
+
| `autoFocus` | `boolean` | `true` | Auto-focus the first empty slot on mount |
|
|
28
|
+
| `mode` | `"numeric" \| "alphanumeric"` | `"numeric"` | Restrict input characters |
|
|
29
|
+
| `autocomplete` | `string` | `"one-time-code"` | Pass-through to first slot for browser/iOS auto-fill |
|
|
30
|
+
| `unstyled` | `boolean` | `false` | Skip default styling |
|
|
31
|
+
| `class` | `string` | — | Additional CSS classes on the root |
|
|
32
|
+
| `el` | `HTMLDivElement` | — | Bindable root element ref |
|
|
37
33
|
|
|
38
34
|
## Behavior
|
|
39
35
|
|
|
@@ -20,10 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.stuic-otp-input-slot:focus {
|
|
23
|
-
border-color: var(
|
|
24
|
-
--stuic-otp-input-border-color-focus,
|
|
25
|
-
var(--stuic-color-primary)
|
|
26
|
-
);
|
|
23
|
+
border-color: var(--stuic-otp-input-border-color-focus, var(--stuic-color-primary));
|
|
27
24
|
outline: none;
|
|
28
25
|
}
|
|
29
26
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as OtpInput, type Props as OtpInputProps
|
|
1
|
+
export { default as OtpInput, type Props as OtpInputProps } from "./OtpInput.svelte";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as OtpInput
|
|
1
|
+
export { default as OtpInput } from "./OtpInput.svelte";
|