@ctrliq/quantic-components 1.67.0 → 1.67.2

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.
Files changed (74) hide show
  1. package/dist/alert/alert.d.ts +1 -1
  2. package/dist/alert/alert.js +4 -12
  3. package/dist/card/card-title.component.d.ts +1 -1
  4. package/dist/card/card-title.component.js +4 -12
  5. package/dist/card/card.component.d.ts +2 -1
  6. package/dist/card/card.component.js +9 -10
  7. package/dist/dialog/dialog-title.d.ts +1 -1
  8. package/dist/dialog/dialog-title.js +3 -11
  9. package/dist/dialog/dialog.d.ts +1 -1
  10. package/dist/dialog/dialog.js +4 -13
  11. package/dist/dropdown-menu/group.component.d.ts +2 -1
  12. package/dist/dropdown-menu/group.component.js +9 -3
  13. package/dist/field/field.component.d.ts +4 -3
  14. package/dist/field/field.component.js +59 -35
  15. package/dist/field/render-as-field.hoc.d.ts +1 -1
  16. package/dist/field/render-as-field.hoc.js +21 -8
  17. package/dist/index.js.map +1 -1
  18. package/dist/inline-edit/index.d.ts +2 -3
  19. package/dist/inline-edit/index.js +16 -8
  20. package/dist/layout/layout.component.d.ts +5 -2
  21. package/dist/layout/layout.component.js +28 -14
  22. package/dist/layout/sidebar.component.d.ts +1 -1
  23. package/dist/layout/sidebar.component.js +5 -5
  24. package/dist/meta/index.js.map +1 -1
  25. package/dist/option-card/option-card.component.d.ts +1 -1
  26. package/dist/option-card/option-card.component.js +4 -12
  27. package/dist/panel/panel-header.component.d.ts +1 -1
  28. package/dist/panel/panel-header.component.js +4 -16
  29. package/dist/panel/panel.component.d.ts +1 -1
  30. package/dist/panel/panel.component.js +4 -12
  31. package/dist/popover/popover-popup.d.ts +1 -1
  32. package/dist/popover/popover-popup.js +3 -3
  33. package/dist/popover/popover.d.ts +2 -2
  34. package/dist/quantic-components.js +252 -307
  35. package/dist/quantic-components.js.map +1 -1
  36. package/dist/quantic-components.min.js +1917 -1977
  37. package/dist/quantic-components.min.js.map +1 -1
  38. package/dist/shared/auto-hide-empty-slots.mixin.d.ts +19 -20
  39. package/dist/shared/auto-hide-empty-slots.mixin.js +43 -43
  40. package/dist/shared/quantic-element.d.ts +11 -1
  41. package/dist/shared/slot-utils.d.ts +24 -0
  42. package/dist/shared/slot-utils.js +38 -0
  43. package/dist/table/index.stories.d.ts +1 -0
  44. package/dist/table/index.stories.js +19 -0
  45. package/dist/table/table.component.d.ts +1 -1
  46. package/dist/table/table.component.js +3 -11
  47. package/dist/toast/toast.d.ts +1 -1
  48. package/dist/toast/toast.js +4 -12
  49. package/dist/toggle/index.d.ts +1 -1
  50. package/dist/toggle/index.js +1 -2
  51. package/dist/types/alert/alert.d.ts +1 -1
  52. package/dist/types/card/card-title.component.d.ts +1 -1
  53. package/dist/types/card/card.component.d.ts +2 -1
  54. package/dist/types/dialog/dialog-title.d.ts +1 -1
  55. package/dist/types/dialog/dialog.d.ts +1 -1
  56. package/dist/types/dropdown-menu/group.component.d.ts +2 -1
  57. package/dist/types/field/field.component.d.ts +4 -3
  58. package/dist/types/field/render-as-field.hoc.d.ts +1 -1
  59. package/dist/types/inline-edit/index.d.ts +2 -3
  60. package/dist/types/layout/layout.component.d.ts +5 -2
  61. package/dist/types/layout/sidebar.component.d.ts +1 -1
  62. package/dist/types/option-card/option-card.component.d.ts +1 -1
  63. package/dist/types/panel/panel-header.component.d.ts +1 -1
  64. package/dist/types/panel/panel.component.d.ts +1 -1
  65. package/dist/types/popover/popover-popup.d.ts +1 -1
  66. package/dist/types/popover/popover.d.ts +2 -2
  67. package/dist/types/shared/auto-hide-empty-slots.mixin.d.ts +19 -20
  68. package/dist/types/shared/quantic-element.d.ts +11 -1
  69. package/dist/types/shared/slot-utils.d.ts +24 -0
  70. package/dist/types/table/index.stories.d.ts +1 -0
  71. package/dist/types/table/table.component.d.ts +1 -1
  72. package/dist/types/toast/toast.d.ts +1 -1
  73. package/dist/types/toggle/index.d.ts +1 -1
  74. package/package.json +4 -4
