@threadlabs/looma 0.12.6 → 0.13.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 (199) hide show
  1. package/components/ui-action-bar/ui-action-bar.html +10 -1
  2. package/components/ui-avatar/ui-avatar.html +18 -0
  3. package/components/ui-avatar-group/ui-avatar-group.html +16 -2
  4. package/components/ui-badge/ui-badge.html +42 -0
  5. package/components/ui-button/ui-button.html +70 -0
  6. package/components/ui-callout/ui-callout.html +55 -4
  7. package/components/ui-checkbox/ui-checkbox.html +16 -3
  8. package/components/ui-cluster/ui-cluster.html +7 -1
  9. package/components/ui-combobox/ui-combobox.html +66 -12
  10. package/components/ui-container/ui-container.html +12 -1
  11. package/components/ui-context-menu/ui-context-menu.html +10 -1
  12. package/components/ui-dialog/ui-dialog.html +21 -4
  13. package/components/ui-disclosure/ui-disclosure.html +23 -4
  14. package/components/ui-editable/ui-editable.html +1 -1
  15. package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +2 -2
  16. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +2 -2
  17. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +8 -8
  18. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +3 -3
  19. package/components/ui-floating-action-button/ui-floating-action-button.html +14 -0
  20. package/components/ui-form-field/ui-form-field.html +10 -1
  21. package/components/ui-grid/ui-grid.html +11 -1
  22. package/components/ui-icon/ui-icon.html +17 -3
  23. package/components/ui-icon-button/ui-icon-button.html +81 -3
  24. package/components/ui-input/ui-input.html +68 -13
  25. package/components/ui-input-group/ui-input-group.html +14 -13
  26. package/components/ui-list/ui-list.html +10 -0
  27. package/components/ui-list-item/ui-list-item.html +22 -1
  28. package/components/ui-menu/ui-menu.html +17 -5
  29. package/components/ui-menu-item/ui-menu-item.html +30 -3
  30. package/components/ui-nav-item/ui-nav-item.html +14 -0
  31. package/components/ui-popover/ui-popover.html +6 -0
  32. package/components/ui-radio/ui-radio.html +16 -3
  33. package/components/ui-reel/ui-reel.html +15 -2
  34. package/components/ui-search-result-row/ui-search-result-row.html +34 -0
  35. package/components/ui-search-shell/ui-search-shell.html +65 -11
  36. package/components/ui-select/ui-select.html +15 -1
  37. package/components/ui-separator/ui-separator.html +9 -2
  38. package/components/ui-sidebar/ui-sidebar.html +22 -1
  39. package/components/ui-stack/ui-stack.html +7 -1
  40. package/components/ui-switch/ui-switch.html +21 -3
  41. package/components/ui-switcher/ui-switcher.html +18 -5
  42. package/components/ui-tabs/ui-tabs.html +21 -2
  43. package/components/ui-textarea/ui-textarea.html +15 -1
  44. package/components/ui-toast-region/ui-toast-region.html +16 -2
  45. package/components/ui-tooltip/ui-tooltip.html +62 -13
  46. package/components/ui-top-bar/ui-top-bar.html +34 -1
  47. package/components/ui-tree/ui-tree.html +27 -4
  48. package/components/ui-tree-item/ui-tree-item.html +39 -10
  49. package/components/ui-tree-item/ui-tree-item.js +1 -1
  50. package/dist/index.js +1 -1
  51. package/package.json +1 -1
  52. package/styles/ui-action-bar.css +14 -3
  53. package/styles/ui-avatar-group.css +20 -4
  54. package/styles/ui-avatar.css +22 -2
  55. package/styles/ui-badge.css +46 -2
  56. package/styles/ui-button.css +74 -2
  57. package/styles/ui-callout.css +59 -6
  58. package/styles/ui-checkbox.css +20 -5
  59. package/styles/ui-cluster.css +10 -2
  60. package/styles/ui-combobox.css +69 -14
  61. package/styles/ui-container.css +14 -2
  62. package/styles/ui-context-menu.css +14 -3
  63. package/styles/ui-dialog.css +25 -6
  64. package/styles/ui-disclosure.css +27 -6
  65. package/styles/ui-editable.css +1 -1
  66. package/styles/ui-editor-slash-menu.css +2 -2
  67. package/styles/ui-editor-table-context-menu.css +2 -2
  68. package/styles/ui-editor-table-overlay.css +8 -8
  69. package/styles/ui-editor-table-toolbar.css +3 -3
  70. package/styles/ui-floating-action-button.css +18 -2
  71. package/styles/ui-form-field.css +14 -3
  72. package/styles/ui-grid.css +14 -2
  73. package/styles/ui-icon-button.css +85 -5
  74. package/styles/ui-icon.css +21 -5
  75. package/styles/ui-input-group.css +14 -13
  76. package/styles/ui-input.css +73 -15
  77. package/styles/ui-list-item.css +26 -3
  78. package/styles/ui-list.css +14 -2
  79. package/styles/ui-menu-item.css +34 -5
  80. package/styles/ui-menu.css +21 -6
  81. package/styles/ui-nav-item.css +18 -2
  82. package/styles/ui-popover.css +10 -2
  83. package/styles/ui-radio.css +20 -5
  84. package/styles/ui-reel.css +18 -3
  85. package/styles/ui-search-result-row.css +38 -2
  86. package/styles/ui-search-shell.css +69 -13
  87. package/styles/ui-select.css +19 -3
  88. package/styles/ui-separator.css +14 -2
  89. package/styles/ui-sidebar.css +26 -3
  90. package/styles/ui-stack.css +10 -2
  91. package/styles/ui-switch.css +25 -5
  92. package/styles/ui-switcher.css +21 -6
  93. package/styles/ui-tabs.css +25 -4
  94. package/styles/ui-textarea.css +19 -3
  95. package/styles/ui-toast-region.css +20 -4
  96. package/styles/ui-tooltip.css +66 -15
  97. package/styles/ui-top-bar.css +38 -3
  98. package/styles/ui-tree-item.css +43 -12
  99. package/styles/ui-tree.css +33 -6
  100. package/theme-dark.css +1 -1
  101. package/theme-light.css +1 -1
  102. package/tokens.css +8 -6
  103. package/vue/UiActionBar.vue +12 -3
  104. package/vue/UiAvatar.vue +18 -0
  105. package/vue/UiAvatarGroup.vue +16 -2
  106. package/vue/UiBadge.vue +42 -0
  107. package/vue/UiButton.vue +70 -0
  108. package/vue/UiCallout.vue +55 -4
  109. package/vue/UiCheckbox.vue +16 -3
  110. package/vue/UiCluster.vue +6 -0
  111. package/vue/UiCombobox.vue +66 -12
  112. package/vue/UiContainer.vue +10 -0
  113. package/vue/UiContextMenu.vue +10 -1
  114. package/vue/UiDialog.vue +21 -4
  115. package/vue/UiDisclosure.vue +23 -4
  116. package/vue/UiEditable.vue +1 -1
  117. package/vue/UiEditorSlashMenu.vue +2 -2
  118. package/vue/UiEditorTableContextMenu.vue +2 -2
  119. package/vue/UiEditorTableOverlay.vue +8 -8
  120. package/vue/UiEditorTableToolbar.vue +3 -3
  121. package/vue/UiFloatingActionButton.vue +14 -0
  122. package/vue/UiFormField.vue +10 -1
  123. package/vue/UiGrid.vue +10 -0
  124. package/vue/UiIcon.vue +17 -3
  125. package/vue/UiIconButton.vue +81 -3
  126. package/vue/UiInput.vue +90 -15
  127. package/vue/UiInputGroup.vue +14 -13
  128. package/vue/UiList.vue +12 -2
  129. package/vue/UiListItem.vue +30 -9
  130. package/vue/UiMenu.vue +17 -5
  131. package/vue/UiMenuItem.vue +42 -4
  132. package/vue/UiNavItem.vue +17 -3
  133. package/vue/UiPopover.vue +6 -0
  134. package/vue/UiRadio.vue +16 -3
  135. package/vue/UiReel.vue +14 -1
  136. package/vue/UiSearchResultRow.vue +34 -0
  137. package/vue/UiSearchShell.vue +66 -12
  138. package/vue/UiSelect.vue +15 -1
  139. package/vue/UiSeparator.vue +9 -2
  140. package/vue/UiSidebar.vue +22 -1
  141. package/vue/UiStack.vue +6 -0
  142. package/vue/UiSwitch.vue +21 -3
  143. package/vue/UiSwitcher.vue +17 -4
  144. package/vue/UiTabs.vue +22 -3
  145. package/vue/UiTextarea.vue +15 -1
  146. package/vue/UiToastRegion.vue +16 -2
  147. package/vue/UiTooltip.vue +62 -13
  148. package/vue/UiTopBar.vue +34 -1
  149. package/vue/UiTree.vue +28 -5
  150. package/vue/UiTreeItem.vue +46 -11
  151. package/vue/chunks/UiActionBar.js +1 -1
  152. package/vue/chunks/UiAvatar.js +1 -1
  153. package/vue/chunks/UiAvatarGroup.js +1 -1
  154. package/vue/chunks/UiBadge.js +1 -1
  155. package/vue/chunks/UiButton.js +1 -1
  156. package/vue/chunks/UiCallout.js +1 -1
  157. package/vue/chunks/UiCheckbox.js +1 -1
  158. package/vue/chunks/UiCluster.js +1 -1
  159. package/vue/chunks/UiCombobox.js +1 -1
  160. package/vue/chunks/UiContainer.js +1 -1
  161. package/vue/chunks/UiContextMenu.js +1 -1
  162. package/vue/chunks/UiDialog.js +1 -1
  163. package/vue/chunks/UiDisclosure.js +1 -1
  164. package/vue/chunks/UiEditable.js +1 -1
  165. package/vue/chunks/UiEditorSlashMenu.js +1 -1
  166. package/vue/chunks/UiEditorTableContextMenu.js +1 -1
  167. package/vue/chunks/UiEditorTableOverlay.js +1 -1
  168. package/vue/chunks/UiEditorTableToolbar.js +1 -1
  169. package/vue/chunks/UiFloatingActionButton.js +1 -1
  170. package/vue/chunks/UiFormField.js +1 -1
  171. package/vue/chunks/UiGrid.js +1 -1
  172. package/vue/chunks/UiIcon.js +1 -1
  173. package/vue/chunks/UiIconButton.js +1 -1
  174. package/vue/chunks/UiInput.js +1 -1
  175. package/vue/chunks/UiInputGroup.js +1 -1
  176. package/vue/chunks/UiList.js +1 -1
  177. package/vue/chunks/UiListItem.js +1 -1
  178. package/vue/chunks/UiMenu.js +1 -1
  179. package/vue/chunks/UiMenuItem.js +1 -1
  180. package/vue/chunks/UiNavItem.js +1 -1
  181. package/vue/chunks/UiPopover.js +1 -1
  182. package/vue/chunks/UiRadio.js +1 -1
  183. package/vue/chunks/UiReel.js +1 -1
  184. package/vue/chunks/UiSearchResultRow.js +1 -1
  185. package/vue/chunks/UiSearchShell.js +1 -1
  186. package/vue/chunks/UiSelect.js +1 -1
  187. package/vue/chunks/UiSeparator.js +1 -1
  188. package/vue/chunks/UiSidebar.js +1 -1
  189. package/vue/chunks/UiStack.js +1 -1
  190. package/vue/chunks/UiSwitch.js +1 -1
  191. package/vue/chunks/UiSwitcher.js +1 -1
  192. package/vue/chunks/UiTabs.js +1 -1
  193. package/vue/chunks/UiTextarea.js +1 -1
  194. package/vue/chunks/UiToastRegion.js +1 -1
  195. package/vue/chunks/UiTooltip.js +1 -1
  196. package/vue/chunks/UiTopBar.js +1 -1
  197. package/vue/chunks/UiTree.js +1 -1
  198. package/vue/chunks/UiTreeItem.js +1 -1
  199. package/vue/components.css +1959 -927
