@threadlabs/looma 0.22.14 → 0.23.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 (217) hide show
  1. package/components/shared/icons.js +2 -0
  2. package/components/ui-avatar/ui-avatar.html +3 -3
  3. package/components/ui-avatar-group/ui-avatar-group.html +1 -1
  4. package/components/ui-badge/ui-badge.html +1 -1
  5. package/components/ui-button/ui-button.html +3 -3
  6. package/components/ui-callout/ui-callout.html +3 -2
  7. package/components/ui-card/ui-card.html +2 -2
  8. package/components/ui-checkbox/ui-checkbox.html +3 -3
  9. package/components/ui-combobox/ui-combobox.html +8 -8
  10. package/components/ui-context-menu/ui-context-menu.html +2 -2
  11. package/components/ui-description-list/ui-description-list.html +1 -1
  12. package/components/ui-dialog/ui-dialog.html +3 -3
  13. package/components/ui-disclosure/ui-disclosure.html +43 -3
  14. package/components/ui-editable/ui-editable.html +2 -2
  15. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +5 -5
  16. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +2 -2
  17. package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +6 -6
  18. package/components/ui-editor-slash-menu-item/ui-editor-slash-menu-item.html +1 -1
  19. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +2 -2
  20. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +11 -11
  21. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +5 -5
  22. package/components/ui-editor-toolbar/ui-editor-toolbar.html +4 -4
  23. package/components/ui-floating-action-button/ui-floating-action-button.html +2 -2
  24. package/components/ui-icon/ui-icon.html +2 -0
  25. package/components/ui-icon-button/ui-icon-button.html +1 -1
  26. package/components/ui-input/ui-input.html +8 -4
  27. package/components/ui-input-group/ui-input-group.html +10 -6
  28. package/components/ui-list/ui-list.html +1 -1
  29. package/components/ui-list-item/ui-list-item.html +20 -4
  30. package/components/ui-listbox/ui-listbox.html +3 -3
  31. package/components/ui-menu/ui-menu.html +2 -2
  32. package/components/ui-menu-item/ui-menu-item.html +4 -4
  33. package/components/ui-meter/ui-meter.html +1 -1
  34. package/components/ui-nav-item/ui-nav-item.html +46 -14
  35. package/components/ui-popover/ui-popover.html +1 -1
  36. package/components/ui-radio/ui-radio.html +2 -2
  37. package/components/ui-search-result-row/ui-search-result-row.html +24 -5
  38. package/components/ui-search-shell/ui-search-shell.html +4 -4
  39. package/components/ui-section/ui-section.html +3 -3
  40. package/components/ui-select/ui-select.html +6 -2
  41. package/components/ui-separator/ui-separator.html +2 -2
  42. package/components/ui-sidebar/ui-sidebar.html +3 -3
  43. package/components/ui-status-message/ui-status-message.html +1 -1
  44. package/components/ui-switch/ui-switch.html +3 -3
  45. package/components/ui-table/ui-table.html +3 -3
  46. package/components/ui-tabs/ui-tabs.html +7 -7
  47. package/components/ui-textarea/ui-textarea.html +6 -2
  48. package/components/ui-toast/ui-toast.html +2 -2
  49. package/components/ui-toast-region/ui-toast-region.html +5 -5
  50. package/components/ui-tooltip/ui-tooltip.html +15 -15
  51. package/components/ui-top-bar/ui-top-bar.html +1 -1
  52. package/components/ui-tree-item/ui-tree-item.html +27 -8
  53. package/dist/index.js +1 -1
  54. package/editor/icons.d.ts +2 -0
  55. package/editor/index.js +3 -1
  56. package/package.json +1 -1
  57. package/styles/ui-avatar-group.css +1 -1
  58. package/styles/ui-avatar.css +3 -3
  59. package/styles/ui-badge.css +1 -1
  60. package/styles/ui-button.css +3 -3
  61. package/styles/ui-callout.css +3 -2
  62. package/styles/ui-card.css +2 -2
  63. package/styles/ui-checkbox.css +3 -3
  64. package/styles/ui-combobox.css +8 -8
  65. package/styles/ui-context-menu.css +2 -2
  66. package/styles/ui-description-list.css +1 -1
  67. package/styles/ui-dialog.css +3 -3
  68. package/styles/ui-disclosure.css +42 -2
  69. package/styles/ui-editable.css +2 -2
  70. package/styles/ui-editor-insert-table-grid.css +5 -5
  71. package/styles/ui-editor-mention-menu.css +2 -2
  72. package/styles/ui-editor-slash-menu-item.css +1 -1
  73. package/styles/ui-editor-slash-menu.css +6 -6
  74. package/styles/ui-editor-table-context-menu.css +2 -2
  75. package/styles/ui-editor-table-overlay.css +11 -11
  76. package/styles/ui-editor-table-toolbar.css +5 -5
  77. package/styles/ui-editor-toolbar.css +4 -4
  78. package/styles/ui-floating-action-button.css +2 -2
  79. package/styles/ui-icon-button.css +1 -1
  80. package/styles/ui-input-group.css +10 -6
  81. package/styles/ui-input.css +8 -4
  82. package/styles/ui-list-item.css +23 -4
  83. package/styles/ui-list.css +1 -1
  84. package/styles/ui-listbox.css +3 -3
  85. package/styles/ui-menu-item.css +4 -4
  86. package/styles/ui-menu.css +2 -2
  87. package/styles/ui-meter.css +1 -1
  88. package/styles/ui-nav-item.css +46 -12
  89. package/styles/ui-popover.css +1 -1
  90. package/styles/ui-radio.css +2 -2
  91. package/styles/ui-search-result-row.css +29 -5
  92. package/styles/ui-search-shell.css +4 -4
  93. package/styles/ui-section.css +3 -3
  94. package/styles/ui-select.css +6 -2
  95. package/styles/ui-separator.css +2 -2
  96. package/styles/ui-sidebar.css +3 -3
  97. package/styles/ui-status-message.css +1 -1
  98. package/styles/ui-switch.css +3 -3
  99. package/styles/ui-table.css +3 -3
  100. package/styles/ui-tabs.css +7 -7
  101. package/styles/ui-textarea.css +6 -2
  102. package/styles/ui-toast-region.css +5 -5
  103. package/styles/ui-toast.css +2 -2
  104. package/styles/ui-tooltip.css +15 -15
  105. package/styles/ui-top-bar.css +1 -1
  106. package/styles/ui-tree-item.css +32 -8
  107. package/tokens.css +30 -9
  108. package/vanilla/UiDisclosure.d.ts +1 -0
  109. package/vanilla/UiDisclosure.js +10 -1
  110. package/vanilla/UiIcon.js +1 -1
  111. package/vanilla/UiNavItem.d.ts +2 -0
  112. package/vanilla/UiNavItem.js +1 -1
  113. package/vue/UiAvatar.vue +3 -3
  114. package/vue/UiAvatarGroup.vue +1 -1
  115. package/vue/UiBadge.vue +2 -1
  116. package/vue/UiButton.vue +3 -3
  117. package/vue/UiCallout.vue +2 -2
  118. package/vue/UiCard.vue +2 -2
  119. package/vue/UiCheckbox.vue +3 -3
  120. package/vue/UiCombobox.vue +11 -8
  121. package/vue/UiContextMenu.vue +2 -2
  122. package/vue/UiDescriptionList.vue +1 -1
  123. package/vue/UiDialog.vue +4 -3
  124. package/vue/UiDisclosure.d.ts +13 -2
  125. package/vue/UiDisclosure.vue +61 -4
  126. package/vue/UiEditable.vue +2 -2
  127. package/vue/UiEditorInsertTableGrid.vue +5 -5
  128. package/vue/UiEditorMentionMenu.vue +2 -2
  129. package/vue/UiEditorSlashMenu.vue +6 -6
  130. package/vue/UiEditorSlashMenuItem.vue +1 -1
  131. package/vue/UiEditorTableContextMenu.vue +2 -2
  132. package/vue/UiEditorTableOverlay.vue +11 -11
  133. package/vue/UiEditorTableToolbar.vue +5 -5
  134. package/vue/UiEditorToolbar.vue +6 -4
  135. package/vue/UiFloatingActionButton.vue +2 -2
  136. package/vue/UiIcon.vue +8 -0
  137. package/vue/UiIconButton.vue +1 -1
  138. package/vue/UiInput.vue +7 -4
  139. package/vue/UiInputGroup.vue +6 -6
  140. package/vue/UiList.vue +1 -1
  141. package/vue/UiListItem.vue +20 -4
  142. package/vue/UiListbox.vue +3 -3
  143. package/vue/UiMenu.vue +3 -2
  144. package/vue/UiMenuItem.vue +4 -4
  145. package/vue/UiMeter.vue +1 -1
  146. package/vue/UiNavItem.d.ts +18 -0
  147. package/vue/UiNavItem.vue +96 -12
  148. package/vue/UiPopover.vue +2 -1
  149. package/vue/UiRadio.vue +2 -2
  150. package/vue/UiSearchResultRow.vue +25 -5
  151. package/vue/UiSearchShell.vue +4 -4
  152. package/vue/UiSection.vue +3 -3
  153. package/vue/UiSelect.vue +3 -2
  154. package/vue/UiSeparator.vue +4 -2
  155. package/vue/UiSidebar.vue +5 -3
  156. package/vue/UiStatusMessage.vue +1 -1
  157. package/vue/UiSwitch.vue +3 -3
  158. package/vue/UiTable.vue +3 -3
  159. package/vue/UiTabs.vue +8 -7
  160. package/vue/UiTextarea.vue +2 -2
  161. package/vue/UiToast.vue +4 -2
  162. package/vue/UiToastRegion.vue +5 -5
  163. package/vue/UiTooltip.vue +19 -15
  164. package/vue/UiTopBar.vue +1 -1
  165. package/vue/UiTreeItem.vue +31 -8
  166. package/vue/chunks/UiAvatar.js +1 -1
  167. package/vue/chunks/UiAvatarGroup.js +1 -1
  168. package/vue/chunks/UiBadge.js +1 -1
  169. package/vue/chunks/UiButton.js +1 -1
  170. package/vue/chunks/UiCallout.js +1 -1
  171. package/vue/chunks/UiCard.js +1 -1
  172. package/vue/chunks/UiCheckbox.js +1 -1
  173. package/vue/chunks/UiCombobox.js +1 -1
  174. package/vue/chunks/UiContextMenu.js +1 -1
  175. package/vue/chunks/UiDescriptionList.js +1 -1
  176. package/vue/chunks/UiDialog.js +1 -1
  177. package/vue/chunks/UiDisclosure.js +27 -4
  178. package/vue/chunks/UiEditable.js +1 -1
  179. package/vue/chunks/UiEditorInsertTableGrid.js +1 -1
  180. package/vue/chunks/UiEditorMentionMenu.js +1 -1
  181. package/vue/chunks/UiEditorSlashMenu.js +1 -1
  182. package/vue/chunks/UiEditorSlashMenuItem.js +1 -1
  183. package/vue/chunks/UiEditorTableContextMenu.js +1 -1
  184. package/vue/chunks/UiEditorTableOverlay.js +1 -1
  185. package/vue/chunks/UiEditorTableToolbar.js +1 -1
  186. package/vue/chunks/UiEditorToolbar.js +1 -1
  187. package/vue/chunks/UiFloatingActionButton.js +1 -1
  188. package/vue/chunks/UiIcon.js +24 -1
  189. package/vue/chunks/UiIconButton.js +1 -1
  190. package/vue/chunks/UiInput.js +1 -1
  191. package/vue/chunks/UiInputGroup.js +1 -1
  192. package/vue/chunks/UiList.js +1 -1
  193. package/vue/chunks/UiListItem.js +1 -1
  194. package/vue/chunks/UiListbox.js +1 -1
  195. package/vue/chunks/UiMenu.js +1 -1
  196. package/vue/chunks/UiMenuItem.js +1 -1
  197. package/vue/chunks/UiMeter.js +1 -1
  198. package/vue/chunks/UiNavItem.js +65 -6
  199. package/vue/chunks/UiPopover.js +1 -1
  200. package/vue/chunks/UiRadio.js +1 -1
  201. package/vue/chunks/UiSearchResultRow.js +1 -1
  202. package/vue/chunks/UiSearchShell.js +1 -1
  203. package/vue/chunks/UiSection.js +1 -1
  204. package/vue/chunks/UiSelect.js +1 -1
  205. package/vue/chunks/UiSeparator.js +1 -1
  206. package/vue/chunks/UiSidebar.js +1 -1
  207. package/vue/chunks/UiStatusMessage.js +1 -1
  208. package/vue/chunks/UiSwitch.js +1 -1
  209. package/vue/chunks/UiTable.js +1 -1
  210. package/vue/chunks/UiTabs.js +1 -1
  211. package/vue/chunks/UiTextarea.js +1 -1
  212. package/vue/chunks/UiToast.js +1 -1
  213. package/vue/chunks/UiToastRegion.js +1 -1
  214. package/vue/chunks/UiTooltip.js +1 -1
  215. package/vue/chunks/UiTopBar.js +1 -1
  216. package/vue/chunks/UiTreeItem.js +1 -1
  217. package/vue/components.css +1348 -1208
