@chromvoid/uikit 0.1.0 → 0.2.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.
Files changed (192) hide show
  1. package/LICENSE +19 -6
  2. package/README.md +1 -0
  3. package/dist/components/cv-accordion-item.d.ts +1 -1
  4. package/dist/components/cv-accordion.d.ts +1 -1
  5. package/dist/components/cv-accordion.js +2 -1
  6. package/dist/components/cv-alert-dialog.d.ts +1 -1
  7. package/dist/components/cv-alert-dialog.js +17 -2
  8. package/dist/components/cv-alert.d.ts +1 -1
  9. package/dist/components/cv-alert.js +2 -1
  10. package/dist/components/cv-badge.d.ts +1 -1
  11. package/dist/components/cv-badge.js +2 -1
  12. package/dist/components/cv-bottom-sheet.d.ts +127 -0
  13. package/dist/components/cv-bottom-sheet.js +513 -0
  14. package/dist/components/cv-breadcrumb-item.d.ts +1 -1
  15. package/dist/components/cv-breadcrumb-item.js +1 -1
  16. package/dist/components/cv-breadcrumb.d.ts +1 -1
  17. package/dist/components/cv-breadcrumb.js +2 -1
  18. package/dist/components/cv-button.d.ts +23 -1
  19. package/dist/components/cv-button.js +194 -37
  20. package/dist/components/cv-callout.d.ts +8 -1
  21. package/dist/components/cv-callout.js +18 -1
  22. package/dist/components/cv-card.d.ts +1 -1
  23. package/dist/components/cv-card.js +2 -2
  24. package/dist/components/cv-carousel-slide.d.ts +1 -1
  25. package/dist/components/cv-carousel.d.ts +1 -1
  26. package/dist/components/cv-carousel.js +2 -1
  27. package/dist/components/cv-checkbox.d.ts +1 -1
  28. package/dist/components/cv-combobox-group.d.ts +1 -1
  29. package/dist/components/cv-combobox-option.d.ts +1 -1
  30. package/dist/components/cv-combobox-option.js +2 -2
  31. package/dist/components/cv-combobox.d.ts +3 -1
  32. package/dist/components/cv-combobox.js +49 -8
  33. package/dist/components/cv-command-item.d.ts +1 -1
  34. package/dist/components/cv-command-item.js +2 -2
  35. package/dist/components/cv-command-palette.d.ts +1 -1
  36. package/dist/components/cv-command-palette.js +21 -1
  37. package/dist/components/cv-context-menu.d.ts +1 -1
  38. package/dist/components/cv-context-menu.js +2 -1
  39. package/dist/components/cv-copy-button.d.ts +37 -9
  40. package/dist/components/cv-copy-button.js +129 -41
  41. package/dist/components/cv-date-picker.d.ts +1 -1
  42. package/dist/components/cv-date-picker.js +20 -1
  43. package/dist/components/cv-dialog.d.ts +44 -2
  44. package/dist/components/cv-dialog.js +686 -74
  45. package/dist/components/cv-disclosure.d.ts +1 -1
  46. package/dist/components/cv-disclosure.js +2 -1
  47. package/dist/components/cv-drawer.d.ts +29 -1
  48. package/dist/components/cv-drawer.js +229 -4
  49. package/dist/components/cv-feed-article.d.ts +1 -1
  50. package/dist/components/cv-feed-article.js +2 -1
  51. package/dist/components/cv-feed.d.ts +1 -1
  52. package/dist/components/cv-feed.js +2 -1
  53. package/dist/components/cv-grid-cell.d.ts +1 -1
  54. package/dist/components/cv-grid-cell.js +3 -3
  55. package/dist/components/cv-grid-column.d.ts +1 -1
  56. package/dist/components/cv-grid-column.js +1 -1
  57. package/dist/components/cv-grid-row.d.ts +1 -1
  58. package/dist/components/cv-grid.d.ts +1 -1
  59. package/dist/components/cv-grid.js +2 -1
  60. package/dist/components/cv-guidance-anchor.d.ts +47 -0
  61. package/dist/components/cv-guidance-anchor.js +113 -0
  62. package/dist/components/cv-guidance-panel.d.ts +29 -0
  63. package/dist/components/cv-guidance-panel.js +245 -0
  64. package/dist/components/cv-icon.d.ts +2 -1
  65. package/dist/components/cv-icon.js +28 -3
  66. package/dist/components/cv-input.d.ts +7 -1
  67. package/dist/components/cv-input.js +33 -1
  68. package/dist/components/cv-landmark.d.ts +1 -1
  69. package/dist/components/cv-landmark.js +2 -1
  70. package/dist/components/cv-link.d.ts +1 -1
  71. package/dist/components/cv-link.js +2 -1
  72. package/dist/components/cv-listbox-group.d.ts +1 -1
  73. package/dist/components/cv-listbox.d.ts +1 -1
  74. package/dist/components/cv-listbox.js +2 -1
  75. package/dist/components/cv-menu-button.d.ts +24 -1
  76. package/dist/components/cv-menu-button.js +226 -18
  77. package/dist/components/cv-menu-group.d.ts +1 -1
  78. package/dist/components/cv-menu-item.d.ts +1 -1
  79. package/dist/components/cv-menu-item.js +6 -2
  80. package/dist/components/cv-menu.d.ts +1 -1
  81. package/dist/components/cv-menu.js +21 -1
  82. package/dist/components/cv-meter.d.ts +1 -1
  83. package/dist/components/cv-meter.js +6 -22
  84. package/dist/components/cv-number.d.ts +1 -1
  85. package/dist/components/cv-option.d.ts +1 -1
  86. package/dist/components/cv-option.js +3 -9
  87. package/dist/components/cv-popover-positioning.d.ts +22 -0
  88. package/dist/components/cv-popover-positioning.js +112 -0
  89. package/dist/components/cv-popover.d.ts +45 -8
  90. package/dist/components/cv-popover.js +395 -113
  91. package/dist/components/cv-progress-ring.d.ts +1 -1
  92. package/dist/components/cv-progress-ring.js +2 -1
  93. package/dist/components/cv-progress.d.ts +8 -1
  94. package/dist/components/cv-progress.js +41 -10
  95. package/dist/components/cv-radio-group.d.ts +1 -1
  96. package/dist/components/cv-radio.d.ts +1 -1
  97. package/dist/components/cv-radio.js +1 -1
  98. package/dist/components/cv-select-group.d.ts +1 -1
  99. package/dist/components/cv-select-option.d.ts +1 -1
  100. package/dist/components/cv-select-option.js +2 -2
  101. package/dist/components/cv-select.d.ts +1 -1
  102. package/dist/components/cv-select.js +28 -1
  103. package/dist/components/cv-sidebar-item.d.ts +1 -1
  104. package/dist/components/cv-sidebar.d.ts +1 -1
  105. package/dist/components/cv-sidebar.js +3 -2
  106. package/dist/components/cv-slider-multi-thumb.d.ts +1 -1
  107. package/dist/components/cv-slider-multi-thumb.js +2 -1
  108. package/dist/components/cv-slider.d.ts +17 -4
  109. package/dist/components/cv-slider.js +63 -21
  110. package/dist/components/cv-spinbutton.d.ts +1 -1
  111. package/dist/components/cv-spinner.d.ts +1 -1
  112. package/dist/components/cv-spinner.js +2 -1
  113. package/dist/components/cv-switch.d.ts +1 -1
  114. package/dist/components/cv-tab-panel.d.ts +1 -1
  115. package/dist/components/cv-tab.d.ts +1 -1
  116. package/dist/components/cv-table-cell.d.ts +1 -1
  117. package/dist/components/cv-table-cell.js +1 -1
  118. package/dist/components/cv-table-column.d.ts +1 -1
  119. package/dist/components/cv-table-column.js +1 -1
  120. package/dist/components/cv-table-row.d.ts +1 -1
  121. package/dist/components/cv-table-row.js +1 -4
  122. package/dist/components/cv-table.d.ts +1 -3
  123. package/dist/components/cv-table.js +4 -11
  124. package/dist/components/cv-tabs.d.ts +1 -1
  125. package/dist/components/cv-tabs.js +3 -2
  126. package/dist/components/cv-textarea.d.ts +11 -1
  127. package/dist/components/cv-textarea.js +33 -0
  128. package/dist/components/cv-toast-region.d.ts +1 -1
  129. package/dist/components/cv-toast-region.js +2 -1
  130. package/dist/components/cv-toast.d.ts +1 -1
  131. package/dist/components/cv-toast.js +20 -27
  132. package/dist/components/cv-toolbar-item.d.ts +1 -1
  133. package/dist/components/cv-toolbar-separator.d.ts +1 -1
  134. package/dist/components/cv-toolbar.d.ts +1 -1
  135. package/dist/components/cv-toolbar.js +2 -1
  136. package/dist/components/cv-tooltip.d.ts +1 -1
  137. package/dist/components/cv-tooltip.js +2 -1
  138. package/dist/components/cv-treegrid-cell.d.ts +1 -1
  139. package/dist/components/cv-treegrid-cell.js +1 -1
  140. package/dist/components/cv-treegrid-column.d.ts +1 -1
  141. package/dist/components/cv-treegrid-column.js +1 -1
  142. package/dist/components/cv-treegrid-row.d.ts +1 -1
  143. package/dist/components/cv-treegrid-row.js +1 -1
  144. package/dist/components/cv-treegrid.d.ts +1 -1
  145. package/dist/components/cv-treegrid.js +4 -3
  146. package/dist/components/cv-treeitem.d.ts +1 -1
  147. package/dist/components/cv-treeitem.js +2 -2
  148. package/dist/components/cv-treeview.d.ts +1 -1
  149. package/dist/components/cv-treeview.js +2 -1
  150. package/dist/components/cv-window-splitter.d.ts +1 -1
  151. package/dist/components/cv-window-splitter.js +2 -1
  152. package/dist/components/index.d.ts +7 -0
  153. package/dist/components/index.js +3 -0
  154. package/dist/dialog/create-dialog-controller.d.ts +12 -4
  155. package/dist/dialog/create-dialog-controller.js +84 -22
  156. package/dist/dialog/index.d.ts +1 -1
  157. package/dist/index.d.ts +1 -1
  158. package/dist/reatom-lit/ReatomLitElement.d.ts +6 -3
  159. package/dist/reatom-lit/ReatomLitElement.js +18 -8
  160. package/dist/reatom-lit/createAfterRenderScheduler.d.ts +10 -0
  161. package/dist/reatom-lit/createAfterRenderScheduler.js +33 -0
  162. package/dist/reatom-lit/index.d.ts +2 -0
  163. package/dist/reatom-lit/index.js +1 -0
  164. package/dist/reatom-lit/watch.d.ts +1 -1
  165. package/dist/reatom-lit/withReatomElement.js +16 -2
  166. package/dist/register.js +4 -1
  167. package/dist/styles/component-styles.js +4 -0
  168. package/dist/styles/uno-generated.d.ts +2 -0
  169. package/dist/styles/uno-generated.js +1 -0
  170. package/dist/styles/uno-utilities.d.ts +5 -0
  171. package/dist/styles/uno-utilities.js +7 -0
  172. package/dist/theme/cv-theme-provider.d.ts +1 -1
  173. package/dist/theme/cv-theme-provider.js +2 -2
  174. package/dist/theme/tokens.css +619 -162
  175. package/package.json +9 -5
  176. package/specs/components/bottom-sheet.md +93 -0
  177. package/specs/components/button.md +8 -0
  178. package/specs/components/callout.md +8 -0
  179. package/specs/components/copy-button.md +54 -17
  180. package/specs/components/dialog.md +72 -43
  181. package/specs/components/drawer.md +18 -13
  182. package/specs/components/guidance-anchor.md +64 -0
  183. package/specs/components/guidance-panel.md +92 -0
  184. package/specs/components/input.md +7 -0
  185. package/specs/components/menu.md +8 -0
  186. package/specs/components/option.md +9 -9
  187. package/specs/components/progress.md +11 -0
  188. package/specs/components/sidebar.md +12 -12
  189. package/specs/components/table.md +13 -13
  190. package/specs/components/theme.md +13 -13
  191. package/specs/components/treegrid.md +15 -15
  192. package/specs/components/treeview.md +10 -10