package/tokens.css CHANGED
@@ -122,10 +122,11 @@
122
122
  --ui-motion-ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
123
123
 
124
124
  /* Neutrals: the ink mixed into the page. One ramp, so a theme that changes either end moves
125
- every step with it. */
125
+ every step with it. Muted is the lightest text that still reads at 4.5:1 (WCAG AA) on the
126
+ sunken surface as well as the page, and secondary sits halfway between it and the ink. */
126
127
  --ui-surface-muted: color-mix(in oklab, var(--ui-surface-sunken) 50%, var(--ui-surface));
127
- --ui-text-secondary: color-mix(in oklab, var(--ui-text) 72%, var(--ui-surface));
128
- --ui-text-muted: color-mix(in oklab, var(--ui-text) 45%, var(--ui-surface));
128
+ --ui-text-secondary: color-mix(in oklab, var(--ui-text) 80%, var(--ui-surface));
129
+ --ui-text-muted: color-mix(in oklab, var(--ui-text) 62%, var(--ui-surface));
129
130
  --ui-border: color-mix(in oklab, var(--ui-text) 12%, var(--ui-surface));
130
131
  --ui-border-strong: color-mix(in oklab, var(--ui-text) 25%, var(--ui-surface));
131
132
  --ui-control-border: color-mix(in oklab, var(--ui-text) 48%, var(--ui-surface));