@@ -52,7 +52,7 @@
52
52
  overflow-y: hidden;
53
53
  overscroll-behavior: contain;
54
54
  scrollbar-width: thin;
55
- border-block-end: 1px solid var(--ui-border-divider);
55
+ border-block-end: var(--ui-border-width) solid var(--ui-border-divider);
56
56
  }
57
57
 
58
58
  /* Centre the glyphs, not the line box: a label without descenders otherwise reads high. */
@@ -78,7 +78,7 @@
78
78
  grid-auto-flow: row;
79
79
  grid-auto-columns: auto;
80
80
  border-block-end: 0;
81
- border-inline-end: 1px solid var(--ui-border-divider);
81
+ border-inline-end: var(--ui-border-width) solid var(--ui-border-divider);
82
82
  }
83
83
 
84
84
  @media (prefers-reduced-motion: reduce) {
@@ -97,10 +97,10 @@
97
97
  .list button,
98
98
  .list > :where([data-slotted], [data-slotted] *):is(button[slot="tab"]) {
99
99
  min-block-size: var(--_ui-tabs-tab-min-block-size, var(--_tab-min-block-size));
100
- margin: 0 0 -1px;
100
+ margin: 0 0 calc(-1 * var(--ui-border-width));
101
101
  padding: var(--_ui-tabs-tab-padding-block, var(--_tab-padding-block)) var(--_ui-tabs-tab-padding-inline, var(--_tab-padding-inline));
102
102
  border: 0;
103
- border-block-end: 2px solid transparent;
103
+ border-block-end: var(--ui-accent-line-width) solid transparent;
104
104
  background: transparent;
105
105
  color: var(--ui-text-secondary);
106
106
  font: inherit;
@@ -146,7 +146,7 @@
146
146
  .list > :where([data-slotted], [data-slotted] *):is(button[slot="tab"]:focus-visible) {
147
147
  position: relative;
148
148
  outline: none;
149
- box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
149
+ box-shadow: inset 0 0 0 var(--ui-focus-width) color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
150
150
  border-radius: var(--ui-radius-sm);
151
151
  }
152
152
  .panels > :where([data-slotted], [data-slotted] *):is(*) {
@@ -155,9 +155,9 @@
155
155
 
156
156
  :scope[data-ui-tabs-state~="orientation=vertical"] .list button,
157
157
  :scope[data-ui-tabs-state~="orientation=vertical"] .list > :where([data-slotted], [data-slotted] *):is(button[slot="tab"]) {
158
- margin: 0 -1px 0 0;
158
+ margin: 0 calc(-1 * var(--ui-border-width)) 0 0;
159
159
  border-block-end: 0;
160
- border-inline-end: 2px solid transparent;
160
+ border-inline-end: var(--ui-accent-line-width) solid transparent;
161
161
  text-align: start;
162
162
  }
163
163
 
@@ -33,7 +33,7 @@
33
33
  padding: var(--ui-space-2) var(--ui-space-3);
34
34
  appearance: none;
35
35
  resize: vertical;
36
- border: 1px solid var(--ui-control-border, var(--ui-border-strong));
36
+ border: var(--ui-border-width) solid var(--ui-control-border, var(--ui-border-strong));
37
37
  border-radius: var(--ui-textarea-radius, var(--ui-field-radius, var(--ui-radius-md)));
38
38
  background: var(--ui-control-surface, var(--ui-surface-elevated));
39
39
  color: var(--ui-text-primary);
@@ -77,7 +77,11 @@
77
77
  box-shadow: var(
78
78
  --ui-textarea-invalid-focus-shadow,
79
79
  var(--ui-control-inset),
80
- 0 0 0 3px color-mix(in srgb, var(--ui-textarea-invalid-border, var(--ui-field-danger, var(--ui-danger-solid))) 22%, transparent)
80
+ 0 0 0 calc(var(--ui-focus-width) * 1.5) color-mix(
81
+ in srgb,
82
+ var(--ui-textarea-invalid-border, var(--ui-field-danger, var(--ui-danger-solid))) 22%,
83
+ transparent
84
+ )
81
85
  );
82
86
  }
83
87
 
@@ -129,7 +129,7 @@
129
129
  grid-template-columns: 1fr auto;
130
130
  gap: var(--ui-space-2);
131
131
  align-items: start;
132
- border: 1px solid var(--_ui-toast-region-border, var(--ui-overlay-border, var(--ui-border-strong)));
132
+ border: var(--ui-border-width) solid var(--_ui-toast-region-border, var(--ui-overlay-border, var(--ui-border-strong)));
133
133
  border-radius: var(--_ui-toast-region-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
134
134
  padding: var(--ui-space-3) var(--ui-space-4);
135
135
  background: var(--_ui-toast-region-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
@@ -139,16 +139,16 @@
139
139
  }
140
140
 
141
141
  .toast[data-tone="info"] {
142
- border-inline-start: 3px solid var(--ui-info-solid);
142
+ border-inline-start: var(--ui-accent-line-width) solid var(--ui-info-solid);
143
143
  }
144
144
  .toast[data-tone="success"] {
145
- border-inline-start: 3px solid var(--ui-success-solid);
145
+ border-inline-start: var(--ui-accent-line-width) solid var(--ui-success-solid);
146
146
  }
147
147
  .toast[data-tone="warning"] {
148
- border-inline-start: 3px solid var(--ui-warning-solid);
148
+ border-inline-start: var(--ui-accent-line-width) solid var(--ui-warning-solid);
149
149
  }
150
150
  .toast[data-tone="danger"] {
151
- border-inline-start: 3px solid var(--ui-danger-solid);
151
+ border-inline-start: var(--ui-accent-line-width) solid var(--ui-danger-solid);
152
152
  }
153
153
 
154
154
  /* Leaving slides on down and fades; the controller removes the toast when this ends. */
@@ -32,8 +32,8 @@
32
32
  inline-size: 100%;
33
33
  margin: 0;
34
34
  padding: var(--ui-space-3) var(--ui-space-4);
35
- border: 1px solid var(--ui-toast-border, var(--ui-overlay-border, var(--ui-border-strong)));
36
- border-inline-start: 3px solid var(--ui-toast-accent, var(--_ui-toast-accent));
35
+ border: var(--ui-border-width) solid var(--ui-toast-border, var(--ui-overlay-border, var(--ui-border-strong)));
36
+ border-inline-start: var(--ui-accent-line-width) solid var(--ui-toast-accent, var(--_ui-toast-accent));
37
37
  border-radius: var(--ui-toast-radius, var(--ui-overlay-radius, var(--ui-radius-lg)));
38
38
  background: var(--ui-toast-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
39
39
  color: var(--ui-text-primary);
@@ -80,7 +80,7 @@
80
80
  position: relative;
81
81
  box-sizing: border-box;
82
82
  max-inline-size: var(--_ui-tooltip-max-inline-size, 18rem);
83
- border: 1px solid var(--_tooltip-line);
83
+ border: var(--ui-border-width) solid var(--_tooltip-line);
84
84
  border-radius: var(--_ui-tooltip-radius, var(--ui-overlay-radius, var(--ui-radius-md)));
85
85
  background: var(--_ui-tooltip-surface, var(--ui-overlay-surface, var(--ui-surface-elevated)));
86
86
  color: var(--_ui-tooltip-text, var(--ui-text-primary));
@@ -125,27 +125,27 @@
125
125
  position: absolute;
126
126
  z-index: 1;
127
127
  inset-inline-start: var(--ui-space-3);
128
- inset-block-end: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - 0.5px);
128
+ inset-block-end: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - var(--ui-border-width) / 2);
129
129
  inline-size: var(--_ui-tooltip-arrow-size, 0.625rem);
130
130
  block-size: var(--_ui-tooltip-arrow-size, 0.625rem);
131
131
  box-sizing: border-box;
132
132
  background: inherit;
133
133
  border: 0 solid var(--_tooltip-line);
134
- border-inline-end-width: 1px;
135
- border-block-end-width: 1px;
136
- border-end-end-radius: 1px;
134
+ border-inline-end-width: var(--ui-border-width);
135
+ border-block-end-width: var(--ui-border-width);
136
+ border-end-end-radius: var(--ui-border-width);
137
137
  transform: rotate(45deg) scaleX(1.25) scaleY(0.85);
138
138
  }
139
139
 
140
140
  :scope[data-ui-actual-placement="bottom"] .surface::after {
141
- inset-block-start: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - 0.5px);
141
+ inset-block-start: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - var(--ui-border-width) / 2);
142
142
  inset-block-end: auto;