@@ -2,6 +2,20 @@ import { createButton } from '@chromvoid/headless-ui/button';
2
2
  import { css, html, nothing } from 'lit';
3
3
  import { FormAssociatedReatomElement } from '../form-associated/FormAssociatedReatomElement.js';
4
4
  let cvButtonNonce = 0;
5
+ const passthroughAttributes = [
6
+ 'aria-controls',
7
+ 'aria-current',
8
+ 'aria-expanded',
9
+ 'aria-haspopup',
10
+ 'aria-hidden',
11
+ 'aria-label',
12
+ 'aria-labelledby',
13
+ 'aria-describedby',
14
+ 'aria-pressed',
15
+ 'aria-selected',
16
+ 'role',
17
+ 'title',
18
+ ];
5
19
  export class CVButton extends FormAssociatedReatomElement {
6
20
  static elementName = 'cv-button';
7
21
  static get properties() {
@@ -14,9 +28,15 @@ export class CVButton extends FormAssociatedReatomElement {
14
28
  outline: { type: Boolean, reflect: true },
15
29
  pill: { type: Boolean, reflect: true },
16
30
  size: { type: String, reflect: true },
31
+ preset: { type: String, reflect: true },
17
32
  type: { type: String, reflect: true },
33
+ unstyled: { type: Boolean, reflect: true },
34
+ buttonTabIndex: { type: String, attribute: 'button-tabindex' },
18
35
  };
19
36
  }
37
+ static get observedAttributes() {
38
+ return Array.from(new Set([...super.observedAttributes, ...passthroughAttributes]));
39
+ }
20
40
  model;
21
41
  suppressKeyboardClick = false;
22
42
  constructor() {
@@ -29,7 +49,10 @@ export class CVButton extends FormAssociatedReatomElement {
29
49
  this.outline = false;
30
50
  this.pill = false;
31
51
  this.size = 'medium';
52
+ this.preset = undefined;
32
53
  this.type = 'button';
54
+ this.unstyled = false;
55
+ this.buttonTabIndex = null;
33
56
  this.model = this.createModel();
34
57
  }
35
58
  static styles = [
@@ -219,31 +242,23 @@ export class CVButton extends FormAssociatedReatomElement {
219
242
  --cv-button-background: transparent;
220
243
  --cv-button-border-color: transparent;
221
244
  --cv-button-border-color-hover: transparent;
222
- --cv-button-background-hover: color-mix(in oklab, var(--cv-button-accent-color) 10%, transparent);
245
+ --cv-button-background-hover: rgb(from var(--cv-button-accent-color) r g b / 0.1);
223
246
  --cv-button-border-color-active: transparent;
224
- --cv-button-background-active: color-mix(in oklab, var(--cv-button-accent-color) 16%, transparent);
247
+ --cv-button-background-active: rgb(from var(--cv-button-accent-color) r g b / 0.16);
225
248
  --cv-button-border-color-pressed: transparent;
226
249
  --cv-button-border-color-pressed-hover: transparent;
227
- --cv-button-background-pressed: color-mix(in oklab, var(--cv-button-accent-color) 14%, transparent);
228
- --cv-button-background-pressed-hover: color-mix(
229
- in oklab,
230
- var(--cv-button-accent-color) 18%,
231
- transparent
232
- );
250
+ --cv-button-background-pressed: rgb(from var(--cv-button-accent-color) r g b / 0.14);
251
+ --cv-button-background-pressed-hover: rgb(from var(--cv-button-accent-color) r g b / 0.18);
233
252
  }
234
253
 
235
254
  /* --- outline modifier --- */
236
255
  :host([outline]) [part='base'] {
237
256
  --cv-button-background: transparent;
238
257
  --cv-button-border-color: var(--cv-color-border, #2a3245);
239
- --cv-button-background-hover: color-mix(in oklab, var(--cv-button-accent-color) 10%, transparent);
240
- --cv-button-background-active: color-mix(in oklab, var(--cv-button-accent-color) 16%, transparent);
241
- --cv-button-background-pressed: color-mix(in oklab, var(--cv-button-accent-color) 16%, transparent);
242
- --cv-button-background-pressed-hover: color-mix(
243
- in oklab,
244
- var(--cv-button-accent-color) 20%,
245
- transparent
246
- );
258
+ --cv-button-background-hover: rgb(from var(--cv-button-accent-color) r g b / 0.1);
259
+ --cv-button-background-active: rgb(from var(--cv-button-accent-color) r g b / 0.16);
260
+ --cv-button-background-pressed: rgb(from var(--cv-button-accent-color) r g b / 0.16);
261
+ --cv-button-background-pressed-hover: rgb(from var(--cv-button-accent-color) r g b / 0.2);
247
262
  }
248
263
 
249
264
  :host([outline][variant='primary']) [part='base'] {
@@ -262,16 +277,8 @@ export class CVButton extends FormAssociatedReatomElement {
262
277
  var(--cv-color-primary, #65d7ff) 90%,
263
278
  var(--cv-color-border, #2a3245)
264
279
  );
265
- --cv-button-background-pressed: color-mix(
266
- in oklab,
267
- var(--cv-color-primary, #65d7ff) 20%,
268
- transparent
269
- );
270
- --cv-button-background-pressed-hover: color-mix(
271
- in oklab,
272
- var(--cv-color-primary, #65d7ff) 24%,
273
- transparent
274
- );
280
+ --cv-button-background-pressed: var(--cv-color-primary-surface-strong);
281
+ --cv-button-background-pressed-hover: var(--cv-color-primary-ring);
275
282
  }
276
283
 
277
284
  :host([outline][variant='danger']) [part='base'] {
@@ -290,12 +297,8 @@ export class CVButton extends FormAssociatedReatomElement {
290
297
  var(--cv-color-danger, #ff7d86) 90%,
291
298
  var(--cv-color-border, #2a3245)
292
299
  );
293
- --cv-button-background-pressed: color-mix(in oklab, var(--cv-color-danger, #ff7d86) 16%, transparent);
294
- --cv-button-background-pressed-hover: color-mix(
295
- in oklab,
296
- var(--cv-color-danger, #ff7d86) 22%,
297
- transparent
298
- );
300
+ --cv-button-background-pressed: var(--cv-color-danger-surface);
301
+ --cv-button-background-pressed-hover: var(--cv-color-danger-surface-strong);
299
302
  }
300
303
 
301
304
  /* --- pill modifier --- */
@@ -349,12 +352,92 @@ export class CVButton extends FormAssociatedReatomElement {
349
352
  --cv-button-font-size: var(--cv-button-font-size-large, var(--cv-font-size-md, 16px));
350
353
  }
351
354
 
355
+ :host([preset='action-primary']) {
356
+ --cv-button-background: var(--cv-button-action-primary-background, var(--cv-color-primary-dark));
357
+ --cv-button-background-hover: var(
358
+ --cv-button-action-primary-background-hover,
359
+ var(--cv-color-primary)
360
+ );
361
+ --cv-button-background-active: var(
362
+ --cv-button-action-primary-background-active,
363
+ var(--cv-color-primary-darker)
364
+ );
365
+ --cv-button-border-color: var(
366
+ --cv-button-action-primary-border-color,
367
+ var(--cv-color-primary-border-strong)
368
+ );
369
+ --cv-button-border-color-hover: var(
370
+ --cv-button-action-primary-border-color-hover,
371
+ var(--cv-color-primary-border-strong)
372
+ );
373
+ --cv-button-border-color-active: var(
374
+ --cv-button-action-primary-border-color-active,
375
+ var(--cv-color-primary-border-strong)
376
+ );
377
+ --cv-button-text-color: var(--cv-button-action-primary-text-color, var(--cv-color-on-primary));
378
+ --cv-button-text-color-hover: var(
379
+ --cv-button-action-primary-text-color-hover,
380
+ var(--cv-color-on-primary)
381
+ );
382
+ --cv-button-text-color-active: var(
383
+ --cv-button-action-primary-text-color-active,
384
+ var(--cv-color-on-primary)
385
+ );
386
+ --cv-button-focus-ring-color: var(
387
+ --cv-button-action-primary-focus-ring-color,
388
+ var(--cv-color-primary-ring)
389
+ );
390
+ }
391
+
392
+ :host([preset='action-primary-subtle']) {
393
+ --cv-button-background: var(
394
+ --cv-button-action-primary-subtle-background,
395
+ var(--cv-color-primary-surface-strong)
396
+ );
397
+ --cv-button-background-hover: var(
398
+ --cv-button-action-primary-subtle-background-hover,
399
+ var(--cv-color-primary-muted)
400
+ );
401
+ --cv-button-background-active: var(
402
+ --cv-button-action-primary-subtle-background-active,
403
+ var(--cv-color-primary-surface)
404
+ );
405
+ --cv-button-border-color: var(
406
+ --cv-button-action-primary-subtle-border-color,
407
+ var(--cv-color-primary-border-strong)
408
+ );
409
+ --cv-button-border-color-hover: var(
410
+ --cv-button-action-primary-subtle-border-color-hover,
411
+ var(--cv-color-primary-border-strong)
412
+ );
413
+ --cv-button-border-color-active: var(
414
+ --cv-button-action-primary-subtle-border-color-active,
415
+ var(--cv-color-primary-border-strong)
416
+ );
417
+ --cv-button-text-color: var(
418
+ --cv-button-action-primary-subtle-text-color,
419
+ var(--cv-color-text-strong)
420
+ );
421
+ --cv-button-text-color-hover: var(
422
+ --cv-button-action-primary-subtle-text-color-hover,
423
+ var(--cv-color-text-strongest)
424
+ );
425
+ --cv-button-text-color-active: var(
426
+ --cv-button-action-primary-subtle-text-color-active,
427
+ var(--cv-color-text-strongest)
428
+ );
429
+ --cv-button-focus-ring-color: var(
430
+ --cv-button-action-primary-subtle-focus-ring-color,
431
+ var(--cv-color-primary-ring)
432
+ );
433
+ }
434
+
352
435
  /* --- spinner --- */
353
436
  [part='spinner'] {
354
437
  inline-size: 14px;
355
438
  block-size: 14px;
356
439
  border-radius: 999px;
357
- border: 2px solid color-mix(in oklab, var(--cv-button-accent-color) 32%, transparent);
440
+ border: 2px solid rgb(from var(--cv-button-accent-color) r g b / 0.32);
358
441
  border-top-color: var(--cv-button-accent-color);
359
442
  animation: cv-button-spin 800ms linear infinite;
360
443
  }
@@ -381,6 +464,40 @@ export class CVButton extends FormAssociatedReatomElement {
381
464
  cursor: not-allowed;
382
465
  }
383
466
 
467
+ :host([unstyled]) {
468
+ --cv-button-min-height: 0;
469
+ --cv-button-padding-inline: 0;
470
+ --cv-button-padding-block: 0;
471
+ --cv-button-border-radius: inherit;
472
+ }
473
+
474
+ :host([unstyled]) [part='base'] {
475
+ box-sizing: border-box;
476
+ inline-size: 100%;
477
+ block-size: 100%;
478
+ min-inline-size: 0;
479
+ min-block-size: 0;
480
+ padding: var(--cv-button-padding-block) var(--cv-button-padding-inline);
481
+ border: 0;
482
+ border-radius: inherit;
483
+ background: transparent;
484
+ color: inherit;
485
+ box-shadow: none;
486
+ font: inherit;
487
+ letter-spacing: inherit;
488
+ line-height: inherit;
489
+ text-align: inherit;
490
+ }
491
+
492
+ :host([unstyled]) [part='base']:hover:not(:disabled),
493
+ :host([unstyled]) [part='base']:active:not(:disabled),
494
+ :host([unstyled][pressed]) [part='base'],
495
+ :host([unstyled][pressed]) [part='base']:hover:not(:disabled) {
496
+ border-color: transparent;
497
+ background: transparent;
498
+ color: inherit;
499
+ }
500
+
384
501
  @keyframes cv-button-spin {
385
502
  to {
386
503
  transform: rotate(360deg);
@@ -393,6 +510,21 @@ export class CVButton extends FormAssociatedReatomElement {
393
510
  customElements.define(this.elementName, this);
394
511
  }
395
512
  }
513
+ connectedCallback() {
514
+ super.connectedCallback();
515
+ this.addEventListener('click', this.handleHostClick, { capture: true });
516
+ }
517
+ disconnectedCallback() {
518
+ this.removeEventListener('click', this.handleHostClick, { capture: true });
519
+ super.disconnectedCallback();
520
+ }
521
+ attributeChangedCallback(name, oldValue, newValue) {
522
+ super.attributeChangedCallback(name, oldValue, newValue);
523
+ if (oldValue !== newValue &&
524
+ passthroughAttributes.includes(name)) {
525
+ this.requestUpdate();
526
+ }
527
+ }
396
528
  willUpdate(changedProperties) {
397
529
  super.willUpdate(changedProperties);
398
530
  if (changedProperties.has('toggle')) {
@@ -484,6 +616,17 @@ export class CVButton extends FormAssociatedReatomElement {
484
616
  this.suppressKeyboardClick = false;
485
617
  this.model.contracts.getButtonProps().onClick();
486
618
  }
619
+ handleHostClick(event) {
620
+ if (event.composedPath()[0] !== this) {
621
+ return;
622
+ }
623
+ if (this.isFormAssociatedDisabled()) {
624
+ event.preventDefault();
625
+ event.stopImmediatePropagation();
626
+ return;
627
+ }
628
+ this.model.contracts.getButtonProps().onClick();
629
+ }
487
630
  handleKeyDown(event) {
488
631
  if (event.key === 'Enter') {
489
632
  this.suppressKeyboardClick = true;
@@ -502,23 +645,37 @@ export class CVButton extends FormAssociatedReatomElement {
502
645
  hasSlotContent(name) {
503
646
  return Array.from(this.children ?? []).some((child) => child.getAttribute('slot') === name);
504
647
  }
648
+ getPassthroughAttribute(name) {
649
+ return this.getAttribute(name) ?? nothing;
650
+ }
505
651
  render() {
506
652
  const props = this.model.contracts.getButtonProps();
507
653
  const isUnavailable = this.disabled || this.loading;
508
654
  const hasPrefixContent = this.hasSlotContent('prefix');
509
655
  const hasSuffixContent = this.hasSlotContent('suffix');
656
+ const tabIndex = this.buttonTabIndex ?? props.tabindex;
657
+ const ariaPressed = props['aria-pressed'] ?? this.getPassthroughAttribute('aria-pressed');
510
658
  return html `
511
659
  <button
512
660
  id=${props.id}
513
661
  type="button"
514
- role=${props.role}
515
- tabindex=${props.tabindex}
662
+ role=${this.getAttribute('role') ?? props.role}
663
+ tabindex=${tabIndex}
516
664
  ?disabled=${isUnavailable}
517
665
  aria-disabled=${props['aria-disabled'] ?? nothing}
518
666
  aria-busy=${props['aria-busy'] ?? nothing}
519
- aria-pressed=${props['aria-pressed'] ?? nothing}
667
+ aria-controls=${this.getPassthroughAttribute('aria-controls')}
668
+ aria-current=${this.getPassthroughAttribute('aria-current')}
669
+ aria-expanded=${this.getPassthroughAttribute('aria-expanded')}
670
+ aria-haspopup=${this.getPassthroughAttribute('aria-haspopup')}
671
+ aria-hidden=${this.getPassthroughAttribute('aria-hidden')}
672
+ aria-label=${this.getPassthroughAttribute('aria-label')}
673
+ aria-labelledby=${this.getPassthroughAttribute('aria-labelledby')}
674
+ aria-describedby=${this.getPassthroughAttribute('aria-describedby')}
675
+ aria-pressed=${ariaPressed}
676
+ aria-selected=${this.getPassthroughAttribute('aria-selected')}
677
+ title=${this.getPassthroughAttribute('title')}
520
678
  part="base"
521
- class="cv-u-control-shell"
522
679
  @click=${this.handleClick}
523
680
  @keydown=${this.handleKeyDown}
524
681
  @keyup=${this.handleKeyUp}
@@ -1,6 +1,7 @@
1
1
  import { type CalloutVariant } from '@chromvoid/headless-ui/callout';
2
2
  import type { PropertyValues } from 'lit';
3
3
  import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
4
+ type CVCalloutDensity = 'compact' | 'dense';
4
5
  export declare class CVCallout extends ReatomLitElement {
5
6
  static elementName: string;
6
7
  static get properties(): {
@@ -8,6 +9,10 @@ export declare class CVCallout extends ReatomLitElement {
8
9
  type: StringConstructor;
9
10
  reflect: boolean;
10
11
  };
12
+ density: {
13
+ type: StringConstructor;
14
+ reflect: boolean;
15
+ };
11
16
  closable: {
12
17
  type: BooleanConstructor;
13
18
  reflect: boolean;
@@ -18,6 +23,7 @@ export declare class CVCallout extends ReatomLitElement {
18
23
  };
19
24
  };
20
25
  variant: CalloutVariant;
26
+ density: CVCalloutDensity | undefined;
21
27
  closable: boolean;
22
28
  open: boolean;
23
29
  private readonly idBase;
@@ -27,6 +33,7 @@ export declare class CVCallout extends ReatomLitElement {
27
33
  static define(): void;
28
34
  willUpdate(changedProperties: PropertyValues): void;
29
35
  private handleClose;
30
- protected render(): import("lit").TemplateResult<1>;
36
+ protected render(): import("lit-html").TemplateResult;
31
37
  private renderCloseButton;
32
38
  }
39
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { createCallout } from '@chromvoid/headless-ui/callout';
2
- import { css, html, nothing } from 'lit';
2
+ import { css, nothing } from 'lit';
3
+ import { html } from '../reatom-lit/index.js';
3
4
  import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
4
5
  let cvCalloutNonce = 0;
5
6
  export class CVCallout extends ReatomLitElement {
@@ -7,6 +8,7 @@ export class CVCallout extends ReatomLitElement {
7
8
  static get properties() {
8
9
  return {
9
10
  variant: { type: String, reflect: true },
11
+ density: { type: String, reflect: true },
10
12
  closable: { type: Boolean, reflect: true },
11
13
  open: { type: Boolean, reflect: true },
12
14
  };
@@ -16,6 +18,7 @@ export class CVCallout extends ReatomLitElement {
16
18
  constructor() {
17
19
  super();
18
20
  this.variant = 'info';
21
+ this.density = undefined;
19
22
  this.closable = false;
20
23
  this.open = true;
21
24
  this.model = createCallout({
@@ -149,6 +152,20 @@ export class CVCallout extends ReatomLitElement {
149
152
  border-color: var(--cv-callout-border-color, var(--cv-color-border, #2a3245));
150
153
  background: var(--cv-callout-background, var(--cv-color-surface-elevated, #1d2432));
151
154
  }
155
+
156
+ :host([density='compact']) {
157
+ --cv-callout-padding-block: var(--cv-callout-compact-padding-block, var(--app-spacing-3, 12px));
158
+ --cv-callout-padding-inline: var(--cv-callout-compact-padding-inline, var(--app-spacing-3, 12px));
159
+ --cv-callout-border-radius: var(--cv-callout-compact-border-radius, var(--cv-radius-2, 10px));
160
+ --cv-callout-font-size: var(--cv-callout-compact-font-size, var(--cv-font-size-sm, 0.875rem));
161
+ }
162
+
163
+ :host([density='dense']) {
164
+ --cv-callout-padding-block: var(--cv-callout-dense-padding-block, var(--app-spacing-2, 8px));
165
+ --cv-callout-padding-inline: var(--cv-callout-dense-padding-inline, var(--app-spacing-3, 12px));
166
+ --cv-callout-border-radius: var(--cv-callout-dense-border-radius, var(--cv-radius-2, 10px));
167
+ --cv-callout-font-size: var(--cv-callout-dense-font-size, var(--cv-font-size-xs, 0.75rem));
168
+ }
152
169
  `,
153
170
  ];
154
171
  static define() {
@@ -43,6 +43,6 @@ export declare class CVCard extends ReatomLitElement {
43
43
  private handleExpandedChange;
44
44
  private handleHeaderClick;
45
45
  private handleHeaderKeyDown;
46
- protected render(): import("lit").TemplateResult<1>;
46
+ protected render(): import("lit-html").TemplateResult;
47
47
  }
48
48
  export {};
@@ -1,5 +1,6 @@
1
1
  import { createCard } from '@chromvoid/headless-ui/card';
2
- import { css, html, nothing } from 'lit';
2
+ import { css, nothing } from 'lit';
3
+ import { html } from '../reatom-lit/index.js';
3
4
  import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
4
5
  let cvCardNonce = 0;
5
6
  export class CVCard extends ReatomLitElement {
@@ -209,7 +210,6 @@ export class CVCard extends ReatomLitElement {
209
210
  }
210
211
  }
211
212
  render() {
212
- const cardProps = this.model.contracts.getCardProps();
213
213
  const triggerProps = this.model.contracts.getTriggerProps();
214
214
  const contentProps = this.model.contracts.getContentProps();
215
215
  const isExpandable = this.model.state.isExpandable();
@@ -21,5 +21,5 @@ export declare class CVCarouselSlide extends LitElement {
21
21
  constructor();
22
22
  static styles: import("lit").CSSResult[];
23
23
  static define(): void;
24
- protected render(): import("lit").TemplateResult<1>;
24
+ protected render(): import("lit-html").TemplateResult<1>;
25
25
  }
@@ -92,5 +92,5 @@ export declare class CVCarousel extends ReatomLitElement {
92
92
  private handleSlidesPointerDown;
93
93
  private handleSlidesPointerMove;
94
94
  private handleSlidesPointerUp;
95
- protected render(): import("lit").TemplateResult<1>;
95
+ protected render(): import("lit-html").TemplateResult;
96
96
  }
@@ -1,5 +1,6 @@
1
1
  import { createCarousel } from '@chromvoid/headless-ui/carousel';
2
- import { css, html, nothing } from 'lit';
2
+ import { css, nothing } from 'lit';
3
+ import { html } from '../reatom-lit/index.js';
3
4
  import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
4
5
  import { CVCarouselSlide } from './cv-carousel-slide.js';
5
6
  const carouselKeysToPrevent = new Set(['ArrowLeft', 'ArrowRight', 'Home', 'End']);
@@ -80,5 +80,5 @@ export declare class CVCheckbox extends FormAssociatedReatomElement {
80
80
  private syncFromModelAndEmit;
81
81
  private handleClick;
82
82
  private handleKeyDown;
83
- protected render(): import("lit").TemplateResult<1>;
83
+ protected render(): import("lit-html").TemplateResult<1>;
84
84
  }
@@ -11,5 +11,5 @@ export declare class CVComboboxGroup extends LitElement {
11
11
  constructor();
12
12
  static styles: import("lit").CSSResult[];
13
13
  static define(): void;
14
- protected render(): import("lit").TemplateResult<1>;
14
+ protected render(): import("lit-html").TemplateResult<1>;
15
15
  }
@@ -26,5 +26,5 @@ export declare class CVComboboxOption extends LitElement {
26
26
  constructor();
27
27
  static styles: import("lit").CSSResultOrNative[];
28
28
  static define(): void;
29
- protected render(): import("lit").TemplateResult<1>;
29
+ protected render(): import("lit-html").TemplateResult<1>;
30
30
  }
@@ -36,11 +36,11 @@ export class CVComboboxOption extends LitElement {
36
36
  }
37
37
 
38
38
  :host([active]) .option {
39
- background: color-mix(in oklab, var(--cv-color-primary, #65d7ff) 24%, transparent);
39
+ background: var(--cv-color-primary-ring);
40
40
  }
41
41
 
42
42
  :host([selected]) .option {
43
- background: color-mix(in oklab, var(--cv-color-primary, #65d7ff) 32%, transparent);
43
+ background: var(--cv-color-primary-border);
44
44
  }
45
45
 
46
46
  :host([disabled]) .option {
@@ -104,6 +104,8 @@ export declare class CVCombobox extends ReatomLitElement {
104
104
  private getOptionElements;
105
105
  private getGroupElements;
106
106
  private ensureOptionValue;
107
+ private parseMultipleValueIds;
108
+ private hasUnknownSelectedIds;
107
109
  private resolveInitialSelected;
108
110
  private rebuildModelFromSlot;
109
111
  private syncHostState;
@@ -131,5 +133,5 @@ export declare class CVCombobox extends ReatomLitElement {
131
133
  private renderTags;
132
134
  private renderClearButton;
133
135
  private renderListboxContent;
134
- protected render(): import("lit").TemplateResult<1>;
136
+ protected render(): import("lit-html").TemplateResult;
135
137
  }
@@ -1,11 +1,15 @@
1
1
  import { createCombobox, } from '@chromvoid/headless-ui/combobox';
2
- import { css, html, nothing } from 'lit';
2
+ import { css, nothing } from 'lit';
3
+ import { html } from '../reatom-lit/index.js';
3
4
  import { ReatomLitElement } from '../reatom-lit/ReatomLitElement.js';
4
5
  import { CVComboboxGroup } from './cv-combobox-group.js';
5
6
  import { CVComboboxOption } from './cv-combobox-option.js';
6
7
  const comboboxNavigationKeys = new Set(['ArrowUp', 'ArrowDown', 'Home', 'End', 'Enter', 'Escape']);
7
8
  function isVisibleGroup(item) {
8
- return 'options' in item && Array.isArray(item.options);
9
+ return (typeof item === 'object' &&
10
+ item !== null &&
11
+ 'options' in item &&
12
+ Array.isArray(item.options));
9
13
  }
10
14
  let cvComboboxNonce = 0;
11
15
  export class CVCombobox extends ReatomLitElement {
@@ -53,6 +57,9 @@ export class CVCombobox extends ReatomLitElement {
53
57
  css `
54
58
  :host {
55
59
  inline-size: 260px;
60
+ --cv-combobox-border-color: var(--cv-color-border, #2a3245);
61
+ --cv-combobox-border-radius: var(--cv-radius-sm, 6px);
62
+ --cv-combobox-background: var(--cv-color-surface, #141923);
56
63
  }
57
64
 
58
65
  [part='base'] {
@@ -65,6 +72,9 @@ export class CVCombobox extends ReatomLitElement {
65
72
  gap: var(--cv-space-1, 4px);
66
73
  min-block-size: 36px;
67
74
  padding: 0 var(--cv-space-3, 12px);
75
+ border: 1px solid var(--cv-combobox-border-color);
76
+ border-radius: var(--cv-combobox-border-radius);
77
+ background: var(--cv-combobox-background);
68
78
  }
69
79
 
70
80
  [part='input'] {
@@ -110,7 +120,7 @@ export class CVCombobox extends ReatomLitElement {
110
120
  gap: var(--cv-space-1, 4px);
111
121
  padding: 2px var(--cv-space-2, 8px);
112
122
  border-radius: var(--cv-radius-sm, 6px);
113
- background: color-mix(in oklab, var(--cv-color-primary, #65d7ff) 24%, transparent);
123
+ background: var(--cv-color-primary-ring);
114
124
  font-size: 0.85em;
115
125
  }
116
126
 
@@ -147,6 +157,28 @@ export class CVCombobox extends ReatomLitElement {
147
157
  overflow: auto;
148
158
  padding: var(--cv-space-1, 4px);
149
159
  background: var(--cv-color-surface, #141923);
160
+ opacity: 1;
161
+ transform: translate3d(0, 0, 0);
162
+ transition:
163
+ opacity var(--cv-combobox-listbox-transition-duration, var(--cv-duration-fast, 120ms))
164
+ var(--cv-easing-standard, ease),
165
+ transform var(--cv-combobox-listbox-transition-duration, var(--cv-duration-fast, 120ms))
166
+ var(--cv-easing-standard, ease),
167
+ display var(--cv-combobox-listbox-transition-duration, var(--cv-duration-fast, 120ms))
168
+ allow-discrete;
169
+ transition-behavior: allow-discrete;
170
+ }
171
+
172
+ [part='listbox'][hidden] {
173
+ opacity: 0;
174
+ transform: translate3d(0, -2px, 0);
175
+ }
176
+
177
+ @starting-style {
178
+ [part='listbox']:not([hidden]) {
179
+ opacity: 0;
180
+ transform: translate3d(0, -2px, 0);
181
+ }
150
182
  }
151
183
 
152
184
  [part='group'] {
@@ -201,9 +233,12 @@ export class CVCombobox extends ReatomLitElement {
201
233
  }
202
234
  else if (this.multiple) {
203
235
  // Multi-mode: parse space-delimited ids
204
- const ids = next.split(/\s+/).filter(Boolean);
236
+ const ids = this.parseMultipleValueIds();
205
237
  const currentIds = this.model.state.selectedIds();
206
238
  if (ids.join(' ') !== currentIds.join(' ')) {
239
+ if (this.hasUnknownSelectedIds(ids)) {
240
+ return;
241
+ }
207
242
  // Clear and re-select each id
208
243
  this.model.actions.clearSelection();
209
244
  for (const id of ids) {
@@ -269,6 +304,13 @@ export class CVCombobox extends ReatomLitElement {
269
304
  option.value = fallback;
270
305
  return fallback;
271
306
  }
307
+ parseMultipleValueIds() {
308
+ return this.value.trim().split(/\s+/).filter(Boolean);
309
+ }
310
+ hasUnknownSelectedIds(ids) {
311
+ const enabledIds = new Set(this.optionRecords.filter((record) => !record.disabled).map((record) => record.id));
312
+ return ids.some((id) => !enabledIds.has(id));
313
+ }
272
314
  resolveInitialSelected(optionElements) {
273
315
  const fromProperty = this.value.trim();
274
316
  if (fromProperty.length > 0)
@@ -287,7 +329,7 @@ export class CVCombobox extends ReatomLitElement {
287
329
  ? this.captureState()
288
330
  : {
289
331
  selectedId: this.resolveInitialSelected(optionElements),
290
- selectedIds: this.multiple ? this.value.trim().split(/\s+/).filter(Boolean) : [],
332
+ selectedIds: this.multiple ? this.parseMultipleValueIds() : [],
291
333
  inputValue: this.inputValue,
292
334
  activeId: null,
293
335
  isOpen: this.open,
@@ -298,7 +340,6 @@ export class CVCombobox extends ReatomLitElement {
298
340
  this.groupRecords = groupElements.map((element) => {
299
341
  const id = `group-${++groupNonce}`;
300
342
  const label = element.label || element.getAttribute('label') || '';
301
- const childOptions = Array.from(element.children).filter((child) => child.tagName.toLowerCase() === CVComboboxOption.elementName);
302
343
  const optionIds = [];
303
344
  return { id, label, element, optionIds };
304
345
  });
@@ -380,7 +421,7 @@ export class CVCombobox extends ReatomLitElement {
380
421
  let initialSelectedId = null;
381
422
  let initialSelectedIds;
382
423
  if (this.multiple) {
383
- const prevIds = previousState.selectedIds ?? [];
424
+ const prevIds = this.parseMultipleValueIds();
384
425
  initialSelectedIds = prevIds.filter((id) => enabledIds.has(id));
385
426
  }
386
427
  else {
@@ -824,7 +865,7 @@ export class CVCombobox extends ReatomLitElement {
824
865
  aria-multiselectable=${listboxProps['aria-multiselectable'] ?? nothing}
825
866
  ?hidden=${!this.open}
826
867
  part="listbox"
827
- class="cv-u-panel-shell"
868
+ class="cv-u-panel-shell cv-u-discrete-presence"
828
869
  >
829
870
  ${hasGroups ? this.renderListboxContent() : html `<slot @slotchange=${this.handleSlotChange}></slot>`}
830
871
  </div>
@@ -26,5 +26,5 @@ export declare class CVCommandItem extends LitElement {
26
26
  constructor();
27
27
  static styles: import("lit").CSSResult[];
28
28
  static define(): void;
29
- protected render(): import("lit").TemplateResult<1>;
29
+ protected render(): import("lit-html").TemplateResult<1>;
30
30
  }