@sveltia/ui 0.75.3 → 0.75.4

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.
@@ -6,6 +6,7 @@
6
6
  -->
7
7
  <script>
8
8
  import { activateKeyShortcuts } from '@sveltia/utils/events';
9
+ import { getValueType } from '../../services/value.js';
9
10
  import TruncatedText from '../typography/truncated-text.svelte';
10
11
  import Popup from '../util/popup.svelte';
11
12
 
@@ -25,7 +26,7 @@
25
26
  name = undefined,
26
27
  value = undefined,
27
28
  // svelte-ignore state_referenced_locally
28
- valueType = typeof value,
29
+ valueType = getValueType(value),
29
30
  hidden = false,
30
31
  disabled = false,
31
32
  readonly = false,
@@ -7,6 +7,7 @@
7
7
  <script>
8
8
  import { onDestroy } from 'svelte';
9
9
  import { getOptionRegistry } from '../../services/select.svelte.js';
10
+ import { getValueType } from '../../services/value.js';
10
11
  import Button from '../button/button.svelte';
11
12
  import Icon from '../icon/icon.svelte';
12
13
 
@@ -92,7 +93,7 @@
92
93
  * @returns {string} Type.
93
94
  */
94
95
  get type() {
95
- return restProps.valueType ?? typeof value;
96
+ return restProps.valueType ?? getValueType(value);
96
97
  },
97
98
  /**
98
99
  * Get whether the option is selected.
@@ -22,8 +22,8 @@
22
22
  * attribute.
23
23
  * @property {string} [name] The `data-name` attribute on the `<button>` element.
24
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
+ * @property {string} [valueType] Data type of the `value`. Typically `string`, `number`,
26
+ * `boolean` or `null`. Default: auto detect.
27
27
  * @property {string} [label] Text label displayed next to the radio button.
28
28
  * @property {string} [ariaLabel] `aria-label` attribute on the `<button>` element, for a radio
29
29
  * button without a visible label.
@@ -37,8 +37,8 @@ declare const Radio: import("svelte").Component<{
37
37
  */
38
38
  value?: any;
39
39
  /**
40
- * Data type of the `value`. Typically `string`, `number` or
41
- * `boolean`. Default: auto detect.
40
+ * Data type of the `value`. Typically `string`, `number`,
41
+ * `boolean` or `null`. Default: auto detect.
42
42
  */
43
43
  valueType?: string | undefined;
44
44
  /**
@@ -101,8 +101,8 @@ type Props = {
101
101
  */
102
102
  value?: any;
103
103
  /**
104
- * Data type of the `value`. Typically `string`, `number` or
105
- * `boolean`. Default: auto detect.
104
+ * Data type of the `value`. Typically `string`, `number`,
105
+ * `boolean` or `null`. Default: auto detect.
106
106
  */
107
107
  valueType?: string | undefined;
108
108
  /**
@@ -250,9 +250,10 @@
250
250
  {required}
251
251
  {invalid}
252
252
  onChange={() => {
253
- // The select only reports a change once an option has been picked
253
+ // The select only reports a change once an option has been picked. Check for `undefined`
254
+ // rather than a falsy value, as `null`, `false`, `0` and an empty string are valid values
254
255
  /* v8 ignore else */
