@sveltia/ui 0.26.9 → 0.26.11

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.
@@ -24,6 +24,7 @@
24
24
  role = 'button',
25
25
  name = undefined,
26
26
  value = undefined,
27
+ valueType = typeof value,
27
28
  hidden = false,
28
29
  disabled = false,
29
30
  readonly = false,
@@ -64,6 +65,10 @@
64
65
  aria-disabled={disabled}
65
66
  aria-readonly={readonly}
66
67
  aria-pressed={pressed}
68
+ data-type={valueType}
69
+ data-name={name}
70
+ data-label={label}
71
+ data-value={value}
67
72
  use:activateKeyShortcuts={keyShortcuts}
68
73
  >
69
74
  {@render startIcon?.()}
@@ -57,8 +57,6 @@
57
57
  {value}
58
58
  {hidden}
59
59
  {disabled}
60
- data-type={typeof value}
61
- data-label={label}
62
60
  data-search-value={searchValue}
63
61
  onChange={(event) => {
64
62
  selected = event.detail.selected;
@@ -20,8 +20,10 @@
20
20
  * attribute.
21
21
  * @property {boolean} [checked] Whether to check the widget. An alias of the `aria-checked`
22
22
  * attribute.
23
- * @property {string} [name] The `name` attribute on the `<button>` element.
24
- * @property {string} [value] The `value` attribute on the `<button>` element.
23
+ * @property {string} [name] The `data-name` attribute on the `<button>` element.
24
+ * @property {any} [value] The `data-value` attribute on the `<button>` element.
25
+ * @property {string} [valueType] Data type of the `value`. Typically `string`, `number` or
26
+ * `boolean`. Default: auto detect.
25
27
  * @property {string} [label] Text label displayed next to the checkbox.
26
28
  * @property {Snippet} [children] Primary slot content.
27
29
  * @property {Snippet} [default] Default slot content.
@@ -40,6 +42,7 @@
40
42
  disabled = false,
41
43
  name = undefined,
42
44
  value = undefined,
45
+ valueType = undefined,
43
46
  label = undefined,
44
47
  children,
45
48
  onChange,
@@ -77,6 +80,7 @@
77
80
  {disabled}
78
81
  {name}
79
82
  {value}
83
+ {valueType}
80
84
  aria-checked={checked}
81
85
  aria-labelledby="{id}-label"
82
86
  onclick={(event) => {
@@ -29,13 +29,18 @@ declare const Radio: import("svelte").Component<{
29
29
  */
30
30
  checked?: boolean | undefined;
31
31
  /**
32
- * The `name` attribute on the `<button>` element.
32
+ * The `data-name` attribute on the `<button>` element.
33
33
  */
34
34
  name?: string | undefined;
35
35
  /**
36
- * The `value` attribute on the `<button>` element.
36
+ * The `data-value` attribute on the `<button>` element.
37
37
  */
38
- value?: string | undefined;
38
+ value?: any;
39
+ /**
40
+ * Data type of the `value`. Typically `string`, `number` or
41
+ * `boolean`. Default: auto detect.
42
+ */
43
+ valueType?: string | undefined;
39
44
  /**
40
45
  * Text label displayed next to the checkbox.
41
46
  */
@@ -77,13 +82,18 @@ type Props = {
77
82
  */
78
83
  checked?: boolean | undefined;
79
84
  /**
80
- * The `name` attribute on the `<button>` element.
85
+ * The `data-name` attribute on the `<button>` element.
81
86
  */
82
87
  name?: string | undefined;
83
88
  /**
84
- * The `value` attribute on the `<button>` element.
89
+ * The `data-value` attribute on the `<button>` element.
90
+ */
91
+ value?: any;
92
+ /**
93
+ * Data type of the `value`. Typically `string`, `number` or
94
+ * `boolean`. Default: auto detect.
85
95
  */
86
- value?: string | undefined;
96
+ valueType?: string | undefined;
87
97
  /**
88
98
  * Text label displayed next to the checkbox.
89
99
  */
@@ -7,6 +7,7 @@
7
7
  -->
8
8
  <script>
9
9
  import { _ } from 'svelte-i18n';
10
+ import { getSelectedItemDetail } from '../../services/select.svelte';
10
11
  import Button from '../button/button.svelte';
11
12
  import Icon from '../icon/icon.svelte';
12
13
  import Listbox from '../listbox/listbox.svelte';
@@ -69,11 +70,11 @@
69
70
  const selected = popupContent?.querySelector(selectedSelector);
70
71
 
71
72
  const target = /** @type {HTMLButtonElement} */ (
72
- popupContent?.querySelector(`[role="option"][value="${value}"]`)
73
+ popupContent?.querySelector(`[role="option"][data-value="${value}"]`)
73
74
  );
74
75
 
75
76
  if (target) {
76
- label = target.dataset.label || target.textContent || target.value;
77
+ label = target.dataset.label || target.dataset.value || target.textContent || '';
77
78
 
78
79
  if (selected !== target) {
79
80
  selected?.setAttribute('aria-selected', 'false');
@@ -87,19 +88,12 @@
87
88
  * @param {HTMLButtonElement} target Selected option.
88
89
  */
89
90
  const _onSelect = (target) => {
90
- // @todo support more types
91
- // @ts-ignore
92
- value = target.dataset.type === 'number' ? Number(target.value) : target.value;
91
+ const detail = getSelectedItemDetail(target);
92
+
93
+ value = detail.value;
94
+
93
95
  _onChange();
94
- onChange?.(
95
- new CustomEvent('Change', {
96
- detail: {
97
- target: inputElement,
98
- name: target.name,
99
- value,
100
- },
101
- }),
102
- );
96
+ onChange?.(new CustomEvent('Change', { detail }));
103
97
  };
104
98
 
105
99
  $effect(() => {
@@ -150,7 +144,7 @@
150
144
  bind:element={inputElement}
151
145
  role="combobox"
152
146
  {id}
153
- {value}
147
+ value={value === undefined ? '' : String(value)}
154
148
  {hidden}
155
149
  {disabled}
156
150
  {readonly}
@@ -11,7 +11,7 @@
11
11
 
12
12
  /**
13
13
  * @typedef {object} Props
14
- * @property {{ label: string, value: string, searchValue?: string }[]} options Available options.
14
+ * @property {{ label: string, value: any, searchValue?: string }[]} options Available options.
15
15
  * @property {string[]} [values] Selected option values.
16
16
  * @property {number} [max] Maximum number of selectable options.
17
17
  * @property {string} [class] The `class` attribute on the wrapper element.
@@ -9,7 +9,7 @@ declare const SelectTags: import("svelte").Component<{
9
9
  */
10
10
  options: {
11
11
  label: string;
12
- value: string;
12
+ value: any;
13
13
  searchValue?: string;
14
14
  }[];
15
15
  /**
@@ -67,7 +67,7 @@ type Props = {
67
67
  */
68
68
  options: {
69
69
  label: string;
70
- value: string;
70
+ value: any;
71
71
  searchValue?: string;
72
72
  }[];
73
73
  /**
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { generateElementId } from '@sveltia/utils/element';
6
6
  import { sleep } from '@sveltia/utils/misc';
7
+ import { getSelectedItemDetail } from './select.svelte';
7
8
 
8
9
  /**
9
10
  * @type {{ [role: string]: {
@@ -328,12 +329,7 @@ class Group {
328
329
  });
329
330
 
330
331
  this.parent.dispatchEvent(
331
- new CustomEvent('Change', {
332
- detail: {
333
- value: /** @type {any} */ (newTarget).value,
334
- name: /** @type {any} */ (newTarget).name,
335
- },
336
- }),
332
+ new CustomEvent('Change', { detail: getSelectedItemDetail(newTarget) }),
337
333
  );
338
334
  }
339
335
 
@@ -0,0 +1,2 @@
1
+ export function getSelectedItemDetail(target: HTMLElement): SelectedItemDetail;
2
+ import type { SelectedItemDetail } from '../typedefs';
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @import { SelectedItemDetail } from '../typedefs';
3
+ */
4
+
5
+ /**
6
+ * Get the detail of the selected element.
7
+ * @param {HTMLElement} target Element to get the detail from.
8
+ * @returns {SelectedItemDetail} Detail of the selected element.
9
+ */
10
+ export const getSelectedItemDetail = (target) => {
11
+ const { type = 'string', name, label } = target.dataset;
12
+ /** @type {any} */
13
+ let { value } = target.dataset;
14
+
15
+ if (type === 'number') {
16
+ value = Number(value);
17
+
18
+ if (Number.isNaN(value)) {
19
+ value = null;
20
+ }
21
+ } else if (type === 'boolean') {
22
+ value = value === 'true';
23
+ } else if (type === 'string') {
24
+ value = value ? String(value) : '';
25
+ }
26
+
27
+ return { target, type, name, label, value };
28
+ };
@@ -16,13 +16,18 @@ export type ButtonProps = {
16
16
  */
17
17
  role?: string | undefined;
18
18
  /**
19
- * The `name` attribute on the `<button>` element.
19
+ * The `data-name` attribute on the `<button>` element.
20
20
  */
21
21
  name?: string | undefined;
22
22
  /**
23
- * The `value` attribute on the `<button>` element.
23
+ * The `data-value` attribute on the `<button>` element.
24
24
  */
25
- value?: string | undefined;
25
+ value?: any;
26
+ /**
27
+ * Data type of the `value`. Typically `string`, `number` or
28
+ * `boolean`. Default: auto detect.
29
+ */
30
+ valueType?: string | undefined;
26
31
  /**
27
32
  * Whether to hide the widget. An alias of the `aria-hidden` attribute.
28
33
  */
@@ -366,7 +371,7 @@ export type ComboboxProps = {
366
371
  /**
367
372
  * Selected option’s value.
368
373
  */
369
- value?: string | undefined;
374
+ value?: any;
370
375
  /**
371
376
  * Whether to make the `combobox` editable.
372
377
  */
@@ -677,6 +682,28 @@ export type TextEditorStore = {
677
682
  */
678
683
  convertMarkdown: () => Promise<void>;
679
684
  };
685
+ export type SelectedItemDetail = {
686
+ /**
687
+ * Element to get the detail from.
688
+ */
689
+ target: HTMLElement;
690
+ /**
691
+ * Data type of the `value`. Typically `string`, `number` or `boolean`.
692
+ */
693
+ type: string;
694
+ /**
695
+ * The `data-name` attribute on the element.
696
+ */
697
+ name: string | undefined;
698
+ /**
699
+ * The `data-label` attribute on the element.
700
+ */
701
+ label: string | undefined;
702
+ /**
703
+ * The `data-value` attribute on the element. Casted to the `valueType`.
704
+ */
705
+ value: any;
706
+ };
680
707
  import type { Snippet } from 'svelte';
681
708
  import type { LexicalNode } from 'lexical';
682
709
  import type { Transformer } from '@lexical/markdown';
package/dist/typedefs.js CHANGED
@@ -10,8 +10,10 @@
10
10
  * @property {string} [class] The `class` attribute on the `<button>` element.
11
11
  * @property {'button' | 'submit' | 'reset'} [type] The `type` attribute on the `<button>` element.
12
12
  * @property {string} [role] The `role` attribute on the `<button>` element.
13
- * @property {string} [name] The `name` attribute on the `<button>` element.
14
- * @property {string} [value] The `value` attribute on the `<button>` element.
13
+ * @property {string} [name] The `data-name` attribute on the `<button>` element.
14
+ * @property {any} [value] The `data-value` attribute on the `<button>` element.
15
+ * @property {string} [valueType] Data type of the `value`. Typically `string`, `number` or
16
+ * `boolean`. Default: auto detect.
15
17
  * @property {boolean} [hidden] Whether to hide the widget. An alias of the `aria-hidden` attribute.
16
18
  * @property {boolean} [disabled] Whether to disable the widget. An alias of the `aria-disabled`
17
19
  * attribute.
@@ -126,7 +128,7 @@
126
128
  * `aria-required` attribute.
127
129
  * @property {boolean} [invalid] Whether to mark the widget invalid. An alias of the `aria-invalid`
128
130
  * attribute.
129
- * @property {string} [value] Selected option’s value.
131
+ * @property {any} [value] Selected option’s value.
130
132
  * @property {boolean} [editable] Whether to make the `combobox` editable.
131
133
  * @property {PopupPosition} [position] Where to show the dropdown menu.
132
134
  * @property {number} [filterThreshold] Number of items to start showing the filter. Default: `5`.
@@ -283,4 +285,13 @@
283
285
  * @property {() => Promise<void>} convertMarkdown Function to trigger the Lexical converter.
284
286
  */
285
287
 
288
+ /**
289
+ * @typedef {object} SelectedItemDetail
290
+ * @property {HTMLElement} target Element to get the detail from.
291
+ * @property {string} type Data type of the `value`. Typically `string`, `number` or `boolean`.
292
+ * @property {string | undefined} name The `data-name` attribute on the element.
293
+ * @property {string | undefined} label The `data-label` attribute on the element.
294
+ * @property {any} value The `data-value` attribute on the element. Casted to the `valueType`.
295
+ */
296
+
286
297
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltia/ui",
3
- "version": "0.26.9",
3
+ "version": "0.26.11",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -28,51 +28,51 @@
28
28
  "test:unit": "vitest"
29
29
  },
30
30
  "dependencies": {
31
- "@lexical/code": "^0.31.2",
32
- "@lexical/dragon": "^0.31.2",
33
- "@lexical/history": "^0.31.2",
34
- "@lexical/link": "^0.31.2",
35
- "@lexical/list": "^0.31.2",
36
- "@lexical/markdown": "^0.31.2",
37
- "@lexical/rich-text": "^0.31.2",
38
- "@lexical/selection": "^0.31.2",
39
- "@lexical/table": "^0.31.2",
40
- "@lexical/utils": "^0.31.2",
41
- "@sveltia/utils": "^0.7.5",
42
- "lexical": "^0.31.2",
31
+ "@lexical/code": "^0.32.1",
32
+ "@lexical/dragon": "^0.32.1",
33
+ "@lexical/history": "^0.32.1",
34
+ "@lexical/link": "^0.32.1",
35
+ "@lexical/list": "^0.32.1",
36
+ "@lexical/markdown": "^0.32.1",
37
+ "@lexical/rich-text": "^0.32.1",
38
+ "@lexical/selection": "^0.32.1",
39
+ "@lexical/table": "^0.32.1",
40
+ "@lexical/utils": "^0.32.1",
41
+ "@sveltia/utils": "^0.8.0",
42
+ "lexical": "^0.32.1",
43
43
  "prismjs": "^1.30.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "svelte": "^5.0.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@playwright/test": "^1.52.0",
49
+ "@playwright/test": "^1.53.0",
50
50
  "@sveltejs/adapter-auto": "^6.0.1",
51
- "@sveltejs/kit": "^2.21.1",
51
+ "@sveltejs/kit": "^2.21.5",
52
52
  "@sveltejs/package": "^2.3.11",
53
- "@sveltejs/vite-plugin-svelte": "5.0.3",
54
- "cspell": "^9.0.2",
53
+ "@sveltejs/vite-plugin-svelte": "5.1.0",
54
+ "cspell": "^9.1.1",
55
55
  "eslint": "^8.57.1",
56
56
  "eslint-config-airbnb-base": "^15.0.0",
57
57
  "eslint-config-prettier": "^10.1.5",
58
58
  "eslint-plugin-import": "^2.31.0",
59
- "eslint-plugin-jsdoc": "^50.6.17",
59
+ "eslint-plugin-jsdoc": "^51.0.1",
60
60
  "eslint-plugin-svelte": "^2.46.1",
61
- "postcss": "^8.5.3",
61
+ "postcss": "^8.5.5",
62
62
  "postcss-html": "^1.8.0",
63
63
  "prettier": "^3.5.3",
64
64
  "prettier-plugin-svelte": "^3.4.0",
65
- "sass": "^1.89.0",
66
- "stylelint": "^16.19.1",
65
+ "sass": "^1.89.2",
66
+ "stylelint": "^16.20.0",
67
67
  "stylelint-config-recommended-scss": "^15.0.1",
68
- "stylelint-scss": "^6.12.0",
69
- "svelte": "5.32.1",
68
+ "stylelint-scss": "^6.12.1",
69
+ "svelte": "5.34.3",
70
70
  "svelte-check": "^4.2.1",
71
71
  "svelte-i18n": "^4.0.1",
72
72
  "svelte-preprocess": "^6.0.3",
73
73
  "tslib": "^2.8.1",
74
74
  "vite": "^6.3.5",
75
- "vitest": "^3.1.4"
75
+ "vitest": "^3.2.3"
76
76
  },
77
77
  "exports": {
78
78
  ".": {