@ctrliq/quantic-components 1.67.4 → 1.67.6

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.
@@ -22,7 +22,10 @@ LucideIconCircleX.ensureDefined();
22
22
  LucideIconInfo.ensureDefined();
23
23
  LucideIconTriangleAlert.ensureDefined();
24
24
  LucideIconX.ensureDefined();
25
- let Alert = class Alert extends AutoHideEmptySlotsMixin(QuanticElement, ['title', 'action']) {
25
+ let Alert = class Alert extends AutoHideEmptySlotsMixin(QuanticElement, [
26
+ 'title',
27
+ 'action',
28
+ ]) {
26
29
  constructor() {
27
30
  super(...arguments);
28
31
  this.type = AlertType.Info;
@@ -73,18 +76,18 @@ let Alert = class Alert extends AutoHideEmptySlotsMixin(QuanticElement, ['title'
73
76
  </div>
74
77
  ${this.showCloseButton
75
78
  ? html `<quantic-button
76
- class="close-button"
77
- variant="ghost"
78
- size="sm"
79
- icon
80
- aria-label="Close"
81
- @click=${this.handleCloseClick}
82
- >
83
- <quantic-icon-lucide-x
79
+ class="close-button"
80
+ variant="ghost"
84
81
  size="sm"
85
- class="close-icon"
86
- ></quantic-icon-lucide-x>
87
- </quantic-button>`
82
+ icon
83
+ aria-label="Close"
84
+ @click=${this.handleCloseClick}
85
+ >
86
+ <quantic-icon-lucide-x
87
+ size="sm"
88
+ class="close-icon"
89
+ ></quantic-icon-lucide-x>
90
+ </quantic-button>`
88
91
  : nothing}
89
92
  </div>
90
93
  `;
@@ -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
+ };
@@ -102,3 +102,29 @@ export const CustomIcon = story().render(() => `
102
102
  You have 3 unread messages in your inbox.
103
103
  </quantic-alert>
104
104
  `);
105
+ /** Repro: slot content inserted asynchronously (simulates React CSR).
106
+ * Title and action should appear after 800 ms. */
107
+ export const AsyncSlotRepro = {
108
+ name: 'Async Slot Repro (React CSR sim)',
109
+ render: () => `
110
+ <quantic-alert type="warning">
111
+ The title and action slots are empty on mount and inserted 800 ms later.
112
+ </quantic-alert>
113
+ `,
114
+ play: async ({ canvasElement }) => {
115
+ await new Promise((r) => setTimeout(r, 800));
116
+ const alert = canvasElement.querySelector('quantic-alert');
117
+ if (!alert)
118
+ return;
119
+ const title = document.createElement('span');
120
+ title.slot = 'title';
121
+ title.textContent = 'Async title (inserted after 800 ms)';
122
+ alert.prepend(title);
123
+ const action = document.createElement('quantic-button');
124
+ action.setAttribute('slot', 'action');
125
+ action.setAttribute('variant', 'ghost');
126
+ action.setAttribute('size', 'sm');
127
+ action.textContent = 'Async action';
128
+ alert.appendChild(action);
129
+ },
130
+ };
@@ -8,7 +8,10 @@ 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, ['pretitle', 'subtitle']) {
11
+ let CardTitle = class CardTitle extends AutoHideEmptySlotsMixin(QuanticElement, [
12
+ 'pretitle',
13
+ 'subtitle',
14
+ ]) {
12
15
  render() {
13
16
  return html `
14
17
  <hgroup>
@@ -13,7 +13,11 @@ import { ifDefined } from 'lit/directives/if-defined.js';
13
13
  import { AutoHideEmptySlotsMixin } from '../shared/auto-hide-empty-slots.mixin';
14
14
  import { QuanticElement, quanticElement } from '../shared/quantic-element';
15
15
  import { prop } from '../shared/component-meta.decorators';
16
- let Card = class Card extends AutoHideEmptySlotsMixin(QuanticElement, ['header', 'footer', 'action-icon']) {
16
+ let Card = class Card extends AutoHideEmptySlotsMixin(QuanticElement, [
17
+ 'header',
18
+ 'footer',
19
+ 'action-icon',
20
+ ]) {
17
21
  constructor() {
18
22
  super(...arguments);
19
23
  this.as = 'div';
@@ -36,10 +40,7 @@ let Card = class Card extends AutoHideEmptySlotsMixin(QuanticElement, ['header',
36
40
  class="header"
37
41
  data-description="Header area — place quantic-card-title and quantic-card-meta here."
38
42
  ></slot>
39
- <slot
40
- class="body"
41
- data-description="Main body content."
42
- ></slot>
43
+ <slot class="body" data-description="Main body content."></slot>
43
44
  <slot
44
45
  name="footer"
45
46
  class="footer"
@@ -90,182 +91,193 @@ Card.meta = {
90
91
  ],
91
92
  relatedTo: ['quantic-card-group', 'quantic-panel'],
92
93
  };
93
- Card.styles = [css `
94
- :host {
95
- display: flex;
96
- flex-direction: column;
97
- width: 100%;
98
- container-name: box-container;
99
- container-type: inline-size;
100
- font-family: var(--quantic-font-family-body);
101
- color: var(--quantic-text-secondary);
102
- position: relative;
103
-
104
- --quantic-component-card-padding: var(--quantic-spacing-6);
105
- --quantic-component-card-font-size: var(--quantic-font-size-body-md);
106
- --quantic-component-card-line-height: var(--quantic-line-height-body-md);
107
- --quantic-component-card-radius: var(--quantic-radius-md);
108
- --quantic-component-card-spacing: var(--quantic-spacing-4);
109
- }
110
-
111
- button.main,
112
- a.main {
113
- outline: 2px solid transparent;
114
- outline-offset: 2px;
115
- }
116
-
117
- button.main:focus-visible,
118
- a.main:focus-visible {
119
- outline-color: var(--quantic-focus-ring);
120
- }
94
+ Card.styles = [
95
+ css `
96
+ :host {
97
+ display: flex;
98
+ flex-direction: column;
99
+ width: 100%;
100
+ container-name: box-container;
101
+ container-type: inline-size;
102
+ font-family: var(--quantic-font-family-body);
103
+ color: var(--quantic-text-secondary);
104
+ position: relative;
121
105
 
122
- :host([disabled]) {
123
- pointer-events: none;
124
- }
125
-
126
- .main {
127
- display: flex;
128
- flex-direction: column;
129
- gap: var(--quantic-component-card-spacing);
130
- padding: var(--quantic-component-card-padding);
131
- border-radius: var(--quantic-component-card-radius);
132
- border: 1px solid var(--quantic-border-primary);
133
- overflow: hidden;
134
- font-size: var(--quantic-component-card-font-size);
135
- line-height: var(--quantic-component-card-line-height);
136
- flex: 1 1 auto;
137
- box-sizing: border-box;
138
- }
106
+ --quantic-component-card-padding: var(--quantic-spacing-6);
107
+ --quantic-component-card-font-size: var(--quantic-font-size-body-md);
108
+ --quantic-component-card-line-height: var(
109
+ --quantic-line-height-body-md
110
+ );
111
+ --quantic-component-card-radius: var(--quantic-radius-md);
112
+ --quantic-component-card-spacing: var(--quantic-spacing-4);
113
+ }
139
114
 
140
- button.main,
141
- a.main {
142
- position: relative;
143
- }
115
+ button.main,
116
+ a.main {
117
+ outline: 2px solid transparent;
118
+ outline-offset: 2px;
119
+ }
144
120
 
145
- .variant--solid {
146
- background-color: var(--quantic-bg-secondary);
147
- border: 1px solid var(--quantic-border-primary);
148
- }
121
+ button.main:focus-visible,
122
+ a.main:focus-visible {
123
+ outline-color: var(--quantic-focus-ring);
124
+ }
149
125
 
150
- .variant--outline {
151
- background-color: transparent;
152
- border: 1px solid var(--quantic-border-primary);
153
- }
126
+ :host([disabled]) {
127
+ pointer-events: none;
128
+ }
154
129
 
155
- .size--xs {
156
- --quantic-component-card-padding: var(--quantic-spacing-3);
157
- --quantic-component-card-spacing: var(--quantic-spacing-1);
158
- --quantic-component-card-radius: var(--quantic-radius-sm);
159
- --quantic-component-card-font-size: var(--quantic-font-size-body-xs);
160
- --quantic-component-card-line-height: var(--quantic-line-height-body-sm);
161
- }
130
+ .main {
131
+ display: flex;
132
+ flex-direction: column;
133
+ gap: var(--quantic-component-card-spacing);
134
+ padding: var(--quantic-component-card-padding);
135
+ border-radius: var(--quantic-component-card-radius);
136
+ border: 1px solid var(--quantic-border-primary);
137
+ overflow: hidden;
138
+ font-size: var(--quantic-component-card-font-size);
139
+ line-height: var(--quantic-component-card-line-height);
140
+ flex: 1 1 auto;
141
+ box-sizing: border-box;
142
+ }
162
143
 
163
- .size--sm {
164
- --quantic-component-card-padding: var(--quantic-spacing-4);
165
- --quantic-component-card-spacing: var(--quantic-spacing-1-5);
166
- --quantic-component-card-radius: var(--quantic-radius-sm);
167
- --quantic-component-card-font-size: var(--quantic-font-size-body-sm);
168
- --quantic-component-card-line-height: var(--quantic-line-height-body-sm);
169
- }
144
+ button.main,
145
+ a.main {
146
+ position: relative;
147
+ }
170
148
 
171
- .size--md {
172
- --quantic-component-card-padding: var(--quantic-spacing-5);
173
- --quantic-component-card-spacing: var(--quantic-spacing-2);
174
- --quantic-component-card-radius: var(--quantic-radius-md);
175
- --quantic-component-card-font-size: var(--quantic-font-size-body-md);
176
- --quantic-component-card-line-height: var(--quantic-line-height-body-md);
177
- }
149
+ .variant--solid {
150
+ background-color: var(--quantic-bg-secondary);
151
+ border: 1px solid var(--quantic-border-primary);
152
+ }
178
153
 
179
- .size--lg {
180
- --quantic-component-card-padding: var(--quantic-spacing-6);
181
- --quantic-component-card-spacing: var(--quantic-spacing-3);
182
- --quantic-component-card-radius: var(--quantic-radius-lg);
183
- --quantic-component-card-font-size: var(--quantic-font-size-body-lg);
184
- --quantic-component-card-line-height: var(--quantic-line-height-body-lg);
185
- }
154
+ .variant--outline {
155
+ background-color: transparent;
156
+ border: 1px solid var(--quantic-border-primary);
157
+ }
186
158
 
187
- @container (min-width: 40rem) {
188
159
  .size--xs {
189
160
  --quantic-component-card-padding: var(--quantic-spacing-3);
161
+ --quantic-component-card-spacing: var(--quantic-spacing-1);
162
+ --quantic-component-card-radius: var(--quantic-radius-sm);
163
+ --quantic-component-card-font-size: var(--quantic-font-size-body-xs);
164
+ --quantic-component-card-line-height: var(
165
+ --quantic-line-height-body-sm
166
+ );
190
167
  }
191
168
 
192
169
  .size--sm {
193
170
  --quantic-component-card-padding: var(--quantic-spacing-4);
171
+ --quantic-component-card-spacing: var(--quantic-spacing-1-5);
172
+ --quantic-component-card-radius: var(--quantic-radius-sm);
173
+ --quantic-component-card-font-size: var(--quantic-font-size-body-sm);
174
+ --quantic-component-card-line-height: var(
175
+ --quantic-line-height-body-sm
176
+ );
194
177
  }
195
178
 
196
179
  .size--md {
197
- --quantic-component-card-padding: var(--quantic-spacing-6);
180
+ --quantic-component-card-padding: var(--quantic-spacing-5);
181
+ --quantic-component-card-spacing: var(--quantic-spacing-2);
182
+ --quantic-component-card-radius: var(--quantic-radius-md);
183
+ --quantic-component-card-font-size: var(--quantic-font-size-body-md);
184
+ --quantic-component-card-line-height: var(
185
+ --quantic-line-height-body-md
186
+ );
198
187
  }
199
188
 
200
189
  .size--lg {
201
- --quantic-component-card-padding: var(--quantic-spacing-8);
190
+ --quantic-component-card-padding: var(--quantic-spacing-6);
191
+ --quantic-component-card-spacing: var(--quantic-spacing-3);
192
+ --quantic-component-card-radius: var(--quantic-radius-lg);
193
+ --quantic-component-card-font-size: var(--quantic-font-size-body-lg);
194
+ --quantic-component-card-line-height: var(
195
+ --quantic-line-height-body-lg
196
+ );
202
197
  }
203
- }
204
198
 
205
- .header,
206
- .body,
207
- .footer {
208
- display: block;
209
- }
199
+ @container (min-width: 40rem) {
200
+ .size--xs {
201
+ --quantic-component-card-padding: var(--quantic-spacing-3);
202
+ }
210
203
 
211
- .footer {
212
- padding-top: var(--quantic-component-card-spacing);
213
- margin-top: auto;
214
- }
204
+ .size--sm {
205
+ --quantic-component-card-padding: var(--quantic-spacing-4);
206
+ }
215
207
 
216
- .action-icon {
217
- position: absolute;
218
- inset: calc(var(--quantic-component-card-padding) / 2);
219
- left: auto;
220
- display: flex;
221
- align-items: center;
222
- justify-content: flex-end;
223
- pointer-events: none;
224
- transition:
225
- color 0.2s ease-in-out,
226
- opacity 0.2s ease-in-out;
227
- color: var(--quantic-text-tertiary);
228
- opacity: 0.6;
229
- }
208
+ .size--md {
209
+ --quantic-component-card-padding: var(--quantic-spacing-6);
210
+ }
230
211
 
231
- .is-interactive {
232
- appearance: none;
233
- font-family: var(--quantic-font-family-body);
234
- color: var(--quantic-text-secondary);
235
- text-decoration: none;
236
- text-align: left;
237
- cursor: pointer;
238
- outline: none;
239
- width: 100%;
240
- transition:
241
- border-color 0.2s ease-in-out,
242
- background-color 0.2s ease-in-out,
243
- box-shadow 0.2s ease-in-out;
244
- }
212
+ .size--lg {
213
+ --quantic-component-card-padding: var(--quantic-spacing-8);
214
+ }
215
+ }
245
216
 
246
- .is-interactive:hover:not(.is-disabled) {
247
- border-color: var(--quantic-focus-ring);
248
- }
217
+ .header,
218
+ .body,
219
+ .footer {
220
+ display: block;
221
+ }
249
222
 
250
- .is-interactive:hover:not(.is-disabled) .action-icon {
251
- color: var(--quantic-focus-ring);
252
- opacity: 1;
253
- }
223
+ .footer {
224
+ padding-top: var(--quantic-component-card-spacing);
225
+ margin-top: auto;
226
+ }
254
227
 
255
- .is-interactive.is-disabled {
256
- cursor: not-allowed;
257
- opacity: 0.6;
258
- }
228
+ .action-icon {
229
+ position: absolute;
230
+ inset: calc(var(--quantic-component-card-padding) / 2);
231
+ left: auto;
232
+ display: flex;
233
+ align-items: center;
234
+ justify-content: flex-end;
235
+ pointer-events: none;
236
+ transition:
237
+ color 0.2s ease-in-out,
238
+ opacity 0.2s ease-in-out;
239
+ color: var(--quantic-text-tertiary);
240
+ opacity: 0.6;
241
+ }
259
242
 
260
- [hidden] {
261
- display: none;
262
- }
263
- `,
243
+ .is-interactive {
244
+ appearance: none;
245
+ font-family: var(--quantic-font-family-body);
246
+ color: var(--quantic-text-secondary);
247
+ text-decoration: none;
248
+ text-align: left;
249
+ cursor: pointer;
250
+ outline: none;
251
+ width: 100%;
252
+ transition:
253
+ border-color 0.2s ease-in-out,
254
+ background-color 0.2s ease-in-out,
255
+ box-shadow 0.2s ease-in-out;
256
+ }
257
+
258
+ .is-interactive:hover:not(.is-disabled) {
259
+ border-color: var(--quantic-focus-ring);
260
+ }
261
+
262
+ .is-interactive:hover:not(.is-disabled) .action-icon {
263
+ color: var(--quantic-focus-ring);
264
+ opacity: 1;
265
+ }
266
+
267
+ .is-interactive.is-disabled {
268
+ cursor: not-allowed;
269
+ opacity: 0.6;
270
+ }
271
+
272
+ [hidden] {
273
+ display: none;
274
+ }
275
+ `,
264
276
  whenSlotPresent('action-icon', css `
265
- .main {
266
- padding-right: calc(var(--quantic-component-card-padding) * 2);
267
- }
268
- `),
277
+ .main {
278
+ padding-right: calc(var(--quantic-component-card-padding) * 2);
279
+ }
280
+ `),
269
281
  ];
270
282
  __decorate([
271
283
  prop({
@@ -9,7 +9,9 @@ import { quanticElement, QuanticElement } from '../shared/quantic-element';
9
9
  import { prop } from '../shared/component-meta.decorators';
10
10
  import { AutoHideEmptySlotsMixin } from '../shared/auto-hide-empty-slots.mixin';
11
11
  import { whenSlotPresent } from '../shared/slot-utils';
12
- let DropdownMenuGroup = class DropdownMenuGroup extends AutoHideEmptySlotsMixin(QuanticElement, ['label']) {
12
+ let DropdownMenuGroup = class DropdownMenuGroup extends AutoHideEmptySlotsMixin(QuanticElement, [
13
+ 'label',
14
+ ]) {
13
15
  constructor() {
14
16
  super(...arguments);
15
17
  this.label = '';
@@ -46,45 +48,46 @@ DropdownMenuGroup.meta = {
46
48
  },
47
49
  relatedTo: ['quantic-dropdown-menu', 'quantic-dropdown-menu-item'],
48
50
  };
49
- DropdownMenuGroup.styles = [css `
50
- :host {
51
- display: block;
52
- padding: var(--quantic-spacing-4) 0 var(--quantic-spacing-2);
53
- border-top: 1px solid var(--quantic-border-tertiary);
54
- }
51
+ DropdownMenuGroup.styles = [
52
+ css `
53
+ :host {
54
+ display: block;
55
+ padding: var(--quantic-spacing-4) 0 var(--quantic-spacing-2);
56
+ border-top: 1px solid var(--quantic-border-tertiary);
57
+ }
55
58
 
56
- :host(:first-of-type) {
57
- border-top: none;
58
- padding-top: var(--quantic-spacing-2);
59
- }
59
+ :host(:first-of-type) {
60
+ border-top: none;
61
+ padding-top: var(--quantic-spacing-2);
62
+ }
60
63
 
61
- .label {
62
- padding: var(--quantic-spacing-1-5) var(--quantic-spacing-3);
63
- font-family: var(--quantic-font-family-body);
64
- font-size: var(--quantic-font-size-body-xs);
65
- font-weight: var(--quantic-font-weight-semibold);
66
- line-height: var(--quantic-line-height-body-xs);
67
- color: var(--quantic-text-tertiary);
68
- text-transform: uppercase;
69
- letter-spacing: 0.05em;
70
- user-select: none;
71
- }
64
+ .label {
65
+ padding: var(--quantic-spacing-1-5) var(--quantic-spacing-3);
66
+ font-family: var(--quantic-font-family-body);
67
+ font-size: var(--quantic-font-size-body-xs);
68
+ font-weight: var(--quantic-font-weight-semibold);
69
+ line-height: var(--quantic-line-height-body-xs);
70
+ color: var(--quantic-text-tertiary);
71
+ text-transform: uppercase;
72
+ letter-spacing: 0.05em;
73
+ user-select: none;
74
+ }
72
75
 
73
- .label[hidden] {
74
- display: none;
75
- }
76
+ .label[hidden] {
77
+ display: none;
78
+ }
76
79
 
77
- .items {
78
- display: flex;
79
- flex-direction: column;
80
- gap: var(--quantic-spacing-0-5);
81
- }
82
- `,
80
+ .items {
81
+ display: flex;
82
+ flex-direction: column;
83
+ gap: var(--quantic-spacing-0-5);
84
+ }
85
+ `,
83
86
  whenSlotPresent('label', css `
84
- .label {
85
- display: block;
86
- }
87
- `),
87
+ .label {
88
+ display: block;
89
+ }
90
+ `),
88
91
  ];
89
92
  __decorate([
90
93
  prop({