143
143
  border-inline-end-width: 0;
144
144
  border-block-end-width: 0;
145
- border-inline-start-width: 1px;
146
- border-block-start-width: 1px;
145
+ border-inline-start-width: var(--ui-border-width);
146
+ border-block-start-width: var(--ui-border-width);
147
147
  border-end-end-radius: 0;
148
- border-start-start-radius: 1px;
148
+ border-start-start-radius: var(--ui-border-width);
149
149
  }
150
150
 
151
151
  :scope[data-ui-actual-align="center"] .surface::after {
@@ -166,16 +166,16 @@
166
166
 
167
167
  :scope[data-ui-actual-placement="left"] .surface::after {
168
168
  inset-inline-start: auto;
169
- inset-inline-end: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - 0.5px);
170
- border-inline-end-width: 1px;
171
- border-block-start-width: 1px;
169
+ inset-inline-end: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - var(--ui-border-width) / 2);
170
+ border-inline-end-width: var(--ui-border-width);
171
+ border-block-start-width: var(--ui-border-width);
172
172
  }
173
173
 
174
174
  :scope[data-ui-actual-placement="right"] .surface::after {
175
- inset-inline-start: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - 0.5px);
175
+ inset-inline-start: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - var(--ui-border-width) / 2);
176
176
  inset-inline-end: auto;
