@threadlabs/looma 0.12.5 → 0.12.7

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 (53) hide show
  1. package/components/ui-avatar/ui-avatar.html +18 -0
  2. package/components/ui-checkbox/ui-checkbox.html +1 -1
  3. package/components/ui-combobox/ui-combobox.html +2 -2
  4. package/components/ui-disclosure/ui-disclosure.html +1 -1
  5. package/components/ui-editable/ui-editable.html +1 -1
  6. package/components/ui-input/ui-input.html +1 -1
  7. package/components/ui-radio/ui-radio.html +1 -1
  8. package/components/ui-select/ui-select.html +1 -1
  9. package/components/ui-switch/ui-switch.html +1 -1
  10. package/components/ui-textarea/ui-textarea.html +1 -1
  11. package/dist/index.js +1 -1
  12. package/package.json +1 -1
  13. package/styles/ui-avatar.css +17 -1
  14. package/styles/ui-checkbox.css +1 -1
  15. package/styles/ui-combobox.css +2 -2
  16. package/styles/ui-disclosure.css +1 -1
  17. package/styles/ui-editable.css +1 -1
  18. package/styles/ui-input.css +1 -1
  19. package/styles/ui-radio.css +1 -1
  20. package/styles/ui-select.css +1 -1
  21. package/styles/ui-switch.css +1 -1
  22. package/styles/ui-textarea.css +1 -1
  23. package/theme-dark.css +1 -1
  24. package/theme-light.css +1 -1
  25. package/tokens.css +8 -6
  26. package/vanilla/UiAvatar.d.ts +2 -0
  27. package/vanilla/UiAvatar.js +1 -1
  28. package/vue/UiAvatar.d.ts +4 -0
  29. package/vue/UiAvatar.vue +32 -2
  30. package/vue/UiButton.d.ts +1 -1
  31. package/vue/UiCheckbox.vue +1 -1
  32. package/vue/UiCombobox.d.ts +1 -1
  33. package/vue/UiCombobox.vue +2 -2
  34. package/vue/UiDisclosure.vue +1 -1
  35. package/vue/UiEditable.vue +1 -1
  36. package/vue/UiIconButton.d.ts +1 -1
  37. package/vue/UiInput.vue +1 -1
  38. package/vue/UiRadio.vue +1 -1
  39. package/vue/UiSelect.vue +1 -1
  40. package/vue/UiSwitch.vue +1 -1
  41. package/vue/UiText.d.ts +1 -1
  42. package/vue/UiTextarea.vue +1 -1
  43. package/vue/chunks/UiAvatar.js +16 -7
  44. package/vue/chunks/UiCheckbox.js +1 -1
  45. package/vue/chunks/UiCombobox.js +1 -1
  46. package/vue/chunks/UiDisclosure.js +1 -1
  47. package/vue/chunks/UiEditable.js +1 -1
  48. package/vue/chunks/UiInput.js +1 -1
  49. package/vue/chunks/UiRadio.js +1 -1
  50. package/vue/chunks/UiSelect.js +1 -1
  51. package/vue/chunks/UiSwitch.js +1 -1
  52. package/vue/chunks/UiTextarea.js +1 -1
  53. package/vue/components.css +177 -165
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.12.5",
3
+ "version": "0.12.7",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -16,6 +16,19 @@
16
16
  text-transform: uppercase;
17
17
  }
18
18
 
19
+ :scope[data-ui-avatar-state~="size=sm"] {
20
+ inline-size: 1.75rem;
21
+ block-size: 1.75rem;
22
+ font-size: var(--ui-font-size-xs);
23
+ }
24
+
25
+ /* An outline, not a dot: the avatar clips its content to the circle, and an outline is drawn
26
+ outside the box, so the ring survives the clip and the overlap in an Avatar Group. */
27
+ :scope[data-ui-avatar-state~="active"] {
28
+ outline: 2px solid var(--ui-avatar-active-ring, var(--ui-success));
29
+ outline-offset: 1px;
30
+ }
31
+
19
32
  .fallback {
20
33
  grid-area: 1 / 1;
21
34
  display: inline-flex;
@@ -48,7 +61,10 @@
48
61
  }