@@ -137,10 +138,11 @@
137
138
  --ui-accent-subtle: color-mix(in oklab, var(--ui-accent) 12%, var(--ui-surface));
138
139
  --ui-danger-hover: color-mix(in oklab, var(--ui-danger) 86%, var(--ui-text));
139
140
 
140
- /* Disabled is one decision, not a per-component one: the sunken surface and the muted ink, at
141
- full opacity, so a disabled control reads as unavailable rather than as a faded variant. */
141
+ /* Disabled is one decision, not a per-component one: the sunken surface and a pale ink, at
142
+ full opacity, so a disabled control reads as unavailable rather than as a faded variant.
143
+ Lighter than muted text, which must stay readable; disabled text is exempt from contrast. */
142
144
  --ui-disabled-surface: var(--ui-surface-sunken);
143
- --ui-disabled-text: var(--ui-text-muted);
145
+ --ui-disabled-text: color-mix(in oklab, var(--ui-text) 45%, var(--ui-surface));
144
146
  /* A disabled button keeps its own look, washed out: less colour, less contrast, toward the page.
145
147
  A filter rather than a second palette, so every variant and tone fades the same way. */
146
148
  --ui-disabled-filter: saturate(0.2) contrast(0.75) brightness(1.25);
@@ -15,10 +15,19 @@ defineOptions({ inheritAttrs: false })
15
15
  </template>
16
16
 
17
17
  <style scoped>
18
+ /* This component's hooks style the element they are set on, and never a nested one. */
19
+ @property --ui-action-bar-gap {
20
+ syntax: "*";
21
+ inherits: false;
22
+ }
23
+
18
24
  /* The action row of a form or dialog. Tertiary actions (Back, Cancel, Discard) sit at the start
19
- edge; secondary actions (Save as draft, Preview) sit just before the primary one, which ends the
20
- row. The bar arranges its actions and leaves their look to them. */
25
+ edge; secondary actions (Save as draft, Preview) sit just before the primary one, which ends the
26
+ row. The bar arranges its actions and leaves their look to them. */
21
27
  [data-component~="ui-action-bar"] {
28
+ /* Hooks do not inherit, so the parts below read them from the root. */
29
+ --_ui-action-bar-gap: var(--ui-action-bar-gap);
30
+
22
31
  --_gap: var(--ui-space-2);
23
32
  display: block;
24
33
  /* A size container sizes itself from its container, never its content. */
@@ -34,7 +43,7 @@ defineOptions({ inheritAttrs: false })
34
43
  display: flex;
35
44
  flex-wrap: wrap;
36
45
  align-items: center;
37
- gap: var(--ui-action-bar-gap, var(--_gap));
46
+ gap: var(--_ui-action-bar-gap, var(--_gap));
38
47
  }