@@ -1,27 +1,26 @@
1
- import { SlotContentInterface } from './slot-content.mixin';
2
1
  import { LitConstructor } from './shared.types';
3
2
  import { QuanticElement } from './quantic-element';
4
- export interface AutoHideEmptySlotsInterface extends SlotContentInterface {
5
- handleAutoHide(e: Event): void;
6
- }
7
3
  /**
8
- * Mixin that automatically hides empty slots using the `hidden` attribute.
9
- * Extends SlotContentMixin to inherit slot checking functionality.
4
+ * Mixin that automatically hides empty named slots using CSS only.
10
5
  *
11
- * This is useful for components with optional sections that should not
12
- * take up space or affect layout when empty.
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:
8
+ *
9
+ * - `:host(:has([slot="name"]))` — Safari and Firefox
10
+ * - `@scope { :scope:has([slot="name"]) }` — Chrome (@scope changes the
11
+ * evaluation context so :has() can see light DOM children)
12
+ *
13
+ * The reveal value is `display: revert-layer` rather than `display: block` so
14
+ * that the component's own display value is restored instead of overridden.
15
+ * Component styles are placed in `@layer quantic-component` and the
16
+ * hide/reveal rules in `@layer quantic-slot-visibility` (declared after, so
17
+ * higher priority). `revert-layer` then falls back to whatever the component
18
+ * set in `quantic-component`.
19
+ *
20
+ * CSS is injected via `finalizeStyles` so it lands in Lit SSR's Declarative
21
+ * Shadow DOM output — no JS, no layout shift.
13
22
  *
14
23
  * @example
15
- * ```typescript
16
- * class MyComponent extends AutoHideEmptySlotsMixin(QuanticElement) {
17
- * render() {
18
- * return html`
19
- * <slot name="header" @slotchange=${this.handleAutoHide}></slot>
20
- * <slot></slot>
21
- * <slot name="footer" @slotchange=${this.handleAutoHide}></slot>
22
- * `;
23
- * }
24
- * }
25
- * ```
24
+ * class MyElement extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {}
26
25
  */
27
- export declare const AutoHideEmptySlotsMixin: <T extends LitConstructor<QuanticElement>>(superClass: T) => T & LitConstructor<AutoHideEmptySlotsInterface>;
26
+ export declare const AutoHideEmptySlotsMixin: <T extends LitConstructor<QuanticElement>>(superClass: T, namedSlots?: string[]) => T;
@@ -1,51 +1,51 @@
1
- import { SlotContentMixin } from './slot-content.mixin';
1
+ import { unsafeCSS, } from 'lit';
2
2
  /**
3
- * Mixin that automatically hides empty slots using the `hidden` attribute.
4
- * Extends SlotContentMixin to inherit slot checking functionality.
3
+ * Mixin that automatically hides empty named slots using CSS only.
5
4
  *
6
- * This is useful for components with optional sections that should not
7
- * take up space or affect layout when empty.
5
+ * Each named slot is hidden by default and revealed when the host has a light
6
+ * DOM child with a matching `slot` attribute. Two rules cover all browsers:
7
+ *
8
+ * - `:host(:has([slot="name"]))` — Safari and Firefox
9
+ * - `@scope { :scope:has([slot="name"]) }` — Chrome (@scope changes the
10
+ * evaluation context so :has() can see light DOM children)
11
+ *
12
+ * The reveal value is `display: revert-layer` rather than `display: block` so
13
+ * that the component's own display value is restored instead of overridden.
14
+ * Component styles are placed in `@layer quantic-component` and the
15
+ * hide/reveal rules in `@layer quantic-slot-visibility` (declared after, so
16
+ * higher priority). `revert-layer` then falls back to whatever the component
17
+ * set in `quantic-component`.
18
+ *
19
+ * CSS is injected via `finalizeStyles` so it lands in Lit SSR's Declarative
20
+ * Shadow DOM output — no JS, no layout shift.
8
21
  *
9
22
  * @example
10
- * ```typescript
11
- * class MyComponent extends AutoHideEmptySlotsMixin(QuanticElement) {
12
- * render() {
13
- * return html`
14
- * <slot name="header" @slotchange=${this.handleAutoHide}></slot>
15
- * <slot></slot>
16
- * <slot name="footer" @slotchange=${this.handleAutoHide}></slot>
17
- * `;
18
- * }
19
- * }
20
- * ```
23
+ * class MyElement extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {}
21
24
  */
