@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
@@ -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;
@@ -22,7 +22,7 @@ LucideIconCircleX.ensureDefined();
22
22
  LucideIconInfo.ensureDefined();
23
23
  LucideIconTriangleAlert.ensureDefined();
24
24
  LucideIconX.ensureDefined();
25
- let Alert = class Alert extends AutoHideEmptySlotsMixin(QuanticElement) {
25
+ let Alert = class Alert extends AutoHideEmptySlotsMixin(QuanticElement, ['title', 'action']) {
26
26
  constructor() {
27
27
  super(...arguments);
28
28
  this.type = AlertType.Info;
@@ -67,17 +67,9 @@ let Alert = class Alert extends AutoHideEmptySlotsMixin(QuanticElement) {
67
67
  <slot name="icon">${this.renderDefaultIcon()}</slot>
68
68
  </span>
69
69
  <div class="content">
70
- <slot
71
- name="title"
72
- class="title"
73
- @slotchange=${this.handleAutoHide}
74
- ></slot>
75
- <slot class="body" @slotchange=${this.handleAutoHide}></slot>
76
- <slot
77
- name="action"
78
- class="action"
79
- @slotchange=${this.handleAutoHide}
80
- ></slot>
70
+ <slot name="title" class="title"></slot>
71
+ <slot class="body"></slot>
72
+ <slot name="action" class="action"></slot>
81
73
  </div>
82
74
  ${this.showCloseButton
83
75
  ? html `<quantic-button
@@ -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;
@@ -8,21 +8,13 @@ import { css } from 'lit';
8
8
  import { html } from 'lit/static-html.js';
9
9
  import { QuanticElement, quanticElement } from '../shared/quantic-element';
10
10
  import { AutoHideEmptySlotsMixin } from '../shared/auto-hide-empty-slots.mixin';
11
- let CardTitle = class CardTitle extends AutoHideEmptySlotsMixin(QuanticElement) {
11
+ let CardTitle = class CardTitle extends AutoHideEmptySlotsMixin(QuanticElement, ['pretitle', 'subtitle']) {
12
12
  render() {
13
13
  return html `
14
14
  <hgroup>
15
- <slot
16
- name="pretitle"
17
- class="pretitle"
18
- @slotchange=${this.handleAutoHide}
19
- ></slot>
20
- <slot class="title" @slotchange=${this.handleAutoHide}></slot>
21
- <slot
22
- name="subtitle"
23
- class="subtitle"
24
- @slotchange=${this.handleAutoHide}
25
- ></slot>
15
+ <slot name="pretitle" class="pretitle"></slot>
16
+ <slot class="title"></slot>
17
+ <slot name="subtitle" class="subtitle"></slot>
26
18
  </hgroup>
27
19
  `;
28
20
  }
@@ -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
  }
@@ -5,14 +5,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { css } from 'lit';
8
+ import { state } from 'lit/decorators.js';
8
9
  import { html } from 'lit/static-html.js';
10
+ import { onSlotChange } from '../shared/slot-utils';
9
11
  import { CardVariant, CardSize } from './index.constants';
10
12
  import { classMap } from 'lit/directives/class-map.js';
11
13
  import { ifDefined } from 'lit/directives/if-defined.js';
12
14
  import { AutoHideEmptySlotsMixin } from '../shared/auto-hide-empty-slots.mixin';
13
15
  import { QuanticElement, quanticElement } from '../shared/quantic-element';
14
16
  import { prop } from '../shared/component-meta.decorators';
15
- let Card = class Card extends AutoHideEmptySlotsMixin(QuanticElement) {
17
+ let Card = class Card extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer', 'action-icon']) {
16
18
  constructor() {
17
19
  super(...arguments);
18
20
  this.as = 'div';
@@ -20,6 +22,7 @@ let Card = class Card extends AutoHideEmptySlotsMixin(QuanticElement) {
20
22
  this.size = CardSize.Medium;
21
23
  this.type = 'button';
22
24
  this.disabled = false;
25
+ this.hasActionIconSlot = false;
23
26
  }
24
27
  render() {
25
28
  const classes = classMap({
@@ -28,35 +31,28 @@ let Card = class Card extends AutoHideEmptySlotsMixin(QuanticElement) {
28
31
  [`size--${this.size}`]: true,
29
32
  ['is-interactive']: this.as === 'button' || this.as === 'a',
30
33
  ['is-disabled']: this.disabled,
31
- [`has-action-icon`]: this.hasSlotContent('action-icon'),
34
+ [`has-action-icon`]: this.hasActionIconSlot,
32
35
  });
33
- const handleSlotChange = (e) => {
34
- this.handleAutoHide(e);
35
- this.requestUpdate();
36
- };
37
36
  const slots = html `
38
37
  <slot
39
38
  name="header"
40
39
  class="header"
41
40
  data-description="Header area — place quantic-card-title and quantic-card-meta here."
42
- @slotchange=${handleSlotChange}
43
41
  ></slot>
44
42
  <slot
45
43
  class="body"
46
44
  data-description="Main body content."
47
- @slotchange=${handleSlotChange}
48
45
  ></slot>
49
46
  <slot
50
47
  name="footer"
51
48
  class="footer"
52
49
  data-description="Footer content, pinned to the bottom of the card."
53
- @slotchange=${handleSlotChange}
54
50
  ></slot>
55
51
  <slot
56
52
  name="action-icon"
57
53
  class="action-icon"
58
54
  data-description="Icon in the top-right corner; only visible on interactive cards."
59
- @slotchange=${handleSlotChange}
55
+ @slotchange=${onSlotChange((has) => (this.hasActionIconSlot = has))}
60
56
  ></slot>
61
57
  `;
62
58
  if (this.as === 'button') {
@@ -323,6 +319,9 @@ __decorate([
323
319
  __decorate([
324
320
  prop({ type: 'string', description: 'Download filename (as="a" only).' })
325
321
  ], Card.prototype, "download", void 0);
322
+ __decorate([
323
+ state()
324
+ ], Card.prototype, "hasActionIconSlot", void 0);
326
325
  Card = __decorate([
327
326
  quanticElement('quantic-card')
328
327
  ], Card);
@@ -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';
@@ -8,7 +8,7 @@ import { css, html } 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 { prop } from '../shared/component-meta.decorators';
11
- let DialogTitle = class DialogTitle extends AutoHideEmptySlotsMixin(QuanticElement) {
11
+ let DialogTitle = class DialogTitle extends AutoHideEmptySlotsMixin(QuanticElement, ['pretitle', 'subtitle']) {
12
12
  constructor() {
13
13
  super(...arguments);
14
14
  this.level = '2';
@@ -17,19 +17,11 @@ let DialogTitle = class DialogTitle extends AutoHideEmptySlotsMixin(QuanticEleme
17
17
  return html `
18
18
  <div class="main">
19
19
  <hgroup>
20
- <slot
21
- name="pretitle"
22
- class="pretitle"
23
- @slotchange=${this.handleAutoHide}
24
- ></slot>
20
+ <slot name="pretitle" class="pretitle"></slot>
25
21
  <div class="title" role="heading" aria-level=${this.level}>
26
22
  <slot></slot>
27
23
  </div>
28
- <slot
29
- name="subtitle"
30
- class="subtitle"
31
- @slotchange=${this.handleAutoHide}
32
- ></slot>
24
+ <slot name="subtitle" class="subtitle"></slot>
33
25
  </hgroup>
34
26
  </div>
35
27
  `;
@@ -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;
@@ -21,7 +21,7 @@ export { DialogSize, DialogBackdrop, DialogRole } from './index.constants';
21
21
  DialogBackdropElement.ensureDefined();
22
22
  Button.ensureDefined();
23
23
  LucideIconX.ensureDefined();
24
- let Dialog = class Dialog extends AutoHideEmptySlotsMixin(QuanticElement) {
24
+ let Dialog = class Dialog extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer']) {
25
25
  constructor() {
26
26
  super(...arguments);
27
27
  this.open = false;
@@ -280,20 +280,11 @@ let Dialog = class Dialog extends AutoHideEmptySlotsMixin(QuanticElement) {
280
280
  </quantic-button>`
281
281
  : ''}
282
282
 
283
- <slot
284
- class="header"
285
- name="header"
286
- id=${this.headerId}
287
- @slotchange=${this.handleAutoHide}
288
- ></slot>
283
+ <slot class="header" name="header" id=${this.headerId}></slot>
289
284
 
290
- <slot class="body" @slotchange=${this.handleAutoHide}></slot>
285
+ <slot class="body"></slot>
291
286
 
292
- <slot
293
- class="footer"
294
- name="footer"
295
- @slotchange=${this.handleAutoHide}
296
- ></slot>
287
+ <slot class="footer" name="footer"></slot>
297
288
  </div>
298
289
  </div>
299
290
  `;
@@ -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
  }
@@ -5,19 +5,22 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { css, html, nothing } from 'lit';
8
+ import { state } from 'lit/decorators.js';
8
9
  import { quanticElement, QuanticElement } from '../shared/quantic-element';
9
10
  import { prop } from '../shared/component-meta.decorators';
10
11
  import { AutoHideEmptySlotsMixin } from '../shared/auto-hide-empty-slots.mixin';
11
- let DropdownMenuGroup = class DropdownMenuGroup extends AutoHideEmptySlotsMixin(QuanticElement) {
12
+ import { onSlotChange } from '../shared/slot-utils';
13
+ let DropdownMenuGroup = class DropdownMenuGroup extends AutoHideEmptySlotsMixin(QuanticElement, ['label']) {
12
14
  constructor() {
13
15
  super(...arguments);
14
16
  this.label = '';
17
+ this.hasLabelSlot = false;
15
18
  }
16
19
  render() {
17
- const hasLabel = this.label || this.hasSlotContent('label');
20
+ const hasLabel = this.label || this.hasLabelSlot;
18
21
  return html `
19
22
  <div class="label" id="group-label" ?hidden=${!hasLabel}>
20
- <slot name="label">${this.label}</slot>
23
+ <slot name="label" @slotchange=${onSlotChange((has) => (this.hasLabelSlot = has))}>${this.label}</slot>
21
24
  </div>
22
25
  <div
23
26
  class="items"
@@ -86,6 +89,9 @@ __decorate([
86
89
  description: 'Section heading displayed above the group items.',
87
90
  })
88
91
  ], DropdownMenuGroup.prototype, "label", void 0);
92
+ __decorate([
93
+ state()
94
+ ], DropdownMenuGroup.prototype, "hasLabelSlot", void 0);
89
95
  DropdownMenuGroup = __decorate([
90
96
  quanticElement('quantic-dropdown-menu-group')
91
97
  ], DropdownMenuGroup);
@@ -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 {};
@@ -5,12 +5,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { html, css } from 'lit';
8
+ import { state } from 'lit/decorators.js';
8
9
  import { quanticElement, QuanticElement } from '../shared/quantic-element';
9
10
  import { classMap } from 'lit/directives/class-map.js';
10
11
  import { FieldValidationStatus, FieldSize, FieldHintPosition, } from './index.constants';
11
- import { SlotContentMixin } from '../shared/slot-content.mixin';
12
12
  import { prop } from '../shared/component-meta.decorators';
13
- let Field = class Field extends SlotContentMixin(QuanticElement) {
13
+ import { onSlotChange } from '../shared/slot-utils';
14
+ let Field = class Field extends QuanticElement {
14
15
  constructor() {
15
16
  super(...arguments);
16
17
  this.fieldId = '';
@@ -20,48 +21,57 @@ let Field = class Field extends SlotContentMixin(QuanticElement) {
20
21
  this.required = false;
21
22
  this.size = FieldSize.Medium;
22
23
  this.hintPosition = FieldHintPosition.Below;
24
+ this.hasLabelSlot = false;
25
+ this.hasHintSlot = false;
26
+ this.hasMessageSlot = false;
23
27
  }
24
28
  render() {
25
- const hasLabel = !!this.getSlotTextContent('label') || this.label;
26
- const hasHint = !!this.getSlotTextContent('hint') || this.hint;
27
- const hasMessage = !!this.getSlotTextContent('message') || this.message;
28
- const hintTemplate = hasHint
29
- ? html `
30
- <div id="hint-${this.fieldId}" class="hint">
31
- <slot name="hint">${this.hint}</slot>
32
- </div>
33
- `
34
- : '';
29
+ const hasLabel = this.hasLabelSlot || !!this.label;
30
+ const hasHint = this.hasHintSlot || !!this.hint;
31
+ const hasMessage = this.hasMessageSlot || !!this.message;
32
+ const hintTemplate = html `
33
+ <div
34
+ id="hint-${this.fieldId}"
35
+ class=${classMap({ hint: true, 'is-empty': !hasHint })}
36
+ >
37
+ <slot
38
+ name="hint"
39
+ @slotchange=${onSlotChange((v) => (this.hasHintSlot = v))}
40
+ >${this.hint}</slot>
41
+ </div>
42
+ `;
35
43
  return html `
36
44
  <div class=${classMap({ main: true, [`size--${this.size}`]: true })}>
37
- ${hasLabel
38
- ? html `
39
- <label id=${this.fieldId} class="label">
40
- <slot name="label">${this.label}</slot>
41
- ${this.required
42
- ? html `<span class="required-indicator">*</span>`
43
- : ''}
44
- </label>
45
- `
45
+ <label
46
+ id=${this.fieldId}
47
+ class=${classMap({ label: true, 'is-empty': !hasLabel })}
48
+ >
49
+ <slot
50
+ name="label"
51
+ @slotchange=${onSlotChange((v) => (this.hasLabelSlot = v))}
52
+ >${this.label}</slot>
53
+ ${this.required
54
+ ? html `<span class="required-indicator">*</span>`
46
55
  : ''}
56
+ </label>
47
57
  ${this.hintPosition === 'above' ? hintTemplate : ''}
48
58
  <div class="control">
49
59
  <slot></slot>
50
60
  ${this.hintPosition === 'below' ? hintTemplate : ''}
51
- ${hasMessage
52
- ? html `
53
- <div
54
- id="message-${this.fieldId}"
55
- class=${classMap({
56
- message: true,
57
- [`message--state-${this.status}`]: !!this.status,
58
- })}
59
- role="alert"
60
- >
61
- <slot name="message">${this.message}</slot>
62
- </div>
63
- `
64
- : ''}
61
+ <div
62
+ id="message-${this.fieldId}"
63
+ class=${classMap({
64
+ message: true,
65
+ 'is-empty': !hasMessage,
66
+ [`message--state-${this.status}`]: !!this.status,
67
+ })}
68
+ role="alert"
69
+ >
70
+ <slot
71
+ name="message"
72
+ @slotchange=${onSlotChange((v) => (this.hasMessageSlot = v))}
73
+ >${this.message}</slot>
74
+ </div>
65
75
  </div>
66
76
  </div>
67
77
  `;
@@ -127,6 +137,11 @@ Field.styles = [
127
137
  color: var(--quantic-text-secondary);
128
138
  }
129
139
 
140
+ /* Sections render unconditionally so their slots exist to fire slotchange. */
141
+ .is-empty {
142
+ display: none;
143
+ }
144
+
130
145
  .size--xs {
131
146
  --quantic-component-field-label-font-size: var(
132
147
  --quantic-font-size-body-xs
@@ -235,6 +250,15 @@ __decorate([
235
250
  __decorate([
236
251
  prop({ type: 'FieldHintPosition', options: Object.values(FieldHintPosition), default: FieldHintPosition.Below, attribute: 'hint-position', description: 'Position of the hint relative to the control.' })
237
252
  ], Field.prototype, "hintPosition", void 0);
253
+ __decorate([
254
+ state()
255
+ ], Field.prototype, "hasLabelSlot", void 0);
256
+ __decorate([
257
+ state()
258
+ ], Field.prototype, "hasHintSlot", void 0);
259
+ __decorate([
260
+ state()
261
+ ], Field.prototype, "hasMessageSlot", void 0);
238
262
  Field = __decorate([
239
263
  quanticElement(`quantic-field`)
240
264
  ], Field);
@@ -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>;
@@ -5,9 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { html, noChange } from 'lit';
8
+ import { state } from 'lit/decorators.js';
9
+ import { onSlotTextChange } from '../shared/slot-utils';
8
10
  import { FieldValidationStatus } from './index.constants';
9
11
  import { prop } from '../shared/component-meta.decorators';
10
- import { SlotContentMixin } from '../shared/slot-content.mixin';
11
12
  import { generateId, compact } from '../shared/shared.utils';
12
13
  import { Field } from './field.component';
13
14
  import { quanticElement } from '../shared/quantic-element';
@@ -23,7 +24,7 @@ Field.ensureDefined();
23
24
  // to focus on its own rendering logic.
24
25
  // @see: https://nolanlawson.com/2022/11/28/shadow-dom-and-accessibility-the-trouble-with-aria/
25
26
  export function renderAsField(name, InputComponent, renderInput) {
26
- let FieldWrapper = class FieldWrapper extends SlotContentMixin(InputComponent) {
27
+ let FieldWrapper = class FieldWrapper extends InputComponent {
27
28
  constructor() {
28
29
  super(...arguments);
29
30
  this.label = '';
@@ -31,15 +32,18 @@ export function renderAsField(name, InputComponent, renderInput) {
31
32
  this.message = '';
32
33
  this.required = false;
33
34
  this.fieldId = generateId('field');
35
+ this.labelSlotText = '';
36
+ this.hintSlotText = '';
37
+ this.messageSlotText = '';
34
38
  }
35
39
  get computedLabel() {
36
- return this.getSlotTextContent('label') || this.label;
40
+ return this.labelSlotText || this.label;
37
41
  }
38
42
  get computedHint() {
39
- return this.getSlotTextContent('hint') || this.hint;
43
+ return this.hintSlotText || this.hint;
40
44
  }
41
45
  get computedMessage() {
42
- return this.getSlotTextContent('message') || this.message;
46
+ return this.messageSlotText || this.message;
43
47
  }
44
48
  getFieldA11yContext() {
45
49
  const description = compact([
@@ -63,10 +67,10 @@ export function renderAsField(name, InputComponent, renderInput) {
63
67
  .status=${this.status}
64
68
  .size=${this.size ?? noChange}
65
69
  >
66
- <slot name="label" slot="label">${this.label}</slot>
67
- <slot name="hint" slot="hint">${this.hint}</slot>
70
+ <slot name="label" slot="label" @slotchange=${onSlotTextChange((v) => (this.labelSlotText = v))}>${this.label}</slot>
71
+ <slot name="hint" slot="hint" @slotchange=${onSlotTextChange((v) => (this.hintSlotText = v))}>${this.hint}</slot>
68
72
  ${renderInput.call(this, a11yContext)}
69
- <slot name="message" slot="message">${this.message}</slot>
73
+ <slot name="message" slot="message" @slotchange=${onSlotTextChange((v) => (this.messageSlotText = v))}>${this.message}</slot>
70
74
  </quantic-field>
71
75
  `;
72
76
  }
@@ -106,6 +110,15 @@ export function renderAsField(name, InputComponent, renderInput) {
106
110
  description: 'Validation state controlling message color.',
107
111
  })
108
112
  ], FieldWrapper.prototype, "status", void 0);
113
+ __decorate([
114
+ state()
115
+ ], FieldWrapper.prototype, "labelSlotText", void 0);
116
+ __decorate([
117
+ state()
118
+ ], FieldWrapper.prototype, "hintSlotText", void 0);
119
+ __decorate([
120
+ state()
121
+ ], FieldWrapper.prototype, "messageSlotText", void 0);
109
122
  FieldWrapper = __decorate([
110
123
  quanticElement(`quantic-${name}-field`)
111
124
  ], FieldWrapper);