@websline/system-components 1.2.9 → 1.3.1

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.
Files changed (31) hide show
  1. package/dist/components/atoms/checkbox/Checkbox.svelte +15 -15
  2. package/dist/components/atoms/checkbox/Checkbox.svelte.d.ts +8 -0
  3. package/dist/components/atoms/checkbox/checkbox.variants.d.ts +9 -0
  4. package/dist/components/atoms/checkbox/checkbox.variants.js +3 -0
  5. package/dist/components/atoms/icon/components/ArrowDown.svelte +22 -0
  6. package/dist/components/atoms/icon/components/ArrowDown.svelte.d.ts +41 -0
  7. package/dist/components/atoms/icon/components/ArrowUp.svelte +22 -0
  8. package/dist/components/atoms/icon/components/ArrowUp.svelte.d.ts +41 -0
  9. package/dist/components/atoms/icon/index.d.ts +36 -0
  10. package/dist/components/atoms/icon/index.js +4 -0
  11. package/dist/components/atoms/input/Input.svelte +14 -18
  12. package/dist/components/atoms/input/input.variants.d.ts +2 -22
  13. package/dist/components/atoms/input/input.variants.js +5 -0
  14. package/dist/components/atoms/radio/Radio.svelte +15 -15
  15. package/dist/components/atoms/radio/Radio.svelte.d.ts +8 -0
  16. package/dist/components/atoms/radio/radio.variants.d.ts +9 -0
  17. package/dist/components/atoms/radio/radio.variants.js +3 -0
  18. package/dist/components/atoms/select/Select.svelte +13 -17
  19. package/dist/components/atoms/switch/Switch.svelte +15 -15
  20. package/dist/components/atoms/switch/Switch.svelte.d.ts +8 -0
  21. package/dist/components/atoms/switch/switch.variants.d.ts +9 -0
  22. package/dist/components/atoms/switch/switch.variants.js +3 -0
  23. package/dist/components/atoms/textarea/Textarea.svelte +14 -18
  24. package/dist/components/molecules/comboBox/ComboBox.svelte +20 -8
  25. package/dist/components/molecules/comboBox/ComboBox.svelte.d.ts +16 -0
  26. package/dist/components/molecules/comboBox/Value.svelte +1 -0
  27. package/dist/components/molecules/comboBox/comboBox.variants.d.ts +5 -0
  28. package/dist/components/molecules/comboBox/comboBox.variants.js +7 -1
  29. package/dist/components/molecules/selectorCard/SelectorCard.svelte +10 -4
  30. package/dist/components/molecules/tagSelector/tagSelector.variants.js +1 -1
  31. package/package.json +26 -26
@@ -6,10 +6,11 @@
6
6
  * @typedef {Object} Props
7
7
  * @property {boolean} [checked=false] Wether this radio is checked or not, bound to the component
8
8
  * @property {string} [class=""] Additional CSS classes to apply to the component
9
- * @property {boolean} [disabled=false] Whether the radio is disabled
10
- * @property {string} [id=""] The ID of the radio element
9
+ * @property {boolean} [disabled] Whether the radio is disabled
10
+ * @property {boolean} [error] Whether the radio has an error state
11
+ * @property {string} [id] The ID of the radio element
11
12
  * @property {string} [name] The name of the radio, used for form submission
12
- * @property {boolean} [required=false] Whether the radio is required
13
+ * @property {boolean} [required] Whether the radio is required
13
14
  * @property {string} [value=""] The value of the radio
14
15
  */
15
16
 
@@ -17,27 +18,25 @@
17
18
  let {
18
19
  checked = $bindable(),
19
20
  class: className = "",
20
- disabled = false,
21
- id = "",
21
+ disabled,
22
+ error,
23
+ id,
22
24
  name,
23
- required = false,
25
+ required,
24
26
  value = "",
25
27
  ...rest
26
28
  } = $props();
27
29
 
28
- let store = getContext("form-field-store");
30
+ let store = getContext("form-field-store") ?? null;
29
31
 
30
32
  let localValues = $derived.by(() => {
31
- if (store) {
32
- return {
33
- ...store(),
34
- };
35
- }
33
+ const storeValues = typeof store === "function" ? store() : {};
36
34
 
37
35
  return {
38
- disabled,
39
- id,
40
- required,
36
+ disabled: disabled ?? storeValues.disabled ?? false,
37
+ error: error ?? storeValues.error ?? false,
38
+ id: id ?? storeValues.id ?? "",
39
+ required: required ?? storeValues.required ?? false,
41
40
  };
42
41
  });
43
42
  </script>
@@ -47,6 +46,7 @@
47
46
  class={checkboxVariants({
48
47
  class: className,
49
48
  disabled: localValues.disabled,
49
+ error: localValues.error,
50
50
  })}
51
51
  disabled={localValues.disabled}
52
52
  id={localValues.id}