177
- border-inline-start-width: 1px;
178
- border-block-end-width: 1px;
177
+ border-inline-start-width: var(--ui-border-width);
178
+ border-block-end-width: var(--ui-border-width);
179
179
  }
180
180
 
181
181
  :scope[data-ui-actual-placement="left"][data-ui-actual-align="start"] .surface::after,
@@ -45,7 +45,7 @@
45
45
  padding-inline-start: max(var(--ui-top-bar-padding-inline, var(--ui-space-4)), env(safe-area-inset-left));
46
46
  padding-inline-end: max(var(--ui-top-bar-padding-inline, var(--ui-space-4)), env(safe-area-inset-right));
47
47
  background: var(--ui-top-bar-surface, var(--ui-surface-elevated));
48
- border-block-end: 1px solid var(--ui-top-bar-border, var(--ui-border-divider));
48
+ border-block-end: var(--ui-border-width) solid var(--ui-top-bar-border, var(--ui-border-divider));
49
49
  }
50
50
 
51
51
  .leading,
@@ -56,7 +56,7 @@
56
56
  min-block-size: var(--_ui-tree-item-min-block-size, var(--_tree-row-min-height));
57
57
  min-inline-size: 0;
58
58
  font-size: var(--_ui-tree-item-font-size, var(--ui-font-size-sm));