49
62
  }
50
63
  @scope ([data-component~="ui-avatar"]) to ([data-component]) {
51
- .image,
64
+ /* An outline, not a dot: the avatar clips its content to the circle, and an outline is drawn
65
+ outside the box, so the ring survives the clip and the overlap in an Avatar Group. */
66
+
67
+ .image,
52
68
  :where([data-slotted], [data-slotted] *):is(img) {
53
69
  grid-area: 1 / 1;
54
70
  inline-size: 100%;
@@ -98,7 +98,7 @@
98
98
  }
99
99
 
100
100
  :scope[data-ui-checkbox-state~="disabled"] {
101
- color: var(--ui-text-muted);
101
+ color: var(--ui-disabled-text);
102
102
  cursor: not-allowed;
103
103
  }
104
104
  :scope[data-ui-checkbox-state~="disabled"] input {
@@ -129,7 +129,7 @@
129
129
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
130
130
  }
131
131
  input:disabled, button:disabled {
132
- color: var(--ui-text-muted);
132
+ color: var(--ui-disabled-text);
133
133
  cursor: not-allowed;
134
134
  }
135
135
  .field:has(input:disabled) {
@@ -167,7 +167,7 @@
167
167
  outline-offset: -1px;
168
168
  }
169
169
  .option[aria-disabled="true"] {
170
- color: var(--ui-text-muted);
170
+ color: var(--ui-disabled-text);
171
171
  cursor: not-allowed;
172
172
  }
173
173
  .primary {
@@ -51,7 +51,7 @@
51
51
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
52
52
  }
53
53
  .trigger:disabled {
54
- color: var(--ui-text-muted);
54
+ color: var(--ui-disabled-text);
55
55
  cursor: not-allowed;
56
56
  }
57
57
 
@@ -120,7 +120,7 @@
120
120
  }
121
121
 
122
122
  :scope[data-ui-editable-state~="disabled"] .preview {
123
- color: var(--ui-text-muted);
123
+ color: var(--ui-disabled-text);
124
124
  cursor: not-allowed;
125
125
  }
126
126
 
@@ -59,7 +59,7 @@
59
59
 
60
60
  :scope:disabled {
61
61
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
62
- color: var(--ui-text-muted);
62
+ color: var(--ui-disabled-text);
63
63
  box-shadow: none;
64
64
  cursor: not-allowed;
65
65
  }
@@ -47,7 +47,7 @@
47
47
  }
48
48
 
49
49
  :scope[data-ui-radio-state~="disabled"] {
50
- color: var(--ui-text-muted);
50
+ color: var(--ui-disabled-text);
51
51
  cursor: not-allowed;
52
52
  }
53
53
  :scope[data-ui-radio-state~="disabled"] input {
@@ -60,7 +60,7 @@
60
60
 
61
61
  :scope:disabled {
62
62
  background-color: var(--ui-control-surface-disabled, var(--ui-surface-muted));
63
- color: var(--ui-text-muted);
63
+ color: var(--ui-disabled-text);
64
64
  box-shadow: none;
65
65
  cursor: not-allowed;
66
66
  }
@@ -78,7 +78,7 @@
78
78
  }
79
79
 
80
80
  :scope[data-ui-switch-state~="disabled"] {
81
- color: var(--ui-text-muted);
81
+ color: var(--ui-disabled-text);
82
82
  cursor: not-allowed;
83
83
  }