@@ -16,6 +16,10 @@ declare const Checkbox: import("svelte").Component<{
16
16
  * Whether the radio is disabled
17
17
  */
18
18
  disabled?: boolean;
19
+ /**
20
+ * Whether the radio has an error state
21
+ */
22
+ error?: boolean;
19
23
  /**
20
24
  * The ID of the radio element
21
25
  */
@@ -46,6 +50,10 @@ type Props = {
46
50
  * Whether the radio is disabled
47
51
  */
48
52
  disabled?: boolean;
53
+ /**
54
+ * Whether the radio has an error state
55
+ */
56
+ error?: boolean;
49
57
  /**
50
58
  * The ID of the radio element
51
59
  */
@@ -2,12 +2,21 @@ export const checkboxVariants: import("tailwind-variants").TVReturnType<{
2
2
  disabled: {
3
3
  true: string;
4
4
  };
5
+ error: {
6
+ true: string;
7
+ };
5
8
  }, undefined, "size-4 cursor-pointer rounded border border-current bg-transparent bg-none text-neutral-900 ring-0 ring-transparent ring-offset-transparent outline-transparent duration-300 after:block after:size-full checked:bg-none checked:after:bg-current focus:outline-1 focus:outline-offset-1 focus:outline-blue-300 dark:text-white", {
6
9
  disabled: {
7
10
  true: string;
8
11
  };
12
+ error: {
13
+ true: string;
14
+ };
9
15
  }, undefined, import("tailwind-variants").TVReturnType<{
10
16
  disabled: {
11
17
  true: string;
12
18
  };
19
+ error: {
20
+ true: string;
21
+ };
13
22
  }, undefined, "size-4 cursor-pointer rounded border border-current bg-transparent bg-none text-neutral-900 ring-0 ring-transparent ring-offset-transparent outline-transparent duration-300 after:block after:size-full checked:bg-none checked:after:bg-current focus:outline-1 focus:outline-offset-1 focus:outline-blue-300 dark:text-white", unknown, unknown, undefined>>;
@@ -6,6 +6,9 @@ const checkboxVariants = tv({
6
6
  disabled: {
7
7
  true: "cursor-not-allowed",
8
8
  },
9
+ error: {
10
+ true: "border-current text-red-500 ring ring-current dark:border-current dark:text-red-500",
11
+ },
9
12
  },
10
13
  });
11
14
 
@@ -0,0 +1,22 @@
1
+ <script>
2
+ /**
3
+ * @typedef {Object} Props
4
+ * @property {string} [color=""] Icon color
5
+ * @property {number} [height=24] Icon height
6
+ * @property {number} [strokeWidth=24] Icon StrokeWidth
7
+ * @property {number} [width=24] Icon width
8
+ */
9
+
10
+ /** @type {Props} */
11
+ let { color, height, width, strokeWidth, ...rest } = $props();
12
+ </script>
13
+
14
+ <svg
15
+ {width}
16
+ {height}
17
+ viewBox="0 0 24 24"
18
+ fill="none"
19
+ xmlns="http://www.w3.org/2000/svg"
20
+ {...rest}>
21
+ <path d="M12,20V4 M12,20l6-5.3 M12,20l-6-5.3" stroke={color} stroke-width={strokeWidth} stroke-linecap="round" stroke-linejoin="round"/>
22
+ </svg>
@@ -0,0 +1,41 @@
1
+ export default ArrowDown;
2
+ type ArrowDown = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<Props>): void;
5
+ };
6
+ declare const ArrowDown: import("svelte").Component<{
7
+ /**
8
+ * Icon color
9
+ */
10
+ color?: string;
11
+ /**
12
+ * Icon height
13
+ */
14
+ height?: number;
15
+ /**
16
+ * Icon StrokeWidth
17
+ */
18
+ strokeWidth?: number;
19
+ /**
20
+ * Icon width
21
+ */
22
+ width?: number;
23
+ }, {}, "">;
24
+ type Props = {
25
+ /**
26
+ * Icon color
27
+ */
28
+ color?: string;
29
+ /**
30
+ * Icon height
31
+ */
32
+ height?: number;
33
+ /**
34
+ * Icon StrokeWidth
35
+ */
36
+ strokeWidth?: number;
37
+ /**
38
+ * Icon width
39
+ */
40
+ width?: number;
41
+ };
@@ -0,0 +1,22 @@
1
+ <script>
2
+ /**
3
+ * @typedef {Object} Props
4
+ * @property {string} [color=""] Icon color
5
+ * @property {number} [height=24] Icon height
6
+ * @property {number} [strokeWidth=24] Icon StrokeWidth
7
+ * @property {number} [width=24] Icon width
8
+ */
9
+
10
+ /** @type {Props} */
11
+ let { color, height, width, strokeWidth, ...rest } = $props();
12
+ </script>
13
+
14
+ <svg
15
+ {width}
16
+ {height}
17
+ viewBox="0 0 24 24"
18
+ fill="none"
19
+ xmlns="http://www.w3.org/2000/svg"
20
+ {...rest}>
21
+ <path d="M12,4v16 M12,4L6,9.3 M12,4l6,5.3" stroke={color} stroke-width={strokeWidth} stroke-linecap="round" stroke-linejoin="round"/>
22
+ </svg>
@@ -0,0 +1,41 @@
1
+ export default ArrowUp;
2
+ type ArrowUp = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<Props>): void;
5
+ };
6
+ declare const ArrowUp: import("svelte").Component<{
7
+ /**
8
+ * Icon color
9
+ */
10
+ color?: string;
11
+ /**
12
+ * Icon height
13
+ */
14
+ height?: number;
15
+ /**
16
+ * Icon StrokeWidth
17
+ */
18
+ strokeWidth?: number;
19
+ /**
20
+ * Icon width
21
+ */
22
+ width?: number;
23
+ }, {}, "">;
24
+ type Props = {
25
+ /**
26
+ * Icon color
27
+ */
28
+ color?: string;
29
+ /**
30
+ * Icon height
31
+ */
32
+ height?: number;
33
+ /**
34
+ * Icon StrokeWidth
35
+ */
36
+ strokeWidth?: number;
37
+ /**
38
+ * Icon width
39
+ */
40
+ width?: number;
41
+ };
@@ -53,6 +53,42 @@ export const registry: {
53
53
  */
54
54
  width?: number;
55
55
  }, {}, "">;
