@websline/system-components 1.0.15 → 1.1.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/dist/components/atoms/colorChip/ColorChip.svelte +2 -2
- package/dist/components/atoms/feedback/spinner/Spinner.svelte +3 -2
- package/dist/components/atoms/helperText/HelperText.svelte +2 -2
- package/dist/components/molecules/comboBox/ComboBox.svelte +200 -0
- package/dist/components/molecules/comboBox/ComboBox.svelte.d.ts +79 -0
- package/dist/components/molecules/comboBox/Dropdown.svelte +92 -0
- package/dist/components/molecules/comboBox/Dropdown.svelte.d.ts +21 -0
- package/dist/components/molecules/comboBox/Value.svelte +39 -0
- package/dist/components/molecules/comboBox/Value.svelte.d.ts +23 -0
- package/dist/components/molecules/comboBox/comboBox.variants.d.ts +84 -0
- package/dist/components/molecules/comboBox/comboBox.variants.js +49 -0
- package/dist/components/molecules/formActions/{formActions.svelte → FormActions.svelte} +3 -1
- package/dist/components/molecules/formField/FormField.svelte +2 -1
- package/dist/components/molecules/formLayout/FormLayout.svelte +2 -2
- package/dist/components/molecules/notification/Notification.svelte +2 -1
- package/dist/components/molecules/pickers/colorSwatch/ColorSwatch.svelte +2 -1
- package/dist/components/molecules/richTextEditor/toolbar/ToolbarColor.svelte +2 -1
- package/dist/components/molecules/toggleGroup/ToggleGroup.svelte +2 -1
- package/dist/components/molecules/toggleGroup/ToggleGroupItem.svelte +2 -1
- package/dist/components/organisms/dialog/DialogActions.svelte +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/package.json +10 -10
- /package/dist/components/molecules/formActions/{formActions.svelte.d.ts → FormActions.svelte.d.ts} +0 -0
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
color = "",
|
|
20
20
|
shape = "square",
|
|
21
21
|
size = "medium",
|
|
22
|
-
...
|
|
22
|
+
...rest
|
|
23
23
|
} = $props();
|
|
24
24
|
|
|
25
25
|
let as = $derived(clickable ? "button" : "div");
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
this={as}
|
|
30
30
|
class={colorChipVariants({ class: className, clickable, shape, size })}
|
|
31
31
|
style="background-color: {color}; border-color: {borderColor};"
|
|
32
|
-
{...
|
|
32
|
+
{...rest}>
|
|
33
33
|
</svelte:element>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
/** @type {Props} */
|
|
11
|
-
let { class: className = "", size = "medium" } = $props();
|
|
11
|
+
let { class: className = "", size = "medium", ...rest } = $props();
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<svg
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
role="status"
|
|
17
17
|
viewBox="0 0 100 101"
|
|
18
18
|
fill="none"
|
|
19
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
19
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
20
|
+
{...rest}>
|
|
20
21
|
<path
|
|
21
22
|
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
|
22
23
|
fill="#fff"></path>
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/** @type {Props} */
|
|
12
|
-
let { children, class: className = "", error = false } = $props();
|
|
12
|
+
let { children, class: className = "", error = false, ...rest } = $props();
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
|
-
<p class={helperTextVariants({ class: className, error })}>
|
|
15
|
+
<p class={helperTextVariants({ class: className, error })} {...rest}>
|
|
16
16
|
{@render children?.()}
|
|
17
17
|
</p>
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { getContext } from "svelte";
|
|
3
|
+
import Dropdown from "./Dropdown.svelte";
|
|
4
|
+
import Value from "./Value.svelte";
|
|
5
|
+
import { comboBoxVariants } from "./comboBox.variants.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {Object} Props
|
|
9
|
+
* @property {boolean} [autofocus=false] Whether the input should be autofocused on mount
|
|
10
|
+
* @property {string} [class=""] Additional CSS classes to apply to the component
|
|
11
|
+
* @property {boolean} [disabled=false] Whether the component is disabled
|
|
12
|
+
* @property {string} [id=""] The ID of the input element
|
|
13
|
+
* @property {string} [name] The name of the input, used for form submission
|
|
14
|
+
* @property {Array<{id: string | number, label: string}>} [options=[]] The available tag options
|
|
15
|
+
* @property {string} [placeholder=""] The placeholder text for the input
|
|
16
|
+
* @property {Array<string | number>} [value=[]] The currently selected tags, bound to the component
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** @type {Props} */
|
|
20
|
+
let {
|
|
21
|
+
autofocus = false,
|
|
22
|
+
class: className = "",
|
|
23
|
+
disabled = false,
|
|
24
|
+
id = "",
|
|
25
|
+
name,
|
|
26
|
+
options = [],
|
|
27
|
+
placeholder = "",
|
|
28
|
+
value = $bindable(""),
|
|
29
|
+
...rest
|
|
30
|
+
} = $props();
|
|
31
|
+
|
|
32
|
+
let store = getContext("form-field-store");
|
|
33
|
+
|
|
34
|
+
let localValues = $derived.by(() => {
|
|
35
|
+
if (store) return { ...store() };
|
|
36
|
+
return { disabled, id };
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
let open = $state(false);
|
|
40
|
+
let highlighted = $state(-1);
|
|
41
|
+
let isEditing = $state(false);
|
|
42
|
+
|
|
43
|
+
let inputRef = $state();
|
|
44
|
+
let rootRef = $state();
|
|
45
|
+
|
|
46
|
+
let valueLabel = $state("");
|
|
47
|
+
|
|
48
|
+
let exactMatch = $derived.by(() =>
|
|
49
|
+
options.find((o) => o.label.toLowerCase() === valueLabel.toLowerCase()),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
let filtered = $derived(
|
|
53
|
+
options.filter((o) => o.label.toLowerCase().includes(valueLabel.toLowerCase())),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
$effect(() => {
|
|
57
|
+
if (autofocus && inputRef) inputRef.focus();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
$effect(() => {
|
|
61
|
+
if (isEditing) return;
|
|
62
|
+
|
|
63
|
+
const option = options.find((o) => String(o.id) === String(value));
|
|
64
|
+
|
|
65
|
+
if (option) {
|
|
66
|
+
if (valueLabel !== option.label) valueLabel = option.label;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (valueLabel !== (value ? String(value) : "")) {
|
|
71
|
+
valueLabel = value ? String(value) : "";
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
$effect(() => {
|
|
76
|
+
if (!isEditing) return;
|
|
77
|
+
|
|
78
|
+
if (!valueLabel) {
|
|
79
|
+
value = "";
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (exactMatch) {
|
|
84
|
+
value = exactMatch.id.toString();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
value = valueLabel;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const openDropdown = () => {
|
|
92
|
+
open = true;
|
|
93
|
+
isEditing = true;
|
|
94
|
+
highlighted = -1;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const closeDropdown = () => {
|
|
98
|
+
open = false;
|
|
99
|
+
isEditing = false;
|
|
100
|
+
highlighted = -1;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const dispatchChange = () => {
|
|
104
|
+
rootRef.dispatchEvent(new CustomEvent("change", { detail: value }));
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const selectItem = (id) => {
|
|
108
|
+
const option = options.find((o) => o.id === id);
|
|
109
|
+
if (!option) return;
|
|
110
|
+
|
|
111
|
+
value = id.toString();
|
|
112
|
+
valueLabel = option.label;
|
|
113
|
+
|
|
114
|
+
dispatchChange();
|
|
115
|
+
closeDropdown();
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const handleFocusOut = (e) => {
|
|
119
|
+
const next = e.relatedTarget;
|
|
120
|
+
if (next && rootRef.contains(next)) return;
|
|
121
|
+
if (document.activeElement === inputRef) return;
|
|
122
|
+
|
|
123
|
+
dispatchChange();
|
|
124
|
+
closeDropdown();
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const handleKey = (e) => {
|
|
128
|
+
if (!open) return;
|
|
129
|
+
|
|
130
|
+
const total = filtered.length;
|
|
131
|
+
|
|
132
|
+
if (e.key === "ArrowDown") {
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
highlighted = (highlighted + 1) % total;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (e.key === "ArrowUp") {
|
|
139
|
+
e.preventDefault();
|
|
140
|
+
highlighted = (highlighted - 1 + total) % total;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (e.key === "Escape") {
|
|
145
|
+
e.preventDefault();
|
|
146
|
+
closeDropdown();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (e.key === "Enter") {
|
|
151
|
+
e.preventDefault();
|
|
152
|
+
|
|
153
|
+
if (highlighted !== -1) {
|
|
154
|
+
selectItem(filtered[highlighted].id);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
dispatchChange();
|
|
159
|
+
closeDropdown();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
let styles = $derived(comboBoxVariants({ disabled: localValues.disabled }));
|
|
164
|
+
</script>
|
|
165
|
+
|
|
166
|
+
<div
|
|
167
|
+
bind:this={rootRef}
|
|
168
|
+
role="combobox"
|
|
169
|
+
aria-expanded={open}
|
|
170
|
+
class={styles.base({ class: className })}
|
|
171
|
+
onfocusout={handleFocusOut}
|
|
172
|
+
{...open
|
|
173
|
+
? {
|
|
174
|
+
"aria-controls": localValues.id,
|
|
175
|
+
"aria-haspopup": "listbox",
|
|
176
|
+
"aria-owns": localValues.id,
|
|
177
|
+
}
|
|
178
|
+
: {}}
|
|
179
|
+
{...rest}>
|
|
180
|
+
<Value
|
|
181
|
+
bind:inputRef
|
|
182
|
+
{localValues}
|
|
183
|
+
{name}
|
|
184
|
+
onKeydown={handleKey}
|
|
185
|
+
onOpenDropdown={openDropdown}
|
|
186
|
+
{open}
|
|
187
|
+
{options}
|
|
188
|
+
{placeholder}
|
|
189
|
+
bind:value={valueLabel} />
|
|
190
|
+
|
|
191
|
+
{#if open}
|
|
192
|
+
<Dropdown
|
|
193
|
+
{filtered}
|
|
194
|
+
{highlighted}
|
|
195
|
+
{inputRef}
|
|
196
|
+
{localValues}
|
|
197
|
+
onSelectItem={selectItem}
|
|
198
|
+
bind:value />
|
|
199
|
+
{/if}
|
|
200
|
+
</div>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export default ComboBox;
|
|
2
|
+
type ComboBox = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<Props>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const ComboBox: import("svelte").Component<{
|
|
7
|
+
/**
|
|
8
|
+
* Whether the input should be autofocused on mount
|
|
9
|
+
*/
|
|
10
|
+
autofocus?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Additional CSS classes to apply to the component
|
|
13
|
+
*/
|
|
14
|
+
class?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the component is disabled
|
|
17
|
+
*/
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The ID of the input element
|
|
21
|
+
*/
|
|
22
|
+
id?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The name of the input, used for form submission
|
|
25
|
+
*/
|
|
26
|
+
name?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The available tag options
|
|
29
|
+
*/
|
|
30
|
+
options?: Array<{
|
|
31
|
+
id: string | number;
|
|
32
|
+
label: string;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* The placeholder text for the input
|
|
36
|
+
*/
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
/**
|
|
39
|
+
* The currently selected tags, bound to the component
|
|
40
|
+
*/
|
|
41
|
+
value?: Array<string | number>;
|
|
42
|
+
}, {}, "value">;
|
|
43
|
+
type Props = {
|
|
44
|
+
/**
|
|
45
|
+
* Whether the input should be autofocused on mount
|
|
46
|
+
*/
|
|
47
|
+
autofocus?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Additional CSS classes to apply to the component
|
|
50
|
+
*/
|
|
51
|
+
class?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Whether the component is disabled
|
|
54
|
+
*/
|
|
55
|
+
disabled?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* The ID of the input element
|
|
58
|
+
*/
|
|
59
|
+
id?: string;
|
|
60
|
+
/**
|
|
61
|
+
* The name of the input, used for form submission
|
|
62
|
+
*/
|
|
63
|
+
name?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The available tag options
|
|
66
|
+
*/
|
|
67
|
+
options?: Array<{
|
|
68
|
+
id: string | number;
|
|
69
|
+
label: string;
|
|
70
|
+
}>;
|
|
71
|
+
/**
|
|
72
|
+
* The placeholder text for the input
|
|
73
|
+
*/
|
|
74
|
+
placeholder?: string;
|
|
75
|
+
/**
|
|
76
|
+
* The currently selected tags, bound to the component
|
|
77
|
+
*/
|
|
78
|
+
value?: Array<string | number>;
|
|
79
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { Icon } from "../../../index.js";
|
|
3
|
+
import { onDestroy, onMount } from "svelte";
|
|
4
|
+
import { comboBoxVariants } from "./comboBox.variants.js";
|
|
5
|
+
|
|
6
|
+
let { filtered, highlighted, inputRef, localValues, onSelectItem, value, ...rest } =
|
|
7
|
+
$props();
|
|
8
|
+
|
|
9
|
+
let styles = $derived(comboBoxVariants());
|
|
10
|
+
|
|
11
|
+
let dropdownPosition = $state("bottom");
|
|
12
|
+
let dropdownMaxHeight = $state(200);
|
|
13
|
+
|
|
14
|
+
const attachHighlightedItem = (item) => {
|
|
15
|
+
if (inputRef) {
|
|
16
|
+
// so the screen reader can read the highlighted option aloud
|
|
17
|
+
if (item.id) inputRef.setAttribute("aria-activedescendant", item.id);
|
|
18
|
+
else inputRef.removeAttribute("aria-activedescendant");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// maybe scroll item into view
|
|
22
|
+
if (item.offsetTop < item.offsetParent.scrollTop)
|
|
23
|
+
item.scrollIntoView({ block: "nearest" });
|
|
24
|
+
else if (
|
|
25
|
+
item.offsetTop + item.offsetHeight >
|
|
26
|
+
item.offsetParent.scrollTop + item.offsetParent.offsetHeight
|
|
27
|
+
)
|
|
28
|
+
item.scrollIntoView({ block: "nearest" });
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const updateDropdownPosition = () => {
|
|
32
|
+
if (!inputRef) return;
|
|
33
|
+
|
|
34
|
+
const rect = inputRef.getBoundingClientRect();
|
|
35
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
36
|
+
const spaceAbove = rect.top;
|
|
37
|
+
|
|
38
|
+
dropdownPosition = spaceBelow > spaceAbove ? "bottom" : "top";
|
|
39
|
+
|
|
40
|
+
dropdownMaxHeight =
|
|
41
|
+
dropdownPosition === "bottom"
|
|
42
|
+
? Math.min(300, spaceBelow - 24)
|
|
43
|
+
: Math.min(300, spaceAbove - 24);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const getOptionId = (itemId) =>
|
|
47
|
+
`${localValues?.id ?? "tagselector"}-option-${itemId}`;
|
|
48
|
+
|
|
49
|
+
onMount(() => updateDropdownPosition());
|
|
50
|
+
onDestroy(() => {
|
|
51
|
+
inputRef?.removeAttribute("aria-activedescendant");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
let showDropdown = $derived(filtered.length > 0);
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<svelte:window onscroll={updateDropdownPosition} onresize={updateDropdownPosition} />
|
|
58
|
+
|
|
59
|
+
<div
|
|
60
|
+
class={styles.dropdown({ dropdownPosition, showDropdown })}
|
|
61
|
+
id={localValues.id}
|
|
62
|
+
role="listbox"
|
|
63
|
+
style={`max-height: ${dropdownMaxHeight}px`}
|
|
64
|
+
tabindex="-1"
|
|
65
|
+
{...rest}>
|
|
66
|
+
{#snippet option({ highlighted, id, label, selected, ...rest })}
|
|
67
|
+
<button
|
|
68
|
+
aria-selected={selected}
|
|
69
|
+
{@attach highlighted ? attachHighlightedItem : null}
|
|
70
|
+
class={styles.dropdownItem()}
|
|
71
|
+
data-highlighted={highlighted}
|
|
72
|
+
{id}
|
|
73
|
+
role="option"
|
|
74
|
+
tabindex="-1"
|
|
75
|
+
{...rest}>
|
|
76
|
+
{label}
|
|
77
|
+
{#if selected}
|
|
78
|
+
<Icon class={styles.dropdownCheckmark()} name="check" size={16} />
|
|
79
|
+
{/if}
|
|
80
|
+
</button>
|
|
81
|
+
{/snippet}
|
|
82
|
+
|
|
83
|
+
{#each filtered as item, i (item.id)}
|
|
84
|
+
{@render option({
|
|
85
|
+
highlighted: highlighted === i,
|
|
86
|
+
id: getOptionId(item.id),
|
|
87
|
+
label: item.label,
|
|
88
|
+
selected: value === item.id.toString(),
|
|
89
|
+
onclick: () => onSelectItem(item.id),
|
|
90
|
+
})}
|
|
91
|
+
{/each}
|
|
92
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default Dropdown;
|
|
2
|
+
type Dropdown = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const Dropdown: import("svelte").Component<{
|
|
7
|
+
filtered: any;
|
|
8
|
+
highlighted: any;
|
|
9
|
+
inputRef: any;
|
|
10
|
+
localValues: any;
|
|
11
|
+
onSelectItem: any;
|
|
12
|
+
value: any;
|
|
13
|
+
} & Record<string, any>, {}, "">;
|
|
14
|
+
type $$ComponentProps = {
|
|
15
|
+
filtered: any;
|
|
16
|
+
highlighted: any;
|
|
17
|
+
inputRef: any;
|
|
18
|
+
localValues: any;
|
|
19
|
+
onSelectItem: any;
|
|
20
|
+
value: any;
|
|
21
|
+
} & Record<string, any>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { comboBoxVariants } from "./comboBox.variants.js";
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
inputRef = $bindable(),
|
|
6
|
+
localValues,
|
|
7
|
+
name,
|
|
8
|
+
onKeydown,
|
|
9
|
+
onOpenDropdown,
|
|
10
|
+
placeholder,
|
|
11
|
+
value = $bindable(),
|
|
12
|
+
} = $props();
|
|
13
|
+
|
|
14
|
+
let styles = $derived(comboBoxVariants());
|
|
15
|
+
|
|
16
|
+
const handleOpenDropdown = (e) => {
|
|
17
|
+
if (localValues.disabled) return;
|
|
18
|
+
onOpenDropdown(e);
|
|
19
|
+
};
|
|
20
|
+
const handleKeydown = (e) => {
|
|
21
|
+
if (localValues.disabled) return;
|
|
22
|
+
onKeydown(e);
|
|
23
|
+
};
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div class={styles.value({ disabled: localValues.disabled })}>
|
|
27
|
+
<input
|
|
28
|
+
bind:this={inputRef}
|
|
29
|
+
bind:value
|
|
30
|
+
autocomplete="off"
|
|
31
|
+
class={styles.searchInput()}
|
|
32
|
+
{name}
|
|
33
|
+
onfocus={handleOpenDropdown}
|
|
34
|
+
onbeforeinput={handleOpenDropdown}
|
|
35
|
+
onkeydown={handleKeydown}
|
|
36
|
+
{placeholder}
|
|
37
|
+
readonly={localValues.disabled}
|
|
38
|
+
role="searchbox" />
|
|
39
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export default Value;
|
|
2
|
+
type Value = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const Value: import("svelte").Component<{
|
|
7
|
+
inputRef?: any;
|
|
8
|
+
localValues: any;
|
|
9
|
+
name: any;
|
|
10
|
+
onKeydown: any;
|
|
11
|
+
onOpenDropdown: any;
|
|
12
|
+
placeholder: any;
|
|
13
|
+
value?: any;
|
|
14
|
+
}, {}, "value" | "inputRef">;
|
|
15
|
+
type $$ComponentProps = {
|
|
16
|
+
inputRef?: any;
|
|
17
|
+
localValues: any;
|
|
18
|
+
name: any;
|
|
19
|
+
onKeydown: any;
|
|
20
|
+
onOpenDropdown: any;
|
|
21
|
+
placeholder: any;
|
|
22
|
+
value?: any;
|
|
23
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export const comboBoxVariants: import("tailwind-variants").TVReturnType<{
|
|
2
|
+
disabled: {
|
|
3
|
+
true: {
|
|
4
|
+
value: string;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
dropdownPosition: {
|
|
8
|
+
bottom: {
|
|
9
|
+
dropdown: string;
|
|
10
|
+
};
|
|
11
|
+
top: {
|
|
12
|
+
dropdown: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
showDropdown: {
|
|
16
|
+
true: {
|
|
17
|
+
dropdown: string;
|
|
18
|
+
};
|
|
19
|
+
false: {
|
|
20
|
+
dropdown: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}, {
|
|
24
|
+
base: string;
|
|
25
|
+
value: string;
|
|
26
|
+
item: string;
|
|
27
|
+
searchField: string;
|
|
28
|
+
searchInput: string;
|
|
29
|
+
dropdown: string;
|
|
30
|
+
dropdownCheckmark: string;
|
|
31
|
+
dropdownItem: string[];
|
|
32
|
+
}, undefined, {
|
|
33
|
+
disabled: {
|
|
34
|
+
true: {
|
|
35
|
+
base: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
error: {
|
|
39
|
+
true: {
|
|
40
|
+
base: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
}, {
|
|
44
|
+
base: string[];
|
|
45
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
46
|
+
disabled: {
|
|
47
|
+
true: {
|
|
48
|
+
base: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
error: {
|
|
52
|
+
true: {
|
|
53
|
+
base: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
}, {
|
|
57
|
+
base: string[];
|
|
58
|
+
}, undefined, {
|
|
59
|
+
disabled: {
|
|
60
|
+
true: {
|
|
61
|
+
base: string;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
error: {
|
|
65
|
+
true: {
|
|
66
|
+
base: string;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
}, {
|
|
70
|
+
base: string[];
|
|
71
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
72
|
+
disabled: {
|
|
73
|
+
true: {
|
|
74
|
+
base: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
error: {
|
|
78
|
+
true: {
|
|
79
|
+
base: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
}, {
|
|
83
|
+
base: string[];
|
|
84
|
+
}, undefined, unknown, unknown, undefined>>>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { tv } from "tailwind-variants";
|
|
2
|
+
import { inputBaseVariant } from "../../atoms/input/input.variants.js";
|
|
3
|
+
|
|
4
|
+
const comboBoxVariants = tv({
|
|
5
|
+
extend: inputBaseVariant,
|
|
6
|
+
slots: {
|
|
7
|
+
base: "relative min-h-10 p-1",
|
|
8
|
+
value: "flex flex-wrap gap-1",
|
|
9
|
+
item: "h-7.5",
|
|
10
|
+
searchField: "relative h-7.5 w-30",
|
|
11
|
+
searchInput:
|
|
12
|
+
"w-full appearance-none border-0 bg-transparent ui-tag-badge placeholder-current focus:ring-0",
|
|
13
|
+
dropdown:
|
|
14
|
+
"absolute w-full max-w-100 overflow-y-auto bg-white p-1 pr-5 shadow-sm dark:border-neutral-700 dark:bg-neutral-800",
|
|
15
|
+
dropdownCheckmark: "ml-auto shrink-0",
|
|
16
|
+
dropdownItem: [
|
|
17
|
+
"flex w-full grow items-center gap-2 rounded-sm p-2 ui-select-label",
|
|
18
|
+
"bg-white dark:bg-neutral-800",
|
|
19
|
+
"bg-linear-to-r to-transparent",
|
|
20
|
+
"cursor-pointer text-neutral-900 hover:from-black/15 dark:text-neutral-200 dark:hover:from-white/15",
|
|
21
|
+
"data-[highlighted=true]:from-black/15 dark:data-[highlighted=true]:from-white/15",
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
variants: {
|
|
25
|
+
disabled: {
|
|
26
|
+
true: {
|
|
27
|
+
value: "pointer-events-none",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
dropdownPosition: {
|
|
31
|
+
bottom: {
|
|
32
|
+
dropdown: "top-full mt-1",
|
|
33
|
+
},
|
|
34
|
+
top: {
|
|
35
|
+
dropdown: "bottom-full mb-1",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
showDropdown: {
|
|
39
|
+
true: {
|
|
40
|
+
dropdown: "block",
|
|
41
|
+
},
|
|
42
|
+
false: {
|
|
43
|
+
dropdown: "hidden",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export { comboBoxVariants };
|
|
@@ -15,11 +15,13 @@
|
|
|
15
15
|
class: className,
|
|
16
16
|
customLayout = false,
|
|
17
17
|
fullWidth = false,
|
|
18
|
+
...rest
|
|
18
19
|
} = $props();
|
|
19
20
|
</script>
|
|
20
21
|
|
|
21
22
|
<div
|
|
22
23
|
class={formActionsVariants({ class: className, customLayout, fullWidth })}
|
|
23
|
-
data-form-actions
|
|
24
|
+
data-form-actions
|
|
25
|
+
{...rest}>
|
|
24
26
|
{@render children?.()}
|
|
25
27
|
</div>
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
label,
|
|
30
30
|
layout = "stacked",
|
|
31
31
|
required = false,
|
|
32
|
+
...rest
|
|
32
33
|
} = $props();
|
|
33
34
|
|
|
34
35
|
setContext("form-field-store", () => {
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
let styles = $derived(formFieldVariants({ disabled, layout }));
|
|
52
53
|
</script>
|
|
53
54
|
|
|
54
|
-
<div class={styles.base({ class: className })}>
|
|
55
|
+
<div class={styles.base({ class: className })} {...rest}>
|
|
55
56
|
{#if label}
|
|
56
57
|
<Label class={styles.label()} for={id} {error} {required}>{label}</Label>
|
|
57
58
|
{/if}
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/** @type {Props} */
|
|
12
|
-
let { children, class: className, gap = 2 } = $props();
|
|
12
|
+
let { children, class: className, gap = 2, ...rest } = $props();
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
|
-
<div class={formLayoutVariants({ class: className, gap })}>
|
|
15
|
+
<div class={formLayoutVariants({ class: className, gap })} {...rest}>
|
|
16
16
|
{@render children?.()}
|
|
17
17
|
</div>
|
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
onClose,
|
|
22
22
|
title = "",
|
|
23
23
|
variant = "",
|
|
24
|
+
...rest
|
|
24
25
|
} = $props();
|
|
25
26
|
|
|
26
27
|
let styles = $derived(notificationVariants({ variant }));
|
|
27
28
|
</script>
|
|
28
29
|
|
|
29
|
-
<div class={styles.base({ class: className })}>
|
|
30
|
+
<div class={styles.base({ class: className })} {...rest}>
|
|
30
31
|
<div class={styles.icon()}>
|
|
31
32
|
<Icon name={icon} />
|
|
32
33
|
</div>
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
size = "medium",
|
|
22
22
|
type = "text",
|
|
23
23
|
variant = "transparent",
|
|
24
|
+
...rest
|
|
24
25
|
} = $props();
|
|
25
26
|
|
|
26
27
|
let styles = $derived(colorSwatchVariants({ isOpen, size, variant }));
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
|
|
68
69
|
<Popover.Root open={isOpen} onOpenChange={(open) => (isOpen = open)}>
|
|
69
70
|
<Popover.Trigger>
|
|
70
|
-
<button class={styles.base({ class: className })}>
|
|
71
|
+
<button class={styles.base({ class: className })} {...rest}>
|
|
71
72
|
<div class={styles.iconText()} style={style()}>
|
|
72
73
|
{@render content()}
|
|
73
74
|
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
let { colors = [], defaultColor = "#121110", editor } = $props();
|
|
5
5
|
|
|
6
6
|
let isOpen = $state(false);
|
|
7
|
-
let selectedColor = $
|
|
7
|
+
let selectedColor = $derived(defaultColor);
|
|
8
8
|
|
|
9
9
|
const handleColorSelect = (color) => {
|
|
10
10
|
selectedColor = color;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
$effect(() => {
|
|
17
17
|
if (!editor) return;
|
|
18
|
+
|
|
18
19
|
const attrs = editor.getAttributes("textStyle");
|
|
19
20
|
selectedColor = attrs.color || defaultColor;
|
|
20
21
|
});
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
size = "medium",
|
|
32
32
|
value = $bindable(),
|
|
33
33
|
variant = "default",
|
|
34
|
+
...rest
|
|
34
35
|
} = $props();
|
|
35
36
|
|
|
36
37
|
let toggleGroupEl;
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
</script>
|
|
60
61
|
|
|
61
62
|
<XScroll class={styles.base({ class: className })}>
|
|
62
|
-
<div bind:this={toggleGroupEl} class={styles.tabs()} role="tablist">
|
|
63
|
+
<div bind:this={toggleGroupEl} class={styles.tabs()} role="tablist" {...rest}>
|
|
63
64
|
{@render children?.()}
|
|
64
65
|
</div>
|
|
65
66
|
</XScroll>
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
class: className = "",
|
|
22
22
|
icon,
|
|
23
23
|
value: localeValue,
|
|
24
|
+
...rest
|
|
24
25
|
} = $props();
|
|
25
26
|
|
|
26
27
|
let store = $derived(getContext("toggle-group-store")());
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
});
|
|
37
38
|
</script>
|
|
38
39
|
|
|
39
|
-
<div class={stylesByVariant.base({ class: baseClass })}>
|
|
40
|
+
<div class={stylesByVariant.base({ class: baseClass })} {...rest}>
|
|
40
41
|
<button
|
|
41
42
|
class={stylesByVariant.button({ appearance, class: className, isActive, size })}
|
|
42
43
|
role="tab"
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/** @type {Props} */
|
|
12
|
-
let { children, class: className = "" } = $props();
|
|
12
|
+
let { children, class: className = "", ...rest } = $props();
|
|
13
13
|
|
|
14
14
|
let styles = $derived(dialogVariants());
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
|
-
<FormActions class={styles.formActions({ class: className })} customLayout>
|
|
17
|
+
<FormActions class={styles.formActions({ class: className })} customLayout {...rest}>
|
|
18
18
|
{@render children?.()}
|
|
19
19
|
</FormActions>
|
package/dist/index.d.ts
CHANGED
|
@@ -19,7 +19,8 @@ export { default as Switch } from "./components/atoms/switch/Switch.svelte";
|
|
|
19
19
|
export { default as Textarea } from "./components/atoms/textarea/Textarea.svelte";
|
|
20
20
|
export { default as XScroll } from "./components/atoms/utils/xScroll/XScroll.svelte";
|
|
21
21
|
export * as ColorSwatch from "./components/molecules/pickers/colorSwatch/index.js";
|
|
22
|
-
export { default as
|
|
22
|
+
export { default as ComboBox } from "./components/molecules/comboBox/ComboBox.svelte";
|
|
23
|
+
export { default as FormActions } from "./components/molecules/formActions/FormActions.svelte";
|
|
23
24
|
export { default as FormField } from "./components/molecules/formField/FormField.svelte";
|
|
24
25
|
export { default as FormLayout } from "./components/molecules/formLayout/FormLayout.svelte";
|
|
25
26
|
export { default as Notification } from "./components/molecules/notification/Notification.svelte";
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,8 @@ export { default as XScroll } from "./components/atoms/utils/xScroll/XScroll.sve
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
export * as ColorSwatch from "./components/molecules/pickers/colorSwatch/index.js";
|
|
32
|
-
export { default as
|
|
32
|
+
export { default as ComboBox } from "./components/molecules/comboBox/ComboBox.svelte";
|
|
33
|
+
export { default as FormActions } from "./components/molecules/formActions/FormActions.svelte";
|
|
33
34
|
export { default as FormField } from "./components/molecules/formField/FormField.svelte";
|
|
34
35
|
export { default as FormLayout } from "./components/molecules/formLayout/FormLayout.svelte";
|
|
35
36
|
export { default as Notification } from "./components/molecules/notification/Notification.svelte";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@websline/system-components",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@tiptap/core": "^3.
|
|
30
|
-
"@tiptap/extension-color": "^3.
|
|
31
|
-
"@tiptap/extension-highlight": "^3.
|
|
32
|
-
"@tiptap/extension-placeholder": "^3.
|
|
33
|
-
"@tiptap/extension-text-align": "^3.
|
|
34
|
-
"@tiptap/extension-text-style": "^3.
|
|
35
|
-
"@tiptap/pm": "^3.
|
|
36
|
-
"@tiptap/starter-kit": "^3.
|
|
29
|
+
"@tiptap/core": "^3.14.0",
|
|
30
|
+
"@tiptap/extension-color": "^3.14.0",
|
|
31
|
+
"@tiptap/extension-highlight": "^3.14.0",
|
|
32
|
+
"@tiptap/extension-placeholder": "^3.14.0",
|
|
33
|
+
"@tiptap/extension-text-align": "^3.14.0",
|
|
34
|
+
"@tiptap/extension-text-style": "^3.14.0",
|
|
35
|
+
"@tiptap/pm": "^3.14.0",
|
|
36
|
+
"@tiptap/starter-kit": "^3.14.0",
|
|
37
37
|
"bits-ui": "^2.14.4",
|
|
38
38
|
"dompurify": "^3.3.1",
|
|
39
39
|
"tailwind-variants": "^3.2.2",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
71
71
|
"publint": "^0.3.16",
|
|
72
72
|
"storybook": "^10.1.10",
|
|
73
|
-
"svelte": "^5.46.
|
|
73
|
+
"svelte": "^5.46.1",
|
|
74
74
|
"tailwindcss": "^4.1.18",
|
|
75
75
|
"typescript": "^5.9.3",
|
|
76
76
|
"vite": "^7.3.0",
|
/package/dist/components/molecules/formActions/{formActions.svelte.d.ts → FormActions.svelte.d.ts}
RENAMED
|
File without changes
|