255
- if (selectedValue) {
256
+ if (selectedValue !== undefined) {
256
257
  values = [...values, selectedValue];
257
258
  onAddValue?.(new CustomEvent('AddValue', { detail: { value: selectedValue } }));
258
259
  // Reset the combobox
@@ -167,20 +167,18 @@
167
167
  event.preventDefault();
168
168
  event.stopPropagation();
169
169
 
170
- if (index > -1) {
171
- if (
172
- multiThumb &&
173
- wouldCrossThumbs({ valueIndex, targetPosition: positionList[index], sliderPositions })
174
- ) {
175
- return;
176
- }
170
+ if (
171
+ multiThumb &&
172
+ wouldCrossThumbs({ valueIndex, targetPosition: positionList[index], sliderPositions })
173
+ ) {
174
+ return;
175
+ }
177
176
 
178
- if (multiThumb) {
179
- /** @type {[number, number]} */ (values)[valueIndex] = valueList[index];
180
- values = [.../** @type {[number, number]} */ (values)];
181
- } else {
182
- value = valueList[index];
183
- }
177
+ if (multiThumb) {
178
+ /** @type {[number, number]} */ (values)[valueIndex] = valueList[index];
179
+ values = [.../** @type {[number, number]} */ (values)];
180
+ } else {
181
+ value = valueList[index];
184
182
  }
185
183
  };
186
184
 
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
3
3
  */
4
- export const UI_VERSION: "0.75.3";
4
+ export const UI_VERSION: "0.75.4";
@@ -3,4 +3,4 @@
3
3
  /**
4
4
  * Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
5
5
  */
6
- export const UI_VERSION = '0.75.3';
6
+ export const UI_VERSION = '0.75.4';
@@ -8,6 +8,7 @@
8
8
  <script>
9
9
  import { isRTL } from '@sveltia/i18n';
10
10
  import { getContext, setContext } from 'svelte';
11
+ import { getValueType } from '../../services/value.js';
11
12
  import Icon from '../icon/icon.svelte';
12
13
 
13
14
  /**
@@ -29,8 +30,8 @@
29
30
  * attribute. Ignored if the item has no `items` slot content.
30
31
  * @property {string} [label] Text label displayed on the item.
31
32
  * @property {any} [value] The `data-value` attribute on the item. Default: the `label`.
32
- * @property {string} [valueType] Data type of the `value`. Typically `string`, `number` or
33
- * `boolean`. Default: auto detect.
33
+ * @property {string} [valueType] Data type of the `value`. Typically `string`, `number`,
34
+ * `boolean` or `null`. Default: auto detect.
34
35
  * @property {Snippet} [children] Primary slot content, used instead of the `label`.
35
36
  * @property {Snippet} [items] Child items slot content, which makes the item a parent node.
36
37
  * @property {Snippet} [startIcon] Start icon slot content.
@@ -57,7 +58,7 @@
57
58
  // svelte-ignore state_referenced_locally
58
59
  value = label,
59
60
  // svelte-ignore state_referenced_locally
60
- valueType = typeof value,
61
+ valueType = getValueType(value),
61
62
  children,
62
63
  items,
63
64
  startIcon,
@@ -43,8 +43,8 @@ declare const TreeItem: import("svelte").Component<import("../../typedefs").Keyb
43
43
  */
44
44
  value?: any;
45
45
  /**
46
- * Data type of the `value`. Typically `string`, `number` or
47
- * `boolean`. Default: auto detect.
46
+ * Data type of the `value`. Typically `string`, `number`,
47
+ * `boolean` or `null`. Default: auto detect.
48
48
  */
49
49
  valueType?: string | undefined;
50
50
  /**
@@ -116,8 +116,8 @@ type Props = {
116
116
  */
117
117
  value?: any;
118
118
  /**
119
- * Data type of the `value`. Typically `string`, `number` or
120
- * `boolean`. Default: auto detect.
119
+ * Data type of the `value`. Typically `string`, `number`,
120
+ * `boolean` or `null`. Default: auto detect.
121
121
  */
122
122
  valueType?: string | undefined;
123
123
  /**
@@ -1,4 +1,5 @@
1
1
  import { getContext, setContext } from 'svelte';
2
+ import { castValue } from './value.js';
2
3
 
3
4
  /**
4
5
  * @import { OptionEntry, SelectedItemDetail } from '../typedefs';
@@ -115,20 +116,7 @@ export const getOptionRegistry = () => getContext(CONTEXT_KEY);
115
116
  */
116
117
  export const getSelectedItemDetail = (target) => {
117
118
  const { type = 'string', name, label } = target.dataset;
118
- /** @type {any} */
119
- let { value } = target.dataset;
120
-
121
- if (type === 'number') {
122
- value = Number(value);
123
-
124
- if (Number.isNaN(value)) {
125
- value = null;
126
- }
127
- } else if (type === 'boolean') {
128
- value = value === 'true';
129
- } else if (type === 'string') {
130
- value = value ? String(value) : '';
131
- }
119
+ const value = castValue(target.dataset.value, type);
132
120
 
133
121
  return { target, type, name, label, value };
134
122
  };
@@ -0,0 +1,2 @@
1
+ export function getValueType(value: any): string;
2
+ export function castValue(value: string | undefined, type: string): any;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Conversion of the values held by buttons and other items: a value is stored in the `data-value`
3
+ * attribute along with its type in the `data-type` attribute, so it can be cast back to the
4
+ * original type when the item is selected.
5
+ */
6
+
7
+ /**
8
+ * Get the data type of a value, to be stored in the `data-type` attribute. `null` gets its own type
9
+ * because `typeof null` is `object`, and the `data-value` attribute is omitted for `null`.
10
+ * @param {any} value Value.
11
+ * @returns {string} Data type, e.g. `string`, `number`, `boolean` or `null`.
12
+ */
13
+ export const getValueType = (value) => (value === null ? 'null' : typeof value);
14
+
15
+ /**
16
+ * Cast a value read from the `data-value` attribute back to its original type.
17
+ * @param {string | undefined} value Attribute value, or `undefined` if the attribute is omitted.
18
+ * @param {string} type Data type stored in the `data-type` attribute.
19
+ * @returns {any} Cast value. Any other type than `number`, `boolean`, `null` and `string` is
20
+ * returned as is.
21
+ */
22
+ export const castValue = (value, type) => {
23
+ if (type === 'number') {
24
+ const number = Number(value);
25
+
26
+ return Number.isNaN(number) ? null : number;
27
+ }
28
+
29
+ if (type === 'boolean') {
30
+ return value === 'true';
31
+ }
32
+
33
+ if (type === 'null') {
34
+ return null;
35
+ }
36
+
37
+ if (type === 'string') {
38
+ return value ? String(value) : '';
39
+ }
40
+
41
+ return value;
42
+ };
@@ -24,8 +24,8 @@ export type ButtonProps = {
24
24
  */
25
25
  value?: any;
26
26
  /**
27
- * Data type of the `value`. Typically `string`, `number` or
28
- * `boolean`. Default: auto detect.
27
+ * Data type of the `value`. Typically `string`, `number`, `boolean`
28
+ * or `null`. Default: auto detect.
29
29
  */
30
30
  valueType?: string | undefined;
31
31
  /**
package/dist/typedefs.js CHANGED
@@ -12,8 +12,8 @@
12
12
  * @property {string} [role] The `role` attribute on the `<button>` element.
13
13
  * @property {string} [name] The `data-name` attribute on the `<button>` element.
14
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
+ * @property {string} [valueType] Data type of the `value`. Typically `string`, `number`, `boolean`
16
+ * or `null`. Default: auto detect.
17
17
  * @property {boolean} [hidden] Whether to hide the widget. An alias of the `aria-hidden` attribute.
18
18
  * @property {boolean} [disabled] Whether to disable the widget. An alias of the `aria-disabled`
19
19
  * attribute.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltia/ui",
3
- "version": "0.75.3",
3
+ "version": "0.75.4",
4
4
  "description": "A collection of Svelte components and utilities for building user interfaces.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -64,16 +64,16 @@
64
64
  "eslint-config-airbnb-extended": "^3.2.0",
65
65
  "eslint-config-prettier": "^10.1.8",
66
66
  "eslint-plugin-import": "^2.32.0",
67
- "eslint-plugin-jsdoc": "^64.5.2",
68
- "eslint-plugin-package-json": "^1.8.1",
67
+ "eslint-plugin-jsdoc": "^64.5.4",
68
+ "eslint-plugin-package-json": "^1.9.0",
69
69
  "eslint-plugin-svelte": "^3.23.0",
70
70
  "globals": "^17.12.0",
71
71
  "happy-dom": "^20.14.5",
72
- "oxlint": "^1.83.0",
72
+ "oxlint": "^1.85.0",
73
73
  "playwright": "^1.63.0",
74
74
  "postcss": "^8.5.28",
75
75
  "postcss-html": "^2.0.0",
76
- "prettier": "^3.9.7",
76
+ "prettier": "^3.9.8",
77
77
  "prettier-plugin-svelte": "^4.1.1",
78
78
  "rolldown": "^1.2.9",
79
79
  "sass": "^1.104.1",
@@ -81,7 +81,7 @@
81
81
  "stylelint": "^17.15.0",
82
82
  "stylelint-config-recommended-scss": "^17.0.1",
83
83
  "stylelint-scss": "^7.3.0",
84
- "svelte": "^5.57.0",
84
+ "svelte": "^5.57.1",
85
85
  "svelte-check": "^4.7.6",
86
86
  "svelte-preprocess": "^6.0.5",
87
87
  "tslib": "^2.8.1",