56
+ arrowDown: import("svelte").Component<{
57
+ /**
58
+ * Icon color
59
+ */
60
+ color?: string;
61
+ /**
62
+ * Icon height
63
+ */
64
+ height?: number;
65
+ /**
66
+ * Icon StrokeWidth
67
+ */
68
+ strokeWidth?: number;
69
+ /**
70
+ * Icon width
71
+ */
72
+ width?: number;
73
+ }, {}, "">;
74
+ arrowUp: import("svelte").Component<{
75
+ /**
76
+ * Icon color
77
+ */
78
+ color?: string;
79
+ /**
80
+ * Icon height
81
+ */
82
+ height?: number;
83
+ /**
84
+ * Icon StrokeWidth
85
+ */
86
+ strokeWidth?: number;
87
+ /**
88
+ * Icon width
89
+ */
90
+ width?: number;
91
+ }, {}, "">;
56
92
  attach: import("svelte").Component<{
57
93
  /**
58
94
  * Icon color
@@ -1,6 +1,8 @@
1
1
  import Academy from "./components/Academy.svelte";
2
2
  import Add from "./components/Add.svelte";
3
3
  import Ai from "./components/Ai.svelte";
4
+ import ArrowDown from "./components/ArrowDown.svelte";
5
+ import ArrowUp from "./components/ArrowUp.svelte";
4
6
  import Attach from "./components/Attach.svelte";
5
7
  import Block from "./components/Block.svelte";
6
8
  import Bold from "./components/Bold.svelte";
@@ -43,6 +45,8 @@ export const registry = {
43
45
  academy: Academy,
44
46
  add: Add,
45
47
  ai: Ai,
48
+ arrowDown: ArrowDown,
49
+ arrowUp: ArrowUp,
46
50
  attach: Attach,
47
51
  block: Block,
48
52
  bold: Bold,
@@ -8,13 +8,13 @@
8
8
  * @property {string|import("svelte").SvelteComponent|Function} [adornmentEnd=""] Content to display at the end of the input (e.g., icon or text)
9
9
  * @property {import("svelte").SvelteComponent} [children] Additional content to render inside the input component
10
10
  * @property {string} [class=""] Additional CSS classes to apply to the component
11
- * @property {boolean} [disabled=false] Whether the input is disabled
12
- * @property {boolean} [error=false] Whether the input has an error state
13
- * @property {string} [id=""] The ID of the input element
11
+ * @property {boolean} [disabled] Whether the input is disabled
12
+ * @property {boolean} [error] Whether the input has an error state
13
+ * @property {string} [id] The ID of the input element
14
14
  * @property {string} [name] The name of the input, used for form submission
15
15
  * @property {string} [placeholder=""] Placeholder text for the input
16
16
  * @property {boolean} [readonly=false] Whether the input is read-only
17
- * @property {boolean} [required=false] Whether the input is required
17
+ * @property {boolean} [required] Whether the input is required
18
18
  * @property {string} [type="text"] The type of the input, e.g. "text", "password", "email"
19
19
  * @property {string} [value=""] The value of the input, bound to the component
20
20
  */
@@ -25,32 +25,28 @@
25
25
  adornmentEnd = "",
26
26
  children,
27
27
  class: className = "",
28
- disabled = false,
29
- error = false,
30
- id = "",
28
+ disabled,
29
+ error,
30
+ id,
31
31
  name,
32
32
  placeholder = "",
33
33
  readonly = false,
34
- required = false,
34
+ required,
35
35
  type = "text",
36
36
  value = $bindable(),
37
37
  ...rest
38
38
  } = $props();
39
39
 
40
- let store = getContext("form-field-store");
40
+ let store = getContext("form-field-store") ?? null;
41
41
 
42
42
  let localValues = $derived.by(() => {
43
- if (store) {
44
- return {
45
- ...store(),
46
- };
47
- }
43
+ const storeValues = typeof store === "function" ? store() : {};
48
44
 
49
45
  return {
50
- disabled,
51
- error,
52
- id,
53
- required,
46
+ disabled: disabled ?? storeValues.disabled ?? false,
47
+ error: error ?? storeValues.error ?? false,
48
+ id: id ?? storeValues.id ?? "",
49
+ required: required ?? storeValues.required ?? false,
54
50
  };
55
51
  });
56
52
 
