@threadlabs/looma 0.5.2 → 0.6.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/components/shared/overlay.js +3 -0
  2. package/components/ui-button/ui-button.html +14 -14
  3. package/components/ui-callout/ui-callout.html +1 -1
  4. package/components/ui-checkbox/ui-checkbox.html +1 -1
  5. package/components/ui-cluster/ui-cluster.html +6 -6
  6. package/components/ui-combobox/ui-combobox.html +23 -23
  7. package/components/ui-container/ui-container.html +4 -4
  8. package/components/ui-context-menu/ui-context-menu.html +2 -2
  9. package/components/ui-dialog/ui-dialog.html +12 -12
  10. package/components/ui-disclosure/ui-disclosure.html +19 -4
  11. package/components/ui-editable/ui-editable.html +6 -6
  12. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +20 -20
  13. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +25 -25
  14. package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +39 -39
  15. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +20 -20
  16. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +48 -48
  17. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +34 -34
  18. package/components/ui-editor-toolbar/ui-editor-toolbar.html +9 -9
  19. package/components/ui-floating-action-button/ui-floating-action-button.html +16 -22
  20. package/components/ui-grid/ui-grid.html +6 -6
  21. package/components/ui-icon-button/ui-icon-button.html +42 -38
  22. package/components/ui-input/ui-input.html +2 -2
  23. package/components/ui-menu/ui-menu.html +15 -4
  24. package/components/ui-menu-item/ui-menu-item.html +5 -5
  25. package/components/ui-popover/ui-popover.html +3 -3
  26. package/components/ui-reel/ui-reel.html +6 -6
  27. package/components/ui-search-result-row/ui-search-result-row.html +9 -9
  28. package/components/ui-search-shell/ui-search-shell.html +3 -3
  29. package/components/ui-select/ui-select.html +2 -2
  30. package/components/ui-sidebar/ui-sidebar.html +11 -11
  31. package/components/ui-stack/ui-stack.html +6 -6
  32. package/components/ui-switcher/ui-switcher.html +6 -6
  33. package/components/ui-tabs/ui-tabs.html +18 -4
  34. package/components/ui-textarea/ui-textarea.html +2 -2
  35. package/components/ui-toast-region/ui-toast-region.html +2 -2
  36. package/components/ui-tooltip/ui-tooltip.html +1 -1
  37. package/components/ui-top-bar/ui-top-bar.html +5 -5
  38. package/components/ui-tree/ui-tree.html +7 -0
  39. package/components/ui-tree-item/ui-tree-item.html +15 -7
  40. package/dist/index.js +1 -1
  41. package/package.json +1 -1
  42. package/styles/ui-button.css +14 -14
  43. package/styles/ui-callout.css +1 -1
  44. package/styles/ui-checkbox.css +1 -1
  45. package/styles/ui-cluster.css +6 -6
  46. package/styles/ui-combobox.css +23 -23
  47. package/styles/ui-container.css +4 -4
  48. package/styles/ui-context-menu.css +2 -2
  49. package/styles/ui-dialog.css +12 -12
  50. package/styles/ui-disclosure.css +22 -6
  51. package/styles/ui-editable.css +6 -6
  52. package/styles/ui-editor-insert-table-grid.css +20 -20
  53. package/styles/ui-editor-mention-menu.css +25 -25
  54. package/styles/ui-editor-slash-menu.css +39 -39
  55. package/styles/ui-editor-table-context-menu.css +20 -20
  56. package/styles/ui-editor-table-overlay.css +48 -48
  57. package/styles/ui-editor-table-toolbar.css +34 -34
  58. package/styles/ui-editor-toolbar.css +9 -9
  59. package/styles/ui-floating-action-button.css +16 -22
  60. package/styles/ui-grid.css +6 -6
  61. package/styles/ui-icon-button.css +42 -38
  62. package/styles/ui-input.css +2 -2
  63. package/styles/ui-menu-item.css +5 -5
  64. package/styles/ui-menu.css +18 -6
  65. package/styles/ui-popover.css +3 -3
  66. package/styles/ui-reel.css +6 -6
  67. package/styles/ui-search-result-row.css +9 -9
  68. package/styles/ui-search-shell.css +3 -3
  69. package/styles/ui-select.css +2 -2
  70. package/styles/ui-sidebar.css +11 -11
  71. package/styles/ui-stack.css +6 -6
  72. package/styles/ui-switcher.css +6 -6
  73. package/styles/ui-tabs.css +20 -6
  74. package/styles/ui-textarea.css +2 -2
  75. package/styles/ui-toast-region.css +2 -2
  76. package/styles/ui-tooltip.css +1 -1
  77. package/styles/ui-top-bar.css +5 -5
  78. package/styles/ui-tree-item.css +21 -8
  79. package/styles/ui-tree.css +7 -1
  80. package/theme-dark.css +42 -103
  81. package/theme-high-contrast.css +18 -22
  82. package/theme-light.css +15 -41
  83. package/tokens.css +149 -201
  84. package/vanilla/UiDisclosure.d.ts +1 -0
  85. package/vanilla/UiDisclosure.js +1 -1
  86. package/vanilla/UiMenu.d.ts +1 -0
  87. package/vanilla/UiMenu.js +1 -1
  88. package/vanilla/UiTabs.d.ts +1 -0
  89. package/vanilla/UiTabs.js +1 -1
  90. package/vanilla/UiTree.d.ts +1 -0
  91. package/vanilla/UiTree.js +1 -1
  92. package/vue/UiButton.vue +20 -14
  93. package/vue/UiCallout.vue +1 -1
  94. package/vue/UiCheckbox.vue +1 -1
  95. package/vue/UiCluster.vue +6 -6
  96. package/vue/UiCombobox.vue +23 -23
  97. package/vue/UiContainer.vue +4 -4
  98. package/vue/UiContextMenu.vue +2 -2
  99. package/vue/UiDialog.vue +12 -12
  100. package/vue/UiDisclosure.d.ts +2 -0
  101. package/vue/UiDisclosure.vue +21 -4
  102. package/vue/UiEditable.vue +6 -6
  103. package/vue/UiEditorInsertTableGrid.vue +20 -20
  104. package/vue/UiEditorMentionMenu.vue +25 -25
  105. package/vue/UiEditorSlashMenu.vue +39 -39
  106. package/vue/UiEditorTableContextMenu.vue +20 -20
  107. package/vue/UiEditorTableOverlay.vue +48 -57
  108. package/vue/UiEditorTableToolbar.vue +34 -34
  109. package/vue/UiEditorToolbar.vue +9 -9
  110. package/vue/UiFloatingActionButton.vue +17 -22
  111. package/vue/UiGrid.vue +6 -6
  112. package/vue/UiIconButton.vue +46 -42
  113. package/vue/UiInput.vue +2 -2
  114. package/vue/UiMenu.d.ts +2 -0
  115. package/vue/UiMenu.vue +17 -7
  116. package/vue/UiMenuItem.vue +6 -5
  117. package/vue/UiPopover.vue +3 -3
  118. package/vue/UiReel.vue +6 -6
  119. package/vue/UiSearchResultRow.vue +10 -13
  120. package/vue/UiSearchShell.vue +3 -3
  121. package/vue/UiSelect.vue +2 -2
  122. package/vue/UiSidebar.vue +11 -16
  123. package/vue/UiStack.vue +6 -6
  124. package/vue/UiSwitcher.vue +6 -6
  125. package/vue/UiTabs.d.ts +2 -0
  126. package/vue/UiTabs.vue +21 -4
  127. package/vue/UiTextarea.vue +2 -2
  128. package/vue/UiToastRegion.vue +2 -2
  129. package/vue/UiTooltip.vue +1 -1
  130. package/vue/UiTopBar.vue +5 -5
  131. package/vue/UiTree.d.ts +2 -0
  132. package/vue/UiTree.vue +24 -1
  133. package/vue/UiTreeItem.vue +16 -8
  134. package/vue/chunks/UiButton.js +1 -1
  135. package/vue/chunks/UiCallout.js +1 -1
  136. package/vue/chunks/UiCheckbox.js +1 -1
  137. package/vue/chunks/UiCluster.js +1 -1
  138. package/vue/chunks/UiCombobox.js +1 -1
  139. package/vue/chunks/UiContainer.js +1 -1
  140. package/vue/chunks/UiContextMenu.js +1 -1
  141. package/vue/chunks/UiDialog.js +1 -1
  142. package/vue/chunks/UiDisclosure.js +3 -2
  143. package/vue/chunks/UiEditable.js +1 -1
  144. package/vue/chunks/UiEditorInsertTableGrid.js +1 -1
  145. package/vue/chunks/UiEditorMentionMenu.js +1 -1
  146. package/vue/chunks/UiEditorSlashMenu.js +1 -1
  147. package/vue/chunks/UiEditorTableContextMenu.js +1 -1
  148. package/vue/chunks/UiEditorTableOverlay.js +1 -1
  149. package/vue/chunks/UiEditorTableToolbar.js +1 -1
  150. package/vue/chunks/UiEditorToolbar.js +1 -1
  151. package/vue/chunks/UiFloatingActionButton.js +1 -1
  152. package/vue/chunks/UiGrid.js +1 -1
  153. package/vue/chunks/UiIconButton.js +1 -1
  154. package/vue/chunks/UiInput.js +1 -1
  155. package/vue/chunks/UiMenu.js +3 -2
  156. package/vue/chunks/UiMenuItem.js +1 -1
  157. package/vue/chunks/UiPopover.js +1 -1
  158. package/vue/chunks/UiReel.js +1 -1
  159. package/vue/chunks/UiSearchResultRow.js +1 -1
  160. package/vue/chunks/UiSearchShell.js +1 -1
  161. package/vue/chunks/UiSelect.js +1 -1
  162. package/vue/chunks/UiSidebar.js +1 -1
  163. package/vue/chunks/UiStack.js +1 -1
  164. package/vue/chunks/UiSwitcher.js +1 -1
  165. package/vue/chunks/UiTabs.js +7 -2
  166. package/vue/chunks/UiTextarea.js +1 -1
  167. package/vue/chunks/UiToastRegion.js +1 -1
  168. package/vue/chunks/UiTooltip.js +1 -1
  169. package/vue/chunks/UiTopBar.js +1 -1
  170. package/vue/chunks/UiTree.js +8 -2
  171. package/vue/chunks/UiTreeItem.js +1 -1
  172. package/vue/components.css +1082 -1048
  173. package/vue/editor/LoomaEditor.d.ts +11 -0
  174. package/vue/editor/index.js +9 -0
