svseeds 0.3.7 → 0.4.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/_svseeds/TagsInput.svelte +52 -82
- package/_svseeds/TagsInput.svelte.d.ts +13 -11
- package/_svseeds/TagsInputField.svelte +169 -0
- package/_svseeds/TagsInputField.svelte.d.ts +35 -0
- package/_svseeds/ToggleGroupField.svelte +134 -0
- package/_svseeds/ToggleGroupField.svelte.d.ts +30 -0
- package/_svseeds/_CheckField.svelte +31 -33
- package/_svseeds/_CheckField.svelte.d.ts +4 -3
- package/_svseeds/_SelectField.svelte +25 -24
- package/_svseeds/_SelectField.svelte.d.ts +3 -2
- package/_svseeds/_TextField.svelte +25 -26
- package/_svseeds/_TextField.svelte.d.ts +3 -2
- package/_svseeds/_Toggle.svelte +5 -6
- package/_svseeds/_Toggle.svelte.d.ts +0 -1
- package/_svseeds/_ToggleGroup.svelte +78 -0
- package/_svseeds/_ToggleGroup.svelte.d.ts +20 -0
- package/_svseeds/core.d.ts +2 -3
- package/_svseeds/core.js +1 -1
- package/index.d.ts +7 -5
- package/index.js +3 -1
- package/package.json +1 -1
- package/_svseeds/_TogglesField.svelte +0 -144
- package/_svseeds/_TogglesField.svelte.d.ts +0 -26
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
options: SvelteMap<string, string> | Map<string, string>,
|
|
4
4
|
label?: string,
|
|
5
5
|
extra?: string,
|
|
6
|
-
aux?: Snippet<[string, string[], HTMLInputElement[]
|
|
6
|
+
aux?: Snippet<[string, string[], HTMLInputElement[]]>, // Snippet<[status,values,elements]>
|
|
7
7
|
bottom?: string,
|
|
8
|
+
descFirst?: boolean, // <false>
|
|
8
9
|
values?: string[], // bindable
|
|
9
10
|
multiple?: boolean, // <true>
|
|
10
|
-
|
|
11
|
-
validations?: ((values: string[], validities?: ValidityState[]) => string)[],
|
|
11
|
+
validations?: CheckFieldValidation[],
|
|
12
12
|
status?: string, // bindable <STATE.DEFAULT>
|
|
13
13
|
style?: SVSStyle,
|
|
14
14
|
attributes?: HTMLInputAttributes,
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
};
|
|
18
18
|
export type CheckFieldReqdProps = "options";
|
|
19
19
|
export type CheckFieldBindProps = "values" | "status" | "elements";
|
|
20
|
+
export type CheckFieldValidation = (values: string[], validity: ValidityState) => string;
|
|
20
21
|
|
|
21
|
-
type CheckFieldTarget = { currentTarget: EventTarget & HTMLInputElement };
|
|
22
22
|
const preset = "svs-check-field";
|
|
23
23
|
|
|
24
24
|
import { type Snippet, untrack } from "svelte";
|
|
@@ -44,27 +44,23 @@
|
|
|
44
44
|
let message = $state(bottom);
|
|
45
45
|
|
|
46
46
|
// *** Status *** //
|
|
47
|
-
|
|
48
|
-
let neutral = isNeutral(status) ? status : STATE.DEFAULT;
|
|
47
|
+
let neutral = $state(isNeutral(status) ? status : STATE.DEFAULT);
|
|
49
48
|
$effect(() => { neutral = isNeutral(status) ? status : neutral });
|
|
50
49
|
let live = $derived(status === STATE.INACTIVE ? "alert" : "status");
|
|
51
50
|
let invalid = $derived(status === STATE.INACTIVE ? true : undefined);
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
message = stat === STATE.INACTIVE ? msg ?? bottom : bottom;
|
|
58
|
-
elements[0]?.setCustomValidity(msg ?? "");
|
|
51
|
+
let idMsg = $derived(status === STATE.INACTIVE && message?.trim() ? idErr : undefined);
|
|
52
|
+
function shift(oninvalid?: boolean) {
|
|
53
|
+
const vmsg = elements[0]?.validationMessage ?? "";
|
|
54
|
+
status = oninvalid && vmsg ? STATE.INACTIVE : (!values.length || vmsg) ? neutral : STATE.ACTIVE;
|
|
55
|
+
message = status === STATE.INACTIVE ? vmsg ? vmsg : bottom : bottom;
|
|
59
56
|
}
|
|
60
|
-
function
|
|
61
|
-
if (!
|
|
62
|
-
const validities = elements.map((x) => x.validity);
|
|
57
|
+
function verify() {
|
|
58
|
+
if (!elements[0]) return;
|
|
63
59
|
for (const v of validations) {
|
|
64
|
-
const msg = v(values,
|
|
65
|
-
if (msg) return
|
|
60
|
+
const msg = v(values, elements[0].validity);
|
|
61
|
+
if (msg) return elements[0].setCustomValidity(msg);
|
|
66
62
|
}
|
|
67
|
-
|
|
63
|
+
elements[0].setCustomValidity("");
|
|
68
64
|
}
|
|
69
65
|
|
|
70
66
|
// *** Bind Handlers *** //
|
|
@@ -73,19 +69,20 @@
|
|
|
73
69
|
values;
|
|
74
70
|
untrack(() => validate());
|
|
75
71
|
});
|
|
72
|
+
function validate() {
|
|
73
|
+
verify();
|
|
74
|
+
shift();
|
|
75
|
+
}
|
|
76
76
|
|
|
77
77
|
// *** Event Handlers *** //
|
|
78
|
-
function onchange(ev: Event
|
|
79
|
-
attributes?.onchange?.(ev);
|
|
80
|
-
values = elements.filter((
|
|
81
|
-
phase.change = true;
|
|
78
|
+
function onchange(ev: Event) {
|
|
79
|
+
attributes?.onchange?.(ev as any);
|
|
80
|
+
values = elements.filter((el) => el.checked).map((el) => el.value);
|
|
82
81
|
}
|
|
83
|
-
function oninvalid(ev: Event
|
|
84
|
-
attributes?.oninvalid?.(ev);
|
|
82
|
+
function oninvalid(ev: Event) {
|
|
83
|
+
attributes?.oninvalid?.(ev as any);
|
|
85
84
|
ev.preventDefault();
|
|
86
|
-
|
|
87
|
-
validate(true);
|
|
88
|
-
if (status !== STATE.INACTIVE) toInvalid(elements[0]?.validationMessage);
|
|
85
|
+
shift(true);
|
|
89
86
|
}
|
|
90
87
|
</script>
|
|
91
88
|
|
|
@@ -118,15 +115,16 @@
|
|
|
118
115
|
{/if}
|
|
119
116
|
{/snippet}
|
|
120
117
|
{#snippet main()}
|
|
121
|
-
<div class={cls(AREA.MIDDLE, status)} role={roleGroup} aria-describedby={idDesc} aria-invalid={!multiple ? invalid : undefined} aria-errormessage={!multiple
|
|
118
|
+
<div class={cls(AREA.MIDDLE, status)} role={roleGroup} aria-describedby={idDesc} aria-invalid={!multiple ? invalid : undefined} aria-errormessage={!multiple ? idMsg : undefined}>
|
|
122
119
|
{#each opts as {value, text, checked}, i (value)}
|
|
123
|
-
|
|
120
|
+
{@const stat = checked ? STATE.ACTIVE : neutral}
|
|
121
|
+
<label class={cls(AREA.MAIN, stat)}>
|
|
124
122
|
{#if action}
|
|
125
|
-
<input bind:this={elements[i]} class={cls(AREA.LEFT,
|
|
123
|
+
<input bind:this={elements[i]} class={cls(AREA.LEFT, stat)} aria-invalid={multiple ? invalid : undefined} aria-errormessage={multiple ? idMsg : undefined} {value} {name} {type} {checked} {onchange} {oninvalid} {...attrs} use:action />
|
|
126
124
|
{:else}
|
|
127
|
-
<input bind:this={elements[i]} class={cls(AREA.LEFT,
|
|
125
|
+
<input bind:this={elements[i]} class={cls(AREA.LEFT, stat)} aria-invalid={multiple ? invalid : undefined} aria-errormessage={multiple ? idMsg : undefined} {value} {name} {type} {checked} {onchange} {oninvalid} {...attrs} />
|
|
128
126
|
{/if}
|
|
129
|
-
<span class={cls(AREA.RIGHT,
|
|
127
|
+
<span class={cls(AREA.RIGHT, stat)}>{text}</span>
|
|
130
128
|
</label>
|
|
131
129
|
{/each}
|
|
132
130
|
</div>
|
|
@@ -2,12 +2,12 @@ export type CheckFieldProps = {
|
|
|
2
2
|
options: SvelteMap<string, string> | Map<string, string>;
|
|
3
3
|
label?: string;
|
|
4
4
|
extra?: string;
|
|
5
|
-
aux?: Snippet<[string, string[], HTMLInputElement[]
|
|
5
|
+
aux?: Snippet<[string, string[], HTMLInputElement[]]>;
|
|
6
6
|
bottom?: string;
|
|
7
|
+
descFirst?: boolean;
|
|
7
8
|
values?: string[];
|
|
8
9
|
multiple?: boolean;
|
|
9
|
-
|
|
10
|
-
validations?: ((values: string[], validities?: ValidityState[]) => string)[];
|
|
10
|
+
validations?: CheckFieldValidation[];
|
|
11
11
|
status?: string;
|
|
12
12
|
style?: SVSStyle;
|
|
13
13
|
attributes?: HTMLInputAttributes;
|
|
@@ -16,6 +16,7 @@ export type CheckFieldProps = {
|
|
|
16
16
|
};
|
|
17
17
|
export type CheckFieldReqdProps = "options";
|
|
18
18
|
export type CheckFieldBindProps = "values" | "status" | "elements";
|
|
19
|
+
export type CheckFieldValidation = (values: string[], validity: ValidityState) => string;
|
|
19
20
|
import { type Snippet } from "svelte";
|
|
20
21
|
import { type Action } from "svelte/action";
|
|
21
22
|
import { type SvelteMap } from "svelte/reactivity";
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
left?: Snippet<[string, string, HTMLSelectElement | undefined]>, // Snippet<[status,value,element]>
|
|
8
8
|
right?: Snippet<[string, string, HTMLSelectElement | undefined]>, // Snippet<[status,value,element]>
|
|
9
9
|
bottom?: string,
|
|
10
|
-
value?: string, // bindable
|
|
11
10
|
descFirst?: boolean, // <false>
|
|
12
|
-
|
|
11
|
+
value?: string, // bindable
|
|
12
|
+
validations?: SelectFieldValidation[],
|
|
13
13
|
status?: string, // bindable <STATE.DEFAULT>
|
|
14
14
|
style?: SVSStyle,
|
|
15
15
|
attributes?: HTMLSelectAttributes;
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
};
|
|
19
19
|
export type SelectFieldReqdProps = "options";
|
|
20
20
|
export type SelectFieldBindProps = "value" | "status" | "element";
|
|
21
|
+
export type SelectFieldValidation = (value: string, validity: ValidityState) => string;
|
|
21
22
|
|
|
22
|
-
type SelectFieldTarget = { currentTarget: EventTarget & HTMLSelectElement };
|
|
23
23
|
const preset = "svs-select-field";
|
|
24
24
|
|
|
25
25
|
import { type Snippet, untrack } from "svelte";
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
</script>
|
|
31
31
|
|
|
32
32
|
<script lang="ts">
|
|
33
|
-
let { options, label, extra, aux, left, right, bottom, value = $bindable(""),
|
|
33
|
+
let { options, label, extra, aux, left, right, bottom, descFirst = false, value = $bindable(""), validations = [], status = $bindable(""), style, attributes, action, element = $bindable() }: SelectFieldProps = $props();
|
|
34
34
|
|
|
35
35
|
// *** Initialize *** //
|
|
36
36
|
if (!status) status = STATE.DEFAULT;
|
|
@@ -44,24 +44,22 @@
|
|
|
44
44
|
|
|
45
45
|
// *** Status *** //
|
|
46
46
|
let neutral = isNeutral(status) ? status : STATE.DEFAULT;
|
|
47
|
-
$effect(() => { neutral = isNeutral(status) ? status : neutral });
|
|
47
|
+
$effect(() => { neutral = isNeutral(status) ? status : neutral; });
|
|
48
48
|
let live = $derived(status === STATE.INACTIVE ? "alert" : "status");
|
|
49
49
|
let invalid = $derived(status === STATE.INACTIVE ? true : undefined);
|
|
50
|
-
let
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
message = msg ?? bottom;
|
|
56
|
-
element?.setCustomValidity(msg ?? "");
|
|
50
|
+
let idMsg = $derived(status === STATE.INACTIVE && message?.trim() ? idErr : undefined);
|
|
51
|
+
function shift(oninvalid?: boolean) {
|
|
52
|
+
const vmsg = element?.validationMessage ?? "";
|
|
53
|
+
status = !value && !oninvalid ? neutral : vmsg ? STATE.INACTIVE : STATE.ACTIVE;
|
|
54
|
+
message = status === STATE.INACTIVE ? vmsg ? vmsg : bottom : bottom;
|
|
57
55
|
}
|
|
58
|
-
function
|
|
59
|
-
if (!
|
|
56
|
+
function verify() {
|
|
57
|
+
if (!element) return;
|
|
60
58
|
for (const v of validations) {
|
|
61
|
-
const msg = v(value, element
|
|
62
|
-
if (msg) return
|
|
59
|
+
const msg = v(value, element.validity);
|
|
60
|
+
if (msg) return element.setCustomValidity(msg);
|
|
63
61
|
}
|
|
64
|
-
|
|
62
|
+
element.setCustomValidity("");
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
// *** Bind Handlers *** //
|
|
@@ -70,14 +68,18 @@
|
|
|
70
68
|
value;
|
|
71
69
|
untrack(() => validate());
|
|
72
70
|
});
|
|
71
|
+
function validate() {
|
|
72
|
+
verify();
|
|
73
|
+
shift();
|
|
74
|
+
}
|
|
73
75
|
|
|
74
76
|
/*** Handle events ***/
|
|
75
|
-
function oninvalid(ev: Event
|
|
76
|
-
attributes?.oninvalid?.(ev);
|
|
77
|
+
function oninvalid(ev: Event) {
|
|
78
|
+
attributes?.oninvalid?.(ev as any);
|
|
77
79
|
ev.preventDefault();
|
|
78
|
-
|
|
79
|
-
if (status !== STATE.INACTIVE) toInvalid(element?.validationMessage);
|
|
80
|
+
shift(true);
|
|
80
81
|
}
|
|
82
|
+
$effect(() => untrack(() => verify()));
|
|
81
83
|
</script>
|
|
82
84
|
|
|
83
85
|
<!---------------------------------------->
|
|
@@ -119,13 +121,12 @@
|
|
|
119
121
|
{/snippet}
|
|
120
122
|
{#snippet main()}
|
|
121
123
|
{@const c = cls(AREA.MAIN, status)}
|
|
122
|
-
{@const msg = message?.trim() ? errMsg : undefined}
|
|
123
124
|
{#if action}
|
|
124
|
-
<select bind:value bind:this={element} class={c} {id} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={
|
|
125
|
+
<select bind:value bind:this={element} class={c} {id} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={idMsg} use:action>
|
|
125
126
|
{@render option()}
|
|
126
127
|
</select>
|
|
127
128
|
{:else}
|
|
128
|
-
<select bind:value bind:this={element} class={c} {id} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={
|
|
129
|
+
<select bind:value bind:this={element} class={c} {id} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={idMsg}>
|
|
129
130
|
{@render option()}
|
|
130
131
|
</select>
|
|
131
132
|
{/if}
|
|
@@ -6,9 +6,9 @@ export type SelectFieldProps = {
|
|
|
6
6
|
left?: Snippet<[string, string, HTMLSelectElement | undefined]>;
|
|
7
7
|
right?: Snippet<[string, string, HTMLSelectElement | undefined]>;
|
|
8
8
|
bottom?: string;
|
|
9
|
-
value?: string;
|
|
10
9
|
descFirst?: boolean;
|
|
11
|
-
|
|
10
|
+
value?: string;
|
|
11
|
+
validations?: SelectFieldValidation[];
|
|
12
12
|
status?: string;
|
|
13
13
|
style?: SVSStyle;
|
|
14
14
|
attributes?: HTMLSelectAttributes;
|
|
@@ -17,6 +17,7 @@ export type SelectFieldProps = {
|
|
|
17
17
|
};
|
|
18
18
|
export type SelectFieldReqdProps = "options";
|
|
19
19
|
export type SelectFieldBindProps = "value" | "status" | "element";
|
|
20
|
+
export type SelectFieldValidation = (value: string, validity: ValidityState) => string;
|
|
20
21
|
import { type Snippet } from "svelte";
|
|
21
22
|
import { type Action } from "svelte/action";
|
|
22
23
|
import { type SvelteMap } from "svelte/reactivity";
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
left?: Snippet<[string, string, HTMLInputElement | HTMLTextAreaElement | undefined]>, // Snippet<[status,value,element]>
|
|
7
7
|
right?: Snippet<[string, string, HTMLInputElement | HTMLTextAreaElement | undefined]>, // Snippet<[status,value,element]>
|
|
8
8
|
bottom?: string,
|
|
9
|
+
descFirst?: boolean, // <false>
|
|
9
10
|
value?: string, // bindable
|
|
10
11
|
type?: "text" | "area" | "email" | "password" | "search" | "tel" | "url" | "number", // bindable <"text">
|
|
11
12
|
options?: SvelteSet<string> | Set<string>,
|
|
12
|
-
|
|
13
|
-
validations?: ((value: string, validity?: ValidityState) => string)[],
|
|
13
|
+
validations?: TextFieldValidation[],
|
|
14
14
|
status?: string, // bindable <STATE.DEFAULT>
|
|
15
15
|
style?: SVSStyle,
|
|
16
16
|
attributes?: HTMLInputAttributes | HTMLTextareaAttributes,
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
};
|
|
20
20
|
export type TextFieldReqdProps = never;
|
|
21
21
|
export type TextFieldBindProps = "value" | "type" | "status" | "element";
|
|
22
|
+
export type TextFieldValidation = (value: string, validity: ValidityState) => string;
|
|
22
23
|
|
|
23
24
|
const preset = "svs-text-field";
|
|
24
25
|
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
</script>
|
|
31
32
|
|
|
32
33
|
<script lang="ts">
|
|
33
|
-
let { label, extra, aux, left, right, bottom, value = $bindable(""), type = $bindable("text"), options,
|
|
34
|
+
let { label, extra, aux, left, right, bottom, descFirst = false, value = $bindable(""), type = $bindable("text"), options, validations = [], status = $bindable(""), style, attributes, action, element = $bindable() }: TextFieldProps = $props();
|
|
34
35
|
|
|
35
36
|
// *** Initialize *** //
|
|
36
37
|
if (!status) status = STATE.DEFAULT;
|
|
@@ -48,31 +49,30 @@
|
|
|
48
49
|
$effect(() => { neutral = isNeutral(status) ? status : neutral });
|
|
49
50
|
let live = $derived(status === STATE.INACTIVE ? "alert" : "status");
|
|
50
51
|
let invalid = $derived(status === STATE.INACTIVE ? true : undefined);
|
|
51
|
-
let
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
message = msg ?? bottom;
|
|
57
|
-
element?.setCustomValidity(msg ?? "");
|
|
52
|
+
let idMsg = $derived(status === STATE.INACTIVE && message?.trim() ? idErr : undefined);
|
|
53
|
+
function shift(oninvalid?: boolean) {
|
|
54
|
+
const vmsg = element?.validationMessage ?? "";
|
|
55
|
+
status = !value && !oninvalid ? neutral : vmsg ? STATE.INACTIVE : STATE.ACTIVE;
|
|
56
|
+
message = status === STATE.INACTIVE ? vmsg ? vmsg : bottom : bottom;
|
|
58
57
|
}
|
|
59
|
-
function
|
|
60
|
-
if (!
|
|
58
|
+
function verify() {
|
|
59
|
+
if (!element) return;
|
|
61
60
|
for (const v of validations) {
|
|
62
|
-
const msg = v(value, element
|
|
63
|
-
if (msg) return
|
|
61
|
+
const msg = v(value, element.validity);
|
|
62
|
+
if (msg) return element.setCustomValidity(msg);
|
|
64
63
|
}
|
|
65
|
-
|
|
64
|
+
element.setCustomValidity("");
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
// *** Bind Handlers *** //
|
|
69
68
|
$effect.pre(() => {
|
|
70
69
|
value;
|
|
71
|
-
untrack(() =>
|
|
70
|
+
untrack(() => validate(true));
|
|
72
71
|
});
|
|
73
|
-
function
|
|
74
|
-
if (isNeutral(status)) return;
|
|
75
|
-
|
|
72
|
+
function validate(effect?: boolean) {
|
|
73
|
+
if (effect && isNeutral(status)) return;
|
|
74
|
+
verify();
|
|
75
|
+
shift();
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// *** Event Handlers *** //
|
|
@@ -83,9 +83,9 @@
|
|
|
83
83
|
function oninvalid(ev: Event) {
|
|
84
84
|
attributes?.oninvalid?.(ev as any);
|
|
85
85
|
ev.preventDefault();
|
|
86
|
-
|
|
87
|
-
if (status !== STATE.INACTIVE) toInvalid(element?.validationMessage);
|
|
86
|
+
shift(true);
|
|
88
87
|
}
|
|
88
|
+
$effect(() => untrack(() => verify()));
|
|
89
89
|
</script>
|
|
90
90
|
|
|
91
91
|
<!---------------------------------------->
|
|
@@ -125,18 +125,17 @@
|
|
|
125
125
|
{/snippet}
|
|
126
126
|
{#snippet main()}
|
|
127
127
|
{@const c = cls(AREA.MAIN, status)}
|
|
128
|
-
{@const msg = message?.trim() ? errMsg : undefined}
|
|
129
128
|
{#if type === "area"}
|
|
130
129
|
{#if action}
|
|
131
|
-
<textarea bind:value bind:this={element} class={c} {id} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={
|
|
130
|
+
<textarea bind:value bind:this={element} class={c} {id} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={idMsg} use:action></textarea>
|
|
132
131
|
{:else}
|
|
133
|
-
<textarea bind:value bind:this={element} class={c} {id} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={
|
|
132
|
+
<textarea bind:value bind:this={element} class={c} {id} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={idMsg}></textarea>
|
|
134
133
|
{/if}
|
|
135
134
|
{:else}
|
|
136
135
|
{#if action}
|
|
137
|
-
<input bind:value bind:this={element} class={c} list={idList} {id} {type} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={
|
|
136
|
+
<input bind:value bind:this={element} class={c} list={idList} {id} {type} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={idMsg} use:action />
|
|
138
137
|
{:else}
|
|
139
|
-
<input bind:value bind:this={element} class={c} list={idList} {id} {type} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={
|
|
138
|
+
<input bind:value bind:this={element} class={c} list={idList} {id} {type} {onchange} {oninvalid} {...attrs} aria-describedby={idDesc} aria-invalid={invalid} aria-errormessage={idMsg} />
|
|
140
139
|
{/if}
|
|
141
140
|
{#if options?.size}
|
|
142
141
|
<datalist id={idList}>
|
|
@@ -5,11 +5,11 @@ export type TextFieldProps = {
|
|
|
5
5
|
left?: Snippet<[string, string, HTMLInputElement | HTMLTextAreaElement | undefined]>;
|
|
6
6
|
right?: Snippet<[string, string, HTMLInputElement | HTMLTextAreaElement | undefined]>;
|
|
7
7
|
bottom?: string;
|
|
8
|
+
descFirst?: boolean;
|
|
8
9
|
value?: string;
|
|
9
10
|
type?: "text" | "area" | "email" | "password" | "search" | "tel" | "url" | "number";
|
|
10
11
|
options?: SvelteSet<string> | Set<string>;
|
|
11
|
-
|
|
12
|
-
validations?: ((value: string, validity?: ValidityState) => string)[];
|
|
12
|
+
validations?: TextFieldValidation[];
|
|
13
13
|
status?: string;
|
|
14
14
|
style?: SVSStyle;
|
|
15
15
|
attributes?: HTMLInputAttributes | HTMLTextareaAttributes;
|
|
@@ -18,6 +18,7 @@ export type TextFieldProps = {
|
|
|
18
18
|
};
|
|
19
19
|
export type TextFieldReqdProps = never;
|
|
20
20
|
export type TextFieldBindProps = "value" | "type" | "status" | "element";
|
|
21
|
+
export type TextFieldValidation = (value: string, validity: ValidityState) => string;
|
|
21
22
|
import { type Snippet } from "svelte";
|
|
22
23
|
import { type Action } from "svelte/action";
|
|
23
24
|
import { type SvelteSet } from "svelte/reactivity";
|
package/_svseeds/_Toggle.svelte
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
export type ToggleProps = {
|
|
3
|
-
label?: string, // for aria-label; should be used if no label tag or no text in main
|
|
4
3
|
main?: Snippet<[string, boolean, HTMLButtonElement | undefined]>, // Snippet<[status,value,element]>
|
|
5
4
|
left?: Snippet<[string, boolean, HTMLButtonElement | undefined]>, // Snippet<[status,value,element]>
|
|
6
5
|
right?: Snippet<[string, boolean, HTMLButtonElement | undefined]>, // Snippet<[status,value,element]>
|
|
@@ -25,7 +24,7 @@
|
|
|
25
24
|
</script>
|
|
26
25
|
|
|
27
26
|
<script lang="ts">
|
|
28
|
-
let {
|
|
27
|
+
let { main, left, right, value = $bindable(false), type = "button", status = $bindable(""), style, attributes, action, element = $bindable() }: ToggleProps = $props();
|
|
29
28
|
|
|
30
29
|
// *** Initialize *** //
|
|
31
30
|
if (!status) status = STATE.DEFAULT;
|
|
@@ -75,22 +74,22 @@
|
|
|
75
74
|
{@const c = cls(AREA.MAIN, status)}
|
|
76
75
|
{#if role === "button"}
|
|
77
76
|
{#if action}
|
|
78
|
-
<button bind:this={element} class={c} type="button" aria-pressed={value}
|
|
77
|
+
<button bind:this={element} class={c} type="button" aria-pressed={value} {onclick} {...attrs} use:action>
|
|
79
78
|
{@render contents()}
|
|
80
79
|
</button>
|
|
81
80
|
{:else}
|
|
82
|
-
<button bind:this={element} class={c} type="button" aria-pressed={value}
|
|
81
|
+
<button bind:this={element} class={c} type="button" aria-pressed={value} {onclick} {...attrs}>
|
|
83
82
|
{@render contents()}
|
|
84
83
|
</button>
|
|
85
84
|
{/if}
|
|
86
85
|
{:else}
|
|
87
86
|
{@const style = "position: relative;"}
|
|
88
87
|
{#if action}
|
|
89
|
-
<button bind:this={element} class={c} {style} type="button" {role} aria-checked={value}
|
|
88
|
+
<button bind:this={element} class={c} {style} type="button" {role} aria-checked={value} {onclick} {...attrs} use:action>
|
|
90
89
|
{@render thumb()}
|
|
91
90
|
</button>
|
|
92
91
|
{:else}
|
|
93
|
-
<button bind:this={element} class={c} {style} type="button" {role} aria-checked={value}
|
|
92
|
+
<button bind:this={element} class={c} {style} type="button" {role} aria-checked={value} {onclick} {...attrs}>
|
|
94
93
|
{@render thumb()}
|
|
95
94
|
</button>
|
|
96
95
|
{/if}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
export type ToggleGroupProps = {
|
|
3
|
+
options: SvelteMap<string, string> | Map<string, string>,
|
|
4
|
+
values?: string[], // bindable
|
|
5
|
+
multiple?: boolean, // <true>
|
|
6
|
+
ariaDescId?: string,
|
|
7
|
+
ariaErrMsgId?: string, // bindable
|
|
8
|
+
status?: string, // bindable <STATE.DEFAULT>
|
|
9
|
+
style?: SVSStyle,
|
|
10
|
+
action?: Action,
|
|
11
|
+
[key: string]: unknown | Snippet<[string]>,
|
|
12
|
+
};
|
|
13
|
+
export type ToggleGroupReqdProps = "options";
|
|
14
|
+
export type ToggleGroupBindProps = "values" | "ariaErrMsgId" | "status";
|
|
15
|
+
|
|
16
|
+
const preset = "svs-toggle-group";
|
|
17
|
+
|
|
18
|
+
function getSnippet(text: string, rest: Record<string, unknown>): Snippet<[string]> | undefined {
|
|
19
|
+
if (!Object.hasOwn(rest, text)) return;
|
|
20
|
+
if (typeof rest[text] !== "function") return;
|
|
21
|
+
return rest[text] as Snippet<[string]>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
import { type Snippet } from "svelte";
|
|
25
|
+
import { type Action } from "svelte/action";
|
|
26
|
+
import { type SvelteMap } from "svelte/reactivity";
|
|
27
|
+
import { type SVSStyle, STATE, AREA, fnClass } from "./core";
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<script lang="ts">
|
|
31
|
+
let { options, values = $bindable([]), multiple = true, ariaDescId, ariaErrMsgId = $bindable(), status = $bindable(""), style, attributes, action, ...rest }: ToggleGroupProps = $props();
|
|
32
|
+
|
|
33
|
+
// *** Initialize *** //
|
|
34
|
+
if (!status) status = STATE.DEFAULT;
|
|
35
|
+
const cls = fnClass(preset, style);
|
|
36
|
+
const role = multiple ? "checkbox" : "radio";
|
|
37
|
+
const roleGroup = multiple ? "group" : "radiogroup";
|
|
38
|
+
|
|
39
|
+
// *** Bind Handlers *** //
|
|
40
|
+
let opts = $derived([...options.entries().map(([value, text]) => ({ value, text, checked: values.includes(value) }))]);
|
|
41
|
+
let invalid = $derived(ariaErrMsgId ? true : undefined);
|
|
42
|
+
|
|
43
|
+
// *** Event Handlers *** //
|
|
44
|
+
const update = multiple
|
|
45
|
+
? (value: string) => (values.includes(value) ? values.filter((x) => x !== value) : opts.map((x) => x.value).filter((x) => [...values, value].includes(x)))
|
|
46
|
+
: (value: string) => (values.includes(value) ? [] : [value]);
|
|
47
|
+
function updateValues(value: string): () => void {
|
|
48
|
+
return () => values = update(value);
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<!---------------------------------------->
|
|
53
|
+
|
|
54
|
+
{#if opts.length}
|
|
55
|
+
<span class={cls(AREA.WHOLE, status)} role={roleGroup} aria-describedby={ariaDescId} aria-invalid={!multiple ? invalid : undefined} aria-errormessage={!multiple ? ariaErrMsgId : undefined}>
|
|
56
|
+
{#each opts as { value, text, checked } (value)}
|
|
57
|
+
{@const c = cls(AREA.MAIN, checked ? STATE.ACTIVE : status)}
|
|
58
|
+
{#if action}
|
|
59
|
+
<button class={c} aria-checked={checked} aria-invalid={multiple ? invalid : undefined} aria-errormessage={multiple ? ariaErrMsgId : undefined} onclick={updateValues(value)} type="button" {role} use:action>
|
|
60
|
+
{@render content(value, text)}
|
|
61
|
+
</button>
|
|
62
|
+
{:else}
|
|
63
|
+
<button class={c} aria-checked={checked} aria-invalid={multiple ? invalid : undefined} aria-errormessage={multiple ? ariaErrMsgId : undefined} onclick={updateValues(value)} type="button" {role}>
|
|
64
|
+
{@render content(value, text)}
|
|
65
|
+
</button>
|
|
66
|
+
{/if}
|
|
67
|
+
{/each}
|
|
68
|
+
</span>
|
|
69
|
+
{/if}
|
|
70
|
+
|
|
71
|
+
{#snippet content(value: string, text: string)}
|
|
72
|
+
{@const snippet = getSnippet(text, rest)}
|
|
73
|
+
{#if snippet}
|
|
74
|
+
{@render snippet(value)}
|
|
75
|
+
{:else}
|
|
76
|
+
{text}
|
|
77
|
+
{/if}
|
|
78
|
+
{/snippet}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ToggleGroupProps = {
|
|
2
|
+
options: SvelteMap<string, string> | Map<string, string>;
|
|
3
|
+
values?: string[];
|
|
4
|
+
multiple?: boolean;
|
|
5
|
+
ariaDescId?: string;
|
|
6
|
+
ariaErrMsgId?: string;
|
|
7
|
+
status?: string;
|
|
8
|
+
style?: SVSStyle;
|
|
9
|
+
action?: Action;
|
|
10
|
+
[key: string]: unknown | Snippet<[string]>;
|
|
11
|
+
};
|
|
12
|
+
export type ToggleGroupReqdProps = "options";
|
|
13
|
+
export type ToggleGroupBindProps = "values" | "ariaErrMsgId" | "status";
|
|
14
|
+
import { type Snippet } from "svelte";
|
|
15
|
+
import { type Action } from "svelte/action";
|
|
16
|
+
import { type SvelteMap } from "svelte/reactivity";
|
|
17
|
+
import { type SVSStyle } from "./core";
|
|
18
|
+
declare const ToggleGroup: import("svelte").Component<ToggleGroupProps, {}, "status" | "values" | "ariaErrMsgId">;
|
|
19
|
+
type ToggleGroup = ReturnType<typeof ToggleGroup>;
|
|
20
|
+
export default ToggleGroup;
|
package/_svseeds/core.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export { type SVSStyle, CONST, STATE, AREA, elemId, fnClass, isNeutral, omit, debounce, throttle, UniqueId, };
|
|
2
|
-
type ClassRule = Record<string, string
|
|
3
|
-
type
|
|
4
|
-
type SVSStyle = ClassRuleSet | ClassRule | string;
|
|
2
|
+
type ClassRule = Record<string, string> | string;
|
|
3
|
+
type SVSStyle = Record<string, ClassRule> | string;
|
|
5
4
|
declare const CONST = "const";
|
|
6
5
|
declare const STATE: Readonly<{
|
|
7
6
|
DEFAULT: "default";
|
package/_svseeds/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t=this&&this.__assign||function(){return t=Object.assign||function(t){for(var r,
|
|
1
|
+
var t=this&&this.__assign||function(){return t=Object.assign||function(t){for(var r,n=1,e=arguments.length;n<e;n++)for(var i in r=arguments[n])Object.prototype.hasOwnProperty.call(r,i)&&(t[i]=r[i]);return t},t.apply(this,arguments)},r=this&&this.__classPrivateFieldSet||function(t,r,n,e,i){if("m"===e)throw new TypeError("Private method is not writable");if("a"===e&&!i)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof r?t!==r||!i:!r.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===e?i.call(t,n):i?i.value=n:r.set(t,n),n},n=this&&this.__classPrivateFieldGet||function(t,r,n,e){if("a"===n&&!e)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof r?t!==r||!e:!r.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?e:"a"===n?e.call(t):e?e.value:r.get(t)},e=this&&this.__spreadArray||function(t,r,n){if(n||2===arguments.length)for(var e,i=0,o=r.length;i<o;i++)!e&&i in r||(e||(e=Array.prototype.slice.call(r,0,i)),e[i]=r[i]);return t.concat(e||Array.prototype.slice.call(r))};export{i as CONST,o as STATE,a as AREA,u as elemId,l as fnClass,s as isNeutral,h as omit,v as debounce,d as throttle,c as UniqueId};var i="const",o=Object.freeze({DEFAULT:"default",ACTIVE:"active",INACTIVE:"inactive"}),a=Object.freeze({WHOLE:"whole",MIDDLE:"middle",MAIN:"main",TOP:"top",LEFT:"left",RIGHT:"right",BOTTOM:"bottom",LABEL:"label",AUX:"aux",EXTRA:"extra"}),c=function(){function t(t){void 0===t&&(t=4),i.add(this),c.set(this,new Set),u.set(this,4),t>2&&r(this,u,t,"f")}var i,o,a,c,u,l,f,s;return Object.defineProperty(t.prototype,"id",{get:function(){return this.get(!0)},enumerable:!1,configurable:!0}),t.prototype.get=function(t){if(t)return n(this,c,"f").size>1e4&&n(this,c,"f").clear(),n(this,i,"m",s).call(this)},o=t,c=new WeakMap,u=new WeakMap,i=new WeakSet,l=function(){return n(o,o,"f",a)[Math.trunc(Math.random()*n(o,o,"f",a).length)]},f=function(){var t=this;return String.fromCharCode.apply(String,Array(n(this,u,"f")).fill(null).map((function(){return n(t,i,"m",l).call(t)})))},s=function(){for(var t=n(this,i,"m",f).call(this);n(this,c,"f").has(t);)t=n(this,i,"m",f).call(this);return n(this,c,"f").add(t),t},a={value:e(e([],Array.from(Array(25).keys(),(function(t){return t+65})),!0),Array.from(Array(25).keys(),(function(t){return t+97})),!0)},t}(),u=new c;function l(t,r){var n,e=null!==(n=f(r))&&void 0!==n?n:f(t);return null==e?function(t,r){}:"string"==typeof e?function(t,r){return"".concat(e," ").concat(t," ").concat(r)}:function(t,r){return function(t,r,n){var e,a,c,u,l,f,s=null!==(a=null===(e=t[r])||void 0===e?void 0:e[i])&&void 0!==a?a:"",h=null!==(f=null!==(u=null===(c=t[r])||void 0===c?void 0:c[n])&&void 0!==u?u:null===(l=t[r])||void 0===l?void 0:l[o.DEFAULT])&&void 0!==f?f:"";if(!s&&!h)return;return"".concat(s).concat(s&&h?" ":"").concat(h)}(e,t,r)}}function f(t){if(null!=t){if("string"==typeof t)return t.trim()?t:void 0;var r=Object.entries(t);if(r.length)return Object.fromEntries(r.map((function(t){var r=t[0],n=t[1];return"string"==typeof n?[r,{const:n}]:[r,n]})))}}function s(t){return t!==o.ACTIVE&&t!==o.INACTIVE}function h(r){for(var n=[],e=1;e<arguments.length;e++)n[e-1]=arguments[e];if(!r)return{};var i=t({},r);return n.forEach((function(t){return delete i[t]})),i}function v(t,r){var n;return function(){for(var i=[],o=0;o<arguments.length;o++)i[o]=arguments[o];n&&clearTimeout(n),n=setTimeout((function(){r.call.apply(r,e([null],i,!1))}),t)}}function d(t,r){var n,i=0,o=function(){return Date.now()-i},a=function(t){r.call.apply(r,e([null],t,!1)),i=Date.now()};return function(){for(var r=[],e=0;e<arguments.length;e++)r[e]=arguments[e];if(!i)return a(r);clearTimeout(n),n=setTimeout((function(){o()>=t&&a(r)}),t-o())}}
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { type SVSStyle, CONST, STATE, AREA, elemId, fnClass, isNeutral, omit, debounce, throttle, UniqueId } from "./_svseeds/core";
|
|
2
2
|
export { default as Badge, type BadgeProps, type BadgeReqdProps, type BadgeBindProps } from "./_svseeds/_Badge.svelte";
|
|
3
3
|
export { default as Button, type ButtonProps, type ButtonReqdProps, type ButtonBindProps } from "./_svseeds/_Button.svelte";
|
|
4
|
-
export { default as CheckField, type CheckFieldProps, type CheckFieldReqdProps, type CheckFieldBindProps } from "./_svseeds/_CheckField.svelte";
|
|
4
|
+
export { default as CheckField, type CheckFieldProps, type CheckFieldReqdProps, type CheckFieldBindProps, type CheckFieldValidation } from "./_svseeds/_CheckField.svelte";
|
|
5
5
|
export { default as ColorPicker, type ColorPickerProps, type ColorPickerReqdProps, type ColorPickerBindProps, getHex } from "./_svseeds/_ColorPicker.svelte";
|
|
6
6
|
export { default as ComboBox, type ComboBoxProps, type ComboBoxReqdProps, type ComboBoxBindProps } from "./_svseeds/_ComboBox.svelte";
|
|
7
7
|
export { default as ContextMenu, type ContextMenuProps, type ContextMenuReqdProps, type ContextMenuBindProps } from "./_svseeds/_ContextMenu.svelte";
|
|
@@ -9,14 +9,16 @@ export { default as Disclosure, type DisclosureProps, type DisclosureReqdProps,
|
|
|
9
9
|
export { default as HotkeyCapture, type HotkeyCaptureProps, type HotkeyCaptureReqdProps, type HotkeyCaptureBindProps } from "./_svseeds/_HotkeyCapture.svelte";
|
|
10
10
|
export { default as Modal, type ModalProps, type ModalReqdProps, type ModalBindProps } from "./_svseeds/_Modal.svelte";
|
|
11
11
|
export { default as ProgressTracker, type ProgressTrackerProps, type ProgressTrackerReqdProps, type ProgressTrackerBindProps } from "./_svseeds/_ProgressTracker.svelte";
|
|
12
|
-
export { default as SelectField, type SelectFieldProps, type SelectFieldReqdProps, type SelectFieldBindProps } from "./_svseeds/_SelectField.svelte";
|
|
12
|
+
export { default as SelectField, type SelectFieldProps, type SelectFieldReqdProps, type SelectFieldBindProps, type SelectFieldValidation } from "./_svseeds/_SelectField.svelte";
|
|
13
13
|
export { default as Slider, type SliderProps, type SliderReqdProps, type SliderBindProps, type Range } from "./_svseeds/_Slider.svelte";
|
|
14
14
|
export { default as Sortable, type SortableProps, type SortableReqdProps, type SortableBindProps, SortableItems } from "./_svseeds/_Sortable.svelte";
|
|
15
15
|
export { default as Tabs, type TabsProps, type TabsReqdProps, type TabsBindProps } from "./_svseeds/_Tabs.svelte";
|
|
16
|
-
export { default as TextField, type TextFieldProps, type TextFieldReqdProps, type TextFieldBindProps } from "./_svseeds/_TextField.svelte";
|
|
16
|
+
export { default as TextField, type TextFieldProps, type TextFieldReqdProps, type TextFieldBindProps, type TextFieldValidation } from "./_svseeds/_TextField.svelte";
|
|
17
17
|
export { default as Toggle, type ToggleProps, type ToggleReqdProps, type ToggleBindProps } from "./_svseeds/_Toggle.svelte";
|
|
18
|
-
export { default as
|
|
18
|
+
export { default as ToggleGroup, type ToggleGroupProps, type ToggleGroupReqdProps, type ToggleGroupBindProps } from "./_svseeds/_ToggleGroup.svelte";
|
|
19
19
|
export { default as Tooltip, type TooltipProps, type TooltipReqdProps, type TooltipBindProps, type Vector, type Position, type Align, tooltip, tooltipAction } from "./_svseeds/_Tooltip.svelte";
|
|
20
20
|
export { default as Accordion, type AccordionProps, type AccordionDeps, type AccordionReqdProps, type AccordionBindProps } from "./_svseeds/Accordion.svelte";
|
|
21
21
|
export { default as DarkToggle, type DarkToggleProps, type DarkToggleDeps, type DarkToggleReqdProps, type DarkToggleBindProps } from "./_svseeds/DarkToggle.svelte";
|
|
22
|
-
export { default as TagsInput, type TagsInputProps, type TagsInputDeps, type TagsInputReqdProps, type TagsInputBindProps, type
|
|
22
|
+
export { default as TagsInput, type TagsInputProps, type TagsInputDeps, type TagsInputReqdProps, type TagsInputBindProps, type TagsInputEvents } from "./_svseeds/TagsInput.svelte";
|
|
23
|
+
export { default as TagsInputField, type TagsInputFieldProps, type TagsInputFieldDeps, type TagsInputFieldReqdProps, type TagsInputFieldBindProps, type TagsInputFieldConstraint, type TagsInputFieldValidation, type TagsInputFieldCountValidation } from "./_svseeds/TagsInputField.svelte";
|
|
24
|
+
export { default as ToggleGroupField, type ToggleGroupFieldProps, type ToggleGroupFieldDeps, type ToggleGroupFieldReqdProps, type ToggleGroupFieldBindProps, type ToggleGroupFieldValidation } from "./_svseeds/ToggleGroupField.svelte";
|
package/index.js
CHANGED
|
@@ -15,8 +15,10 @@ export { default as Sortable, SortableItems } from "./_svseeds/_Sortable.svelte"
|
|
|
15
15
|
export { default as Tabs } from "./_svseeds/_Tabs.svelte";
|
|
16
16
|
export { default as TextField } from "./_svseeds/_TextField.svelte";
|
|
17
17
|
export { default as Toggle } from "./_svseeds/_Toggle.svelte";
|
|
18
|
-
export { default as
|
|
18
|
+
export { default as ToggleGroup } from "./_svseeds/_ToggleGroup.svelte";
|
|
19
19
|
export { default as Tooltip, tooltip, tooltipAction } from "./_svseeds/_Tooltip.svelte";
|
|
20
20
|
export { default as Accordion } from "./_svseeds/Accordion.svelte";
|
|
21
21
|
export { default as DarkToggle } from "./_svseeds/DarkToggle.svelte";
|
|
22
22
|
export { default as TagsInput } from "./_svseeds/TagsInput.svelte";
|
|
23
|
+
export { default as TagsInputField } from "./_svseeds/TagsInputField.svelte";
|
|
24
|
+
export { default as ToggleGroupField } from "./_svseeds/ToggleGroupField.svelte";
|