@@ -1,27 +1,7 @@
1
1
  export const inputVariants: import("tailwind-variants").TVReturnType<{
2
- [key: string]: {
3
- [key: string]: import("tailwind-variants").ClassValue | {
4
- base?: import("tailwind-variants").ClassValue;
5
- input?: import("tailwind-variants").ClassValue;
6
- adornmentStart?: import("tailwind-variants").ClassValue;
7
- adornmentEnd?: import("tailwind-variants").ClassValue;
8
- };
9
- };
10
- } | {
11
2
  disabled: {
12
- true: import("tailwind-variants").ClassValue | {
13
- base?: import("tailwind-variants").ClassValue;
14
- input?: import("tailwind-variants").ClassValue;
15
- adornmentStart?: import("tailwind-variants").ClassValue;
16
- adornmentEnd?: import("tailwind-variants").ClassValue;
17
- };
18
- };
19
- error: {
20
- true: import("tailwind-variants").ClassValue | {
21
- base?: import("tailwind-variants").ClassValue;
22
- input?: import("tailwind-variants").ClassValue;
23
- adornmentStart?: import("tailwind-variants").ClassValue;
24
- adornmentEnd?: import("tailwind-variants").ClassValue;
3
+ true: {
4
+ input: string;
25
5
  };
26
6
  };
27
7
  }, {
@@ -11,6 +11,11 @@ const inputVariants = tv({
11
11
  input:
12
12
  "h-full w-full border-0 bg-transparent p-0 [font-size:inherit] leading-[inherit] focus:shadow-none focus:ring-0 focus:outline-0",
13
13
  },
14
+ variants: {
15
+ disabled: {
16
+ true: { input: "cursor-not-allowed" },
17
+ },
18
+ },
14
19
  });
15
20
 
16
21
  export { inputVariants };
@@ -6,10 +6,11 @@
6
6
  * @typedef {Object} Props
7
7
  * @property {boolean} [checked=false] Wether this radio is checked or not, bound to the component
8
8
  * @property {string} [class=""] Additional CSS classes to apply to the component
9
- * @property {boolean} [disabled=false] Whether the radio is disabled
10
- * @property {string} [id=""] The ID of the radio element
9
+ * @property {boolean} [disabled] Whether the radio is disabled
10
+ * @property {boolean} [error] Whether the radio has an error state
11
+ * @property {string} [id] The ID of the radio element
11
12
  * @property {string} [name] The name of the radio, used for form submission
12
- * @property {boolean} [required=false] Whether the radio is required
13
+ * @property {boolean} [required] Whether the radio is required
13
14
  * @property {string} [value=""] The value of the radio
14
15
  */
15
16
 
@@ -17,27 +18,25 @@
17
18
  let {
18
19
  checked = $bindable(),
19
20
  class: className = "",
20
- disabled = false,
21
- id = "",
21
+ disabled,
22
+ error,
23
+ id,
22
24
  name,
23
- required = false,
25
+ required,
24
26
  value = "",
25
27
  ...rest
26
28
  } = $props();
27
29
 
28
- let store = getContext("form-field-store");
30
+ let store = getContext("form-field-store") ?? null;
29
31
 
30
32
  let localValues = $derived.by(() => {
31
- if (store) {
32
- return {
33
- ...store(),
34
- };
35
- }
33
+ const storeValues = typeof store === "function" ? store() : {};
36
34
 
37
35
  return {
38
- disabled,
39
- id,
40
- required,
36
+ disabled: disabled ?? storeValues.disabled ?? false,
37
+ error: error ?? storeValues.error ?? false,
38
+ id: id ?? storeValues.id ?? "",
39
+ required: required ?? storeValues.required ?? false,
41
40
  };
42
41
  });
43
42
  </script>
@@ -49,6 +48,7 @@
49
48
  checked,
50
49
  class: className,
51
50
  disabled: localValues.disabled,
51
+ error: localValues.error,
52
52
  })}
53
53
  disabled={localValues.disabled}
54
54
  id={localValues.id}