59
- border-radius: var(--ui-radius-md);
59
+ border-radius: var(--ui-selection-radius);
60
60
  color: var(--ui-text-secondary);
61
61
  transition:
62
62
  background-color var(--ui-motion-fast) var(--ui-motion-ease),
@@ -67,12 +67,20 @@
67
67
  }
68
68
 
69
69
  .row:hover,
70
- :scope[data-ui-tree-item-state~="selected"] .row,
71
70
  .row:focus-within {
72
71
  color: var(--ui-text-primary);
73
72
  background: var(--ui-surface-muted);
74
73
  }
75
74
 
75
+ /* Selection is the same surface recipe as destination and choice rows. */
76
+ :scope[data-ui-tree-item-state~="selected"] > .row {
77
+ color: var(--ui-selection-text);
78
+ background: var(--ui-selection-surface);
79
+ }
80
+ :scope[data-ui-tree-item-state~="selected"]:not([aria-disabled="true"]) > .row > .leading {
81
+ color: var(--ui-selection-text);
82
+ }
83
+
76
84
  :scope[data-ui-tree-item-state~="disabled"] .row {
77
85
  color: var(--ui-disabled-text);
78
86
  background: var(--ui-disabled-surface);
@@ -87,13 +95,13 @@
87
95
  }
88
96
 
89
97
  :scope:focus-visible .row {
90
- box-shadow: 0 0 0 2px var(--ui-focus-ring);
98
+ box-shadow: 0 0 0 var(--ui-focus-width) var(--ui-focus-ring);
91
99
  }
92
100
 
93
101
  /* Child combinators: drop feedback belongs to this item's own row, not the rows nested in it. */
94
102
  :scope[data-drop-position="inside"] > .row {
95
103
  background: var(--ui-accent-subtle);
96
- box-shadow: inset 0 0 0 1px var(--_ui-tree-drop-color, var(--ui-accent-solid));
104
+ box-shadow: inset 0 0 0 var(--ui-accent-line-width) var(--_ui-tree-drop-color, var(--ui-accent-solid));
97
105
  }
98
106
 
99
107
  .disclosure,
@@ -389,7 +397,7 @@
389
397
  z-index: 3;
390
398
  inset-inline: 1px;
391
399
  display: none;
392
- block-size: 2px;
400
+ block-size: var(--ui-accent-line-width);
393
401
  border-radius: var(--ui-radius-round);
394
402
  background: var(--_ui-tree-drop-color, var(--ui-accent-solid));
395
403
  pointer-events: none;
@@ -402,7 +410,7 @@
402
410
  inset-block-start: 50%;