84
84
  :scope[data-ui-switch-state~="disabled"] input {
@@ -58,7 +58,7 @@
58
58
 
59
59
  :scope:disabled {
60
60
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
61
- color: var(--ui-text-muted);
61
+ color: var(--ui-disabled-text);
62
62
  box-shadow: none;
63
63
  cursor: not-allowed;
64
64
  }
package/theme-dark.css CHANGED
@@ -1,6 +1,6 @@
1
1
  @layer base {
2
2
  @media (prefers-color-scheme: dark) {
3
- :root:not([data-theme]) {
3
+ :root:not([data-theme], [data-contrast="high"]) {
4
4
  color-scheme: dark;
5
5
  /* The same eleven seeds the light theme sets. Every neutral, tint, hover, and disabled
6
6
  colour is mixed from these, and the mixes read the scheme from them: toward this ink
package/theme-light.css CHANGED
@@ -1,5 +1,5 @@
1
1
  @layer base {
2
- :root:not([data-theme]),
2
+ :root:not([data-theme], [data-contrast="high"]),
3
3
  [data-theme="light"] {
4
4
  color-scheme: light;
5
5
  /* The seeds, and only the seeds. Neutrals, hovers, tints, and disabled colours are mixed from
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);
@@ -6,9 +6,11 @@ export interface UiAvatarElement extends HTMLSpanElement {
6
6
  removeEventListener<K extends keyof UiAvatarEventMap>(type: K, listener: (this: UiAvatarElement, event: UiAvatarEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
7
7
  }
8
8
  export interface UiAvatarProps {
9
+ active?: boolean | null;
9
10
  alt?: string | null;
10
11
  fallback?: string | null;
11
12
  name?: string | null;
13
+ size?: "sm" | "md" | null;
12
14
  src?: string | null;
13
15
  attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
14
16
  children?: readonly (string | Node)[];
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
3
3
  import * as controller from "../components/ui-avatar/ui-avatar.js";
4
4
  import "../styles/ui-avatar.css";
5
5
 
6
- const definition = {...{"contract":{"tag":"ui-avatar","props":{"alt":{"type":"string","required":false,"target":{"attribute":"alt"},"default":""},"fallback":{"type":"string","required":false,"target":{"attribute":"fallback"},"default":""},"name":{"type":"string","required":false,"target":{"attribute":"name"},"default":""},"src":{"type":"string","required":false,"target":{"attribute":"src"}}}},"template":{"kind":"element","name":"span","attributes":[],"children":[{"kind":"slot"},{"kind":"element","name":"img","attributes":[{"kind":"literal","name":"class","value":"image"},{"kind":"attribute","name":"src","expression":"src","expressionPlan":{"source":"src","ast":{"kind":"id","name":"src"},"dependencies":["src"]}},{"kind":"literal","name":"alt","value":""},{"kind":"literal","name":"aria-hidden","value":"true"},{"kind":"attribute","name":"hidden","expression":"hasAuthoredImage or not hasImage","expressionPlan":{"source":"hasAuthoredImage or not hasImage","ast":{"kind":"binary","op":"or","left":{"kind":"id","name":"hasAuthoredImage"},"right":{"kind":"unary","op":"not","operand":{"kind":"id","name":"hasImage"}}},"dependencies":["hasAuthoredImage","hasImage"]}}],"children":[],"ref":"image"},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"fallback"},{"kind":"attribute","name":"aria-hidden","expression":"hasImage","expressionPlan":{"source":"hasImage","ast":{"kind":"id","name":"hasImage"},"dependencies":["hasImage"]}},{"kind":"attribute","name":"hidden","expression":"hasImage","expressionPlan":{"source":"hasImage","ast":{"kind":"id","name":"hasImage"},"dependencies":["hasImage"]}},{"kind":"directive","name":"value","expression":"initials","expressionPlan":{"source":"initials","ast":{"kind":"id","name":"initials"},"dependencies":["initials"]}}],"children":[]}]},"declarations":[{"kind":"state","name":"hasImage","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"hasAuthoredImage","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"initials","expression":{"source":"'?'","ast":{"kind":"literal","value":"?"},"dependencies":[]}}],"root":{"kind":"native","element":"span","choices":["span"]}},source:{file:import.meta.url},css:""};
6
+ const definition = {...{"contract":{"tag":"ui-avatar","props":{"active":{"type":"boolean","required":false,"target":{"attribute":"active"},"default":false},"alt":{"type":"string","required":false,"target":{"attribute":"alt"},"default":""},"fallback":{"type":"string","required":false,"target":{"attribute":"fallback"},"default":""},"name":{"type":"string","required":false,"target":{"attribute":"name"},"default":""},"size":{"type":{"enum":["sm","md"]},"required":false,"target":{"attribute":"size"},"default":"md"},"src":{"type":"string","required":false,"target":{"attribute":"src"}}}},"template":{"kind":"element","name":"span","attributes":[],"children":[{"kind":"slot"},{"kind":"element","name":"img","attributes":[{"kind":"literal","name":"class","value":"image"},{"kind":"attribute","name":"src","expression":"src","expressionPlan":{"source":"src","ast":{"kind":"id","name":"src"},"dependencies":["src"]}},{"kind":"literal","name":"alt","value":""},{"kind":"literal","name":"aria-hidden","value":"true"},{"kind":"attribute","name":"hidden","expression":"hasAuthoredImage or not hasImage","expressionPlan":{"source":"hasAuthoredImage or not hasImage","ast":{"kind":"binary","op":"or","left":{"kind":"id","name":"hasAuthoredImage"},"right":{"kind":"unary","op":"not","operand":{"kind":"id","name":"hasImage"}}},"dependencies":["hasAuthoredImage","hasImage"]}}],"children":[],"ref":"image"},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"fallback"},{"kind":"attribute","name":"aria-hidden","expression":"hasImage","expressionPlan":{"source":"hasImage","ast":{"kind":"id","name":"hasImage"},"dependencies":["hasImage"]}},{"kind":"attribute","name":"hidden","expression":"hasImage","expressionPlan":{"source":"hasImage","ast":{"kind":"id","name":"hasImage"},"dependencies":["hasImage"]}},{"kind":"directive","name":"value","expression":"initials","expressionPlan":{"source":"initials","ast":{"kind":"id","name":"initials"},"dependencies":["initials"]}}],"children":[]}]},"declarations":[{"kind":"state","name":"hasImage","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"hasAuthoredImage","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"initials","expression":{"source":"'?'","ast":{"kind":"literal","value":"?"},"dependencies":[]}}],"root":{"kind":"native","element":"span","choices":["span"]}},source:{file:import.meta.url},css:""};
7
7
 
8
8
  export function createUiAvatar(options = {}) {
9
9
  const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
package/vue/UiAvatar.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  type __VLS_Props = {
2
+ active?: boolean;
2
3
  alt?: string;
3
4
  fallback?: string;
4
5
  name?: string;
6
+ size?: 'sm' | 'md';
5
7
  src?: string;
6
8
  };
7
9
  declare var __VLS_1: {};
@@ -10,8 +12,10 @@ type __VLS_Slots = {} & {
10
12
  };
11
13
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
12
14
  name: string;
15
+ active: boolean;
13
16
  alt: string;
14
17
  fallback: string;
18
+ size: "sm" | "md";
15
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
20
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
17
21
  declare const _default: typeof __VLS_export;
package/vue/UiAvatar.vue CHANGED
@@ -1,6 +1,6 @@
1
1
  <!-- Generated by HTML Next 1.0.0-alpha.5 for Vue 3.5. Do not edit. -->
2
2
  <script setup lang="ts">
3
- import { ref, useTemplateRef } from 'vue'
3
+ import { computed, ref, useTemplateRef } from 'vue'
4
4
  import * as controllerModule from '../components/ui-avatar/ui-avatar.js'
5
5
  import { createDispatch, useComponentHost } from './host'
6
6
 
@@ -8,15 +8,19 @@ defineOptions({ inheritAttrs: false })
8
8
 
9
9
  const props = withDefaults(
10
10
  defineProps<{
11
+ active?: boolean
11
12
  alt?: string
12
13
  fallback?: string
13
14
  name?: string
15
+ size?: 'sm' | 'md'
14
16
  src?: string
15
17
  }>(),
16
18
  {
19
+ active: false,
17
20
  alt: '',
18
21
  fallback: '',
19
22
  name: '',
23
+ size: 'md',
20
24
  },
21
25
  )
22
26
 
@@ -26,6 +30,14 @@ const hasImage = ref(false)
26
30
  const hasAuthoredImage = ref(false)
27
31
  const initials = ref('?')
28
32
 
33
+ /** The values the styles' :host-state() rules test. */
34
+ const hostState = computed(() =>
35
+ [
36
+ props.size && `size size=${props.size}`,
37
+ props.active && 'active',
38
+ ].filter(Boolean).join(' ')
39
+ )
40
+
29
41
  const dispatch = createDispatch(root)
30
42
 
31
43
  useComponentHost(controllerModule.default, {
@@ -38,7 +50,12 @@ useComponentHost(controllerModule.default, {
38
50
  </script>
39
51
 
40
52
  <template>
41
- <span data-component="ui-avatar" v-bind="$attrs" ref="root"><slot />
53
+ <span
54
+ data-component="ui-avatar"
55
+ v-bind="$attrs"
56
+ :data-ui-avatar-state="hostState || undefined"
57
+ ref="root"
58
+ ><slot />
42
59
  <img
43
60
  class="image"
44
61
  alt=""
@@ -67,6 +84,19 @@ useComponentHost(controllerModule.default, {
67
84
  text-transform: uppercase;
68
85
  }
69
86
 
87
+ [data-component~="ui-avatar"][data-ui-avatar-state~="size=sm"] {
88
+ inline-size: 1.75rem;
89
+ block-size: 1.75rem;
90
+ font-size: var(--ui-font-size-xs);
91
+ }
92
+
93
+ /* An outline, not a dot: the avatar clips its content to the circle, and an outline is drawn
94
+ outside the box, so the ring survives the clip and the overlap in an Avatar Group. */
95
+ [data-component~="ui-avatar"][data-ui-avatar-state~="active"] {
96
+ outline: 2px solid var(--ui-avatar-active-ring, var(--ui-success));
97
+ outline-offset: 1px;
98
+ }
99
+
70
100
  .image,
71
101
  :slotted(img) {
72
102
  grid-area: 1 / 1;
package/vue/UiButton.d.ts CHANGED
@@ -17,12 +17,12 @@ type __VLS_Slots = {} & {
17
17
  };
18
18
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
19
19
  type: "button" | "submit" | "reset";
20
+ size: "sm" | "md" | "lg";
20
21
  tone: "accent" | "neutral" | "danger" | "success" | "warning" | "info";
21
22
  variant: "outline" | "solid" | "danger" | "ghost" | "link";
22
23
  as: "button" | "a";
23
24
  align: "center" | "start";
24
25
  disabled: boolean;
25
- size: "sm" | "md" | "lg";
26
26
  stretch: boolean;
27
27
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
28
28
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -193,7 +193,7 @@ input:focus-visible {
193
193
  }
194
194
 
195
195
  [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"] {
196
- color: var(--ui-text-muted);
196
+ color: var(--ui-disabled-text);
197
197
  cursor: not-allowed;
198
198
  }
199
199
  [data-component~="ui-checkbox"][data-ui-checkbox-state~="disabled"] input {
@@ -236,8 +236,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
236
236
  }>, {
237
237
  label: string;
238
238
  name: string;
239
- disabled: boolean;
240
239
  size: "sm" | "md";
240
+ disabled: boolean;
241
241
  required: boolean;
242
242
  allowCreate: boolean;
243
243
  allowFreeText: boolean;
@@ -795,7 +795,7 @@ button:focus-visible {
795
795
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
796
796
  }
797
797
  input:disabled, button:disabled {
798
- color: var(--ui-text-muted);
798
+ color: var(--ui-disabled-text);
799
799
  cursor: not-allowed;
800
800
  }
801
801
  .field:has(input:disabled) {
@@ -833,7 +833,7 @@ input:disabled, button:disabled {
833
833
  outline-offset: -1px;
834
834
  }
835
835
  .option[aria-disabled="true"] {
836
- color: var(--ui-text-muted);
836
+ color: var(--ui-disabled-text);
837
837
  cursor: not-allowed;
838
838
  }
839
839
  .primary {
@@ -155,7 +155,7 @@ useComponentHost(controllerModule.default, {
155
155
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ui-focus-ring) 45%, transparent);
156
156
  }
157
157
  .trigger:disabled {
158
- color: var(--ui-text-muted);
158
+ color: var(--ui-disabled-text);
159
159
  cursor: not-allowed;
160
160
  }
161
161
 
@@ -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
 
@@ -11,10 +11,10 @@ type __VLS_Slots = {} & {
11
11
  default?: (props: typeof __VLS_1) => any;
12
12
  };
13
13
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
14
+ size: "sm" | "md" | "lg";
14
15
  variant: "ghost" | "outline" | "solid";
15
16
  round: boolean;
16
17
  disabled: boolean;
17
- size: "sm" | "md" | "lg";
18
18
  anticipatory: boolean;
19
19
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
20
20
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
package/vue/UiInput.vue CHANGED
@@ -122,7 +122,7 @@ useComponentHost(controllerModule.default, {
122
122
 
123
123
  [data-component~="ui-input"]:disabled {
124
124
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
125
- color: var(--ui-text-muted);
125
+ color: var(--ui-disabled-text);
126
126
  box-shadow: none;
127
127
  cursor: not-allowed;
128
128
  }
package/vue/UiRadio.vue CHANGED
@@ -139,7 +139,7 @@ input:focus-visible {
139
139
  }
140
140
 
141
141
  [data-component~="ui-radio"][data-ui-radio-state~="disabled"] {
142
- color: var(--ui-text-muted);
142
+ color: var(--ui-disabled-text);
143
143
  cursor: not-allowed;
144
144
  }
145
145
  [data-component~="ui-radio"][data-ui-radio-state~="disabled"] input {
package/vue/UiSelect.vue CHANGED
@@ -118,7 +118,7 @@ useComponentHost(controllerModule.default, {
118
118
 
119
119
  [data-component~="ui-select"]:disabled {
120
120
  background-color: var(--ui-control-surface-disabled, var(--ui-surface-muted));
121
- color: var(--ui-text-muted);
121
+ color: var(--ui-disabled-text);
122
122
  box-shadow: none;
123
123
  cursor: not-allowed;
124
124
  }
package/vue/UiSwitch.vue CHANGED
@@ -173,7 +173,7 @@ input:focus-visible {
173
173
  }
174
174
 
175
175
  [data-component~="ui-switch"][data-ui-switch-state~="disabled"] {
176
- color: var(--ui-text-muted);
176
+ color: var(--ui-disabled-text);
177
177
  cursor: not-allowed;
178
178
  }
179
179
  [data-component~="ui-switch"][data-ui-switch-state~="disabled"] input {
package/vue/UiText.d.ts CHANGED
@@ -12,11 +12,11 @@ type __VLS_Slots = {} & {
12
12
  default?: (props: typeof __VLS_8) => any;
13
13
  };
14
14
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
15
+ size: "inherit" | "xs" | "sm" | "md" | "lg";
15
16
  tone: "default" | "secondary" | "muted" | "accent" | "danger" | "success";
16
17
  variant: "body" | "eyebrow" | "code";
17
18
  as: "p" | "span" | "div" | "small" | "strong" | "label";
18
19
  align: "start" | "center";
19
- size: "inherit" | "xs" | "sm" | "md" | "lg";
20
20
  truncate: boolean;
21
21
  weight: "inherit" | "normal" | "medium" | "semibold";
22
22
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -120,7 +120,7 @@ useComponentHost(controllerModule.default, {
120
120
 
121
121
  [data-component~="ui-textarea"]:disabled {
122
122
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
123
- color: var(--ui-text-muted);
123
+ color: var(--ui-disabled-text);
124
124
  box-shadow: none;
125
125
  cursor: not-allowed;
126
126
  }
@@ -1,19 +1,25 @@
1
1
  import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
2
2
  import { n as useComponentHost, t as createDispatch } from "./host.js";
3
- import { createElementBlock, createElementVNode, defineComponent, mergeProps, openBlock, ref, renderSlot, toDisplayString, useTemplateRef } from "vue";
3
+ import { computed, createElementBlock, createElementVNode, defineComponent, mergeProps, openBlock, ref, renderSlot, toDisplayString, useTemplateRef } from "vue";
4
4
  import * as controllerModule from "@threadlabs/looma/components/ui-avatar/ui-avatar.js";
5
5
  //#region .build/vue/UiAvatar.vue?vue&type=script&setup=true&lang.ts
6
- var _hoisted_1 = ["src", "hidden"];
7
- var _hoisted_2 = ["aria-hidden", "hidden"];
6
+ var _hoisted_1 = ["data-ui-avatar-state"];
7
+ var _hoisted_2 = ["src", "hidden"];
8
+ var _hoisted_3 = ["aria-hidden", "hidden"];
8
9
  //#endregion
9
10
  //#region .build/vue/UiAvatar.vue
10
11
  var UiAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
11
12
  inheritAttrs: false,
12
13
  __name: "UiAvatar",
13
14
  props: {
15
+ active: {
16
+ type: Boolean,
17
+ default: false
18
+ },
14
19
  alt: { default: "" },
15
20
  fallback: { default: "" },
16
21
  name: { default: "" },
22
+ size: { default: "md" },
17
23
  src: {}
18
24
  },
19
25
  setup(__props) {
@@ -23,6 +29,8 @@ var UiAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
23
29
  const hasImage = ref(false);
24
30
  const hasAuthoredImage = ref(false);
25
31
  const initials = ref("?");
32
+ /** The values the styles' :host-state() rules test. */
33
+ const hostState = computed(() => [props.size && `size size=${props.size}`, props.active && "active"].filter(Boolean).join(" "));
26
34
  const dispatch = createDispatch(root);
27
35
  useComponentHost(controllerModule.default, {
28
36
  root,
@@ -37,6 +45,7 @@ var UiAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
37
45
  });
38
46
  return (_ctx, _cache) => {
39
47
  return openBlock(), createElementBlock("span", mergeProps({ "data-component": "ui-avatar" }, _ctx.$attrs, {
48
+ "data-ui-avatar-state": hostState.value || void 0,
40
49
  ref_key: "root",
41
50
  ref: root
42
51
  }), [
@@ -48,15 +57,15 @@ var UiAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
48
57
  src: __props.src,
49
58
  hidden: hasAuthoredImage.value || !hasImage.value,
50
59
  ref: "image"
51
- }, null, 8, _hoisted_1),
60
+ }, null, 8, _hoisted_2),
52
61
  createElementVNode("span", {
53
62
  class: "fallback",
54
63
  "aria-hidden": hasImage.value,
55
64
  hidden: hasImage.value
56
- }, toDisplayString(initials.value), 9, _hoisted_2)
57
- ], 16);
65
+ }, toDisplayString(initials.value), 9, _hoisted_3)
66
+ ], 16, _hoisted_1);
58
67
  };
59
68
  }
60
- }), [["__scopeId", "data-v-ebb1bbbb"]]);
69
+ }), [["__scopeId", "data-v-a5e0e48e"]]);
61
70
  //#endregion
62
71
  export { UiAvatar_default as t };
@@ -94,6 +94,6 @@ var UiCheckbox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
94
94
  }, null, 40, _hoisted_2), createElementVNode("span", _hoisted_3, [createElementVNode("span", _hoisted_4, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]), createElementVNode("span", _hoisted_5, [renderSlot(_ctx.$slots, "description", {}, void 0, true)], 512)])], 16, _hoisted_1);
95
95
  };
96
96
  }