22
- export const AutoHideEmptySlotsMixin = (superClass) => {
23
- // First apply SlotContentMixin to get slot checking functionality
24
- const SlotContentBase = SlotContentMixin(superClass);
25
- class AutoHideEmptySlotsClass extends SlotContentBase {
26
- /**
27
- * Updates the visibility of a slot based on whether it has content.
28
- * @param slot The slot element to update
29
- */
30
- updateSlotVisibility(slot) {
31
- slot.toggleAttribute('hidden', this.isSlotEmpty(slot));
32
- }
33
- /**
34
- * Event handler for slotchange events.
35
- * Call this from your template to auto-hide slots on change.
36
- * @example `<slot name="header" @slotchange=${this.handleAutoHide}></slot>`
37
- */
38
- handleAutoHide(e) {
39
- this.updateSlotVisibility(e.target);
40
- }
41
- /**
42
- * Initialize slot visibility on first render.
43
- */
44
- firstUpdated(changedProperties) {
45
- super.firstUpdated(changedProperties);
46
- this.renderRoot
47
- .querySelectorAll('slot')
48
- .forEach((e) => this.updateSlotVisibility(e));
25
+ export const AutoHideEmptySlotsMixin = (superClass, namedSlots = []) => {
26
+ if (namedSlots.length === 0)
27
+ return superClass;
28
+ // A component may declare a native CSSStyleSheet, which Lit passes through
29
+ // untouched wherever adoptedStyleSheets is supported.
30
+ const toCssText = (style) => 'cssText' in style
31
+ ? style.cssText
32
+ : Array.from(style.cssRules, (rule) => rule.cssText).join('\n');
33
+ const slotRulesCSS = namedSlots
34
+ .map((name) => [
35
+ `slot[name="${name}"] { display: none; }`,
36
+ `:host(:has([slot="${name}"])) slot[name="${name}"] { display: revert-layer; }`,
37
+ `@scope { :scope:has([slot="${name}"]) slot[name="${name}"] { display: revert-layer; } }`,
38
+ ].join(' '))
39
+ .join(' ');
40
+ class AutoHideEmptySlotsClass extends superClass {
41
+ static finalizeStyles(styles) {
42
+ const base = superClass.finalizeStyles?.call(this, styles) ?? [];
43
+ const baseCSS = base.map(toCssText).join('\n');
44
+ return [
45
+ unsafeCSS(`@layer quantic-component, quantic-slot-visibility;` +
46
+ ` @layer quantic-component { ${baseCSS} }` +
47
+ ` @layer quantic-slot-visibility { ${slotRulesCSS} }`),
48
+ ];
49
49
  }
50
50
  }
51
51
  return AutoHideEmptySlotsClass;
@@ -1,4 +1,5 @@
1
1
  import { LitElement } from 'lit';
2
+ import type { LitConstructor } from './shared.types';
2
3
  import type { ComponentMeta } from './meta.types';
3
4
  /**
4
5
  * Base class for Quantic components.
@@ -8,10 +9,19 @@ export declare class QuanticElement extends LitElement {
8
9
  static meta?: ComponentMeta;
9
10
  static ensureDefined(): void;
10
11
  }
12
+ /**
13
+ * Any QuanticElement subclass, including the anonymous ones mixins and HOCs
14
+ * return — those are plain constructors, so their statics are declared here
15
+ * rather than inferred from `typeof QuanticElement`.
16
+ */
17
+ export type QuanticElementConstructor = LitConstructor<QuanticElement> & {
18
+ tagName?: string;
19
+ meta?: ComponentMeta;
20
+ };
11
21
  /**
12
22
  * Decorator that registers a QuanticElement subclass as a custom element and sets its tagName.
13
23
  * The class must extend QuanticElement to inherit the ensureDefined() static method.
14
24
  *
15
25
  * @param tagName - The custom element tag name (e.g., 'quantic-badge')
16
26
  */
17
- export declare function quanticElement(tagName: string): <T extends typeof QuanticElement>(target: T) => T;
27
+ export declare function quanticElement(tagName: string): <T extends QuanticElementConstructor>(target: T) => T;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Returns true if a slot has at least one non-whitespace node assigned.
3
+ */
4
+ export declare function slotHasContent(slot: HTMLSlotElement): boolean;
5
+ /**
6
+ * Returns the concatenated trimmed text content of all assigned nodes.
7
+ */
8
+ export declare function slotTextContent(slot: HTMLSlotElement): string;
9
+ /**
10
+ * Returns a slotchange event handler that calls `setter` with whether the slot
11
+ * has non-empty content.
12
+ *
13
+ * @example
14
+ * html`<slot @slotchange=${onSlotChange((has) => (this._hasLabel = has))}></slot>`
15
+ */
16
+ export declare function onSlotChange(setter: (has: boolean) => void): (e: Event) => void;
17
+ /**
18
+ * Returns a slotchange event handler that calls `setter` with the slot's text
19
+ * content, falling back to `''` when empty.
20
+ *
21
+ * @example
22
+ * html`<slot @slotchange=${onSlotTextChange((t) => (this._labelText = t))}></slot>`
23
+ */
24
+ export declare function onSlotTextChange(setter: (text: string) => void): (e: Event) => void;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Returns true if a slot has at least one non-whitespace node assigned.
3
+ */
4
+ export function slotHasContent(slot) {
5
+ return slot
6
+ .assignedNodes({ flatten: true })
7
+ .some((n) => n.nodeType !== Node.TEXT_NODE || (n.textContent?.trim() ?? '') !== '');
8
+ }
9
+ /**
10
+ * Returns the concatenated trimmed text content of all assigned nodes.
11
+ */
12
+ export function slotTextContent(slot) {
13
+ return slot
14
+ .assignedNodes({ flatten: true })
15
+ .map((n) => n.textContent?.trim() ?? '')
16
+ .filter(Boolean)
17
+ .join(' ');
18
+ }
19
+ /**
20
+ * Returns a slotchange event handler that calls `setter` with whether the slot
21
+ * has non-empty content.
22
+ *
23
+ * @example
24
+ * html`<slot @slotchange=${onSlotChange((has) => (this._hasLabel = has))}></slot>`
25
+ */
26
+ export function onSlotChange(setter) {
27
+ return (e) => setter(slotHasContent(e.target));
28
+ }
29
+ /**
30
+ * Returns a slotchange event handler that calls `setter` with the slot's text
31
+ * content, falling back to `''` when empty.
32
+ *
33
+ * @example
34
+ * html`<slot @slotchange=${onSlotTextChange((t) => (this._labelText = t))}></slot>`
35
+ */
36
+ export function onSlotTextChange(setter) {
37
+ return (e) => setter(slotTextContent(e.target));
38
+ }
@@ -20,4 +20,5 @@ export declare const WithToolbar: import("../shared/story").StoryObject<Args>;
20
20
  export declare const WithControls: import("../shared/story").StoryObject<Args>;
21
21
  export declare const WithToolbarAndControls: import("../shared/story").StoryObject<Args>;
22
22
  export declare const SortChange: import("../shared/story").StoryObject<Args>;
23
+ export declare const EmptyOptionalSlots: any;
23
24
  export declare const CustomColumnWidths: import("../shared/story").StoryObject<Args>;
@@ -178,6 +178,25 @@ export const SortChange = story({
178
178
  </quantic-panel>
179
179
  </div>
180
180
  `);
181
+ // TODO: remove once autohide CSS fix is verified — toolbar, footer, and controls slot wrappers should be invisible, not red
182
+ export const EmptyOptionalSlots = Object.assign(story({
183
+ description: 'Table without toolbar, footer, or controls — their slot wrappers should be invisible. A red bar means the autohide fix is missing.',
184
+ }).render(() => `
185
+ <quantic-table>
186
+ <quantic-table-header slot="header">
187
+ <quantic-table-row>
188
+ <quantic-table-head>Name</quantic-table-head>
189
+ <quantic-table-head>Type</quantic-table-head>
190
+ </quantic-table-row>
191
+ </quantic-table-header>
192
+ <quantic-table-body>
193
+ <quantic-table-row>
194
+ <quantic-table-cell>Example row</quantic-table-cell>
195
+ <quantic-table-cell>Data</quantic-table-cell>
196
+ </quantic-table-row>
197
+ </quantic-table-body>
198
+ </quantic-table>
199
+ `));
181
200
  export const CustomColumnWidths = story({
182
201
  args: { size: TableSize.Medium, variant: TableVariant.Outline, dense: false },
183
202
  }).render(({ size, variant, dense }) => `
@@ -1,7 +1,7 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import { TableSize, TableVariant } from './index.constants';
3
3
  import type { ComponentMeta } from '../shared/meta.types';
4
- declare const Table_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
4
+ declare const Table_base: typeof QuanticElement;
5
5
  export declare class Table extends Table_base {
6
6
  static meta: ComponentMeta;
7
7
  size: TableSize;
@@ -12,7 +12,7 @@ import { tableVariantContext } from './index.context';
12
12
  import { AutoHideEmptySlotsMixin } from '../shared/auto-hide-empty-slots.mixin';
13
13
  import { ifDefined } from 'lit/directives/if-defined.js';
14
14
  import { prop } from '../shared/component-meta.decorators';
15
- let Table = class Table extends AutoHideEmptySlotsMixin(QuanticElement) {
15
+ let Table = class Table extends AutoHideEmptySlotsMixin(QuanticElement, ['toolbar', 'header', 'footer', 'controls']) {
16
16
  constructor() {
17
17
  super(...arguments);
18
18
  this.size = TableSize.Medium;
@@ -22,11 +22,7 @@ let Table = class Table extends AutoHideEmptySlotsMixin(QuanticElement) {
22
22
  }
23
23
  render() {
24
24
  return html `
25
- <slot
26
- name="toolbar"
27
- class="toolbar"
28
- @slotchange=${this.handleAutoHide}
29
- ></slot>
25
+ <slot name="toolbar" class="toolbar"></slot>
30
26
  <div
31
27
  role="table"
32
28
  class="table"
@@ -37,11 +33,7 @@ let Table = class Table extends AutoHideEmptySlotsMixin(QuanticElement) {
37
33
  <slot></slot>
38
34
  <slot name="footer"></slot>
39
35
  </div>
40
- <slot
41
- name="controls"
42
- class="controls"
43
- @slotchange=${this.handleAutoHide}
44
- ></slot>
36
+ <slot name="controls" class="controls"></slot>
45
37
  `;
46
38
  }
47
39
  };
@@ -3,7 +3,7 @@ import { QuanticElement } from '../shared/quantic-element';
3
3
  import { ToastType } from './index.constants';
4
4
  import type { ComponentMeta } from '../shared/meta.types';
5
5
  export { ToastType } from './index.constants';
6
- declare const Toast_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
6
+ declare const Toast_base: typeof QuanticElement;
7
7
  export declare class Toast extends Toast_base {
8
8
  static meta: ComponentMeta;
9
9
  open: boolean;
@@ -23,7 +23,7 @@ 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, ['title', 'action']) {
27
27
  constructor() {
28
28
  super(...arguments);
29
29
  this.open = false;
@@ -80,17 +80,9 @@ let Toast = class Toast extends AutoHideEmptySlotsMixin(QuanticElement) {
80
80
  <slot name="icon">${this.renderDefaultIcon()}</slot>
81
81
  </span>
82
82
  <div class="content">
83
- <slot
84
- name="title"
85
- class="title"
86
- @slotchange=${this.handleAutoHide}
87
- ></slot>
88
- <slot class="body" @slotchange=${this.handleAutoHide}></slot>
89
- <slot
90
- name="action"
91
- class="action"
92
- @slotchange=${this.handleAutoHide}
93
- ></slot>
83
+ <slot name="title" class="title"></slot>
84
+ <slot class="body"></slot>
85
+ <slot name="action" class="action"></slot>
94
86
  </div>
95
87
  ${this.showCloseButton
96
88
  ? html `<quantic-button
@@ -14,7 +14,7 @@ declare const Toggle_base: {
14
14
  invalid?: boolean;
15
15
  } | undefined): import("../shared/a11y-attributes.mixin").A11yAttributeValues;
16
16
  };
17
- } & typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/slot-content.mixin").SlotContentInterface>;
17
+ } & typeof QuanticElement;
18
18
  export declare class Toggle extends Toggle_base {
19
19
  static meta: ComponentMeta;
20
20
  static formAssociated: boolean;
@@ -8,11 +8,10 @@ import { css, html } from 'lit';
8
8
  import { quanticElement, QuanticElement } from '../shared/quantic-element';
9
9
  import { classMap } from 'lit/directives/class-map.js';
10
10
  import { ToggleSize } from './index.constants';
11
- import { SlotContentMixin } from '../shared/slot-content.mixin';
12
11
  import { A11yAttributesMixin } from '../shared/a11y-attributes.mixin';
13
12
  import { event, prop } from '../shared/component-meta.decorators';
14
13
  export { ToggleSize } from './index.constants';
15
- let Toggle = class Toggle extends A11yAttributesMixin(SlotContentMixin(QuanticElement)) {
14
+ let Toggle = class Toggle extends A11yAttributesMixin(QuanticElement) {
16
15
  constructor() {
17
16
  super();
18
17
  this.checked = false;
@@ -3,7 +3,7 @@ import { QuanticElement } from '../shared/quantic-element';
3
3
  import { AlertType } from './index.constants';
4
4
  import type { ComponentMeta } from '../shared/meta.types';
5
5
  export { AlertType } from './index.constants';
6
- declare const Alert_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
6
+ declare const Alert_base: typeof QuanticElement;
7
7
  export declare class Alert extends Alert_base {
8
8
  static meta: ComponentMeta;
9
9
  type: AlertType;
@@ -1,6 +1,6 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import type { ComponentMeta } from '../shared/meta.types';
3
- declare const CardTitle_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
3
+ declare const CardTitle_base: typeof QuanticElement;
4
4
  export declare class CardTitle extends CardTitle_base {
5
5
  static meta: ComponentMeta;
6
6
  static styles: import("lit").CSSResult;
@@ -1,7 +1,7 @@
1
1
  import { CardVariant, CardSize } from './index.constants';
2
2
  import { QuanticElement } from '../shared/quantic-element';
3
3
  import type { ComponentMeta } from '../shared/meta.types';
4
- declare const Card_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
4
+ declare const Card_base: typeof QuanticElement;
5
5
  export declare class Card extends Card_base {
6
6
  static meta: ComponentMeta;
7
7
  as: keyof Pick<HTMLElementTagNameMap, 'div' | 'button' | 'a'>;
@@ -13,6 +13,7 @@ export declare class Card extends Card_base {
13
13
  target: string | undefined;
14
14
  rel: string | undefined;
15
15
  download: string | undefined;
16
+ private hasActionIconSlot;
16
17
  static styles: import("lit").CSSResult;
17
18
  render(): import("lit").TemplateResult;
18
19
  }
@@ -1,6 +1,6 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import type { ComponentMeta } from '../shared/meta.types';
3
- declare const DialogTitle_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
3
+ declare const DialogTitle_base: typeof QuanticElement;
4
4
  export declare class DialogTitle extends DialogTitle_base {
5
5
  static meta: ComponentMeta;
6
6
  level: '1' | '2' | '3' | '4' | '5' | '6';
@@ -3,7 +3,7 @@ import { QuanticElement } from '../shared/quantic-element';
3
3
  import { DialogSize, DialogBackdrop, DialogRole } from './index.constants';
4
4
  import type { ComponentMeta } from '../shared/meta.types';
5
5
  export { DialogSize, DialogBackdrop, DialogRole } from './index.constants';
6
- declare const Dialog_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
6
+ declare const Dialog_base: typeof QuanticElement;
7
7
  export declare class Dialog extends Dialog_base {
8
8
  static meta: ComponentMeta;
9
9
  open: boolean;
@@ -1,9 +1,10 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import type { ComponentMeta } from '../shared/meta.types';
3
- declare const DropdownMenuGroup_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
3
+ declare const DropdownMenuGroup_base: typeof QuanticElement;
4
4
  export declare class DropdownMenuGroup extends DropdownMenuGroup_base {
5
5
  static meta: ComponentMeta;
6
6
  label: string;
7
+ private hasLabelSlot;
7
8
  static styles: import("lit").CSSResult;
8
9
  render(): import("lit").TemplateResult<1>;
9
10
  }
@@ -1,8 +1,7 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import { FieldValidationStatus, FieldSize, FieldHintPosition } from './index.constants';
3
3
  import type { ComponentMeta } from '../shared/meta.types';
4
- declare const Field_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/slot-content.mixin").SlotContentInterface>;
5
- export declare class Field extends Field_base {
4
+ export declare class Field extends QuanticElement {
6
5
  static meta: ComponentMeta;
7
6
  fieldId: string;
8
7
  label: string;
@@ -12,7 +11,9 @@ export declare class Field extends Field_base {
12
11
  status: FieldValidationStatus | undefined;
13
12
  size: FieldSize;
14
13
  hintPosition: FieldHintPosition;
14
+ private hasLabelSlot;
15
+ private hasHintSlot;
16
+ private hasMessageSlot;
15
17
  static styles: import("lit").CSSResult[];
16
18
  render(): import("lit").TemplateResult<1>;
17
19
  }
18
- export {};
@@ -16,4 +16,4 @@ export type FieldProps = {
16
16
  required: boolean;
17
17
  status: FieldValidationStatus | undefined;
18
18
  };
19
- export declare function renderAsField<T extends typeof QuanticElement>(name: string, InputComponent: T, renderInput: (this: InstanceType<T>, a11yContext: FieldA11yContext | null) => TemplateResult): T & LitConstructor<FieldProps>;
19
+ export declare function renderAsField<T extends LitConstructor<QuanticElement>>(name: string, InputComponent: T, renderInput: (this: InstanceType<T>, a11yContext: FieldA11yContext | null) => TemplateResult): T & LitConstructor<FieldProps>;
@@ -1,11 +1,11 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import type { ComponentMeta } from '../shared/meta.types';
3
- declare const InlineEdit_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/slot-content.mixin").SlotContentInterface>;
4
- export declare class InlineEdit extends InlineEdit_base {
3
+ export declare class InlineEdit extends QuanticElement {
5
4
  static meta: ComponentMeta;
6
5
  label: string;
7
6
  active: boolean;
8
7
  invalid: boolean;
8
+ private hasLabelSlot;
9
9
  connectedCallback(): void;
10
10
  disconnectedCallback(): void;
11
11
  static styles: import("lit").CSSResult;
@@ -17,4 +17,3 @@ export declare class InlineEdit extends InlineEdit_base {
17
17
  private handleFocusOut;
18
18
  render(): import("lit").TemplateResult<1>;
19
19
  }
20
- export {};
@@ -2,12 +2,16 @@ import { type PropertyValues } from 'lit';
2
2
  import { LayoutVariant } from './index.constants';
3
3
  import { QuanticElement } from '../shared/quantic-element';
4
4
  import type { ComponentMeta } from '../shared/meta.types';
5
- declare const Layout_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
5
+ declare const Layout_base: typeof QuanticElement;
6
6
  export declare class Layout extends Layout_base {
7
7
  static meta: ComponentMeta;
8
8
  variant: LayoutVariant;
9
9
  private isSmallViewport;
10
10
  private previousIsSmallViewport?;
11
+ private hasSidebarSlot;
12
+ private hasTitlebarSlot;
13
+ private hasNavbarSlot;
14
+ private hasLogoSlot;
11
15
  private asideElement?;
12
16
  private toggleButtonElement?;
13
17
  private focusTrap?;
@@ -23,7 +27,6 @@ export declare class Layout extends Layout_base {
23
27
  disconnectedCallback(): void;
24
28
  protected willUpdate(_props: PropertyValues): void;
25
29
  protected updated(props: PropertyValues): void;
26
- private handleSlotChange;
27
30
  static styles: import("lit").CSSResult;
28
31
  private get isAsideCollapsible();
29
32
  private get hasSidebar();
@@ -1,6 +1,6 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import type { ComponentMeta } from '../shared/meta.types';
3
- declare const Sidebar_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
3
+ declare const Sidebar_base: typeof QuanticElement;
4
4
  export declare class Sidebar extends Sidebar_base {
5
5
  static meta: ComponentMeta;
6
6
  isAsideExpanded?: boolean;
@@ -3,7 +3,7 @@ import { QuanticElement } from '../shared/quantic-element';
3
3
  import { OptionCardVariant, OptionCardSize } from './index.constants';
4
4
  import { type OptionCardGroupContext } from './index.context';
5
5
  import type { ComponentMeta } from '../shared/meta.types';
6
- declare const OptionCard_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
6
+ declare const OptionCard_base: typeof QuanticElement;
7
7
  export declare class OptionCard extends OptionCard_base {
8
8
  static meta: ComponentMeta;
9
9
  static formAssociated: boolean;
@@ -1,7 +1,7 @@
1
1
  import { PanelHeaderSize } from './index.constants';
2
2
  import { QuanticElement } from '../shared/quantic-element';
3
3
  import type { ComponentMeta } from '../shared/meta.types';
4
- declare const PanelHeader_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
4
+ declare const PanelHeader_base: typeof QuanticElement;
5
5
  export declare class PanelHeader extends PanelHeader_base {
6
6
  static meta: ComponentMeta;
7
7
  size: PanelHeaderSize;
@@ -1,7 +1,7 @@
1
1
  import { PanelVariant } from './index.constants';
2
2
  import { QuanticElement } from '../shared/quantic-element';
3
3
  import type { ComponentMeta } from '../shared/meta.types';
4
- declare const Panel_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
4
+ declare const Panel_base: typeof QuanticElement;
5
5
  export declare class Panel extends Panel_base {
6
6
  static meta: ComponentMeta;
7
7
  variant: PanelVariant;
@@ -1,6 +1,6 @@
1
1
  import { QuanticElement } from '../shared/quantic-element';
2
2
  import type { ComponentMeta } from '../shared/meta.types';
3
- declare const PopoverPopup_base: typeof QuanticElement & import("../shared/shared.types").LitConstructor<import("../shared/auto-hide-empty-slots.mixin").AutoHideEmptySlotsInterface>;
3
+ declare const PopoverPopup_base: typeof QuanticElement;
4
4
  export declare class PopoverPopup extends PopoverPopup_base {
5
5
  static meta: ComponentMeta;
6
6
  visible: boolean;
@@ -43,7 +43,7 @@ export declare class Popover extends QuanticElement {
43
43
  isRightAligned(): boolean;
44
44
  isTopAligned(): boolean;
45
45
  isBottomAligned(): boolean;
46
- get originY(): 1 | -1 | 0;
47
- get originX(): 1 | -1 | 0;
46
+ get originY(): 0 | 1 | -1;
47
+ get originX(): 0 | 1 | -1;
48
48
  render(): import("lit").TemplateResult<1>;
49
49
  }
@@ -1,27 +1,26 @@
1
- import { SlotContentInterface } from './slot-content.mixin';
2
1
  import { LitConstructor } from './shared.types';
3
2
  import { QuanticElement } from './quantic-element';
4
- export interface AutoHideEmptySlotsInterface extends SlotContentInterface {
5
- handleAutoHide(e: Event): void;
6
- }
7
3
  /**
8
- * Mixin that automatically hides empty slots using the `hidden` attribute.
9
- * Extends SlotContentMixin to inherit slot checking functionality.
4
+ * Mixin that automatically hides empty named slots using CSS only.
10
5
  *
11
- * This is useful for components with optional sections that should not
12
- * take up space or affect layout when empty.
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:
8
+ *
9
+ * - `:host(:has([slot="name"]))` — Safari and Firefox
10
+ * - `@scope { :scope:has([slot="name"]) }` — Chrome (@scope changes the
11
+ * evaluation context so :has() can see light DOM children)
12
+ *
13
+ * The reveal value is `display: revert-layer` rather than `display: block` so
14
+ * that the component's own display value is restored instead of overridden.
15
+ * Component styles are placed in `@layer quantic-component` and the
16
+ * hide/reveal rules in `@layer quantic-slot-visibility` (declared after, so
17
+ * higher priority). `revert-layer` then falls back to whatever the component
18
+ * set in `quantic-component`.
19
+ *
20
+ * CSS is injected via `finalizeStyles` so it lands in Lit SSR's Declarative
21
+ * Shadow DOM output — no JS, no layout shift.
13
22
  *
14
23
  * @example
15
- * ```typescript
16
- * class MyComponent extends AutoHideEmptySlotsMixin(QuanticElement) {
17
- * render() {
18
- * return html`
19
- * <slot name="header" @slotchange=${this.handleAutoHide}></slot>
20
- * <slot></slot>
21
- * <slot name="footer" @slotchange=${this.handleAutoHide}></slot>
22
- * `;
23
- * }
24
- * }
25
- * ```
24
+ * class MyElement extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {}
26
25
  */
27
- export declare const AutoHideEmptySlotsMixin: <T extends LitConstructor<QuanticElement>>(superClass: T) => T & LitConstructor<AutoHideEmptySlotsInterface>;
26
+ export declare const AutoHideEmptySlotsMixin: <T extends LitConstructor<QuanticElement>>(superClass: T, namedSlots?: string[]) => T;