403
411
  inline-size: 7px;
404
412
  block-size: 7px;
405
- border: 2px solid var(--_ui-tree-drop-color, var(--ui-accent-solid));
413
+ border: var(--ui-accent-line-width) solid var(--_ui-tree-drop-color, var(--ui-accent-solid));
406
414
  border-radius: var(--ui-radius-round);
407
415
  background: var(--ui-surface-elevated);
408
416
  transform: translateY(-50%);
@@ -417,12 +425,12 @@
417
425
 
418
426
  :scope[data-drop-position="before"] > .row > .row-drop-indicator {
419
427
  display: block;
420
- inset-block-start: -1px;
428
+ inset-block-start: calc(-0.5 * var(--ui-accent-line-width));
421
429
  }
422
430
 
423
431
  :scope[data-drop-position="after"] > .subtree-drop-indicator {
424
432
  display: block;
425
- inset-block-end: -1px;
433
+ inset-block-end: calc(-0.5 * var(--ui-accent-line-width));
426
434
  }
427
435
 
428
436
  .children[hidden] {
@@ -484,6 +492,17 @@
484
492
  }
485
493
  }
486
494
 
495
+ @media (forced-colors: active) {
496
+ :scope:focus-visible > .row {
497
+ outline: var(--ui-focus-width) solid Highlight;
498
+ outline-offset: calc(-1 * var(--ui-focus-width));
499
+ }
500
+ :scope[data-ui-tree-item-state~="selected"]:not(:focus-visible):not([aria-disabled="true"]) > .row {
501
+ outline: var(--ui-border-width) solid Highlight;
502
+ outline-offset: calc(-1 * var(--ui-border-width));
503
+ }
504
+ }
505
+
487
506
  /* A component that sets its display still honours the hidden attribute on its root. */