97
- }), [["__scopeId", "data-v-4d65c3b0"]]);
97
+ }), [["__scopeId", "data-v-cc7306ec"]]);
98
98
  //#endregion
99
99
  export { UiCheckbox_default as t };
@@ -479,6 +479,6 @@ var UiCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
479
479
  ], 16, _hoisted_1);
480
480
  };
481
481
  }
482
- }), [["__scopeId", "data-v-0bd7ecc4"]]);
482
+ }), [["__scopeId", "data-v-b3cdd263"]]);
483
483
  //#endregion
484
484
  export { UiCombobox_default as t };
@@ -86,6 +86,6 @@ var UiDisclosure_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
86
86
  }, [createElementVNode("div", _hoisted_4, [renderSlot(_ctx.$slots, "default", {}, void 0, true)])], 8, _hoisted_3)], 16, _hoisted_1);
87
87
  };
88
88
  }
89
- }), [["__scopeId", "data-v-54a22a7e"]]);
89
+ }), [["__scopeId", "data-v-af289043"]]);
90
90
  //#endregion
91
91
  export { UiDisclosure_default as t };
@@ -120,6 +120,6 @@ var UiEditable_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
120
120
  }, "Cancel", -1)])])) : createCommentVNode("v-if", true)], 16, _hoisted_1);
