@ctrliq/quantic-components 1.63.1 → 1.63.3
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/alert/alert.d.ts +0 -2
- package/dist/alert/alert.js +12 -2
- package/dist/code-input/index.js +4 -11
- package/dist/index.js.map +1 -1
- package/dist/meta/index.js.map +1 -1
- package/dist/number-input/index.js +3 -7
- package/dist/quantic-components.js +34539 -34533
- package/dist/quantic-components.js.map +1 -1
- package/dist/quantic-components.min.js +18232 -18232
- package/dist/quantic-components.min.js.map +1 -1
- package/dist/select/index.js +4 -8
- package/dist/shared/shared.utils.d.ts +22 -0
- package/dist/shared/shared.utils.js +27 -0
- package/dist/shared/shared.utils.test.js +39 -2
- package/dist/text-input/index.js +4 -11
- package/dist/textarea/index.js +4 -10
- package/dist/toast/toast.d.ts +0 -2
- package/dist/toast/toast.js +12 -2
- package/dist/types/alert/alert.d.ts +0 -2
- package/dist/types/shared/shared.utils.d.ts +22 -0
- package/dist/types/toast/toast.d.ts +0 -2
- package/package.json +1 -1
package/dist/select/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export { SelectSize } from './index.constants';
|
|
|
15
15
|
import { LucideIconCircleAlert } from '../icon/__generated__/lucide/circle-alert';
|
|
16
16
|
import { LucideIconChevronDown } from '../icon/__generated__/lucide/chevron-down';
|
|
17
17
|
import { event, prop } from '../shared/component-meta.decorators';
|
|
18
|
+
import { emitValueChanged } from '../shared/shared.utils';
|
|
18
19
|
LucideIconCircleAlert.ensureDefined();
|
|
19
20
|
LucideIconChevronDown.ensureDefined();
|
|
20
21
|
let Select = class Select extends A11yAttributesMixin(QuanticElement) {
|
|
@@ -32,13 +33,7 @@ let Select = class Select extends A11yAttributesMixin(QuanticElement) {
|
|
|
32
33
|
this._slottedOptions = [];
|
|
33
34
|
}
|
|
34
35
|
dispatchValueChanged(e) {
|
|
35
|
-
|
|
36
|
-
this.value = selectEl.value;
|
|
37
|
-
this.dispatchEvent(new CustomEvent('value-changed', {
|
|
38
|
-
detail: { value: this.value },
|
|
39
|
-
bubbles: true,
|
|
40
|
-
composed: true,
|
|
41
|
-
}));
|
|
36
|
+
this.value = e.target.value;
|
|
42
37
|
}
|
|
43
38
|
openDropdown(e) {
|
|
44
39
|
if (!this.disabled) {
|
|
@@ -57,6 +52,7 @@ let Select = class Select extends A11yAttributesMixin(QuanticElement) {
|
|
|
57
52
|
select.value = option[1];
|
|
58
53
|
}
|
|
59
54
|
}
|
|
55
|
+
emitValueChanged(this, changed, this.value);
|
|
60
56
|
}
|
|
61
57
|
forwardNative(e) {
|
|
62
58
|
this.dispatchEvent(new Event(e.type, { bubbles: true, composed: true }));
|
|
@@ -286,7 +282,7 @@ __decorate([
|
|
|
286
282
|
], Select.prototype, "invalid", void 0);
|
|
287
283
|
Select = __decorate([
|
|
288
284
|
event('value-changed', {
|
|
289
|
-
description:
|
|
285
|
+
description: 'Fired whenever the value changes, from user selection or a programmatic update. Not fired on initial render.',
|
|
290
286
|
detail: '{ value: string }',
|
|
291
287
|
}),
|
|
292
288
|
event('focus', { forwarded: true }),
|
|
@@ -10,6 +10,28 @@ export declare function generateId(prefix?: string): string;
|
|
|
10
10
|
* Removes null, undefined and empty string values from an array.
|
|
11
11
|
*/
|
|
12
12
|
export declare function compact<T>(items: (T | null | undefined)[]): T[];
|
|
13
|
+
/**
|
|
14
|
+
* Dispatches the standard `value-changed` event for a form control from its
|
|
15
|
+
* `updated()` lifecycle, so it fires on real changes — user input *and*
|
|
16
|
+
* programmatic `el.value = ...` updates — but not on the initial render.
|
|
17
|
+
*
|
|
18
|
+
* Lit records the old value as `undefined` for any change made before the first
|
|
19
|
+
* update, so `changed.get(key) !== undefined` reliably skips initial hydration
|
|
20
|
+
* even when the value was set imperatively beforehand.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* updated(changed: Map<string, unknown>) {
|
|
24
|
+
* if (changed.has('value')) {
|
|
25
|
+
* this.internals.setFormValue(this.value);
|
|
26
|
+
* this.updateValidity();
|
|
27
|
+
* }
|
|
28
|
+
* emitValueChanged(this, changed, this.value);
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
export declare function emitValueChanged(host: EventTarget, changed: {
|
|
32
|
+
has(key: string): boolean;
|
|
33
|
+
get(key: string): unknown;
|
|
34
|
+
}, value: unknown, key?: string): void;
|
|
13
35
|
/**
|
|
14
36
|
* Ensure a custom element is defined
|
|
15
37
|
*
|
|
@@ -33,6 +33,33 @@ export function generateId(prefix) {
|
|
|
33
33
|
export function compact(items) {
|
|
34
34
|
return items.filter((item) => item != null && item !== '');
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Dispatches the standard `value-changed` event for a form control from its
|
|
38
|
+
* `updated()` lifecycle, so it fires on real changes — user input *and*
|
|
39
|
+
* programmatic `el.value = ...` updates — but not on the initial render.
|
|
40
|
+
*
|
|
41
|
+
* Lit records the old value as `undefined` for any change made before the first
|
|
42
|
+
* update, so `changed.get(key) !== undefined` reliably skips initial hydration
|
|
43
|
+
* even when the value was set imperatively beforehand.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* updated(changed: Map<string, unknown>) {
|
|
47
|
+
* if (changed.has('value')) {
|
|
48
|
+
* this.internals.setFormValue(this.value);
|
|
49
|
+
* this.updateValidity();
|
|
50
|
+
* }
|
|
51
|
+
* emitValueChanged(this, changed, this.value);
|
|
52
|
+
* }
|
|
53
|
+
*/
|
|
54
|
+
export function emitValueChanged(host, changed, value, key = 'value') {
|
|
55
|
+
if (changed.has(key) && changed.get(key) !== undefined) {
|
|
56
|
+
host.dispatchEvent(new CustomEvent('value-changed', {
|
|
57
|
+
detail: { value },
|
|
58
|
+
bubbles: true,
|
|
59
|
+
composed: true,
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
36
63
|
/**
|
|
37
64
|
* Ensure a custom element is defined
|
|
38
65
|
*
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { clamp } from './shared.utils';
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { clamp, emitValueChanged } from './shared.utils';
|
|
3
|
+
function fakeHost() {
|
|
4
|
+
const dispatchEvent = vi.fn();
|
|
5
|
+
return { host: { dispatchEvent }, dispatchEvent };
|
|
6
|
+
}
|
|
3
7
|
describe('clamp', () => {
|
|
4
8
|
it('returns value when within range', () => {
|
|
5
9
|
expect(clamp(5, 0, 10)).toBe(5);
|
|
@@ -26,3 +30,36 @@ describe('clamp', () => {
|
|
|
26
30
|
expect(clamp(10, 5, 5)).toBe(5);
|
|
27
31
|
});
|
|
28
32
|
});
|
|
33
|
+
describe('emitValueChanged', () => {
|
|
34
|
+
it('dispatches value-changed carrying the given value on a real change', () => {
|
|
35
|
+
const { host, dispatchEvent } = fakeHost();
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
emitValueChanged(host, new Map([['value', 'old']]), 'new');
|
|
38
|
+
expect(dispatchEvent).toHaveBeenCalledTimes(1);
|
|
39
|
+
const event = dispatchEvent.mock.calls[0][0];
|
|
40
|
+
expect(event.type).toBe('value-changed');
|
|
41
|
+
expect(event.detail).toEqual({ value: 'new' });
|
|
42
|
+
expect(event.bubbles).toBe(true);
|
|
43
|
+
expect(event.composed).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
it('does not dispatch on the initial render (Lit reports undefined old value)', () => {
|
|
46
|
+
const { host, dispatchEvent } = fakeHost();
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
emitValueChanged(host, new Map([['value', undefined]]), 'preset');
|
|
49
|
+
expect(dispatchEvent).not.toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
|
+
it('does not dispatch when the key did not change', () => {
|
|
52
|
+
const { host, dispatchEvent } = fakeHost();
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
emitValueChanged(host, new Map([['other', 'x']]), 'same');
|
|
55
|
+
expect(dispatchEvent).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
it('supports gating on a custom key', () => {
|
|
58
|
+
const { host, dispatchEvent } = fakeHost();
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
+
emitValueChanged(host, new Map([['count', 0]]), 42, 'count');
|
|
61
|
+
expect(dispatchEvent).toHaveBeenCalledTimes(1);
|
|
62
|
+
const event = dispatchEvent.mock.calls[0][0];
|
|
63
|
+
expect(event.detail).toEqual({ value: 42 });
|
|
64
|
+
});
|
|
65
|
+
});
|
package/dist/text-input/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Button } from '../button';
|
|
|
16
16
|
import { TextInputSize } from './index.constants';
|
|
17
17
|
import { A11yAttributesMixin } from '../shared/a11y-attributes.mixin';
|
|
18
18
|
import { event, prop } from '../shared/component-meta.decorators';
|
|
19
|
+
import { emitValueChanged } from '../shared/shared.utils';
|
|
19
20
|
export { TextInputSize } from './index.constants';
|
|
20
21
|
LucideIconCircleAlert.ensureDefined();
|
|
21
22
|
LucideIconEye.ensureDefined();
|
|
@@ -54,6 +55,7 @@ let TextInput = class TextInput extends A11yAttributesMixin(QuanticElement) {
|
|
|
54
55
|
this.internals.setFormValue(this.value);
|
|
55
56
|
this.updateValidity();
|
|
56
57
|
}
|
|
58
|
+
emitValueChanged(this, changedProperties, this.value);
|
|
57
59
|
}
|
|
58
60
|
forwardNative(e) {
|
|
59
61
|
const target = e.target;
|
|
@@ -67,16 +69,7 @@ let TextInput = class TextInput extends A11yAttributesMixin(QuanticElement) {
|
|
|
67
69
|
}
|
|
68
70
|
}
|
|
69
71
|
dispatchValueChanged(e) {
|
|
70
|
-
|
|
71
|
-
this.value = inputEl.value;
|
|
72
|
-
// Update form value
|
|
73
|
-
this.internals.setFormValue(this.value);
|
|
74
|
-
this.updateValidity();
|
|
75
|
-
this.dispatchEvent(new CustomEvent('value-changed', {
|
|
76
|
-
detail: { value: this.value },
|
|
77
|
-
bubbles: true,
|
|
78
|
-
composed: true,
|
|
79
|
-
}));
|
|
72
|
+
this.value = e.target.value;
|
|
80
73
|
}
|
|
81
74
|
formResetCallback() {
|
|
82
75
|
this.value = '';
|
|
@@ -376,7 +369,7 @@ __decorate([
|
|
|
376
369
|
], TextInput.prototype, "showPassword", void 0);
|
|
377
370
|
TextInput = __decorate([
|
|
378
371
|
event('value-changed', {
|
|
379
|
-
description: 'Fired
|
|
372
|
+
description: 'Fired whenever the value changes, from user input or a programmatic update. Not fired on initial render.',
|
|
380
373
|
detail: '{ value: string }',
|
|
381
374
|
}),
|
|
382
375
|
event('input', { forwarded: true }),
|
package/dist/textarea/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { LucideIconCircleAlert } from '../icon/__generated__/lucide/circle-alert
|
|
|
13
13
|
import { TextareaSize, TextareaResize } from './index.constants';
|
|
14
14
|
import { A11yAttributesMixin } from '../shared/a11y-attributes.mixin';
|
|
15
15
|
import { event, prop } from '../shared/component-meta.decorators';
|
|
16
|
+
import { emitValueChanged } from '../shared/shared.utils';
|
|
16
17
|
export { TextareaSize, TextareaResize } from './index.constants';
|
|
17
18
|
LucideIconCircleAlert.ensureDefined();
|
|
18
19
|
let Textarea = class Textarea extends A11yAttributesMixin(QuanticElement) {
|
|
@@ -36,6 +37,7 @@ let Textarea = class Textarea extends A11yAttributesMixin(QuanticElement) {
|
|
|
36
37
|
this.internals.setFormValue(this.value);
|
|
37
38
|
this.updateValidity();
|
|
38
39
|
}
|
|
40
|
+
emitValueChanged(this, changedProperties, this.value);
|
|
39
41
|
}
|
|
40
42
|
forwardNative(e) {
|
|
41
43
|
const target = e.target;
|
|
@@ -43,15 +45,7 @@ let Textarea = class Textarea extends A11yAttributesMixin(QuanticElement) {
|
|
|
43
45
|
this.dispatchEvent(new Event(e.type, { bubbles: true, composed: true }));
|
|
44
46
|
}
|
|
45
47
|
dispatchValueChanged(e) {
|
|
46
|
-
|
|
47
|
-
this.value = textareaEl.value;
|
|
48
|
-
this.internals.setFormValue(this.value);
|
|
49
|
-
this.updateValidity();
|
|
50
|
-
this.dispatchEvent(new CustomEvent('value-changed', {
|
|
51
|
-
detail: { value: this.value },
|
|
52
|
-
bubbles: true,
|
|
53
|
-
composed: true,
|
|
54
|
-
}));
|
|
48
|
+
this.value = e.target.value;
|
|
55
49
|
}
|
|
56
50
|
formResetCallback() {
|
|
57
51
|
this.value = '';
|
|
@@ -312,7 +306,7 @@ __decorate([
|
|
|
312
306
|
], Textarea.prototype, "autoComplete", void 0);
|
|
313
307
|
Textarea = __decorate([
|
|
314
308
|
event('value-changed', {
|
|
315
|
-
description: 'Fired
|
|
309
|
+
description: 'Fired whenever the value changes, from user input or a programmatic update. Not fired on initial render.',
|
|
316
310
|
detail: '{ value: string }',
|
|
317
311
|
}),
|
|
318
312
|
event('input', { forwarded: true }),
|
package/dist/toast/toast.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { type PropertyValues } from 'lit';
|
|
2
2
|
import { QuanticElement } from '../shared/quantic-element';
|
|
3
3
|
import { ToastType } from './index.constants';
|
|
4
|
-
import '../button';
|
|
5
|
-
import '../icon';
|
|
6
4
|
import type { ComponentMeta } from '../shared/meta.types';
|
|
7
5
|
export { ToastType } from './index.constants';
|
|
8
6
|
declare const Toast_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
|
package/dist/toast/toast.js
CHANGED
|
@@ -8,11 +8,21 @@ import { css, html, nothing } from 'lit';
|
|
|
8
8
|
import { quanticElement, QuanticElement } from '../shared/quantic-element';
|
|
9
9
|
import { AutoHideEmptySlotsMixin } from '../shared/auto-hide-empty-slots.mixin';
|
|
10
10
|
import { ToastType } from './index.constants';
|
|
11
|
-
import '../button';
|
|
12
|
-
import '../icon';
|
|
11
|
+
import { Button } from '../button';
|
|
12
|
+
import { LucideIconCircleCheck } from '../icon/__generated__/lucide/circle-check';
|
|
13
|
+
import { LucideIconCircleX } from '../icon/__generated__/lucide/circle-x';
|
|
14
|
+
import { LucideIconInfo } from '../icon/__generated__/lucide/info';
|
|
15
|
+
import { LucideIconTriangleAlert } from '../icon/__generated__/lucide/triangle-alert';
|
|
16
|
+
import { LucideIconX } from '../icon/__generated__/lucide/x';
|
|
13
17
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
14
18
|
import { event, prop } from '../shared/component-meta.decorators';
|
|
15
19
|
export { ToastType } from './index.constants';
|
|
20
|
+
Button.ensureDefined();
|
|
21
|
+
LucideIconCircleCheck.ensureDefined();
|
|
22
|
+
LucideIconCircleX.ensureDefined();
|
|
23
|
+
LucideIconInfo.ensureDefined();
|
|
24
|
+
LucideIconTriangleAlert.ensureDefined();
|
|
25
|
+
LucideIconX.ensureDefined();
|
|
16
26
|
let Toast = class Toast extends AutoHideEmptySlotsMixin(QuanticElement) {
|
|
17
27
|
constructor() {
|
|
18
28
|
super(...arguments);
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { type PropertyValues } from 'lit';
|
|
2
2
|
import { QuanticElement } from '../shared/quantic-element';
|
|
3
3
|
import { AlertType } from './index.constants';
|
|
4
|
-
import '../button';
|
|
5
|
-
import '../icon';
|
|
6
4
|
import type { ComponentMeta } from '../shared/meta.types';
|
|
7
5
|
export { AlertType } from './index.constants';
|
|
8
6
|
declare const Alert_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
|
|
@@ -10,6 +10,28 @@ export declare function generateId(prefix?: string): string;
|
|
|
10
10
|
* Removes null, undefined and empty string values from an array.
|
|
11
11
|
*/
|
|
12
12
|
export declare function compact<T>(items: (T | null | undefined)[]): T[];
|
|
13
|
+
/**
|
|
14
|
+
* Dispatches the standard `value-changed` event for a form control from its
|
|
15
|
+
* `updated()` lifecycle, so it fires on real changes — user input *and*
|
|
16
|
+
* programmatic `el.value = ...` updates — but not on the initial render.
|
|
17
|
+
*
|
|
18
|
+
* Lit records the old value as `undefined` for any change made before the first
|
|
19
|
+
* update, so `changed.get(key) !== undefined` reliably skips initial hydration
|
|
20
|
+
* even when the value was set imperatively beforehand.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* updated(changed: Map<string, unknown>) {
|
|
24
|
+
* if (changed.has('value')) {
|
|
25
|
+
* this.internals.setFormValue(this.value);
|
|
26
|
+
* this.updateValidity();
|
|
27
|
+
* }
|
|
28
|
+
* emitValueChanged(this, changed, this.value);
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
export declare function emitValueChanged(host: EventTarget, changed: {
|
|
32
|
+
has(key: string): boolean;
|
|
33
|
+
get(key: string): unknown;
|
|
34
|
+
}, value: unknown, key?: string): void;
|
|
13
35
|
/**
|
|
14
36
|
* Ensure a custom element is defined
|
|
15
37
|
*
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { type PropertyValues } from 'lit';
|
|
2
2
|
import { QuanticElement } from '../shared/quantic-element';
|
|
3
3
|
import { ToastType } from './index.constants';
|
|
4
|
-
import '../button';
|
|
5
|
-
import '../icon';
|
|
6
4
|
import type { ComponentMeta } from '../shared/meta.types';
|
|
7
5
|
export { ToastType } from './index.constants';
|
|
8
6
|
declare const Toast_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
|