488
507
  :scope[hidden] {
489
508
  display: none;
@@ -492,6 +511,8 @@
492
511
  @scope ([data-component~="ui-tree-item"]) to ([data-component]) {
493
512
  /* This component's hooks style the element they are set on, and never a nested one. */
494
513
 
514
+ /* Selection is the same surface recipe as destination and choice rows. */
515
+
495
516
  /* Child combinators: drop feedback belongs to this item's own row, not the rows nested in it. */
496
517
 
497
518
  /* Lucide grip-vertical, filling the handle as in Looma 0.2. */
@@ -552,5 +573,8 @@
552
573
  @media (prefers-reduced-motion: reduce) {
553
574
  }
554
575
 
576
+ @media (forced-colors: active) {
577
+ }
578
+
555
579
  /* A component that sets its display still honours the hidden attribute on its root. */
556
580
  }
package/tokens.css CHANGED
@@ -23,7 +23,7 @@
23
23
  --ui-surface-raised: #ffffff;
24
24
  --ui-surface-sunken: #f0f0ec;
25
25
  --ui-text: #1a1a1a;
26
- --ui-focus-halo: 0 0 0 3px color-mix(in srgb, var(--ui-focus-ring) 40%, transparent);
26
+ --ui-focus-halo: 0 0 0 calc(var(--ui-focus-width) * 1.5) color-mix(in srgb, var(--ui-focus-ring) 40%, transparent);
27
27
 
28
28
  /* Type. */
29
29
  --ui-font-sans:
@@ -48,6 +48,11 @@
48
48
  --ui-space-3: 0.75rem;
49
49
  --ui-space-4: 1rem;
50
50
 
51
+ /* Line dimensions by role. Accent edges follow ordinary lines unless deliberately themed;
52
+ keyboard focus is independent so a quiet border theme cannot erase the focus indicator. */
53
+ --ui-border-width: 1px;
54
+ --ui-focus-width: 2px;
55
+
51
56
  /* Radius. */
52
57
  --ui-radius-sm: 0.25rem;
53
58
  --ui-radius-md: 0.5rem;
@@ -80,6 +85,8 @@
80
85
  never has to: these exist so components share one vocabulary, not to be configured. */
81
86
  :root,
82
87
  :where([data-theme], [data-contrast]) {
88
+ --ui-accent-line-width: var(--ui-border-width);
89
+
83
90
  /* Type scale, from the base size. */
84
91
  --ui-font-size-2xs: calc(var(--ui-font-size) * 0.6875);
85
92
  --ui-font-size-xs: calc(var(--ui-font-size) * 0.75);
@@ -168,6 +175,12 @@
168
175
 
169
176
  /* Intent tones: a solid surface, its foreground, and a soft tint of each. */
170
177
  --ui-accent-solid: var(--ui-accent);
178
+ /* One quiet selection recipe for destination/content rows. Hue derives from the brand;
179
+ corners derive from the scale, and selected labels retain their resting weight. */
180
+ --ui-selection-surface: color-mix(in oklab, var(--ui-accent) 6%, var(--ui-surface));
181
+ --ui-selection-text: var(--ui-accent-subtle-text);
182
+ --ui-selection-radius: var(--ui-radius-md);
183
+
171
184
  --ui-accent-soft: var(--ui-accent-subtle);
172
185
  --ui-accent-contrast: var(--ui-on-accent);
173
186
  --ui-accent-strong-surface: var(--ui-accent);
@@ -210,7 +223,7 @@
210
223
  --ui-control-focus: var(--ui-focus-ring);
211
224
  /* Derived from the ring, not a near-white tint, so the halo shows on any surface. */
212
225
  --ui-control-focus-halo: color-mix(in srgb, var(--ui-focus-ring) 24%, transparent);
213
- --ui-control-focus-halo-shadow: 0 0 0 3px var(--ui-control-focus-halo);
226
+ --ui-control-focus-halo-shadow: 0 0 0 calc(var(--ui-focus-width) * 1.5) var(--ui-control-focus-halo);
214
227
  --ui-control-size-md: var(--ui-control-size);
215
228
  --ui-control-size-lg: calc(var(--ui-control-size) * 1.2);
216
229
 
@@ -292,15 +305,16 @@
292
305
  @layer components {
293
306
  [data-ui-choice-option] {
294
307
  padding: var(--ui-space-2) var(--ui-space-3);
295
- border-radius: var(--ui-radius-sm);
308
+ border-radius: var(--ui-selection-radius);
309
+ color: var(--ui-text-primary);
296
310
  cursor: pointer;
297
311
  overflow-wrap: anywhere;
298
312
  }
299
313
 
300
314
  [data-ui-choice-option]:is(:hover, .active) {
301
315
  background: var(--ui-surface-muted);
302
- outline: 1px solid var(--ui-focus-ring);
303
- outline-offset: -1px;
316
+ outline: var(--ui-border-width) solid var(--ui-focus-ring);
317
+ outline-offset: calc(-1 * var(--ui-border-width));
304
318
  }
305
319
 
306
320
  [data-ui-choice-option][aria-disabled="true"],
@@ -311,9 +325,9 @@
311
325
  cursor: not-allowed;
312
326
  }
313
327
 
314
- [data-ui-choice-option]:not([data-multiple])[aria-selected="true"] {
315
- background: color-mix(in srgb, var(--ui-accent-solid) 10%, var(--ui-control-surface));
316
- box-shadow: inset 2px 0 var(--ui-accent-solid);
328
+ [data-ui-choice-option][aria-selected="true"]:not([aria-disabled="true"]) {
329
+ background: var(--ui-selection-surface);
330
+ color: var(--ui-selection-text);
317
331
  }
318
332
 
319
333
  [data-ui-choice-option][data-multiple] {
@@ -327,7 +341,7 @@
327
341
  flex: none;
328
342
  inline-size: 1.125rem;
329
343
  block-size: 1.125rem;
330
- border: 1px solid var(--ui-control-border-hover, var(--ui-border-strong));
344
+ border: var(--ui-border-width) solid var(--ui-control-border-hover, var(--ui-border-strong));
331
345
  border-radius: var(--ui-radius-sm);
332
346
  background-color: var(--ui-control-surface);
333
347
  background-repeat: no-repeat;
@@ -347,6 +361,13 @@
347
361
  );
348
362
  }
349
363
 
364
+ @media (forced-colors: active) {
365
+ [data-ui-choice-option][aria-selected="true"]:not([aria-disabled="true"]):not(.active) {
366
+ outline: var(--ui-border-width) solid Highlight;
367
+ outline-offset: calc(-1 * var(--ui-border-width));
368
+ }
369
+ }
370
+
350
371
  [aria-disabled="true"] [data-ui-choice-option] {
351
372
  color: var(--ui-disabled-text);
352
373
  cursor: not-allowed;
@@ -10,6 +10,7 @@ export interface UiDisclosureElement extends HTMLDivElement {
10
10
  export interface UiDisclosureProps {
11
11
  density?: "comfortable" | "compact" | null;
12
12
  disabled?: boolean | null;
13
+ fill?: boolean | null;
13
14
  headingLevel?: number | null;
14
15
  name?: string | null;
15
16
  open?: boolean | null;
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
3
3
  import * as controller from "../components/ui-disclosure/ui-disclosure.js";
4
4
  import "../styles/ui-disclosure.css";
5
5
 
6
- const definition = {...{"contract":{"tag":"ui-disclosure","props":{"density":{"type":{"kind":"terminal","name":"keyword"},"values":["comfortable","compact"],"required":false,"target":{"attribute":"density"},"default":"comfortable"},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"headingLevel":{"type":{"kind":"terminal","name":"integer"},"required":false,"target":{"attribute":"headinglevel"},"default":0},"name":{"type":"string","required":false,"target":{"attribute":"name"},"default":""},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false},"summary":{"type":"string","required":false,"target":{"attribute":"summary"},"default":"Details"}}},"template":{"kind":"element","name":"div","attributes":[],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"heading"},{"kind":"attribute","name":"role","expression":"headingRole","expressionPlan":{"source":"headingRole","ast":{"kind":"id","name":"headingRole"},"dependencies":["headingRole"]}},{"kind":"attribute","name":"aria-level","expression":"headingAriaLevel","expressionPlan":{"source":"headingAriaLevel","ast":{"kind":"id","name":"headingAriaLevel"},"dependencies":["headingAriaLevel"]}}],"children":[{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"class","value":"trigger"},{"kind":"literal","name":"type","value":"button"},{"kind":"attribute","name":"aria-controls","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}},{"kind":"attribute","name":"aria-expanded","expression":"internalOpen","expressionPlan":{"source":"internalOpen","ast":{"kind":"id","name":"internalOpen"},"dependencies":["internalOpen"]}},{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"summary"}],"children":[{"kind":"slot","fallback":[{"kind":"element","name":"template","attributes":[{"kind":"directive","name":"value","expression":"summary","expressionPlan":{"source":"summary","ast":{"kind":"id","name":"summary"},"dependencies":["summary"]}}],"children":[]}],"name":"summary"}]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"chevron"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]}],"ref":"trigger"}]},{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel"},{"kind":"attribute","name":"id","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel-inner"}],"children":[{"kind":"slot"}]}],"ref":"panel"}]},"declarations":[{"kind":"state","name":"internalOpen","type":"boolean","value":"false","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"contentId","type":"string","value":"","expression":{"source":"\"\"","ast":{"kind":"literal","value":""},"dependencies":[]}},{"kind":"state","name":"headingRole","type":"keyword"},{"kind":"state","name":"headingAriaLevel","type":"integer"},{"kind":"event","name":"open","type":"object","shape":{"kind":"object","fields":[{"name":"open","type":{"kind":"terminal","name":"boolean"},"optional":false},{"name":"reason","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["action","programmatic","light-dismiss","escape"]},"optional":false},{"name":"trigger","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["keyboard","pointer","programmatic"]},"optional":false}],"open":false},"bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"close","type":"object","shape":{"kind":"object","fields":[{"name":"open","type":{"kind":"terminal","name":"boolean"},"optional":false},{"name":"reason","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["action","programmatic","light-dismiss","escape"]},"optional":false},{"name":"trigger","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["keyboard","pointer","programmatic"]},"optional":false}],"open":false},"bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
6
+ const definition = {...{"contract":{"tag":"ui-disclosure","props":{"density":{"type":{"kind":"terminal","name":"keyword"},"values":["comfortable","compact"],"required":false,"target":{"attribute":"density"},"default":"comfortable"},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"fill":{"type":"boolean","required":false,"target":{"attribute":"fill"},"default":false},"headingLevel":{"type":{"kind":"terminal","name":"integer"},"required":false,"target":{"attribute":"headinglevel"},"default":0},"name":{"type":"string","required":false,"target":{"attribute":"name"},"default":""},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false},"summary":{"type":"string","required":false,"target":{"attribute":"summary"},"default":"Details"}}},"template":{"kind":"element","name":"div","attributes":[],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"heading"},{"kind":"attribute","name":"role","expression":"headingRole","expressionPlan":{"source":"headingRole","ast":{"kind":"id","name":"headingRole"},"dependencies":["headingRole"]}},{"kind":"attribute","name":"aria-level","expression":"headingAriaLevel","expressionPlan":{"source":"headingAriaLevel","ast":{"kind":"id","name":"headingAriaLevel"},"dependencies":["headingAriaLevel"]}}],"children":[{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"class","value":"trigger"},{"kind":"literal","name":"type","value":"button"},{"kind":"attribute","name":"aria-controls","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}},{"kind":"attribute","name":"aria-expanded","expression":"internalOpen","expressionPlan":{"source":"internalOpen","ast":{"kind":"id","name":"internalOpen"},"dependencies":["internalOpen"]}},{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"summary"}],"children":[{"kind":"slot","fallback":[{"kind":"element","name":"template","attributes":[{"kind":"directive","name":"value","expression":"summary","expressionPlan":{"source":"summary","ast":{"kind":"id","name":"summary"},"dependencies":["summary"]}}],"children":[]}],"name":"summary"}]},{"kind":"slot","fallback":[{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"chevron"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]}],"name":"indicator"}],"ref":"trigger"}]},{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel"},{"kind":"attribute","name":"id","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel-inner"}],"children":[{"kind":"slot"}]}],"ref":"panel"}]},"declarations":[{"kind":"state","name":"internalOpen","type":"boolean","value":"false","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"contentId","type":"string","value":"","expression":{"source":"\"\"","ast":{"kind":"literal","value":""},"dependencies":[]}},{"kind":"state","name":"headingRole","type":"keyword"},{"kind":"state","name":"headingAriaLevel","type":"integer"},{"kind":"event","name":"open","type":"object","shape":{"kind":"object","fields":[{"name":"open","type":{"kind":"terminal","name":"boolean"},"optional":false},{"name":"reason","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["action","programmatic","light-dismiss","escape"]},"optional":false},{"name":"trigger","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["keyboard","pointer","programmatic"]},"optional":false}],"open":false},"bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"close","type":"object","shape":{"kind":"object","fields":[{"name":"open","type":{"kind":"terminal","name":"boolean"},"optional":false},{"name":"reason","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["action","programmatic","light-dismiss","escape"]},"optional":false},{"name":"trigger","type":{"kind":"constrained","base":{"kind":"terminal","name":"keyword"},"values":["keyboard","pointer","programmatic"]},"optional":false}],"open":false},"bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
7
7
 
8
8
  export function createUiDisclosure(options = {}) {
9
9
  const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
@@ -36,10 +36,19 @@ export function createUiDisclosure(options = {}) {
36
36
  element2.append(element3);
37
37
  }
38
38
  element1.append(element2);
39
+ if (slots["indicator"] ?? [].length > 0) {
40
+ for (const child of slots["indicator"] ?? []) {
41
+ const node = typeof child === "string" ? document.createTextNode(child) : child;
42
+ if (node.nodeType === 1) node.setAttribute("data-slotted", "");
43
+ projected.push([node, "indicator"]);
44
+ element1.append(node);
45
+ }
46
+ } else {
39
47
  const element4 = document.createElement("span");
40
48
  element4.setAttribute("class", "chevron");
41
49
  element4.setAttribute("aria-hidden", "true");
42
50
  element1.append(element4);
51
+ }
43
52
  element0.append(element1);
44
53
  element.append(element0);
45
54
  const element5 = document.createElement("div");