39
48
 
40
49
  /* The tertiary group takes the spare space, pushing the rest to the end edge; without it, the
package/vue/UiAvatar.vue CHANGED
@@ -68,6 +68,24 @@ useComponentHost(controllerModule.default, {
68
68
  </template>
69
69
 
70
70
  <style scoped>
71
+ /* This component's hooks style the element they are set on, and never a nested one. */
72
+ @property --ui-avatar-border {
73
+ syntax: "*";
74
+ inherits: false;
75
+ }
76
+ @property --ui-avatar-surface {
77
+ syntax: "*";
78
+ inherits: false;
79
+ }
80
+ @property --ui-avatar-text {
81
+ syntax: "*";
82
+ inherits: false;
83
+ }
84
+ @property --ui-avatar-active-ring {
85
+ syntax: "*";
86
+ inherits: false;
87
+ }
88
+
71
89
  [data-component~="ui-avatar"] {
72
90
  display: inline-grid;
73
91
  place-items: center;
@@ -46,7 +46,21 @@ useComponentHost(controllerModule.default, {
46
46
  </template>
47
47
 
48
48
  <style scoped>
49
+ /* This component's hooks style the element they are set on, and never a nested one. */
50
+ @property --ui-avatar-group-edge-ring {
51
+ syntax: "*";
52
+ inherits: false;
53
+ }
54
+ @property --ui-avatar-group-overlap-shadow {
55
+ syntax: "*";
56
+ inherits: false;
57
+ }
58
+
49
59
  [data-component~="ui-avatar-group"] {
60
+ /* Hooks do not inherit, so the parts below read them from the root. */
61
+ --_ui-avatar-group-overlap-shadow: var(--ui-avatar-group-overlap-shadow);
62
+ --_ui-avatar-group-edge-ring: var(--ui-avatar-group-edge-ring);
63
+
50
64
  /* Each avatar is ringed in the surface colour, so where one overlaps the next it reads as a
51
65
  * whole circle set on top, not a shape cut into the one beneath. */
52
66
  --_overlap-shadow: 0 0 0 0 transparent;
@@ -82,8 +96,8 @@ useComponentHost(controllerModule.default, {
82
96
  background: var(--ui-surface-elevated);
83
97
  color: var(--ui-text-primary);
84
98
  box-shadow:
85
- var(--ui-avatar-group-overlap-shadow, var(--_overlap-shadow)),
86
- var(--ui-avatar-group-edge-ring, var(--_edge-ring));
99
+ var(--_ui-avatar-group-overlap-shadow, var(--_overlap-shadow)),
100
+ var(--_ui-avatar-group-edge-ring, var(--_edge-ring));
87
101
  font: inherit;
88
102
  font-size: var(--ui-font-size-xs);
89
103
  font-weight: 600;
package/vue/UiBadge.vue CHANGED
@@ -36,6 +36,48 @@ const hostState = computed(() =>
36
36
  </template>
37
37
 
38
38
  <style scoped>
39
+ /* This component's hooks style the element they are set on, and never a nested one. */
40
+ @property --ui-badge-border {
41
+ syntax: "*";
42
+ inherits: false;
43
+ }
44
+ @property --ui-badge-font-size {
45
+ syntax: "*";
46
+ inherits: false;
47
+ }
48
+ @property --ui-badge-font-weight {
49
+ syntax: "*";
50
+ inherits: false;
51
+ }
52
+ @property --ui-badge-line-height {
53
+ syntax: "*";
54
+ inherits: false;
55
+ }
56
+ @property --ui-badge-min-block-size {
57
+ syntax: "*";
58
+ inherits: false;
59
+ }
60
+ @property --ui-badge-padding-block {
61
+ syntax: "*";
62
+ inherits: false;
63
+ }
64
+ @property --ui-badge-padding-inline {
65
+ syntax: "*";
66
+ inherits: false;
67
+ }
68
+ @property --ui-badge-point {
69
+ syntax: "*";
70
+ inherits: false;
71
+ }
72
+ @property --ui-badge-surface {
73
+ syntax: "*";
74
+ inherits: false;
75
+ }
76
+ @property --ui-badge-text {
77
+ syntax: "*";
78
+ inherits: false;
79
+ }
80
+
39
81
  [data-component~="ui-badge"] {
40
82
  --_badge-surface: var(--ui-surface-subtle);
41
83
  --_badge-text: var(--ui-text-secondary);
package/vue/UiButton.vue CHANGED
@@ -75,6 +75,76 @@ function attribute(value: unknown): any {
75
75
  </template>
76
76
 
77
77
  <style scoped>
78
+ /* This component's hooks style the element they are set on, and never a nested one. */
79
+ @property --ui-button-active-surface {
80
+ syntax: "*";
81
+ inherits: false;
82
+ }
83
+ @property --ui-button-border {
84
+ syntax: "*";
85
+ inherits: false;
86
+ }
87
+ @property --ui-button-disabled-filter {
88
+ syntax: "*";
89
+ inherits: false;
90
+ }
91
+ @property --ui-button-disabled-opacity {
92
+ syntax: "*";
93
+ inherits: false;
94
+ }
95
+ @property --ui-button-ghost-active-surface {
96
+ syntax: "*";
97
+ inherits: false;
98
+ }
99
+ @property --ui-button-ghost-hover-surface {
100
+ syntax: "*";
101
+ inherits: false;
102
+ }
103
+ @property --ui-button-ghost-text {
104
+ syntax: "*";
105
+ inherits: false;
106
+ }
107
+ @property --ui-button-hover-border {
108
+ syntax: "*";
109
+ inherits: false;
110
+ }
111
+ @property --ui-button-hover-surface {
112
+ syntax: "*";
113
+ inherits: false;
114
+ }
115
+ @property --ui-button-link-hover-text {
116
+ syntax: "*";
117
+ inherits: false;
118
+ }
119
+ @property --ui-button-link-text {
120
+ syntax: "*";
121
+ inherits: false;
122
+ }
123
+ @property --ui-button-min-block-size {
124
+ syntax: "*";
125
+ inherits: false;
126
+ }
127
+ @property --ui-button-radius {
128
+ syntax: "*";
129
+ inherits: false;
130
+ }
131
+ @property --ui-button-shadow {
132
+ syntax: "*";
133
+ inherits: false;
134
+ }
135
+ @property --ui-button-solid-shadow {
136
+ syntax: "*";
137
+ inherits: false;
138
+ }
139
+ @property --ui-button-surface {
140
+ syntax: "*";
141
+ inherits: false;
142
+ }
143
+ @property --ui-button-text {
144
+ syntax: "*";
145
+ inherits: false;
146
+ }
147
+
78
148
  [data-component~="ui-button"] {
79
149
  --_hue: var(--ui-accent);
80
150
  --_hue-hover: var(--ui-accent-hover);
package/vue/UiCallout.vue CHANGED
@@ -97,7 +97,58 @@ const hostState = computed(() =>
97
97
  </template>
98
98
 
99
99
  <style scoped>
100
+ /* This component's hooks style the element they are set on, and never a nested one. */
101
+ @property --ui-callout-border {
102
+ syntax: "*";
103
+ inherits: false;
104
+ }
105
+ @property --ui-callout-border-width {
106
+ syntax: "*";
107
+ inherits: false;
108
+ }
109
+ @property --ui-callout-gap {
110
+ syntax: "*";
111
+ inherits: false;
112
+ }
113
+ @property --ui-callout-icon {
114
+ syntax: "*";
115
+ inherits: false;
116
+ }
117
+ @property --ui-callout-icon-column {
118
+ syntax: "*";
119
+ inherits: false;
120
+ }
121
+ @property --ui-callout-icon-size {
122
+ syntax: "*";
123
+ inherits: false;
124
+ }
125
+ @property --ui-callout-leading-border-width {
126
+ syntax: "*";
127
+ inherits: false;
128
+ }
129
+ @property --ui-callout-padding-block {
130
+ syntax: "*";
131
+ inherits: false;
132
+ }
133
+ @property --ui-callout-padding-inline {
134
+ syntax: "*";
135
+ inherits: false;
136
+ }
137
+ @property --ui-callout-surface {
138
+ syntax: "*";
139
+ inherits: false;
140
+ }
141
+ @property --ui-callout-text {
142
+ syntax: "*";
143
+ inherits: false;
144
+ }
145
+
100
146
  [data-component~="ui-callout"] {
147
+ /* Hooks do not inherit, so the parts below read them from the root. */
148
+ --_ui-callout-icon-column: var(--ui-callout-icon-column);
149
+ --_ui-callout-icon: var(--ui-callout-icon);
150
+ --_ui-callout-icon-size: var(--ui-callout-icon-size);
151
+
101
152
  --_callout-surface: var(--ui-info-soft);
102
153
  --_callout-border: var(--ui-info-solid);
103
154
  --_callout-icon: var(--ui-info-solid);
@@ -126,14 +177,14 @@ const hostState = computed(() =>
126
177
  .icon {
127
178
  display: grid;
128
179
  place-items: center;
129
- inline-size: var(--ui-callout-icon-column, 1.125rem);
180
+ inline-size: var(--_ui-callout-icon-column, 1.125rem);
130
181
  block-size: 1lh;
131
- color: var(--ui-callout-icon, var(--_callout-icon));
182
+ color: var(--_ui-callout-icon, var(--_callout-icon));
132
183
  }
133
184
 
134
185
  .icon svg {
135
- inline-size: var(--ui-callout-icon-size, 1.125rem);
136
- block-size: var(--ui-callout-icon-size, 1.125rem);
186
+ inline-size: var(--_ui-callout-icon-size, 1.125rem);
187
+ block-size: var(--_ui-callout-icon-size, 1.125rem);
137
188
  }
138
189
 
139
190
  .content {
@@ -95,7 +95,20 @@ useComponentHost(controllerModule.default, {
95
95
  </template>
96
96
 
97
97
  <style scoped>
98
+ /* This component's hooks style the element they are set on, and never a nested one. */
99
+ @property --ui-checkbox-gap {
100
+ syntax: "*";
101
+ inherits: false;
102
+ }
103
+ @property --ui-checkbox-size {
104
+ syntax: "*";
105
+ inherits: false;
106
+ }
107
+
98
108
  [data-component~="ui-checkbox"] {
109
+ /* Hooks do not inherit, so the parts below read them from the root. */
110
+ --_ui-checkbox-size: var(--ui-checkbox-size);
111
+
99
112
  display: inline-flex;
100
113
  align-items: flex-start;
101
114
  gap: var(--ui-checkbox-gap, var(--ui-space-2));
@@ -132,8 +145,8 @@ input {
132
145
  -webkit-appearance: none;
133
146
  position: relative;
134
147
  flex: 0 0 auto;
135
- inline-size: var(--ui-checkbox-size, 1.125rem);
136
- block-size: var(--ui-checkbox-size, 1.125rem);
148
+ inline-size: var(--_ui-checkbox-size, 1.125rem);
149
+ block-size: var(--_ui-checkbox-size, 1.125rem);
137
150
  margin: 0.125em 0 0;
138
151
  border: 1px solid var(--ui-control-border-hover, var(--ui-border-strong));
139
152
  border-radius: var(--ui-radius-sm);
@@ -193,7 +206,7 @@ input:focus-visible {
193
206
  }
194
207
 
195
208
  [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"] {
196
- color: var(--ui-text-muted);
209
+ color: var(--ui-disabled-text);
197
210
  cursor: not-allowed;
198
211
  }
199
212
  [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"] input {
package/vue/UiCluster.vue CHANGED
@@ -25,6 +25,12 @@ const hostState = computed(() =>
25
25
  </template>
26
26
 
27
27
  <style scoped>
28
+ /* This component's hooks style the element they are set on, and never a nested one. */
29
+ @property --ui-cluster-gap {
30
+ syntax: "*";
31
+ inherits: false;
32
+ }
33
+
28
34
  [data-component~="ui-cluster"] {
29
35
  --_layout-gap: var(--ui-space-3);
30
36
  display: flex;
@@ -662,7 +662,61 @@ defineExpose({
662
662
  </template>
663
663
 
664
664
  <style scoped>
665
+ /* This component's hooks style the element they are set on, and never a nested one. */
666
+ @property --ui-combobox-affordance-text {
667
+ syntax: "*";
668
+ inherits: false;
669
+ }
670
+ @property --ui-combobox-item-input-min-inline-size {
671
+ syntax: "*";
672
+ inherits: false;
673
+ }
674
+ @property --ui-combobox-item-item-max-inline-size {
675
+ syntax: "*";
676
+ inherits: false;
677
+ }
678
+ @property --ui-combobox-item-min-block-size {
679
+ syntax: "*";
680
+ inherits: false;
681
+ }
682
+ @property --ui-combobox-label-font-size {
683
+ syntax: "*";
684
+ inherits: false;
685
+ }
686
+ @property --ui-combobox-label-text {
687
+ syntax: "*";
688
+ inherits: false;
689
+ }
690
+ @property --ui-combobox-max-block-size {
691
+ syntax: "*";
692
+ inherits: false;
693
+ }
694
+ @property --ui-combobox-message-text {
695
+ syntax: "*";
696
+ inherits: false;
697
+ }
698
+ @property --ui-combobox-option-check {
699
+ syntax: "*";
700
+ inherits: false;
701
+ }
702
+ @property --ui-combobox-option-text {
703
+ syntax: "*";
704
+ inherits: false;
705
+ }
706
+
665
707
  [data-component~="ui-combobox"] {
708
+ /* Hooks do not inherit, so the parts below read them from the root. */
709
+ --_ui-combobox-label-text: var(--ui-combobox-label-text);
710
+ --_ui-combobox-label-font-size: var(--ui-combobox-label-font-size);
711
+ --_ui-combobox-affordance-text: var(--ui-combobox-affordance-text);
712
+ --_ui-combobox-max-block-size: var(--ui-combobox-max-block-size);
713
+ --_ui-combobox-option-text: var(--ui-combobox-option-text);
714
+ --_ui-combobox-message-text: var(--ui-combobox-message-text);
715
+ --_ui-combobox-option-check: var(--ui-combobox-option-check);
716
+ --_ui-combobox-item-min-block-size: var(--ui-combobox-item-min-block-size);
717
+ --_ui-combobox-item-input-min-inline-size: var(--ui-combobox-item-input-min-inline-size);
718
+ --_ui-combobox-item-item-max-inline-size: var(--ui-combobox-item-item-max-inline-size);
719
+
666
720
  display: grid;
667
721
  gap: var(--ui-space-1);
668
722
  min-inline-size: 0;
@@ -670,8 +724,8 @@ defineExpose({
670
724
  font: inherit;
671
725
  }
672
726
  label {
673
- color: var(--ui-combobox-label-text, var(--ui-text-primary));
674
- font-size: var(--ui-combobox-label-font-size, var(--ui-font-size-sm));
727
+ color: var(--_ui-combobox-label-text, var(--ui-text-primary));
728
+ font-size: var(--_ui-combobox-label-font-size, var(--ui-font-size-sm));
675
729
  font-weight: 500;
676
730
  }
677
731
  /* The field and anything that annotates it sit on one row; the help button is beside the box,
@@ -773,7 +827,7 @@ button {
773
827
  border: 0;
774
828
  border-radius: var(--ui-radius-md);
775
829
  background: transparent;
776
- color: var(--ui-combobox-affordance-text, var(--ui-text-secondary));
830
+ color: var(--_ui-combobox-affordance-text, var(--ui-text-secondary));
777
831
  font: inherit;
778
832
  font-weight: 400;
779
833
  min-inline-size: 2rem;
@@ -795,7 +849,7 @@ button:focus-visible {
795
849
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
796
850
  }
797
851
  input:disabled, button:disabled {
798
- color: var(--ui-text-muted);
852
+ color: var(--ui-disabled-text);
799
853
  cursor: not-allowed;
800
854
  }
801
855
  .field:has(input:disabled) {
@@ -808,7 +862,7 @@ input:disabled, button:disabled {
808
862
  box-sizing: border-box;
809
863
  min-inline-size: 12rem;
810
864
  max-inline-size: calc(100vw - 1rem);
811
- max-block-size: var(--ui-combobox-max-block-size, 18rem);
865
+ max-block-size: var(--_ui-combobox-max-block-size, 18rem);
812
866
  overflow: auto;
813
867
  margin: 0;
814
868
  padding: var(--ui-space-1);
@@ -833,16 +887,16 @@ input:disabled, button:disabled {
833
887
  outline-offset: -1px;
834
888
  }
835
889
  .option[aria-disabled="true"] {
836
- color: var(--ui-text-muted);
890
+ color: var(--ui-disabled-text);
837
891
  cursor: not-allowed;
838
892
  }
839
893
  .primary {
840
894
  display: block;
841
- color: var(--ui-combobox-option-text, var(--ui-text-primary));
895
+ color: var(--_ui-combobox-option-text, var(--ui-text-primary));
842
896
  font-weight: 500;
843
897
  }
844
898
  .message, .group {
845
- color: var(--ui-combobox-message-text, var(--ui-text-secondary));
899
+ color: var(--_ui-combobox-message-text, var(--ui-text-secondary));
846
900
  font-weight: 400;
847
901
  font-size: var(--ui-font-size-sm);
848
902
  line-height: var(--ui-line-height-md);
@@ -903,7 +957,7 @@ input:disabled, button:disabled {
903
957
  border-color: var(--ui-accent-solid);
904
958
  background-color: var(--ui-accent-solid);
905
959
  background-image: var(
906
- --ui-combobox-option-check,
960
+ --_ui-combobox-option-check,
907
961
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-9'/%3E%3C/svg%3E")
908
962
  );
909
963
  }
@@ -913,11 +967,11 @@ input:disabled, button:disabled {
913
967
  flex-wrap: wrap;
914
968
  align-items: center;
915
969
  gap: var(--ui-space-1);
916
- min-block-size: var(--ui-combobox-item-min-block-size, 2.5rem);
970
+ min-block-size: var(--_ui-combobox-item-min-block-size, 2.5rem);
917
971
  padding: var(--ui-space-1);
918
972
  }
919
973
  [data-component~="ui-combobox"][data-ui-combobox-state~="multiple"] input {
920
- flex: 1 0 var(--ui-combobox-item-input-min-inline-size, 5rem);
974
+ flex: 1 0 var(--_ui-combobox-item-input-min-inline-size, 5rem);
921
975
  width: auto;
922
976
  min-block-size: 1.75rem;
923
977
  padding: var(--ui-space-0-5) var(--ui-space-1);
@@ -926,7 +980,7 @@ input:disabled, button:disabled {
926
980
  appearance: none;
927
981
  display: inline-flex;
928
982
  min-inline-size: 0;
929
- max-inline-size: min(100%, var(--ui-combobox-item-item-max-inline-size, 12rem));
983
+ max-inline-size: min(100%, var(--_ui-combobox-item-item-max-inline-size, 12rem));
930
984
  overflow: hidden;
931
985
  padding: 0;
932
986
  border: 0;
@@ -29,6 +29,16 @@ const hostState = computed(() =>
29
29
  </template>
30
30
 
31
31
  <style scoped>
32
+ /* This component's hooks style the element they are set on, and never a nested one. */
33
+ @property --ui-container-gutters {
34
+ syntax: "*";
35
+ inherits: false;
36
+ }
37
+ @property --ui-container-measure {
38
+ syntax: "*";
39
+ inherits: false;
40
+ }
41
+
32
42
  [data-component~="ui-container"] {
33
43
  --_container-measure: 65ch;
34
44
  --_container-gutters: var(--ui-space-4);
@@ -89,7 +89,16 @@ useComponentHost(controllerModule.default, {
89
89
  </template>
90
90
 
91
91
  <style scoped>
92
+ /* This component's hooks style the element they are set on, and never a nested one. */
93
+ @property --ui-context-menu-z-index {
94
+ syntax: "*";
95
+ inherits: false;
96
+ }
97
+
92
98
  [data-component~="ui-context-menu"] {
99
+ /* Hooks do not inherit, so the parts below read them from the root. */
100
+ --_ui-context-menu-z-index: var(--ui-context-menu-z-index);
101
+
93
102
  display: contents;
94
103
  }
95
104
 
@@ -107,7 +116,7 @@ useComponentHost(controllerModule.default, {
107
116
  box-shadow: var(--ui-elevation-overlay, var(--ui-shadow-lg));
108
117
  outline: 0;
109
118
  overflow: auto;
110
- z-index: var(--ui-context-menu-z-index, 1000);
119
+ z-index: var(--_ui-context-menu-z-index, 1000);
111
120
  min-width: 12rem;
112
121
  opacity: 0;
113
122
  transform: translateY(-4px) scale(0.99);
package/vue/UiDialog.vue CHANGED
@@ -76,7 +76,24 @@ useComponentHost(controllerModule.default, {
76
76
  </template>
77
77
 
78
78
  <style scoped>
79
+ /* This component's hooks style the element they are set on, and never a nested one. */
80
+ @property --ui-dialog-duration {
81
+ syntax: "*";
82
+ inherits: false;
83
+ }
84
+ @property --ui-dialog-max-width {
85
+ syntax: "*";
86
+ inherits: false;
87
+ }
88
+ @property --ui-dialog-viewport-gap {
89
+ syntax: "*";
90
+ inherits: false;
91
+ }
92
+
79
93
  [data-component~="ui-dialog"] {
94
+ /* Hooks do not inherit, so the parts below read them from the root. */
95
+ --_ui-dialog-duration: var(--ui-dialog-duration);
96
+
80
97
  position: fixed;
81
98
  inset: 0;
82
99
  box-sizing: border-box;
@@ -249,14 +266,14 @@ footer:empty {
249
266
  [data-component~="ui-dialog"]::backdrop {
250
267
  background-color: transparent;
251
268
  transition:
252
- background-color var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease),
253
- display var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete,
254
- overlay var(--ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
269
+ background-color var(--_ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease),
270
+ display var(--_ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete,
271
+ overlay var(--_ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
255
272
  }
256
273
 
257
274
  [data-component~="ui-dialog"][open]::backdrop {
258
275
  background-color: var(--ui-overlay-backdrop);
259
- animation: ui-dialog-backdrop-enter var(--ui-dialog-duration, var(--ui-motion-base))
276
+ animation: ui-dialog-backdrop-enter var(--_ui-dialog-duration, var(--ui-motion-base))
260
277
  var(--ui-motion-ease);
261
278
  }
262
279
 
@@ -104,8 +104,27 @@ useComponentHost(controllerModule.default, {
104
104
  </template>
105
105
 
106
106
  <style scoped>
107
+ /* This component's hooks style the element they are set on, and never a nested one. */
108
+ @property --ui-disclosure-trigger-min-block-size {
109
+ syntax: "*";
110
+ inherits: false;
111
+ }
112
+ @property --ui-disclosure-trigger-padding-block {
113
+ syntax: "*";
114
+ inherits: false;
115
+ }
116
+ @property --ui-disclosure-trigger-padding-inline {
117
+ syntax: "*";
118
+ inherits: false;
119
+ }
120
+
107
121
  /* Density resolves into the summary row's own values; the public tokens still override them. */
108
122
  [data-component~="ui-disclosure"] {
123
+ /* Hooks do not inherit, so the parts below read them from the root. */
124
+ --_ui-disclosure-trigger-min-block-size: var(--ui-disclosure-trigger-min-block-size);
125
+ --_ui-disclosure-trigger-padding-block: var(--ui-disclosure-trigger-padding-block);
126
+ --_ui-disclosure-trigger-padding-inline: var(--ui-disclosure-trigger-padding-inline);
127
+
109
128
  --_trigger-min-block-size: var(--ui-control-size);
110
129
  --_trigger-padding-block: var(--ui-space-2);
111
130
  --_trigger-padding-inline: var(--ui-space-3);
@@ -133,9 +152,9 @@ useComponentHost(controllerModule.default, {
133
152
  gap: var(--ui-space-3);
134
153
  align-items: center;
135
154
  inline-size: 100%;
136
- min-block-size: var(--ui-disclosure-trigger-min-block-size, var(--_trigger-min-block-size));
137
- padding: var(--ui-disclosure-trigger-padding-block, var(--_trigger-padding-block))
138
- var(--ui-disclosure-trigger-padding-inline, var(--_trigger-padding-inline));
155
+ min-block-size: var(--_ui-disclosure-trigger-min-block-size, var(--_trigger-min-block-size));
156
+ padding: var(--_ui-disclosure-trigger-padding-block, var(--_trigger-padding-block))
157
+ var(--_ui-disclosure-trigger-padding-inline, var(--_trigger-padding-inline));
139
158
  border: 0;
140
159
  background: transparent;
141
160
  color: inherit;
@@ -155,7 +174,7 @@ useComponentHost(controllerModule.default, {
155
174
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
156
175
  }
157
176
  .trigger:disabled {
158
- color: var(--ui-text-muted);
177
+ color: var(--ui-disabled-text);
159
178
  cursor: not-allowed;
160
179
  }
161
180
 
@@ -264,7 +264,7 @@ useComponentHost(controllerModule.default, {
264
264
  }
265
265
 
266
266
  [data-component~="ui-editable"][data-ui-editable-state~="disabled"] .preview {
267
- color: var(--ui-text-muted);
267
+ color: var(--ui-disabled-text);
268
268
  cursor: not-allowed;
269
269
  }
270
270