@@ -16,6 +16,10 @@ declare const Radio: import("svelte").Component<{
16
16
  * Whether the radio is disabled
17
17
  */
18
18
  disabled?: boolean;
19
+ /**
20
+ * Whether the radio has an error state
21
+ */
22
+ error?: boolean;
19
23
  /**
20
24
  * The ID of the radio element
21
25
  */
@@ -46,6 +50,10 @@ type Props = {
46
50
  * Whether the radio is disabled
47
51
  */
48
52
  disabled?: boolean;
53
+ /**
54
+ * Whether the radio has an error state
55
+ */
56
+ error?: boolean;
49
57
  /**
50
58
  * The ID of the radio element
51
59
  */
@@ -2,6 +2,9 @@ export const radioVariants: import("tailwind-variants").TVReturnType<{
2
2
  checked: {
3
3
  true: string;
4
4
  };
5
+ error: {
6
+ true: string;
7
+ };
5
8
  disabled: {
6
9
  true: string;
7
10
  };
@@ -9,6 +12,9 @@ export const radioVariants: import("tailwind-variants").TVReturnType<{
9
12
  checked: {
10
13
  true: string;
11
14
  };
15
+ error: {
16
+ true: string;
17
+ };
12
18
  disabled: {
13
19
  true: string;
14
20
  };
@@ -16,6 +22,9 @@ export const radioVariants: import("tailwind-variants").TVReturnType<{
16
22
  checked: {
17
23
  true: string;
18
24
  };
25
+ error: {
26
+ true: string;
27
+ };
19
28
  disabled: {
20
29
  true: string;
21
30
  };
@@ -6,6 +6,9 @@ const radioVariants = tv({
6
6
  checked: {
7
7
  true: "inset-ring-4 inset-ring-neutral-900 dark:inset-ring-neutral-600",
8
8
  },
9
+ error: {
10
+ true: "border-current text-red-500 ring ring-current dark:border-current dark:text-red-500",
11
+ },
9
12
  disabled: {
10
13
  true: "cursor-not-allowed",
11
14
  },
@@ -7,12 +7,12 @@
7
7
  * @property {"default" | "raised"} [buttonAppearance="default"] Appearance of the button variant
8
8
  * @property {"small" | "medium" | "large"} [buttonSize="medium"] Size of the button variant
9
9
  * @property {string} [class=""] Additional CSS classes for the select
10
- * @property {boolean} [disabled=false] Whether the select field is disabled
11
- * @property {boolean} [error=false] Whether the select field has an error
12
- * @property {string} [id=""] The id attr of the select field
10
+ * @property {boolean} [disabled] Whether the select field is disabled
11
+ * @property {boolean} [error] Whether the select field has an error
12
+ * @property {string} [id] The id attr of the select field
13
13
  * @property {{ disabled?: boolean, label: string, value: string }[]} [options=[]] required array of option objects for the select
14
14
  * @property {string} [placeholder=""] The placeholder text that shows when no option is preselected
15
- * @property {boolean} [required=false] Whether the select field is required
15
+ * @property {boolean} [required] Whether the select field is required
16
16
  * @property {string} [value=""] The value of the input, bound to the component
17
17
  * @property {"default" | "button"} [variant="default"] The variant of the component
18
18
  */
@@ -22,31 +22,27 @@
22
22
  buttonAppearance = "default",
23
23
  buttonSize = "medium",
24
24
  class: className = "",
25
- disabled = false,
26
- error = false,
25
+ disabled,
26
+ error,
27
27
  id,
28
28
  options = [],
29
29
  placeholder = "",
30
- required = false,
30
+ required,
31
31
  value = $bindable(),
32
32
  variant = "default",
33
33
  ...rest
34
34
  } = $props();
35
35
 
36
- let store = getContext("form-field-store");
36
+ let store = getContext("form-field-store") ?? null;
37
37
 
38
38
  let localValues = $derived.by(() => {
39
- if (store) {
40
- return {
41
- ...store(),
42
- };
43
- }
39
+ const storeValues = typeof store === "function" ? store() : {};
44
40
 
45
41
  return {
46
- disabled,
47
- error,
48
- id,
49
- required,
42
+ disabled: disabled ?? storeValues.disabled ?? false,
43
+ error: error ?? storeValues.error ?? false,
44
+ id: id ?? storeValues.id ?? "",
45
+ required: required ?? storeValues.required ?? false,
50
46
  };
51
47
  });
52
48
 
@@ -6,10 +6,11 @@
6
6
  * @typedef {Object} Props
7
7
  * @property {boolean} [checked=false] Wether this switch is checked or not, bound to the component
8
8
  * @property {string} [class=""] Additional CSS classes to apply to the component
9
- * @property {boolean} [disabled=false] Whether the switch is disabled
10
- * @property {string} [id=""] The ID of the switch element
9
+ * @property {boolean} [disabled] Whether the switch is disabled
10
+ * @property {boolean} [error] Whether the switch has an error state
11
+ * @property {string} [id] The ID of the switch element
11
12
  * @property {string} [name] The name of the switch, used for form submission
12
- * @property {boolean} [required=false] Whether the switch is required
13
+ * @property {boolean} [required] Whether the switch is required
13
14
  * @property {string} [value=""] The value of the switch
14
15
  */
15
16
 
@@ -17,27 +18,25 @@
17
18
  let {
18
19
  checked = $bindable(),
19
20
  class: className = "",
20
- disabled = false,
21
- id = "",
21
+ disabled,
22
+ error,
23
+ id,
22
24
  name,
23
- required = false,
25
+ required,
24
26
  value = "",
25
27
  ...rest
26
28
  } = $props();
27
29
 
28
- let store = getContext("form-field-store");
30
+ let store = getContext("form-field-store") ?? null;
29
31
 
30
32
  let localValues = $derived.by(() => {
31
- if (store) {
32
- return {
33
- ...store(),
34
- };
35
- }
33
+ const storeValues = typeof store === "function" ? store() : {};
36
34
 
37
35
  return {
38
- disabled,
39
- id,
40
- required,
36
+ disabled: disabled ?? storeValues.disabled ?? false,
37
+ error: error ?? storeValues.error ?? false,
38
+ id: id ?? storeValues.id ?? "",
39
+ required: required ?? storeValues.required ?? false,
41
40
  };
42
41
  });
43
42
  </script>
@@ -48,6 +47,7 @@
48
47
  checked,
49
48
  class: className,
50
49
  disabled: localValues.disabled,
50
+ error: localValues.error,
51
51
  })}
52
52
  disabled={localValues.disabled}
53
53
  id={localValues.id}
@@ -16,6 +16,10 @@ declare const Switch: import("svelte").Component<{
16
16
  * Whether the switch is disabled
17
17
  */
18
18
  disabled?: boolean;
19
+ /**
20
+ * Whether the switch has an error state
21
+ */
22
+ error?: boolean;
19
23
  /**
20
24
  * The ID of the switch element
21
25
  */
@@ -46,6 +50,10 @@ type Props = {
46
50
  * Whether the switch is disabled
47
51
  */
48
52
  disabled?: boolean;
53
+ /**
54
+ * Whether the switch has an error state
55
+ */
56
+ error?: boolean;
49
57
  /**
50
58
  * The ID of the switch element
51
59
  */
@@ -5,6 +5,9 @@ export const switchVariants: import("tailwind-variants").TVReturnType<{
5
5
  disabled: {
6
6
  true: string;
7
7
  };
8
+ error: {
9
+ true: string;
10
+ };
8
11
  }, undefined, "relative h-4 w-7 cursor-pointer appearance-none rounded-full border-0 bg-neutral-300 ring-inherit ring-offset-transparent outline-transparent transition-[outline] after:absolute after:top-0 after:left-0 after:m-0.25 after:h-3.5 after:w-3.5 after:translate-x-0 after:rounded-full after:bg-neutral-200 after:shadow-toggle after:transition-transform after:duration-300 checked:bg-none focus:outline-1 focus:outline-offset-1 focus:outline-blue-500 dark:bg-neutral-300 dark:after:bg-neutral-300 dark:focus:outline-blue-300", {
9
12
  checked: {
10
13
  true: string;
@@ -12,6 +15,9 @@ export const switchVariants: import("tailwind-variants").TVReturnType<{
12
15
  disabled: {
13
16
  true: string;
14
17
  };
18
+ error: {
19
+ true: string;
20
+ };
15
21
  }, undefined, import("tailwind-variants").TVReturnType<{
16
22
  checked: {
17
23
  true: string;
@@ -19,4 +25,7 @@ export const switchVariants: import("tailwind-variants").TVReturnType<{
19
25
  disabled: {
20
26
  true: string;
21
27
  };
28
+ error: {
29
+ true: string;
30
+ };
22
31
  }, undefined, "relative h-4 w-7 cursor-pointer appearance-none rounded-full border-0 bg-neutral-300 ring-inherit ring-offset-transparent outline-transparent transition-[outline] after:absolute after:top-0 after:left-0 after:m-0.25 after:h-3.5 after:w-3.5 after:translate-x-0 after:rounded-full after:bg-neutral-200 after:shadow-toggle after:transition-transform after:duration-300 checked:bg-none focus:outline-1 focus:outline-offset-1 focus:outline-blue-500 dark:bg-neutral-300 dark:after:bg-neutral-300 dark:focus:outline-blue-300", unknown, unknown, undefined>>;
@@ -9,6 +9,9 @@ const switchVariants = tv({
9
9
  disabled: {
10
10
  true: "cursor-not-allowed bg-neutral-300",
11
11
  },
12
+ error: {
13
+ true: "border-current text-red-500 ring ring-current dark:border-current dark:text-red-500",
14
+ },
12
15
  },
13
16
  });
14
17
 
@@ -5,13 +5,13 @@
5
5
  /**
6
6
  * @typedef {Object} Props
7
7
  * @property {string} [class=""] Additional CSS classes to apply to the component
8
- * @property {boolean} [disabled=false] Whether the textarea is disabled
9
- * @property {boolean} [error=false] Whether the textarea has an error state
10
- * @property {string} [id=""] The ID of the textarea element
8
+ * @property {boolean} [disabled] Whether the textarea is disabled
9
+ * @property {boolean} [error] Whether the textarea has an error state
10
+ * @property {string} [id] The ID of the textarea element
11
11
  * @property {string} [name] The name of the textarea, used for form submission
12
12
  * @property {string} [placeholder=""] Placeholder text for the textarea
13
13
  * @property {boolean} [readonly=false] Whether the textarea is read-only
14
- * @property {boolean} [required=false] Whether the textarea is required
14
+ * @property {boolean} [required] Whether the textarea is required
15
15
  * @property {"small" | "medium" | "large"} [size="medium"] Textarea size
16
16
  * @property {string} [value=""] The value of the textarea, bound to the component
17
17
  */
@@ -19,32 +19,28 @@
19
19
  /** @type {Props} */
20
20
  let {
21
21
  class: className = "",
22
- disabled = false,
23
- error = false,
24
- id = "",
22
+ disabled,
23
+ error,
24
+ id,
25
25
  name,
26
26
  placeholder = "",
27
27
  readonly = false,
28
- required = false,
28
+ required,
29
29
  size = "medium",
30
30
  value = $bindable(),
31
31
  ...rest
32
32
  } = $props();
33
33
 
34
- let store = getContext("form-field-store");
34
+ let store = getContext("form-field-store") ?? null;
35
35
 
36
36
  let localValues = $derived.by(() => {
37
- if (store) {
38
- return {
39
- ...store(),
40
- };
41
- }
37
+ const storeValues = typeof store === "function" ? store() : {};
42
38
 
43
39
  return {
44
- disabled,
45
- error,
46
- id,
47
- required,
40
+ disabled: disabled ?? storeValues.disabled ?? false,
41
+ error: error ?? storeValues.error ?? false,
42
+ id: id ?? storeValues.id ?? "",
43
+ required: required ?? storeValues.required ?? false,
48
44
  };
49
45
  });
50
46
  </script>
@@ -8,11 +8,13 @@
8
8
  * @typedef {Object} Props
9
9
  * @property {boolean} [autofocus=false] Whether the input should be autofocused on mount
10
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
11
+ * @property {boolean} [disabled] Whether the component is disabled
12
+ * @property {boolean} [error] Whether the component has an error state
13
+ * @property {string} [id] The ID of the input element
13
14
  * @property {string} [name] The name of the input, used for form submission
14
15
  * @property {Array<{id: string | number, label: string}>} [options=[]] The available tag options
15
16
  * @property {string} [placeholder=""] The placeholder text for the input
17
+ * @property {boolean} [required] Whether the component is required
16
18
  * @property {Array<string | number>} [value=[]] The currently selected tags, bound to the component
17
19
  */
18
20
 
@@ -20,20 +22,28 @@
20
22
  let {
21
23
  autofocus = false,
22
24
  class: className = "",
23
- disabled = false,
24
- id = "",
25
+ disabled,
26
+ error,
27
+ id,
25
28
  name,
26
29
  options = [],
27
30
  placeholder = "",
31
+ required,
28
32
  value = $bindable(""),
29
33
  ...rest
30
34
  } = $props();
31
35
 
32
- let store = getContext("form-field-store");
36
+ let store = getContext("form-field-store") ?? null;
33
37
 
34
38
  let localValues = $derived.by(() => {
35
- if (store) return { ...store() };
36
- return { disabled, id };
39
+ const storeValues = typeof store === "function" ? store() : {};
40
+
41
+ return {
42
+ disabled: disabled ?? storeValues.disabled ?? false,
43
+ error: error ?? storeValues.error ?? false,
44
+ id: id ?? storeValues.id ?? "",
45
+ required: required ?? storeValues.required ?? false,
46
+ };
37
47
  });
38
48
 
39
49
  let open = $state(false);
@@ -160,7 +170,9 @@
160
170
  }
161
171
  };
162
172
 
163
- let styles = $derived(comboBoxVariants({ disabled: localValues.disabled }));
173
+ let styles = $derived(
174
+ comboBoxVariants({ disabled: localValues.disabled, error: localValues.error }),
175
+ );
164
176
  </script>
165
177
 
166
178
  <div
@@ -16,6 +16,10 @@ declare const ComboBox: import("svelte").Component<{
16
16
  * Whether the component is disabled
17
17
  */
18
18
  disabled?: boolean;
19
+ /**
20
+ * Whether the component has an error state
21
+ */
22
+ error?: boolean;
19
23
  /**
20
24
  * The ID of the input element
21
25
  */
@@ -35,6 +39,10 @@ declare const ComboBox: import("svelte").Component<{
35
39
  * The placeholder text for the input
36
40
  */
37
41
  placeholder?: string;
42
+ /**
43
+ * Whether the component is required
44
+ */
45
+ required?: boolean;
38
46
  /**
39
47
  * The currently selected tags, bound to the component
40
48
  */
@@ -53,6 +61,10 @@ type Props = {
53
61
  * Whether the component is disabled
54
62
  */
55
63
  disabled?: boolean;
64
+ /**
65
+ * Whether the component has an error state
66
+ */
67
+ error?: boolean;
56
68
  /**
57
69
  * The ID of the input element
58
70
  */
@@ -72,6 +84,10 @@ type Props = {
72
84
  * The placeholder text for the input
73
85
  */
74
86
  placeholder?: string;
87
+ /**
88
+ * Whether the component is required
89
+ */
90
+ required?: boolean;
75
91
  /**
76
92
  * The currently selected tags, bound to the component
77
93
  */
@@ -29,6 +29,7 @@
29
29
  bind:value
30
30
  autocomplete="off"
31
31
  class={styles.searchInput()}
32
+ id={localValues.id}
32
33
  {name}
33
34
  onfocus={handleOpenDropdown}
34
35
  onbeforeinput={handleOpenDropdown}
@@ -4,6 +4,11 @@ export const comboBoxVariants: import("tailwind-variants").TVReturnType<{
4
4
  value: string;
5
5
  };
6
6
  };
7
+ error: {
8
+ true: {
9
+ searchInput: string;
10
+ };
11
+ };
7
12
  dropdownPosition: {
8
13
  bottom: {
9
14
  dropdown: string;
@@ -8,7 +8,7 @@ const comboBoxVariants = tv({
8
8
  searchInput:
9
9
  "h-7.5 w-full appearance-none border-0 bg-transparent py-0 body-small placeholder-neutral-500 focus:ring-0",
10
10
  dropdown:
11
- "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",
11
+ "absolute z-1 w-full max-w-100 overflow-y-auto bg-white p-1 pr-5 shadow-sm dark:border-neutral-700 dark:bg-neutral-800",
12
12
  dropdownCheckmark: "ml-auto shrink-0",
13
13
  dropdownItem: [
14
14
  "flex w-full grow items-center gap-2 rounded-sm p-2 ui-select-label",
@@ -24,6 +24,12 @@ const comboBoxVariants = tv({
24
24
  value: "pointer-events-none",
25
25
  },
26
26
  },
27
+ error: {
28
+ true: {
29
+ searchInput:
30
+ "border-current text-red-500 ring ring-current dark:border-current dark:text-red-500",
31
+ },
32
+ },
27
33
  dropdownPosition: {
28
34
  bottom: {
29
35
  dropdown: "top-full mt-1",
@@ -35,7 +35,15 @@
35
35
  ...rest
36
36
  } = $props();
37
37
 
38
- let inputProps = $derived({ disabled, id, name, required, value });
38
+ let inputProps = $derived({
39
+ disabled,
40
+ id,
41
+ name,
42
+ required,
43
+ value,
44
+ // prevent input click from colliding with card clicks
45
+ onclick: (e) => e.stopPropagation(),
46
+ });
39
47
  let styles = $derived(selectorCardVariants({ checked, disabled, error, type }));
40
48
 
41
49
  let localHelperText = $derived.by(() => {
@@ -47,17 +55,15 @@
47
55
  });
48
56
 
49
57
  let handleClick = () => {
50
- if (disabled) return;
51
58
  if (type === "radio" && checked) return;
52
-
53
59
  checked = !checked;
54
60
  };
55
61
  </script>
56
62
 
57
63
  <div
58
- aria-disabled={disabled}
59
64
  class={styles.base({ class: className })}
60
65
  onclick={handleClick}
66
+ inert={disabled}
61
67
  {...rest}>
62
68
  {#if type === "radio"}
63
69
  <Radio bind:checked class={styles.input()} {...inputProps} />
@@ -10,7 +10,7 @@ const tagSelectorVariants = tv({
10
10
  searchInput:
11
11
  "absolute inset-0 appearance-none border-0 bg-transparent pr-1 pl-8 ui-tag-badge placeholder-current focus:ring-0",
12
12
  dropdown:
13
- "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",
13
+ "absolute z-1 w-full max-w-100 overflow-y-auto bg-white p-1 pr-5 shadow-sm dark:border-neutral-700 dark:bg-neutral-800",
14
14
  dropdownCheckmark: "ml-auto shrink-0",
15
15
  dropdownItem: [
16
16
  "flex w-full grow items-center gap-2 rounded-sm p-2 ui-select-label",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@websline/system-components",
3
- "version": "1.2.9",
3
+ "version": "1.3.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -26,14 +26,14 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@tiptap/core": "^3.15.3",
30
- "@tiptap/extension-color": "^3.15.3",
31
- "@tiptap/extension-highlight": "^3.15.3",
32
- "@tiptap/extension-placeholder": "^3.15.3",
33
- "@tiptap/extension-text-align": "^3.15.3",
34
- "@tiptap/extension-text-style": "^3.15.3",
35
- "@tiptap/pm": "^3.15.3",
36
- "@tiptap/starter-kit": "^3.15.3",
29
+ "@tiptap/core": "^3.17.1",
30
+ "@tiptap/extension-color": "^3.17.1",
31
+ "@tiptap/extension-highlight": "^3.17.1",
32
+ "@tiptap/extension-placeholder": "^3.17.1",
33
+ "@tiptap/extension-text-align": "^3.17.1",
34
+ "@tiptap/extension-text-style": "^3.17.1",
35
+ "@tiptap/pm": "^3.17.1",
36
+ "@tiptap/starter-kit": "^3.17.1",
37
37
  "bits-ui": "^2.15.4",
38
38
  "dompurify": "^3.3.1",
39
39
  "tailwind-variants": "^3.2.2",
@@ -43,39 +43,39 @@
43
43
  "svelte": "^5.38.7"
44
44
  },
45
45
  "devDependencies": {
46
- "@eslint/compat": "^2.0.0",
46
+ "@eslint/compat": "^2.0.1",
47
47
  "@eslint/js": "^9.39.2",
48
- "@storybook/addon-a11y": "^10.1.11",
49
- "@storybook/addon-docs": "^10.1.11",
48
+ "@storybook/addon-a11y": "^10.2.0",
49
+ "@storybook/addon-docs": "^10.2.0",
50
50
  "@storybook/addon-svelte-csf": "^5.0.10",
51
- "@storybook/sveltekit": "^10.1.11",
51
+ "@storybook/sveltekit": "^10.2.0",
52
52
  "@sveltejs/adapter-auto": "^7.0.0",
53
- "@sveltejs/kit": "^2.49.4",
53
+ "@sveltejs/kit": "^2.50.1",
54
54
  "@sveltejs/package": "^2.5.7",
55
- "@sveltejs/vite-plugin-svelte": "^6.2.3",
55
+ "@sveltejs/vite-plugin-svelte": "^6.2.4",
56
56
  "@tailwindcss/forms": "^0.5.11",
57
57
  "@tailwindcss/typography": "^0.5.19",
58
58
  "@tailwindcss/vite": "^4.1.18",
59
- "@types/node": "^25.0.3",
60
- "@vitest/browser": "^4.0.16",
59
+ "@types/node": "^25.0.10",
60
+ "@vitest/browser": "^4.0.18",
61
61
  "eslint": "^9.39.2",
62
62
  "eslint-config-prettier": "^10.1.8",
63
- "eslint-plugin-storybook": "^10.1.11",
63
+ "eslint-plugin-storybook": "^10.2.0",
64
64
  "eslint-plugin-svelte": "^3.14.0",
65
- "globals": "^17.0.0",
66
- "playwright": "^1.57.0",
65
+ "globals": "^17.1.0",
66
+ "playwright": "^1.58.0",
67
67
  "postcss-url": "^10.1.3",
68
- "prettier": "^3.7.4",
68
+ "prettier": "^3.8.1",
69
69
  "prettier-plugin-svelte": "^3.4.1",
70
70
  "prettier-plugin-tailwindcss": "^0.7.2",
71
- "publint": "^0.3.16",
72
- "storybook": "^10.1.11",
73
- "svelte": "^5.46.1",
71
+ "publint": "^0.3.17",
72
+ "storybook": "^10.2.0",
73
+ "svelte": "^5.48.3",
74
74
  "tailwindcss": "^4.1.18",
75
75
  "typescript": "^5.9.3",
76
76
  "vite": "^7.3.1",
77
- "vitest": "^4.0.16",
78
- "vitest-browser-svelte": "^2.0.1"
77
+ "vitest": "^4.0.18",
78
+ "vitest-browser-svelte": "^2.0.2"
79
79
  },
80
80
  "keywords": [
81
81
  "svelte"