@@ -341,13 +341,13 @@ onBeforeUnmount(() => {
341
341
 
342
342
  .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button.active,
343
343
  .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] button.selected {
344
- background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
344
+ background: var(--ui-accent-soft, var(--ui-accent-subtle));
345
345
  }
346
346
 
347
347
  .looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] .menu {
348
348
  top: auto;
349
349
  right: 0;
350
- bottom: calc(100% + var(--ui-space-2, 8px));
350
+ bottom: calc(100% + var(--ui-space-2));
351
351
  max-height: min(50dvh, 22rem);
352
352
  overflow-y: auto;
353
353
  overscroll-behavior: contain;
@@ -355,11 +355,11 @@ onBeforeUnmount(() => {
355
355
  [data-component~="ui-editor-table-toolbar"] {
356
356
  display: inline-flex;
357
357
  align-items: center;
358
- gap: var(--ui-space-1, 4px);
359
- padding: var(--ui-space-1, 4px);
360
- background: color-mix(in srgb, var(--ui-surface, #fff) 94%, transparent);
361
- border: 1px solid var(--ui-border, #e5e7eb);
362
- border-radius: calc(var(--ui-radius-md, 6px) + 2px);
358
+ gap: var(--ui-space-1);
359
+ padding: var(--ui-space-1);
360
+ background: color-mix(in srgb, var(--ui-surface) 94%, transparent);
361
+ border: 1px solid var(--ui-border);
362
+ border-radius: calc(var(--ui-radius-md) + 2px);
363
363
  box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
364
364
  backdrop-filter: blur(10px);
365
365
  }
@@ -374,7 +374,7 @@ onBeforeUnmount(() => {
374
374
  .sep {
375
375
  width: 1px;
376
376
  align-self: stretch;
377
- background: var(--ui-border, #e5e7eb);
377
+ background: var(--ui-border);
378
378
  }
379
379
 
380
380
  .overflow {
@@ -385,31 +385,31 @@ onBeforeUnmount(() => {
385
385
  display: inline-flex;
386
386
  align-items: center;
387
387
  justify-content: center;
388
- gap: var(--ui-space-1-5, 6px);
388
+ gap: var(--ui-space-2);
389
389
  min-height: 32px;
390
390
  border: 0;
391
- border-radius: var(--ui-radius-sm, 4px);
391
+ border-radius: var(--ui-radius-sm);
392
392
  background: transparent;
393
- color: var(--ui-text-primary, #111827);
393
+ color: var(--ui-text-primary);
394
394
  cursor: pointer;
395
- font-size: var(--ui-text-sm, 0.875rem);
395
+ font-size: var(--ui-font-size-sm);
396
396
  font-weight: 500;
397
397
  line-height: 1;
398
- padding: var(--ui-space-1-5, 6px) var(--ui-space-2, 8px);
398
+ padding: var(--ui-space-2) var(--ui-space-2);
399
399
  white-space: nowrap;
400
400
  }
401
401
 
402
402
  [data-component~="ui-editor-table-toolbar"] button:hover {
403
- background: var(--ui-surface-hover, #f3f4f6);
403
+ background: var(--ui-surface-hover);
404
404
  }
405
405
 
406
406
  [data-component~="ui-editor-table-toolbar"] button.active {
407
- background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
408
- color: var(--ui-accent-active, #003d7a);
407
+ background: var(--ui-accent-soft, var(--ui-accent-subtle));
408
+ color: var(--ui-accent-active);
409
409
  }
410
410
 
411
411
  .group button {
412
- border-radius: var(--ui-radius-sm, 4px);
412
+ border-radius: var(--ui-radius-sm);
413
413
  }
414
414
 
415
415
  .group button + button {
@@ -418,11 +418,11 @@ onBeforeUnmount(() => {
418
418
 
419
419
  [data-component~="ui-editor-table-toolbar"] .more {
420
420
  border: 0;
421
- border-radius: var(--ui-radius-sm, 4px);
421
+ border-radius: var(--ui-radius-sm);
422
422
  }
423
423
 
424
424
  [data-component~="ui-editor-table-toolbar"] button.danger {
425
- color: var(--ui-danger, #dc2626);
425
+ color: var(--ui-danger);
426
426
  }
427
427
 
428
428
  [data-component~="ui-editor-table-toolbar"] {
@@ -442,13 +442,13 @@ onBeforeUnmount(() => {
442
442
 
443
443
  .menu {
444
444
  position: absolute;
445
- top: calc(100% + var(--ui-space-2, 8px));
445
+ top: calc(100% + var(--ui-space-2));
446
446
  right: 0;
447
447
  min-width: 12rem;
448
- padding: var(--ui-space-1, 4px);
449
- background: var(--ui-surface, #fff);
450
- border: 1px solid var(--ui-border, #e5e7eb);
451
- border-radius: var(--ui-radius-md, 6px);
448
+ padding: var(--ui-space-1);
449
+ background: var(--ui-surface);
450
+ border: 1px solid var(--ui-border);
451
+ border-radius: var(--ui-radius-md);
452
452
  box-shadow: var(--ui-shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1));
453
453
  display: flex;
454
454
  flex-direction: column;
@@ -457,18 +457,18 @@ onBeforeUnmount(() => {
457
457
  }
458
458
 
459
459
  .menu-section + .menu-section {
460
- margin-top: var(--ui-space-1, 4px);
461
- padding-top: var(--ui-space-1, 4px);
462
- border-top: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, transparent);
460
+ margin-top: var(--ui-space-1);
461
+ padding-top: var(--ui-space-1);
462
+ border-top: 1px solid color-mix(in srgb, var(--ui-border) 80%, transparent);
463
463
  }
464
464
 
465
465
  .menu-heading {
466
- padding: var(--ui-space-1, 4px) var(--ui-space-2, 8px);
466
+ padding: var(--ui-space-1) var(--ui-space-2);
467
467
  font-size: 0.6875rem;
468
468
  font-weight: 700;
469
469
  letter-spacing: 0.05em;
470
470
  text-transform: uppercase;
471
- color: var(--ui-text-muted, #6b7280);
471
+ color: var(--ui-text-muted);
472
472
  }
473
473
 
474
474
  .menu button {
@@ -485,7 +485,7 @@ onBeforeUnmount(() => {
485
485
  }
486
486
 
487
487
  [data-component~="ui-editor-table-toolbar"] .swatch-button {
488
- gap: var(--ui-space-1, 4px);
488
+ gap: var(--ui-space-1);
489
489
  justify-content: flex-start;
490
490
  }
491
491
 
@@ -493,19 +493,19 @@ onBeforeUnmount(() => {
493
493
  width: 14px;
494
494
  height: 14px;
495
495
  flex: 0 0 14px;
496
- border: 1px solid color-mix(in srgb, var(--ui-border, #e5e7eb) 80%, #000);
496
+ border: 1px solid color-mix(in srgb, var(--ui-border) 80%, #000);
497
497
  border-radius: 3px;
498
498
  background: var(--ui-editor-table-toolbar-swatch);
499
499
  }
500
500
 
501
501
  .swatch.default {
502
502
  background:
503
- linear-gradient(135deg, transparent 44%, var(--ui-danger, #dc2626) 46% 54%, transparent 56%),
504
- var(--ui-surface, #fff);
503
+ linear-gradient(135deg, transparent 44%, var(--ui-danger) 46% 54%, transparent 56%),
504
+ var(--ui-surface);
505
505
  }
506
506
 
507
507
  .swatch-button.selected {
508
- background: var(--ui-accent-soft, var(--ui-accent-subtle, #e8f0fb));
508
+ background: var(--ui-accent-soft, var(--ui-accent-subtle));
509
509
  }
510
510
 
511
511
  [data-component~="ui-editor-table-toolbar"][hidden] {
@@ -48,8 +48,8 @@ const hostState = computed(() =>
48
48
  overflow-x: auto;
49
49
  scrollbar-width: none;
50
50
  white-space: nowrap;
51
- background: var(--ui-editor-toolbar-bg, var(--ui-surface, #fff));
52
- border-bottom: 1px solid var(--ui-editor-toolbar-border, var(--ui-border, #e5e7eb));
51
+ background: var(--ui-editor-toolbar-surface, var(--ui-surface));
52
+ border-bottom: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
53
53
  }
54
54
 
55
55
  [data-component~="ui-editor-toolbar"]::-webkit-scrollbar {
@@ -63,7 +63,7 @@ const hostState = computed(() =>
63
63
  :slotted(.divider) {
64
64
  width: 1px;
65
65
  height: 20px;
66
- background: var(--ui-editor-toolbar-divider, var(--ui-border, #e5e7eb));
66
+ background: var(--ui-editor-toolbar-divider, var(--ui-border));
67
67
  flex-shrink: 0;
68
68
  margin: 0 var(--ui-editor-toolbar-divider-margin, 4px);
69
69
  }
@@ -78,11 +78,11 @@ const hostState = computed(() =>
78
78
  overflow-x: visible;
79
79
  background: color-mix(
80
80
  in srgb,
81
- var(--ui-editor-toolbar-bg, var(--ui-surface, #fff)) 96%,
81
+ var(--ui-editor-toolbar-surface, var(--ui-surface)) 96%,
82
82
  transparent
83
83
  );
84
- border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border, #e5e7eb));
85
- border-radius: var(--ui-editor-toolbar-floating-radius, var(--ui-radius-lg, 10px));
84
+ border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
85
+ border-radius: var(--ui-editor-toolbar-floating-radius, var(--ui-radius-lg));
86
86
  box-shadow: var(
87
87
  --ui-editor-toolbar-floating-shadow,
88
88
  var(--ui-shadow-lg, 0 10px 24px rgb(0 0 0 / 0.12))
@@ -98,7 +98,7 @@ const hostState = computed(() =>
98
98
  left: 0;
99
99
  right: 0;
100
100
  min-height: var(--ui-editor-toolbar-mobile-min-height, 56px);
101
- border-top: 1px solid var(--ui-editor-toolbar-border, var(--ui-border, #e5e7eb));
101
+ border-top: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
102
102
  border-bottom: none;
103
103
  box-shadow: var(--ui-editor-toolbar-mobile-shadow, 0 -2px 8px rgb(0 0 0 / 0.06));
104
104
  }
@@ -107,8 +107,8 @@ const hostState = computed(() =>
107
107
  position: static;
108
108
  inset: auto;
109
109
  min-height: auto;
110
- border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border, #e5e7eb));
111
- border-radius: var(--ui-editor-toolbar-floating-radius, var(--ui-radius-lg, 10px));
110
+ border: 1px solid var(--ui-editor-toolbar-border, var(--ui-border));
111
+ border-radius: var(--ui-editor-toolbar-floating-radius, var(--ui-radius-lg));
112
112
  box-shadow: var(
113
113
  --ui-editor-toolbar-floating-shadow,
114
114
  var(--ui-shadow-lg, 0 10px 24px rgb(0 0 0 / 0.12))
@@ -42,14 +42,15 @@ const hostState = computed(() =>
42
42
  [data-component~="ui-floating-action-button"] {
43
43
  position: fixed;
44
44
  inset-block-end: calc(
45
- var(--ui-floating-action-button-bottom, var(--ui-space-6, 1.5rem)) + env(safe-area-inset-bottom)
45
+ var(--ui-floating-action-button-inset-block-end, var(--ui-space-6)) +
46
+ env(safe-area-inset-bottom)
46
47
  );
47
48
  inset-inline-end: max(
48
- var(--ui-floating-action-button-inline-end, var(--ui-space-5, 1.25rem)),
49
+ var(--ui-floating-action-button-inset-inline-end, var(--ui-space-5)),
49
50
  env(safe-area-inset-right)
50
51
  );
51
- inline-size: var(--ui-floating-action-button-size, 56px);
52
- block-size: var(--ui-floating-action-button-size, 56px);
52
+ inline-size: var(--ui-control-min-block-size);
53
+ block-size: var(--ui-control-min-block-size);
53
54
  display: inline-flex;
54
55
  z-index: var(--ui-floating-action-button-z-index, 100);
55
56
  }
@@ -63,33 +64,27 @@ const hostState = computed(() =>
63
64
  display: inline-flex;
64
65
  align-items: center;
65
66
  justify-content: center;
66
- background: var(--ui-floating-action-button-bg, var(--ui-accent-solid));
67
- color: var(--ui-floating-action-button-color, var(--ui-text-on-accent));
68
- box-shadow: var(
69
- --ui-floating-action-button-shadow,
70
- 0 4px 12px color-mix(in srgb, var(--ui-accent-solid) 40%, transparent)
71
- );
67
+ background: var(--ui-accent);
68
+ color: var(--ui-on-accent);
69
+ box-shadow: 0 4px 12px color-mix(in srgb, var(--ui-accent) 40%, transparent);
72
70
  cursor: pointer;
73
71
  transition:
74
- background-color var(--ui-motion-fast, 160ms) var(--ui-motion-ease, ease),
75
- transform var(--ui-motion-fast, 160ms) var(--ui-motion-ease, ease),
76
- box-shadow var(--ui-motion-fast, 160ms) var(--ui-motion-ease, ease);
72
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
73
+ transform var(--ui-motion-fast) var(--ui-motion-ease),
74
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
77
75
  }
78
76
 
79
77
  [data-component~="ui-floating-action-button"]:hover:enabled {
80
- background: var(--ui-floating-action-button-hover-bg, var(--ui-accent-hover));
81
- box-shadow: var(
82
- --ui-floating-action-button-hover-shadow,
83
- 0 6px 16px color-mix(in srgb, var(--ui-accent-solid) 50%, transparent)
84
- );
78
+ background: var(--ui-accent-hover);
79
+ box-shadow: 0 6px 16px color-mix(in srgb, var(--ui-accent) 50%, transparent);
85
80
  }
86
81
 
87
82
  [data-component~="ui-floating-action-button"]:active:enabled {
88
- transform: scale(var(--ui-floating-action-button-active-scale, 0.94));
83
+ transform: scale(0.94);
89
84
  }
90
85
 
91
86
  [data-component~="ui-floating-action-button"]:focus-visible {
92
- outline: 2px solid var(--ui-focus-ring, currentColor);
87
+ outline: 2px solid var(--ui-focus-ring);
93
88
  outline-offset: 2px;
94
89
  }
95
90
 
@@ -99,8 +94,8 @@ const hostState = computed(() =>
99
94
  }
100
95
 
101
96
  :slotted(svg) {
102
- inline-size: var(--ui-floating-action-button-icon-size, 24px);
103
- block-size: var(--ui-floating-action-button-icon-size, 24px);
97
+ inline-size: var(--ui-icon-size-lg);
98
+ block-size: var(--ui-icon-size-lg);
104
99
  flex-shrink: 0;
105
100
  }
106
101
 
package/vue/UiGrid.vue CHANGED
@@ -26,7 +26,7 @@ const hostState = computed(() =>
26
26
 
27
27
  <style scoped>
28
28
  [data-component~="ui-grid"] {
29
- --_grid-gap: var(--ui-space-4, 1rem);
29
+ --_grid-gap: var(--ui-space-4);
30
30
  --_grid-min: 12rem;
31
31
  display: grid;
32
32
  gap: var(--ui-grid-gap, var(--_grid-gap));
@@ -38,19 +38,19 @@ const hostState = computed(() =>
38
38
  }
39
39
 
40
40
  [data-component~="ui-grid"][data-ui-grid-state~="gap=xs"] {
41
- --_grid-gap: var(--ui-space-2, 0.5rem);
41
+ --_grid-gap: var(--ui-space-2);
42
42
  }
43
43
  [data-component~="ui-grid"][data-ui-grid-state~="gap=s"] {
44
- --_grid-gap: var(--ui-space-3, 0.75rem);
44
+ --_grid-gap: var(--ui-space-3);
45
45
  }
46
46
  [data-component~="ui-grid"][data-ui-grid-state~="gap=m"] {
47
- --_grid-gap: var(--ui-space-4, 1rem);
47
+ --_grid-gap: var(--ui-space-4);
48
48
  }
49
49
  [data-component~="ui-grid"][data-ui-grid-state~="gap=l"] {
50
- --_grid-gap: var(--ui-space-5, 1.5rem);
50
+ --_grid-gap: var(--ui-space-5);
51
51
  }
52
52
  [data-component~="ui-grid"][data-ui-grid-state~="gap=xl"] {
53
- --_grid-gap: var(--ui-space-6, 2rem);
53
+ --_grid-gap: var(--ui-space-6);
54
54
  }
55
55
  [data-component~="ui-grid"][data-ui-grid-state~="min=md"] {
56
56
  --_grid-min: 16rem;
@@ -146,11 +146,11 @@ onBeforeUnmount(() => {
146
146
  position: absolute;
147
147
  inset: 50% auto auto 50%;
148
148
  z-index: 1;
149
- inline-size: var(--ui-affordance-guide-size, 0.25rem);
150
- block-size: var(--ui-affordance-guide-size, 0.25rem);
151
- border-radius: var(--ui-radius-round, 999px);
149
+ inline-size: var(--ui-affordance-guide-size);
150
+ block-size: var(--ui-affordance-guide-size);
151
+ border-radius: var(--ui-radius-round);
152
152
  background: var(--ui-affordance-guide-color, var(--ui-border-strong));
153
- opacity: var(--ui-affordance-guide-opacity, 0.42);
153
+ opacity: var(--ui-affordance-guide-opacity);
154
154
  transform: translate(-50%, -50%);
155
155
  transition: opacity var(--ui-affordance-motion, var(--ui-motion-fast)) var(--ui-motion-ease);
156
156
  pointer-events: none;
@@ -173,16 +173,18 @@ onBeforeUnmount(() => {
173
173
  }
174
174
 
175
175
  [data-component~="ui-icon-button"] {
176
+ /* The size prop resolves here; --ui-icon-button-size overrides it on an element. */
177
+ --_size: 2rem;
176
178
  appearance: none;
177
- inline-size: var(--ui-icon-button-size, 2rem);
178
- block-size: var(--ui-icon-button-size, 2rem);
179
- min-inline-size: var(--ui-icon-button-size, 2rem);
180
- min-block-size: var(--ui-icon-button-size, 2rem);
179
+ inline-size: var(--ui-icon-button-size, var(--_size));
180
+ block-size: var(--ui-icon-button-size, var(--_size));
181
+ min-inline-size: var(--ui-icon-button-size, var(--_size));
182
+ min-block-size: var(--ui-icon-button-size, var(--_size));
181
183
  padding: 0;
182
184
  margin: 0;
183
185
  border: 1px solid transparent;
184
- border-radius: var(--ui-icon-button-radius, var(--ui-radius-2));
185
- background: var(--ui-icon-button-bg, transparent);
186
+ border-radius: var(--ui-icon-button-radius, var(--ui-radius-md));
187
+ background: var(--ui-icon-button-surface, transparent);
186
188
  color: inherit;
187
189
  display: inline-flex;
188
190
  align-items: center;
@@ -213,8 +215,8 @@ onBeforeUnmount(() => {
213
215
  content: "";
214
216
  position: absolute;
215
217
  inset: 50% auto auto 50%;
216
- inline-size: max(100%, var(--ui-control-min-block-size, 2.75rem));
217
- block-size: max(100%, var(--ui-control-min-block-size, 2.75rem));
218
+ inline-size: max(100%, var(--ui-control-min-block-size));
219
+ block-size: max(100%, var(--ui-control-min-block-size));
218
220
  transform: translate(-50%, -50%);
219
221
  }
220
222
  }
@@ -227,38 +229,40 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
227
229
  content: "";
228
230
  position: absolute;
229
231
  inset: 50% auto auto 50%;
230
- inline-size: max(100%, var(--ui-control-min-block-size, 2.75rem));
231
- block-size: max(100%, var(--ui-control-min-block-size, 2.75rem));
232
+ inline-size: max(100%, var(--ui-control-min-block-size));
233
+ block-size: max(100%, var(--ui-control-min-block-size));
232
234
  transform: translate(-50%, -50%);
233
235
  }
234
236
 
235
237
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"] {
236
- inline-size: var(--ui-icon-button-size-sm, 1.75rem);
237
- block-size: var(--ui-icon-button-size-sm, 1.75rem);
238
- min-inline-size: var(--ui-icon-button-size-sm, 1.75rem);
239
- min-block-size: var(--ui-icon-button-size-sm, 1.75rem);
238
+ --_size: 1.75rem;
239
+ inline-size: var(--ui-icon-button-size, var(--_size));
240
+ block-size: var(--ui-icon-button-size, var(--_size));
241
+ min-inline-size: var(--ui-icon-button-size, var(--_size));
242
+ min-block-size: var(--ui-icon-button-size, var(--_size));
240
243
  }
241
244
 
242
245
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"] {
243
- inline-size: var(--ui-icon-button-size-lg, 2.5rem);
244
- block-size: var(--ui-icon-button-size-lg, 2.5rem);
245
- min-inline-size: var(--ui-icon-button-size-lg, 2.5rem);
246
- min-block-size: var(--ui-icon-button-size-lg, 2.5rem);
246
+ --_size: 2.5rem;
247
+ inline-size: var(--ui-icon-button-size, var(--_size));
248
+ block-size: var(--ui-icon-button-size, var(--_size));
249
+ min-inline-size: var(--ui-icon-button-size, var(--_size));
250
+ min-block-size: var(--ui-icon-button-size, var(--_size));
247
251
  }
248
252
 
249
253
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="round"] {
250
- border-radius: var(--ui-radius-round, 999px);
254
+ border-radius: var(--ui-radius-round);
251
255
  }
252
256
 
253
257
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"] {
254
258
  border-color: var(--ui-icon-button-border, var(--ui-border-default));
255
- background: var(--ui-icon-button-outline-bg, var(--ui-surface-default));
256
- color: var(--ui-icon-button-outline-color, var(--ui-text-primary));
259
+ background: var(--ui-icon-button-outline-surface, var(--ui-surface-default));
260
+ color: var(--ui-icon-button-outline-text, var(--ui-text-primary));
257
261
  }
258
262
 
259
263
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"] {
260
- background: var(--ui-icon-button-solid-bg, var(--ui-accent-solid));
261
- color: var(--ui-icon-button-solid-color, var(--ui-text-on-accent));
264
+ background: var(--ui-icon-button-solid-surface, var(--ui-accent-solid));
265
+ color: var(--ui-icon-button-solid-text, var(--ui-text-on-accent));
262
266
  box-shadow: var(
263
267
  --ui-icon-button-solid-shadow,
264
268
  0 1px 2px color-mix(in srgb, var(--ui-accent-solid) 18%, transparent)
@@ -267,8 +271,8 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
267
271
 
268
272
  [data-component~="ui-icon-button"]:hover:enabled {
269
273
  /* Derived from the text colour so the ghost hover shows on any background. */
270
- background: var(--ui-icon-button-hover-bg, color-mix(in srgb, currentColor 8%, transparent));
271
- color: var(--ui-icon-button-hover-color, var(--ui-text-primary));
274
+ background: var(--ui-icon-button-hover-surface, color-mix(in srgb, currentColor 8%, transparent));
275
+ color: var(--ui-icon-button-hover-text, var(--ui-text-primary));
272
276
  }
273
277
 
274
278
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=outline"]:hover:enabled {
@@ -276,7 +280,7 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
276
280
  }
277
281
 
278
282
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"]:hover:enabled {
279
- background: var(--ui-icon-button-solid-hover-bg, var(--ui-accent-hover));
283
+ background: var(--ui-icon-button-solid-hover-surface, var(--ui-accent-hover));
280
284
  }
281
285
 
282
286
  [data-component~="ui-icon-button"]:active:enabled {
@@ -291,7 +295,7 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
291
295
  /* Disabled colours fall back to each variant's own; ghost takes only the icon colour. */
292
296
  [data-component~="ui-icon-button"]:disabled {
293
297
  opacity: var(--ui-icon-button-disabled-opacity, 0.6);
294
- color: var(--ui-icon-button-disabled-color, inherit);
298
+ color: var(--ui-icon-button-disabled-text, inherit);
295
299
  cursor: not-allowed;
296
300
  }
297
301
 
@@ -301,36 +305,36 @@ html[data-ui-input-modality="touch"] [data-component~="ui-icon-button"]::after {
301
305
  var(--ui-icon-button-border, var(--ui-border-default))
302
306
  );
303
307
  background-color: var(
304
- --ui-icon-button-disabled-bg,
305
- var(--ui-icon-button-outline-bg, var(--ui-surface-default))
308
+ --ui-icon-button-disabled-surface,
309
+ var(--ui-icon-button-outline-surface, var(--ui-surface-default))
306
310
  );
307
311
  color: var(
308
- --ui-icon-button-disabled-color,
309
- var(--ui-icon-button-outline-color, var(--ui-text-primary))
312
+ --ui-icon-button-disabled-text,
313
+ var(--ui-icon-button-outline-text, var(--ui-text-primary))
310
314
  );
311
315
  }
312
316
 
313
317
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="variant=solid"]:disabled {
314
318
  background-color: var(
315
- --ui-icon-button-disabled-bg,
316
- var(--ui-icon-button-solid-bg, var(--ui-accent-solid))
319
+ --ui-icon-button-disabled-surface,
320
+ var(--ui-icon-button-solid-surface, var(--ui-accent-solid))
317
321
  );
318
322
  color: var(
319
- --ui-icon-button-disabled-color,
320
- var(--ui-icon-button-solid-color, var(--ui-text-on-accent))
323
+ --ui-icon-button-disabled-text,
324
+ var(--ui-icon-button-solid-text, var(--ui-text-on-accent))
321
325
  );
322
326
  }
323
327
 
324
328
  [data-component~="ui-icon-button"] {
325
- --_icon-button-icon-default: var(--ui-icon-size-md, 1.25rem);
329
+ --_icon-button-icon-default: var(--ui-icon-size-md);
326
330
  }
327
331
 
328
332
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=sm"] {
329
- --_icon-button-icon-default: var(--ui-icon-size-sm, 1rem);
333
+ --_icon-button-icon-default: var(--ui-icon-size-sm);
330
334
  }
331
335
 
332
336
  [data-component~="ui-icon-button"][data-ui-icon-button-state~="size=lg"] {
333
- --_icon-button-icon-default: var(--ui-icon-size-lg, 1.5rem);
337
+ --_icon-button-icon-default: var(--ui-icon-size-lg);
334
338
  }
335
339
 
336
340
  :slotted(svg) {
package/vue/UiInput.vue CHANGED
@@ -132,12 +132,12 @@ onBeforeUnmount(() => {
132
132
  display: inline-block;
133
133
  inline-size: 100%;
134
134
  min-inline-size: 0;
135
- min-block-size: var(--ui-control-size-md, 2.5rem);
135
+ min-block-size: var(--ui-control-size-md);
136
136
  margin: 0;
137
137
  padding: var(--ui-space-2) var(--ui-space-3);
138
138
  appearance: none;
139
139
  border: 1px solid var(--ui-control-border, var(--ui-border-strong));
140
- border-radius: var(--ui-input-radius, var(--ui-radius-2));
140
+ border-radius: var(--ui-input-radius, var(--ui-radius-md));
141
141
  background: var(--ui-control-surface, var(--ui-surface-elevated));
142
142
  color: var(--ui-text-primary);
143
143
  font: inherit;
package/vue/UiMenu.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  type __VLS_Props = {
2
+ density?: 'comfortable' | 'compact';
2
3
  for?: string;
3
4
  open?: boolean;
4
5
  placement?: string;
@@ -43,6 +44,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
43
44
  for: string;
44
45
  open: boolean;
45
46
  placement: string;
47
+ density: "comfortable" | "compact";
46
48
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
47
49
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
48
50
  declare const _default: typeof __VLS_export;
package/vue/UiMenu.vue CHANGED
@@ -7,11 +7,13 @@ defineOptions({ inheritAttrs: false })
7
7
 
8
8
  const props = withDefaults(
9
9
  defineProps<{
10
+ density?: 'comfortable' | 'compact'
10
11
  for?: string
11
12
  open?: boolean
12
13
  placement?: string
13
14
  }>(),
14
15
  {
16
+ density: 'comfortable',
15
17
  for: '',
16
18
  open: false,
17
19
  placement: 'bottom-start',
@@ -44,6 +46,7 @@ const internalOpen = ref(false)
44
46
  /** The values the styles' :host-state() rules test. */
45
47
  const hostState = computed(() =>
46
48
  [
49
+ props.density && `density density=${props.density}`,
47
50
  internalOpen.value && 'internalOpen',
48
51
  ].filter(Boolean).join(' ')
49
52
  )
@@ -192,16 +195,23 @@ onBeforeUnmount(() => {
192
195
  </template>
193
196
 
194
197
  <style scoped>
198
+ /* Compact sets the part tokens its items read, so nothing has to rescale a global. */
199
+ [data-component~="ui-menu"][data-ui-menu-state~="density=compact"] {
200
+ --ui-menu-item-padding-block: var(--ui-space-1);
201
+ --ui-menu-item-padding-inline: var(--ui-space-2);
202
+ --ui-menu-item-font-size: var(--ui-font-size-sm);
203
+ --ui-menu-item-radius: var(--ui-radius-sm);
204
+ padding: var(--ui-space-1);
205
+ gap: 0;
206
+ }
207
+
195
208
  [data-component~="ui-menu"] {
196
209
  display: flex;
197
210
  flex-direction: column;
198
211
  box-sizing: border-box;
199
212
  inline-size: max-content;
200
- min-inline-size: min(
201
- 12rem,
202
- calc(100vw - var(--ui-menu-viewport-gap, var(--ui-space-2, 0.5rem)) * 2)
203
- );
204
- max-inline-size: calc(100vw - var(--ui-menu-viewport-gap, var(--ui-space-2, 0.5rem)) * 2);
213
+ min-inline-size: min(12rem, calc(100vw - var(--ui-menu-viewport-gap, var(--ui-space-2)) * 2));
214
+ max-inline-size: calc(100vw - var(--ui-menu-viewport-gap, var(--ui-space-2)) * 2);
205
215
  padding: 0;
206
216
  border: 0;
207
217
  outline: 0;
@@ -219,7 +229,7 @@ onBeforeUnmount(() => {
219
229
  padding: var(--ui-space-1);
220
230
  background: var(--ui-surface-elevated);
221
231
  border: 1px solid var(--ui-border-default);
222
- border-radius: var(--ui-radius-3);
232
+ border-radius: var(--ui-radius-lg);
223
233
  box-shadow: var(--ui-elevation-overlay, var(--ui-shadow-lg));
224
234
  max-block-size: inherit;
225
235
  overflow: auto;
@@ -234,7 +244,7 @@ onBeforeUnmount(() => {
234
244
  inset: auto;
235
245
  margin: 0;
236
246
  overflow: visible;
237
- max-block-size: calc(100dvh - var(--ui-menu-viewport-gap, var(--ui-space-2, 0.5rem)) * 2);
247
+ max-block-size: calc(100dvh - var(--ui-menu-viewport-gap, var(--ui-space-2)) * 2);
238
248
  opacity: 0;
239
249
  transform: translateY(-4px) scale(0.99);
240
250
  transition:
@@ -32,12 +32,13 @@ withDefaults(
32
32
  display: block;
33
33
  box-sizing: border-box;
34
34
  width: 100%;
35
- padding: var(--ui-space-2) var(--ui-space-3);
35
+ padding: var(--ui-menu-item-padding-block, var(--ui-space-2))
36
+ var(--ui-menu-item-padding-inline, var(--ui-space-3));
36
37
  text-align: left;
37
- border-radius: var(--ui-radius-2);
38
+ border-radius: var(--ui-menu-item-radius, var(--ui-radius-md));
38
39
  color: var(--ui-text-primary);
39
- font-size: var(--ui-font-size-md);
40
- font-weight: var(--ui-font-medium, 500);
40
+ font-size: var(--ui-menu-item-font-size, var(--ui-font-size-md));
41
+ font-weight: var(--ui-font-medium);
41
42
  cursor: pointer;
42
43
  outline: none;
43
44
  transition:
@@ -46,7 +47,7 @@ withDefaults(
46
47
  }
47
48
 
48
49
  [data-component~="ui-menu-item"]:is(:hover, :focus-visible):not([aria-disabled="true"]) {
49
- background: var(--ui-surface-subtle);
50
+ background: var(--ui-menu-item-hover-surface, var(--ui-surface-subtle));
50
51
  }
51
52
 
52
53
  [data-component~="ui-menu-item"][aria-disabled="true"] {
package/vue/UiPopover.vue CHANGED
@@ -183,9 +183,9 @@ onBeforeUnmount(() => {
183
183
  box-sizing: border-box;
184
184
  max-inline-size: min(
185
185
  20rem,
186
- calc(100vw - var(--ui-popover-viewport-gap, var(--ui-space-2, 0.5rem)) * 2)
186
+ calc(100vw - var(--ui-popover-viewport-gap, var(--ui-space-2)) * 2)
187
187
  );
188
- max-block-size: calc(100dvh - var(--ui-popover-viewport-gap, var(--ui-space-2, 0.5rem)) * 2);
188
+ max-block-size: calc(100dvh - var(--ui-popover-viewport-gap, var(--ui-space-2)) * 2);
189
189
  overflow: visible;
190
190
  padding: 0;
191
191
  border: 0;
@@ -203,7 +203,7 @@ onBeforeUnmount(() => {
203
203
  padding: var(--ui-space-3);
204
204
  background: var(--ui-surface-elevated);
205
205
  border: 1px solid var(--ui-border-default);
206
- border-radius: var(--ui-radius-3);
206
+ border-radius: var(--ui-radius-lg);
207
207
  box-shadow: var(--ui-elevation-overlay, var(--ui-shadow-lg));
208
208
  }
209
209