@ctrliq/quantic-components 1.84.1 → 1.85.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.
- package/dist/action-group/action-group.component.js +2 -1
- package/dist/alert/alert.js +2 -1
- package/dist/alert/index.stories.d.ts +7 -0
- package/dist/alert/index.stories.js +1 -0
- package/dist/badge/badge-group.component.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/meta/index.js.map +1 -1
- package/dist/meta/sibling-groups.test.d.ts +1 -0
- package/dist/meta/sibling-groups.test.js +42 -0
- package/dist/meta.json +4 -4
- package/dist/quantic-components.js +19 -7
- package/dist/quantic-components.js.map +1 -1
- package/dist/quantic-components.min.js +1852 -1851
- package/dist/quantic-components.min.js.map +1 -1
- package/dist/register.js.map +1 -1
- package/dist/shared/auto-hide-empty-slots.mixin.d.ts +0 -35
- package/dist/shared/auto-hide-empty-slots.mixin.js +11 -3
- package/dist/shared/auto-hide-empty-slots.mixin.test.d.ts +1 -0
- package/dist/shared/auto-hide-empty-slots.mixin.test.js +57 -0
- package/dist/tag/tag-group.component.js +2 -1
- package/dist/types/alert/index.stories.d.ts +7 -0
- package/dist/types/meta/sibling-groups.test.d.ts +1 -0
- package/dist/types/shared/auto-hide-empty-slots.mixin.d.ts +0 -35
- package/dist/types/shared/auto-hide-empty-slots.mixin.test.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
const SRC_DIR = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
6
|
+
// quantic-action-group, quantic-tag-group and quantic-badge-group are the same component
|
|
7
|
+
// with different children. They exist to carry one accessible name and one gap over a run
|
|
8
|
+
// of siblings, and they deliberately take no layout props: Cluster was deprecated rather
|
|
9
|
+
// than have three copies of its axis and align. That makes ::part(group) the only way out
|
|
10
|
+
// for a caller who needs a column, so it has to be on all three or the escape hatch is a
|
|
11
|
+
// coin flip.
|
|
12
|
+
const GROUPS = [
|
|
13
|
+
'action-group/action-group.component.ts',
|
|
14
|
+
'tag/tag-group.component.ts',
|
|
15
|
+
'badge/badge-group.component.ts',
|
|
16
|
+
];
|
|
17
|
+
const LAYOUT_PROPS = /attribute:\s*'(axis|direction|align|orientation|gap|wrap)'/;
|
|
18
|
+
function source(file) {
|
|
19
|
+
return readFileSync(join(SRC_DIR, file), 'utf-8');
|
|
20
|
+
}
|
|
21
|
+
describe('sibling groups', () => {
|
|
22
|
+
it.each(GROUPS)('%s exposes the role container as ::part(group)', (file) => {
|
|
23
|
+
const roleContainer = /<div[^>]*role="group"[^>]*>/.exec(source(file));
|
|
24
|
+
expect(roleContainer, 'expected a div carrying role="group"').not.toBeNull();
|
|
25
|
+
expect(roleContainer?.[0]).toContain('part="group"');
|
|
26
|
+
});
|
|
27
|
+
it.each(GROUPS)('%s takes no layout prop', (file) => {
|
|
28
|
+
expect(LAYOUT_PROPS.exec(source(file))?.[1]).toBeUndefined();
|
|
29
|
+
});
|
|
30
|
+
it('gives all three the same public surface', () => {
|
|
31
|
+
const surfaces = GROUPS.map((file) => {
|
|
32
|
+
const text = source(file);
|
|
33
|
+
return {
|
|
34
|
+
props: [...text.matchAll(/attribute:\s*'([a-z-]+)'/g)].map(([, name]) => name).sort(),
|
|
35
|
+
parts: [...text.matchAll(/part="([a-z-]+)"/g)].map(([, name]) => name).sort(),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
expect(surfaces[0]).toEqual({ props: ['aria-label'], parts: ['group'] });
|
|
39
|
+
for (const surface of surfaces.slice(1))
|
|
40
|
+
expect(surface).toEqual(surfaces[0]);
|
|
41
|
+
});
|
|
42
|
+
});
|
package/dist/meta.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generated": "2026-08-
|
|
3
|
+
"generated": "2026-08-28T16:42:21.311Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"tag": "quantic-action-group",
|
|
7
|
-
"description": "A row of related actions sharing one accessible name and a consistent gap. Takes quantic-button, and quantic-dropdown-menu or quantic-popover when the trigger is a button. Wraps when the row runs out of width. Gap: --quantic-component-action-group-gap. Use quantic-button-bar when the buttons should read as one joined control.",
|
|
7
|
+
"description": "A row of related actions sharing one accessible name and a consistent gap. Takes quantic-button, and quantic-dropdown-menu or quantic-popover when the trigger is a button. Wraps when the row runs out of width. Gap: --quantic-component-action-group-gap. Layout: ::part(group), for a column or a different alignment. Use quantic-button-bar when the buttons should read as one joined control.",
|
|
8
8
|
"category": "action",
|
|
9
9
|
"props": [
|
|
10
10
|
{
|
|
@@ -183,7 +183,7 @@
|
|
|
183
183
|
},
|
|
184
184
|
{
|
|
185
185
|
"tag": "quantic-badge-group",
|
|
186
|
-
"description": "A run of quantic-badge or quantic-status-badge sharing one accessible name and a consistent gap. Wraps across lines, and each badge keeps its own size. Gap: --quantic-component-badge-group-gap. Use quantic-tag-group for tags.",
|
|
186
|
+
"description": "A run of quantic-badge or quantic-status-badge sharing one accessible name and a consistent gap. Wraps across lines, and each badge keeps its own size. Gap: --quantic-component-badge-group-gap. Layout: ::part(group), for a column or a different alignment. Use quantic-tag-group for tags.",
|
|
187
187
|
"category": "display",
|
|
188
188
|
"props": [
|
|
189
189
|
{
|
|
@@ -4774,7 +4774,7 @@
|
|
|
4774
4774
|
},
|
|
4775
4775
|
{
|
|
4776
4776
|
"tag": "quantic-tag-group",
|
|
4777
|
-
"description": "A run of quantic-tag, quantic-status-tag or quantic-count-tag sharing one accessible name and a consistent gap. Wraps across lines, and each tag keeps its own size. Gap: --quantic-component-tag-group-gap. Use quantic-badge-group for badges.",
|
|
4777
|
+
"description": "A run of quantic-tag, quantic-status-tag or quantic-count-tag sharing one accessible name and a consistent gap. Wraps across lines, and each tag keeps its own size. Gap: --quantic-component-tag-group-gap. Layout: ::part(group), for a column or a different alignment. Use quantic-badge-group for badges.",
|
|
4778
4778
|
"category": "display",
|
|
4779
4779
|
"props": [
|
|
4780
4780
|
{
|
|
@@ -322,13 +322,20 @@
|
|
|
322
322
|
*
|
|
323
323
|
* Chrome doesn't re-evaluate :has() in shadow DOM when light-DOM children
|
|
324
324
|
* arrive asynchronously (e.g. React CSR). A capture listener on the shadow
|
|
325
|
-
* root intercepts all slotchange events internally and
|
|
326
|
-
*
|
|
325
|
+
* root intercepts all slotchange events internally and marks filled slots with
|
|
326
|
+
* `data-slot-filled`, no wiring required in component templates.
|
|
327
|
+
*
|
|
328
|
+
* That reveal has to be a rule inside `quantic-slot-visibility`, not an inline
|
|
329
|
+
* style. Inline declarations sit in the implicit unlayered layer, which the
|
|
330
|
+
* cascade orders after every explicit layer, so an inline
|
|
331
|
+
* `display: revert-layer` reverts to the `display: none` above rather than
|
|
332
|
+
* past it.
|
|
327
333
|
*
|
|
328
334
|
* @example
|
|
329
335
|
* class MyElement extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {}
|
|
330
336
|
* class Toast extends AutoHideEmptySlotsMixin(QuanticElement, ['title', '', 'action']) {}
|
|
331
337
|
*/
|
|
338
|
+
const FILLED_ATTRIBUTE = 'data-slot-filled';
|
|
332
339
|
const AutoHideEmptySlotsMixin = (superClass, slots = []) => {
|
|
333
340
|
var _AutoHideEmptySlotsClass_instances, _AutoHideEmptySlotsClass_slotListenerAttached, _AutoHideEmptySlotsClass_isMeaningful, _AutoHideEmptySlotsClass_onSlotChange, _AutoHideEmptySlotsClass_attachSlotListener, _AutoHideEmptySlotsClass_detachSlotListener;
|
|
334
341
|
if (slots.length === 0)
|
|
@@ -346,6 +353,7 @@
|
|
|
346
353
|
`${sel} { display: none; }`,
|
|
347
354
|
whenSlotPresent(name, r$6(`${sel} { display: revert-layer; }`))
|
|
348
355
|
.cssText,
|
|
356
|
+
`${sel}[${FILLED_ATTRIBUTE}] { display: revert-layer; }`,
|
|
349
357
|
].join(' ');
|
|
350
358
|
})
|
|
351
359
|
.join(' ');
|
|
@@ -367,7 +375,7 @@
|
|
|
367
375
|
const hasContent = slot
|
|
368
376
|
.assignedNodes({ flatten: true })
|
|
369
377
|
.some(__classPrivateFieldGet(this, _AutoHideEmptySlotsClass_isMeaningful, "f"));
|
|
370
|
-
slot.
|
|
378
|
+
slot.toggleAttribute(FILLED_ATTRIBUTE, hasContent);
|
|
371
379
|
});
|
|
372
380
|
}
|
|
373
381
|
static finalizeStyles(styles) {
|
|
@@ -2956,9 +2964,10 @@
|
|
|
2956
2964
|
|
|
2957
2965
|
.icon {
|
|
2958
2966
|
display: inline-flex;
|
|
2967
|
+
align-items: center;
|
|
2959
2968
|
flex-shrink: 0;
|
|
2969
|
+
height: var(--quantic-line-height-body-sm);
|
|
2960
2970
|
color: var(--quantic-component-alert-icon-color);
|
|
2961
|
-
line-height: 0;
|
|
2962
2971
|
}
|
|
2963
2972
|
|
|
2964
2973
|
.content {
|
|
@@ -5761,7 +5770,7 @@
|
|
|
5761
5770
|
}
|
|
5762
5771
|
render() {
|
|
5763
5772
|
return b `
|
|
5764
|
-
<div class="group" role="group" aria-label=${this.ariaLabel ?? 'Badges'}>
|
|
5773
|
+
<div class="group" part="group" role="group" aria-label=${this.ariaLabel ?? 'Badges'}>
|
|
5765
5774
|
<slot></slot>
|
|
5766
5775
|
</div>
|
|
5767
5776
|
`;
|
|
@@ -5771,6 +5780,7 @@
|
|
|
5771
5780
|
tag: 'quantic-badge-group',
|
|
5772
5781
|
description: 'A run of quantic-badge or quantic-status-badge sharing one accessible name and a consistent gap. ' +
|
|
5773
5782
|
'Wraps across lines, and each badge keeps its own size. Gap: --quantic-component-badge-group-gap. ' +
|
|
5783
|
+
'Layout: ::part(group), for a column or a different alignment. ' +
|
|
5774
5784
|
'Use quantic-tag-group for tags.',
|
|
5775
5785
|
category: 'display',
|
|
5776
5786
|
slots: {
|
|
@@ -6003,7 +6013,7 @@
|
|
|
6003
6013
|
}
|
|
6004
6014
|
render() {
|
|
6005
6015
|
return b `
|
|
6006
|
-
<div class="group" role="group" aria-label=${this.ariaLabel ?? 'Actions'}>
|
|
6016
|
+
<div class="group" part="group" role="group" aria-label=${this.ariaLabel ?? 'Actions'}>
|
|
6007
6017
|
<slot></slot>
|
|
6008
6018
|
</div>
|
|
6009
6019
|
`;
|
|
@@ -6014,6 +6024,7 @@
|
|
|
6014
6024
|
description: 'A row of related actions sharing one accessible name and a consistent gap. ' +
|
|
6015
6025
|
'Takes quantic-button, and quantic-dropdown-menu or quantic-popover when the trigger is a button. ' +
|
|
6016
6026
|
'Wraps when the row runs out of width. Gap: --quantic-component-action-group-gap. ' +
|
|
6027
|
+
'Layout: ::part(group), for a column or a different alignment. ' +
|
|
6017
6028
|
'Use quantic-button-bar when the buttons should read as one joined control.',
|
|
6018
6029
|
category: 'action',
|
|
6019
6030
|
slots: {
|
|
@@ -70057,7 +70068,7 @@
|
|
|
70057
70068
|
}
|
|
70058
70069
|
render() {
|
|
70059
70070
|
return b `
|
|
70060
|
-
<div class="group" role="group" aria-label=${this.ariaLabel ?? 'Tags'}>
|
|
70071
|
+
<div class="group" part="group" role="group" aria-label=${this.ariaLabel ?? 'Tags'}>
|
|
70061
70072
|
<slot></slot>
|
|
70062
70073
|
</div>
|
|
70063
70074
|
`;
|
|
@@ -70067,6 +70078,7 @@
|
|
|
70067
70078
|
tag: 'quantic-tag-group',
|
|
70068
70079
|
description: 'A run of quantic-tag, quantic-status-tag or quantic-count-tag sharing one accessible name and a consistent gap. ' +
|
|
70069
70080
|
'Wraps across lines, and each tag keeps its own size. Gap: --quantic-component-tag-group-gap. ' +
|
|
70081
|
+
'Layout: ::part(group), for a column or a different alignment. ' +
|
|
70070
70082
|
'Use quantic-badge-group for badges.',
|
|
70071
70083
|
category: 'display',
|
|
70072
70084
|
slots: {
|