@ctrliq/quantic-components 1.67.5 → 1.68.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/alert/alert.js +15 -12
- package/dist/alert/index.stories.d.ts +9 -0
- package/dist/alert/index.stories.js +26 -0
- package/dist/card/card-title.component.js +4 -1
- package/dist/card/card.component.js +162 -150
- package/dist/code-input/index.js +2 -6
- package/dist/dropdown-menu/group.component.js +38 -35
- package/dist/index.js.map +1 -1
- package/dist/layout/sidebar.component.js +44 -25
- package/dist/log-output/log-output.component.js +1 -7
- package/dist/meta/index.js.map +1 -1
- package/dist/option-card/option-card.component.js +67 -25
- package/dist/panel/panel-header.component.js +11 -2
- package/dist/panel/panel.component.js +18 -4
- package/dist/popover/popover-popup.js +10 -2
- package/dist/quantic-components.js +437 -284
- package/dist/quantic-components.js.map +1 -1
- package/dist/quantic-components.min.js +2224 -2227
- package/dist/quantic-components.min.js.map +1 -1
- package/dist/shared/auto-hide-empty-slots.mixin.d.ts +8 -3
- package/dist/shared/auto-hide-empty-slots.mixin.js +49 -3
- package/dist/toast/toast.js +15 -12
- package/dist/types/alert/index.stories.d.ts +9 -0
- package/dist/types/shared/auto-hide-empty-slots.mixin.d.ts +8 -3
- package/package.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { LitConstructor } from './shared.types';
|
|
2
2
|
import { QuanticElement } from './quantic-element';
|
|
3
3
|
/**
|
|
4
|
-
* Mixin that automatically hides empty named slots
|
|
4
|
+
* Mixin that automatically hides empty named slots.
|
|
5
5
|
*
|
|
6
6
|
* Each named slot is hidden by default and revealed when the host has a light
|
|
7
|
-
* DOM child with a matching `slot` attribute. Two rules cover all browsers:
|
|
7
|
+
* DOM child with a matching `slot` attribute. Two CSS rules cover all browsers:
|
|
8
8
|
*
|
|
9
9
|
* - `:host(:has([slot="name"]))` — Safari and Firefox
|
|
10
10
|
* - `@scope { :scope:has([slot="name"]) }` — Chrome (@scope changes the
|
|
@@ -18,7 +18,12 @@ import { QuanticElement } from './quantic-element';
|
|
|
18
18
|
* set in `quantic-component`.
|
|
19
19
|
*
|
|
20
20
|
* CSS is injected via `finalizeStyles` so it lands in Lit SSR's Declarative
|
|
21
|
-
* Shadow DOM output — no JS, no layout shift.
|
|
21
|
+
* Shadow DOM output — no JS, no layout shift for SSR.
|
|
22
|
+
*
|
|
23
|
+
* Chrome doesn't re-evaluate :has() in shadow DOM when light-DOM children
|
|
24
|
+
* arrive asynchronously (e.g. React CSR). A capture listener on the shadow
|
|
25
|
+
* root intercepts all slotchange events internally and sets inline styles to
|
|
26
|
+
* override the CSS — no wiring required in component templates.
|
|
22
27
|
*
|
|
23
28
|
* @example
|
|
24
29
|
* class MyElement extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
1
6
|
import { unsafeCSS, } from 'lit';
|
|
2
7
|
import { escapeCssString, whenSlotPresent } from './slot-utils';
|
|
3
8
|
/**
|
|
4
|
-
* Mixin that automatically hides empty named slots
|
|
9
|
+
* Mixin that automatically hides empty named slots.
|
|
5
10
|
*
|
|
6
11
|
* Each named slot is hidden by default and revealed when the host has a light
|
|
7
|
-
* DOM child with a matching `slot` attribute. Two rules cover all browsers:
|
|
12
|
+
* DOM child with a matching `slot` attribute. Two CSS rules cover all browsers:
|
|
8
13
|
*
|
|
9
14
|
* - `:host(:has([slot="name"]))` — Safari and Firefox
|
|
10
15
|
* - `@scope { :scope:has([slot="name"]) }` — Chrome (@scope changes the
|
|
@@ -18,12 +23,18 @@ import { escapeCssString, whenSlotPresent } from './slot-utils';
|
|
|
18
23
|
* set in `quantic-component`.
|
|
19
24
|
*
|
|
20
25
|
* CSS is injected via `finalizeStyles` so it lands in Lit SSR's Declarative
|
|
21
|
-
* Shadow DOM output — no JS, no layout shift.
|
|
26
|
+
* Shadow DOM output — no JS, no layout shift for SSR.
|
|
27
|
+
*
|
|
28
|
+
* Chrome doesn't re-evaluate :has() in shadow DOM when light-DOM children
|
|
29
|
+
* arrive asynchronously (e.g. React CSR). A capture listener on the shadow
|
|
30
|
+
* root intercepts all slotchange events internally and sets inline styles to
|
|
31
|
+
* override the CSS — no wiring required in component templates.
|
|
22
32
|
*
|
|
23
33
|
* @example
|
|
24
34
|
* class MyElement extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {}
|
|
25
35
|
*/
|
|
26
36
|
export const AutoHideEmptySlotsMixin = (superClass, namedSlots = []) => {
|
|
37
|
+
var _AutoHideEmptySlotsClass_onSlotChange;
|
|
27
38
|
if (namedSlots.length === 0)
|
|
28
39
|
return superClass;
|
|
29
40
|
// A component may declare a native CSSStyleSheet, which Lit passes through
|
|
@@ -41,6 +52,18 @@ export const AutoHideEmptySlotsMixin = (superClass, namedSlots = []) => {
|
|
|
41
52
|
})
|
|
42
53
|
.join(' ');
|
|
43
54
|
class AutoHideEmptySlotsClass extends superClass {
|
|
55
|
+
constructor() {
|
|
56
|
+
super(...arguments);
|
|
57
|
+
// slotchange doesn't bubble, but capture intercepts it on the way down
|
|
58
|
+
// to the slot element — one listener covers all named slots.
|
|
59
|
+
_AutoHideEmptySlotsClass_onSlotChange.set(this, (e) => {
|
|
60
|
+
const slot = e.target;
|
|
61
|
+
if (!namedSlots.includes(slot.name))
|
|
62
|
+
return;
|
|
63
|
+
const hasContent = slot.assignedNodes({ flatten: true }).length > 0;
|
|
64
|
+
slot.style.display = hasContent ? 'block' : '';
|
|
65
|
+
});
|
|
66
|
+
}
|
|
44
67
|
static finalizeStyles(styles) {
|
|
45
68
|
const base = superClass.finalizeStyles?.call(this, styles) ?? [];
|
|
46
69
|
const baseCSS = base.map(toCssText).join('\n');
|
|
@@ -50,6 +73,29 @@ export const AutoHideEmptySlotsMixin = (superClass, namedSlots = []) => {
|
|
|
50
73
|
` @layer quantic-slot-visibility { ${slotRulesCSS} }`),
|
|
51
74
|
];
|
|
52
75
|
}
|
|
76
|
+
connectedCallback() {
|
|
77
|
+
super.connectedCallback();
|
|
78
|
+
this.renderRoot.addEventListener('slotchange', __classPrivateFieldGet(this, _AutoHideEmptySlotsClass_onSlotChange, "f"), {
|
|
79
|
+
capture: true,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
disconnectedCallback() {
|
|
83
|
+
super.disconnectedCallback();
|
|
84
|
+
this.renderRoot.removeEventListener('slotchange', __classPrivateFieldGet(this, _AutoHideEmptySlotsClass_onSlotChange, "f"), {
|
|
85
|
+
capture: true,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// Sync initial state for slots that already have content on first render
|
|
89
|
+
// (e.g. synchronous React CSR or SSR hydration with light DOM present).
|
|
90
|
+
firstUpdated(changed) {
|
|
91
|
+
super.firstUpdated?.(changed);
|
|
92
|
+
for (const name of namedSlots) {
|
|
93
|
+
const slot = this.renderRoot.querySelector(`slot[name="${CSS.escape(name)}"]`);
|
|
94
|
+
if (slot)
|
|
95
|
+
__classPrivateFieldGet(this, _AutoHideEmptySlotsClass_onSlotChange, "f").call(this, { target: slot });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
53
98
|
}
|
|
99
|
+
_AutoHideEmptySlotsClass_onSlotChange = new WeakMap();
|
|
54
100
|
return AutoHideEmptySlotsClass;
|
|
55
101
|
};
|
package/dist/toast/toast.js
CHANGED
|
@@ -23,7 +23,10 @@ LucideIconCircleX.ensureDefined();
|
|
|
23
23
|
LucideIconInfo.ensureDefined();
|
|
24
24
|
LucideIconTriangleAlert.ensureDefined();
|
|
25
25
|
LucideIconX.ensureDefined();
|
|
26
|
-
let Toast = class Toast extends AutoHideEmptySlotsMixin(QuanticElement, [
|
|
26
|
+
let Toast = class Toast extends AutoHideEmptySlotsMixin(QuanticElement, [
|
|
27
|
+
'title',
|
|
28
|
+
'action',
|
|
29
|
+
]) {
|
|
27
30
|
constructor() {
|
|
28
31
|
super(...arguments);
|
|
29
32
|
this.open = false;
|
|
@@ -86,18 +89,18 @@ let Toast = class Toast extends AutoHideEmptySlotsMixin(QuanticElement, ['title'
|
|
|
86
89
|
</div>
|
|
87
90
|
${this.showCloseButton
|
|
88
91
|
? html `<quantic-button
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
size="sm"
|
|
92
|
-
icon
|
|
93
|
-
aria-label="Close"
|
|
94
|
-
@click=${this.handleCloseClick}
|
|
95
|
-
>
|
|
96
|
-
<quantic-icon-lucide-x
|
|
92
|
+
class="close-button"
|
|
93
|
+
variant="ghost"
|
|
97
94
|
size="sm"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
icon
|
|
96
|
+
aria-label="Close"
|
|
97
|
+
@click=${this.handleCloseClick}
|
|
98
|
+
>
|
|
99
|
+
<quantic-icon-lucide-x
|
|
100
|
+
size="sm"
|
|
101
|
+
class="close-icon"
|
|
102
|
+
></quantic-icon-lucide-x>
|
|
103
|
+
</quantic-button>`
|
|
101
104
|
: nothing}
|
|
102
105
|
</div>
|
|
103
106
|
`;
|
|
@@ -17,3 +17,12 @@ export declare const WithCloseButton: import("../shared/story").StoryObject<Args
|
|
|
17
17
|
export declare const WithoutTitle: import("../shared/story").StoryObject<Args>;
|
|
18
18
|
export declare const WithAction: import("../shared/story").StoryObject<object>;
|
|
19
19
|
export declare const CustomIcon: import("../shared/story").StoryObject<object>;
|
|
20
|
+
/** Repro: slot content inserted asynchronously (simulates React CSR).
|
|
21
|
+
* Title and action should appear after 800 ms. */
|
|
22
|
+
export declare const AsyncSlotRepro: {
|
|
23
|
+
name: string;
|
|
24
|
+
render: () => string;
|
|
25
|
+
play: ({ canvasElement }: {
|
|
26
|
+
canvasElement: HTMLElement;
|
|
27
|
+
}) => Promise<void>;
|
|
28
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { LitConstructor } from './shared.types';
|
|
2
2
|
import { QuanticElement } from './quantic-element';
|
|
3
3
|
/**
|
|
4
|
-
* Mixin that automatically hides empty named slots
|
|
4
|
+
* Mixin that automatically hides empty named slots.
|
|
5
5
|
*
|
|
6
6
|
* Each named slot is hidden by default and revealed when the host has a light
|
|
7
|
-
* DOM child with a matching `slot` attribute. Two rules cover all browsers:
|
|
7
|
+
* DOM child with a matching `slot` attribute. Two CSS rules cover all browsers:
|
|
8
8
|
*
|
|
9
9
|
* - `:host(:has([slot="name"]))` — Safari and Firefox
|
|
10
10
|
* - `@scope { :scope:has([slot="name"]) }` — Chrome (@scope changes the
|
|
@@ -18,7 +18,12 @@ import { QuanticElement } from './quantic-element';
|
|
|
18
18
|
* set in `quantic-component`.
|
|
19
19
|
*
|
|
20
20
|
* CSS is injected via `finalizeStyles` so it lands in Lit SSR's Declarative
|
|
21
|
-
* Shadow DOM output — no JS, no layout shift.
|
|
21
|
+
* Shadow DOM output — no JS, no layout shift for SSR.
|
|
22
|
+
*
|
|
23
|
+
* Chrome doesn't re-evaluate :has() in shadow DOM when light-DOM children
|
|
24
|
+
* arrive asynchronously (e.g. React CSR). A capture listener on the shadow
|
|
25
|
+
* root intercepts all slotchange events internally and sets inline styles to
|
|
26
|
+
* override the CSS — no wiring required in component templates.
|
|
22
27
|
*
|
|
23
28
|
* @example
|
|
24
29
|
* class MyElement extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {}
|