121
121
  };
122
122
  }
123
- }), [["__scopeId", "data-v-8fe1c571"]]);
123
+ }), [["__scopeId", "data-v-3b785d66"]]);
124
124
  //#endregion
125
125
  export { UiEditable_default as t };
@@ -61,6 +61,6 @@ var UiInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
61
61
  }), null, 16, _hoisted_1)), [[vModelDynamic, model.value]]);
62
62
  };
63
63
  }
64
- }), [["__scopeId", "data-v-e7c851a2"]]);
64
+ }), [["__scopeId", "data-v-08811f22"]]);
65
65
  //#endregion
66
66
  export { UiInput_default as t };
@@ -88,6 +88,6 @@ var UiRadio_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
88
88
  }, null, 40, _hoisted_2), createElementVNode("span", _hoisted_3, [createElementVNode("span", _hoisted_4, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]), createElementVNode("span", _hoisted_5, [renderSlot(_ctx.$slots, "description", {}, void 0, true)], 512)])], 16, _hoisted_1);
89
89
  };
90
90
  }
91
- }), [["__scopeId", "data-v-f9c61d50"]]);
91
+ }), [["__scopeId", "data-v-c4f88d99"]]);
92
92
  //#endregion
93
93
  export { UiRadio_default as t };
@@ -55,6 +55,6 @@ var UiSelect_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
55
55
  }), [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 16, _hoisted_1)), [[vModelSelect, model.value]]);
56
56
  };
57
57
  }
58
- }), [["__scopeId", "data-v-f9be4ab9"]]);
58
+ }), [["__scopeId", "data-v-e15c964d"]]);
59
59
  //#endregion
60
60
  export { UiSelect_default as t };
@@ -89,6 +89,6 @@ var UiSwitch_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
89
89
  }, null, 40, _hoisted_2), createElementVNode("span", _hoisted_3, [createElementVNode("span", _hoisted_4, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]), createElementVNode("span", _hoisted_5, [renderSlot(_ctx.$slots, "description", {}, void 0, true)], 512)])], 16, _hoisted_1);
90
90
  };
91
91
  }
92
- }), [["__scopeId", "data-v-85cb3260"]]);
92
+ }), [["__scopeId", "data-v-afb9ea1d"]]);
93
93
  //#endregion
94
94
  export { UiSwitch_default as t };
@@ -64,6 +64,6 @@ var UiTextarea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
64
64
  }), null, 16, _hoisted_1)), [[vModelText, model.value]]);
65
65
  };
66
66
  }
67
- }), [["__scopeId", "data-v-0352d397"]]);
67
+ }), [["__scopeId", "data-v-860b69d7"]]);
68
68
  //#endregion
69
69
  export { UiTextarea_default as t };