@threadlabs/looma 0.17.3 → 0.18.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 (71) hide show
  1. package/components/ui-avatar/ui-avatar.html +8 -4
  2. package/components/ui-badge/ui-badge.html +28 -34
  3. package/components/ui-button/ui-button.html +5 -0
  4. package/components/ui-checkbox/ui-checkbox.html +5 -5
  5. package/components/ui-combobox/ui-combobox.html +4 -48
  6. package/components/ui-icon-button/ui-icon-button.html +7 -7
  7. package/components/ui-input/ui-input.html +1 -1
  8. package/components/ui-input-group/ui-input-group.html +2 -2
  9. package/components/ui-listbox/ui-listbox.html +88 -12
  10. package/components/ui-listbox/ui-listbox.js +162 -18
  11. package/components/ui-search-result-row/ui-search-result-row.html +2 -6
  12. package/components/ui-search-shell/ui-search-shell.html +2 -11
  13. package/components/ui-select/ui-select.html +1 -1
  14. package/components/ui-spinner/ui-spinner.html +45 -18
  15. package/components/ui-textarea/ui-textarea.html +1 -1
  16. package/components/ui-tooltip/ui-tooltip.html +2 -2
  17. package/dist/index.js +1 -1
  18. package/editor/chunks/extensions.js +5 -0
  19. package/package.json +1 -1
  20. package/styles/ui-avatar.css +6 -2
  21. package/styles/ui-badge.css +30 -40
  22. package/styles/ui-button.css +7 -0
  23. package/styles/ui-checkbox.css +6 -6
  24. package/styles/ui-combobox.css +0 -52
  25. package/styles/ui-icon-button.css +7 -7
  26. package/styles/ui-input-group.css +2 -2
  27. package/styles/ui-input.css +1 -1
  28. package/styles/ui-listbox.css +33 -8
  29. package/styles/ui-search-result-row.css +2 -6
  30. package/styles/ui-search-shell.css +2 -13
  31. package/styles/ui-select.css +1 -1
  32. package/styles/ui-spinner.css +38 -19
  33. package/styles/ui-textarea.css +1 -1
  34. package/styles/ui-tooltip.css +2 -2
  35. package/tokens.css +67 -2
  36. package/vanilla/UiCombobox.js +9 -1
  37. package/vanilla/UiListbox.d.ts +3 -1
  38. package/vanilla/UiListbox.js +65 -18
  39. package/vanilla/UiSpinner.js +19 -1
  40. package/vue/UiAvatar.vue +11 -2
  41. package/vue/UiBadge.vue +30 -36
  42. package/vue/UiButton.vue +5 -0
  43. package/vue/UiCheckbox.vue +5 -5
  44. package/vue/UiCombobox.vue +4 -49
  45. package/vue/UiIconButton.vue +10 -7
  46. package/vue/UiInput.vue +1 -1
  47. package/vue/UiInputGroup.vue +2 -2
  48. package/vue/UiListbox.d.ts +18 -5
  49. package/vue/UiListbox.vue +142 -25
  50. package/vue/UiSearchResultRow.vue +2 -6
  51. package/vue/UiSearchShell.vue +2 -13
  52. package/vue/UiSelect.vue +1 -1
  53. package/vue/UiSpinner.vue +45 -18
  54. package/vue/UiTextarea.vue +1 -1
  55. package/vue/UiTooltip.vue +2 -2
  56. package/vue/chunks/UiAvatar.js +2 -1
  57. package/vue/chunks/UiBadge.js +1 -1
  58. package/vue/chunks/UiButton.js +1 -1
  59. package/vue/chunks/UiCheckbox.js +1 -1
  60. package/vue/chunks/UiCombobox.js +11 -2
  61. package/vue/chunks/UiIconButton.js +1 -1
  62. package/vue/chunks/UiInput.js +1 -1
  63. package/vue/chunks/UiInputGroup.js +1 -1
  64. package/vue/chunks/UiListbox.js +134 -20
  65. package/vue/chunks/UiSearchResultRow.js +1 -1
  66. package/vue/chunks/UiSearchShell.js +1 -1
  67. package/vue/chunks/UiSelect.js +1 -1
  68. package/vue/chunks/UiSpinner.js +29 -3
  69. package/vue/chunks/UiTextarea.js +1 -1
  70. package/vue/chunks/UiTooltip.js +1 -1
  71. package/vue/components.css +426 -440
@@ -2,21 +2,34 @@ type __VLS_Props = {
2
2
  disabled?: boolean;
3
3
  invalid?: boolean;
4
4
  multiple?: boolean;
5
+ name?: string;
5
6
  required?: boolean;
6
7
  rows?: number;
7
8
  value?: string;
8
9
  values?: readonly (string)[];
9
- modelValue?: string | null;
10
10
  };
11
- declare var __VLS_1: {};
11
+ declare var __VLS_9: {};
12
12
  type __VLS_Slots = {} & {
13
- default?: (props: typeof __VLS_1) => any;
13
+ default?: (props: typeof __VLS_9) => any;
14
14
  };
15
15
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
16
- "update:modelValue": (value: string) => any;
16
+ change: (detail: {
17
+ readonly value: string | null;
18
+ readonly values: readonly (string)[];
19
+ readonly trigger: "keyboard" | "pointer";
20
+ }) => any;
21
+ "update:value": (value: string) => any;
22
+ "update:values": (value: readonly string[]) => any;
17
23
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
18
- "onUpdate:modelValue"?: ((value: string) => any) | undefined;
24
+ onChange?: ((detail: {
25
+ readonly value: string | null;
26
+ readonly values: readonly (string)[];
27
+ readonly trigger: "keyboard" | "pointer";
28
+ }) => any) | undefined;
29
+ "onUpdate:value"?: ((value: string) => any) | undefined;
30
+ "onUpdate:values"?: ((value: readonly string[]) => any) | undefined;
19
31
  }>, {
32
+ name: string;
20
33
  invalid: boolean;
21
34
  disabled: boolean;
22
35
  required: boolean;
package/vue/UiListbox.vue CHANGED
@@ -1,8 +1,9 @@
1
1
  <!-- Generated by HTML Next 1.0.0-alpha.7 for Vue 3.5. Do not edit. -->
2
2
  <script setup lang="ts">
3
- import { computed, ref } from 'vue'
3
+ import { ref, useTemplateRef } from 'vue'
4
4
  import * as controllerModule from '../components/ui-listbox/ui-listbox.js'
5
5
  import { createDispatch, useComponentHost } from './host'
6
+ import UiScrollArea from './UiScrollArea.vue'
6
7
 
7
8
  defineOptions({ inheritAttrs: false })
8
9
 
@@ -11,53 +12,144 @@ const props = withDefaults(
11
12
  disabled?: boolean
12
13
  invalid?: boolean
13
14
  multiple?: boolean
15
+ name?: string
14
16
  required?: boolean
15
17
  rows?: number
16
18
  value?: string
17
19
  values?: readonly (string)[]
18
- modelValue?: string | null
19
20
  }>(),
20
21
  {
21
22
  disabled: false,
22
23
  invalid: false,
23
24
  multiple: false,
25
+ name: '',
24
26
  required: false,
25
27
  rows: 5,
26
28
  },
27
29
  )
28
30
  const emit = defineEmits<{
29
- 'update:modelValue': [value: string]
31
+ 'update:value': [value: string]
32
+ 'update:values': [value: readonly (string)[]]
33
+ change: [
34
+ detail: {
35
+ readonly value: string | null
36
+ readonly values: readonly (string)[]
37
+ readonly trigger: 'keyboard' | 'pointer'
38
+ },
39
+ ]
30
40
  }>()
31
- const model = computed({
32
- get: () => props.modelValue ?? props.value ?? undefined,
33
- set: (value) => emit('update:modelValue', value as string),
34
- })
35
41
 
36
42
  const root = ref<HTMLElement | null>(null)
43
+ const choicesElement = useTemplateRef<HTMLElement>('choices')
44
+ const optionsElement = useTemplateRef<HTMLElement>('options')
45
+ const validityElement = useTemplateRef<HTMLElement>('validity')
46
+ const choices = ref<
47
+ { value: string; label: string; disabled: boolean; selected: boolean; index: number }[]
48
+ >([])
49
+ const selection = ref<string[]>([])
50
+ const hasSelection = ref(false)
51
+ const active = ref(-1)
52
+ const uid = ref('')
53
+ const validationError = ref(false)
37
54
 
38
- const dispatch = createDispatch(root)
55
+ const isChangeDetail = (detail: unknown): boolean =>
56
+ detail !== null && typeof detail === 'object' && !Array.isArray(detail)
57
+ && (typeof (detail as Record<string, unknown>)['value'] === 'string'
58
+ || (detail as Record<string, unknown>)['value'] === null)
59
+ && (Array.isArray((detail as Record<string, unknown>)['values'])
60
+ && ((detail as Record<string, unknown>)['values'] as unknown[]).every((item: unknown) =>
61
+ typeof item === 'string'
62
+ ))
63
+ && ((detail as Record<string, unknown>)['trigger'] === 'keyboard'
64
+ || (detail as Record<string, unknown>)['trigger'] === 'pointer')
65
+ && Object.keys(detail as object).every((key) => ['value', 'values', 'trigger'].includes(key))
66
+ const dispatch = createDispatch(root, emit as (name: string, detail: unknown) => void, {
67
+ checks: {
68
+ change: isChangeDetail,
69
+ },
70
+ modeled: ['value', 'values'],
71
+ })
39
72
 
40
73
  useComponentHost(controllerModule.default, {
41
74
  root,
42
75
  dispatch,
43
76
  props,
77
+ refs: { choices: choicesElement, options: optionsElement, validity: validityElement },
78
+ state: { choices, selection, hasSelection, active, uid, validationError },
44
79
  })
80
+
81
+ function text(value: unknown): string {
82
+ if (Array.isArray(value)) return value.map(text).join(' ')
83
+ return value === null || value === undefined || typeof value === 'object' ? '' : String(value)
84
+ }
85
+
86
+ function attribute(value: unknown): any {
87
+ if (
88
+ value === null || value === undefined || value === false
89
+ || (typeof value === 'object' && !Array.isArray(value))
90
+ ) return undefined
91
+ return value === true ? '' : text(value)
92
+ }
45
93
  </script>
46
94
 
47
95
  <template>
48
- <select
96
+ <div
49
97
  data-component="ui-listbox"
98
+ role="listbox"
50
99
  v-bind="$attrs"
51
- :size="rows"
52
- :multiple="multiple"
53
- :disabled="disabled"
54
- :required="required"
55
- :aria-invalid="invalid"
56
- v-model="model"
100
+ :tabindex="attribute(({ true: '-1', false: '0' })[`${disabled}`])"
101
+ :aria-multiselectable="multiple"
102
+ :aria-disabled="disabled"
103
+ :aria-required="required"
104
+ :aria-invalid="invalid || validationError"
105
+ :style="{ '--_rows': rows }"
57
106
  ref="root"
58
107
  >
59
- <slot />
60
- </select>
108
+ <UiScrollArea class="choices" ref="choices"><div
109
+ v-for="choice in choices"
110
+ :key="choice.index"
111
+ class="option"
112
+ role="option"
113
+ data-ui-choice-option=""
114
+ :data-multiple="multiple ? '' : undefined"
115
+ :id="`${uid}-option-${choice.index}`"
116
+ :data-index="choice.index"
117
+ :aria-selected="choice.selected"
118
+ :aria-disabled="choice.disabled"
119
+ :class="{ active: choice.index === active }"
120
+ >
121
+ <span>{{ choice.label }}</span>
122
+ </div></UiScrollArea>
123
+ <select
124
+ class="fallback"
125
+ aria-label="Choices"
126
+ :size="rows"
127
+ :multiple="multiple"
128
+ :disabled="disabled"
129
+ :required="required"
130
+ :name="name"
131
+ ref="options"
132
+ >
133
+ <slot />
134
+ </select>
135
+ <template v-if="name && !disabled"><input
136
+ v-for="(selected, index) in selection"
137
+ :key="index"
138
+ type="hidden"
139
+ :name="name"
140
+ :value="selected"
141
+ ></template>
142
+ <input
143
+ class="validity"
144
+ type="checkbox"
145
+ aria-hidden="true"
146
+ tabindex="-1"
147
+ :required="required && !hasSelection && !disabled"
148
+ :checked="hasSelection"
149
+ :disabled="disabled"
150
+ ref="validity"
151
+ >
152
+ </div>
61
153
  </template>
62
154
 
63
155
  <style scoped>
@@ -83,29 +175,55 @@ useComponentHost(controllerModule.default, {
83
175
  }
84
176
 
85
177
  [data-component~="ui-listbox"] {
178
+ position: relative;
86
179
  box-sizing: border-box;
87
180
  display: block;
88
181
  inline-size: 100%;
89
182
  min-inline-size: 0;
90
- min-block-size: var(--ui-control-min-block-size);
91
183
  margin: 0;
92
184
  padding: var(--ui-space-1);
93
185
  border: 1px solid var(--ui-listbox-border, var(--ui-control-border));
94
186
  border-radius: var(--ui-listbox-radius, var(--ui-field-radius, var(--ui-radius-md)));
95
187
  background: var(--ui-listbox-surface, var(--ui-control-surface));
96
188
  color: var(--ui-text-primary);
97
- color-scheme: light dark;
98
189
  font: inherit;
99
190
  line-height: var(--ui-line-height-md);
100
191
  box-shadow: var(--ui-control-inset);
192
+ outline: none;
101
193
  }
102
194
 
103
- [data-component~="ui-listbox"] option,
104
- [data-component~="ui-listbox"] optgroup {
105
- padding: var(--ui-space-2);
195
+ .choices {
196
+ max-block-size: calc(max(2, var(--_rows, 5)) * var(--ui-control-size-md));
197
+ }
198
+
199
+ [data-component~="ui-listbox"]:not([data-enhanced]) {
200
+ padding: 0;
201
+ border: 0;
202
+ background: transparent;
203
+ box-shadow: none;
204
+ }
205
+
206
+ [data-component~="ui-listbox"]:not([data-enhanced]) .choices,
207
+ [data-component~="ui-listbox"][data-enhanced] .fallback {
208
+ display: none;
209
+ }
210
+
211
+ .fallback {
212
+ box-sizing: border-box;
213
+ inline-size: 100%;
106
214
  font: inherit;
107
215
  }
108
216
 
217
+ .validity {
218
+ position: absolute;
219
+ inline-size: 1px;
220
+ block-size: 1px;
221
+ overflow: hidden;
222
+ clip-path: inset(50%);
223
+ opacity: 0;
224
+ pointer-events: none;
225
+ }
226
+
109
227
  [data-component~="ui-listbox"]:focus-visible {
110
228
  border-color: var(--ui-control-focus);
111
229
  outline: 2px solid var(--ui-focus-ring);
@@ -113,12 +231,11 @@ useComponentHost(controllerModule.default, {
113
231
  box-shadow: var(--ui-listbox-focus-shadow, var(--ui-focus-halo));
114
232
  }
115
233
 
116
- [data-component~="ui-listbox"][aria-invalid="true"],
117
- [data-component~="ui-listbox"]:is(:user-invalid, [data-user-invalid]) {
234
+ [data-component~="ui-listbox"][aria-invalid="true"] {
118
235
  border-color: var(--ui-listbox-invalid-border, var(--ui-field-danger, var(--ui-danger)));
119
236
  }
120
237
 
121
- [data-component~="ui-listbox"]:disabled {
238
+ [data-component~="ui-listbox"][aria-disabled="true"] {
122
239
  background: var(--ui-control-surface-disabled);
123
240
  color: var(--ui-disabled-text);
124
241
  box-shadow: none;
@@ -86,18 +86,14 @@ const hostState = computed(() =>
86
86
  align-items: flex-start;
87
87
  gap: var(--ui-search-result-row-gap, var(--ui-space-3));
88
88
  background: var(--ui-search-result-row-surface, transparent);
89
- border: none;
90
- border-block-end: 1px solid var(--ui-search-result-row-border, var(--ui-border-divider));
89
+ border: 1px solid var(--ui-search-result-row-border, transparent);
90
+ border-radius: var(--ui-radius-md);
91
91
  color: inherit;
92
92
  cursor: pointer;
93
93
  text-align: left;
94
94
  transition: background-color var(--ui-motion-fast) var(--ui-motion-ease);
95
95
  }
96
96
 
97
- [data-component~="ui-search-result-row"]:last-child {
98
- border-block-end: none;
99
- }
100
-
101
97
  [data-component~="ui-search-result-row"]:hover:enabled {
102
98
  background: var(
103
99
  --ui-search-result-row-hover-surface,
@@ -180,16 +180,6 @@ dialog::backdrop {
180
180
 
181
181
  .search {
182
182
  padding: var(--ui-space-3);
183
- border-block-end: 1px solid var(--ui-border-divider);
184
- transition:
185
- border-color var(--ui-motion-fast) var(--ui-motion-ease),
186
- box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
187
- }
188
-
189
- /* The search region shows where typing goes, whatever the author put in it. */
190
- .search:focus-within {
191
- border-block-end-color: var(--_ui-search-shell-focus-color, var(--ui-control-focus));
192
- box-shadow: inset 0 -1px 0 var(--_ui-search-shell-focus-color, var(--ui-control-focus));
193
183
  }
194
184
 
195
185
  :slotted(input[slot="search"]) {
@@ -206,7 +196,7 @@ dialog::backdrop {
206
196
  }
207
197
 
208
198
  :slotted(input[slot="search"]:focus-visible) {
209
- border-color: var(--ui-control-focus);
199
+ border-color: var(--_ui-search-shell-focus-color, var(--ui-control-focus));
210
200
  outline: 2px solid var(--ui-focus-ring);
211
201
  outline-offset: 2px;
212
202
  }
@@ -220,7 +210,7 @@ dialog::backdrop {
220
210
  }
221
211
 
222
212
  .status {
223
- border-block-end: 1px solid var(--ui-border-divider);
213
+ padding-block-start: 0;
224
214
  }
225
215
 
226
216
  /* Laid out like the dialog's action row: actions right-aligned, spaced as buttons, no fill. */
@@ -231,7 +221,6 @@ dialog::backdrop {
231
221
  justify-content: flex-end;
232
222
  gap: var(--ui-space-2);
233
223
  padding: var(--ui-space-3) var(--ui-space-4);
234
- border-block-start: 1px solid var(--ui-border-divider);
235
224
  }
236
225
 
237
226
  .status:empty,
package/vue/UiSelect.vue CHANGED
@@ -142,7 +142,7 @@ useComponentHost(controllerModule.default, {
142
142
  background-size: 1.125rem 1.125rem;
143
143
  }
144
144
 
145
- [data-component~="ui-select"]:hover:not(:focus):not(:disabled) {
145
+ [data-component~="ui-select"]:hover:not(:focus):not(:disabled):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])) {
146
146
  border-color: var(
147
147
  --ui-select-border-hover,
148
148
  var(--ui-control-border-hover, var(--ui-text-secondary))
package/vue/UiSpinner.vue CHANGED
@@ -45,21 +45,27 @@ function attribute(value: unknown): any {
45
45
  :aria-label="typeof (({ true: label, false: null })[`${label !== ''}`]) === 'boolean'
46
46
  ? String(({ true: label, false: null })[`${label !== ''}`])
47
47
  : attribute(({ true: label, false: null })[`${label !== ''}`])"
48
+ :aria-live="typeof (({ true: 'polite', false: null })[`${label !== ''}`]) === 'boolean'
49
+ ? String(({ true: 'polite', false: null })[`${label !== ''}`])
50
+ : attribute(({ true: 'polite', false: null })[`${label !== ''}`])"
48
51
  :aria-hidden="typeof (({ true: null, false: 'true' })[`${label !== ''}`]) === 'boolean'
49
52
  ? String(({ true: null, false: 'true' })[`${label !== ''}`])
50
53
  : attribute(({ true: null, false: 'true' })[`${label !== ''}`])"
51
54
  :data-ui-spinner-state="hostState || undefined"
52
- ></span>
55
+ ><svg viewBox="0 0 50 50" fill="none" aria-hidden="true" focusable="false">
56
+ <circle class="track" cx="25" cy="25" r="20"></circle>
57
+ <circle class="arc" cx="25" cy="25" r="20"></circle>
58
+ </svg></span>
53
59
  </template>
54
60
 
55
61
  <style scoped>
56
- /* Something is on its way. The ring chases in the current text colour; with reduced motion it holds still,
57
- and the label (or the text beside it) still says what is happening. */
62
+ /* A rounded SVG arc grows and recedes over a quiet full-circle track. */
58
63
  [data-component~="ui-spinner"] {
59
64
  display: inline-flex;
60
65
  flex: none;
61
66
  align-items: center;
62
67
  justify-content: center;
68
+ box-sizing: border-box;
63
69
  inline-size: 1em;
64
70
  block-size: 1em;
65
71
  color: currentColor;
@@ -67,36 +73,57 @@ function attribute(value: unknown): any {
67
73
  line-height: 1;
68
74
  }
69
75
 
70
- .ring {
76
+ [data-component~="ui-spinner"][data-ui-spinner-state~="size=sm"] {
77
+ font-size: var(--ui-font-size-md);
78
+ }
79
+
80
+ svg {
71
81
  display: block;
72
- box-sizing: border-box;
73
82
  inline-size: 100%;
74
83
  block-size: 100%;
75
- border: 2px solid transparent;
76
- border-block-start-color: currentColor;
77
- border-inline-end-color: color-mix(in srgb, currentColor 52%, transparent);
78
- border-radius: 50%;
79
- animation: ui-spinner-chase 1s linear infinite;
84
+ animation: ui-spinner-rotate 2s linear infinite;
80
85
  }
81
86
 
82
- [data-component~="ui-spinner"][data-ui-spinner-state~="size=sm"] {
83
- font-size: var(--ui-font-size-md);
87
+ circle {
88
+ stroke-width: 3;
89
+ stroke-linecap: round;
90
+ }
91
+
92
+ .track {
93
+ stroke: color-mix(in srgb, currentColor 16%, transparent);
94
+ }
95
+
96
+ .arc {
97
+ stroke: currentColor;
98
+ stroke-dasharray: 90, 150;
99
+ stroke-dashoffset: 0;
100
+ animation: ui-spinner-dash 1.5s ease-in-out infinite;
84
101
  }
85
102
 
86
- @keyframes ui-spinner-chase {
103
+ @keyframes ui-spinner-rotate {
104
+ 100% {
105
+ transform: rotate(1turn);
106
+ }
107
+ }
108
+
109
+ @keyframes ui-spinner-dash {
87
110
  0% {
88
- transform: rotate(0);
111
+ stroke-dasharray: 1, 150;
112
+ stroke-dashoffset: 0;
89
113
  }
90
- 70% {
91
- transform: rotate(160deg);
114
+ 50% {
115
+ stroke-dasharray: 90, 150;
116
+ stroke-dashoffset: -35;
92
117
  }
93
118
  100% {
94
- transform: rotate(1turn);
119
+ stroke-dasharray: 90, 150;
120
+ stroke-dashoffset: -124;
95
121
  }
96
122
  }
97
123
 
98
124
  @media (prefers-reduced-motion: reduce) {
99
- .ring {
125
+ svg,
126
+ .arc {
100
127
  animation: none;
101
128
  }
102
129
  }
@@ -129,7 +129,7 @@ useComponentHost(controllerModule.default, {
129
129
  opacity: 1;
130
130
  }
131
131
 
132
- [data-component~="ui-textarea"]:hover:not(:focus):not(:disabled) {
132
+ [data-component~="ui-textarea"]:hover:not(:focus):not(:disabled):not(:read-only):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])) {
133
133
  border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
134
134
  }
135
135
 
package/vue/UiTooltip.vue CHANGED
@@ -256,14 +256,14 @@ useComponentHost(controllerModule.default, {
256
256
  inset-inline-start: auto;
257
257
  inset-inline-end: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - 0.5px);
258
258
  border-inline-end-width: 1px;
259
- border-block-end-width: 1px;
259
+ border-block-start-width: 1px;
260
260
  }
261
261
 
262
262
  [data-component~="ui-tooltip"][data-ui-actual-placement="right"] .surface::after {
263
263
  inset-inline-start: calc(var(--_ui-tooltip-arrow-size, 0.625rem) / -2 - 0.5px);
264
264
  inset-inline-end: auto;
265
265
  border-inline-start-width: 1px;
266
- border-block-start-width: 1px;
266
+ border-block-end-width: 1px;
267
267
  }
268
268
 
269
269
  [data-component~="ui-tooltip"][data-ui-actual-placement="left"][data-ui-actual-align="start"]
@@ -41,6 +41,7 @@ var UiAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
41
41
  /** The values the styles' :host-state() rules test. */
42
42
  const hostState = computed(() => [
43
43
  props.size && `size size=${props.size}`,
44
+ hasImage.value && "hasImage",
44
45
  props.shape && `shape shape=${props.shape}`,
45
46
  props.active && "active"
46
47
  ].filter(Boolean).join(" "));
@@ -80,6 +81,6 @@ var UiAvatar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
80
81
  ], 16, _hoisted_1);
81
82
  };
82
83
  }
83
- }), [["__scopeId", "data-v-f9a69ac3"]]);
84
+ }), [["__scopeId", "data-v-f0891fb1"]]);
84
85
  //#endregion
85
86
  export { UiAvatar_default as t };
@@ -24,6 +24,6 @@ var UiBadge_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
24
24
  return openBlock(), createElementBlock("span", mergeProps({ "data-component": "ui-badge" }, _ctx.$attrs, { "data-ui-badge-state": hostState.value || void 0 }), [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 16, _hoisted_1);
25
25
  };
26
26
  }
27
- }), [["__scopeId", "data-v-38a29166"]]);
27
+ }), [["__scopeId", "data-v-fe098822"]]);
28
28
  //#endregion
29
29
  export { UiBadge_default as t };
@@ -139,6 +139,6 @@ var UiButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
139
139
  }), [__props.loading || __props.pending ? (openBlock(), createElementBlock("span", _hoisted_4, [createVNode(UiSpinner_default, { size: "sm" })])) : createCommentVNode("v-if", true), renderSlot(_ctx.$slots, "default", {}, void 0, true)], 16, _hoisted_3));
140
140
  };
141
141
  }
142
- }), [["__scopeId", "data-v-84ef27e9"]]);
142
+ }), [["__scopeId", "data-v-a89a1895"]]);
143
143
  //#endregion
144
144
  export { UiButton_default as t };
@@ -105,6 +105,6 @@ var UiCheckbox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
105
105
  }, 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);
106
106
  };
107
107
  }
108
- }), [["__scopeId", "data-v-62f133c7"]]);
108
+ }), [["__scopeId", "data-v-9a218638"]]);
109
109
  //#endregion
110
110
  export { UiCheckbox_default as t };
@@ -55,6 +55,7 @@ var _hoisted_16 = {
55
55
  class: "group"
56
56
  };
57
57
  var _hoisted_17 = [
58
+ "data-multiple",
58
59
  "id",
59
60
  "aria-selected",
60
61
  "aria-disabled",
@@ -74,7 +75,11 @@ var _hoisted_23 = {
74
75
  key: 1,
75
76
  class: "primary"
76
77
  };
77
- var _hoisted_24 = ["id", "data-index"];
78
+ var _hoisted_24 = [
79
+ "data-multiple",
80
+ "id",
81
+ "data-index"
82
+ ];
78
83
  var _hoisted_25 = {
79
84
  key: 1,
80
85
  class: "message"
@@ -521,6 +526,8 @@ var UiCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
521
526
  key: row.id,
522
527
  class: normalizeClass(["option", { active: row.index === active.value }]),
523
528
  role: "option",
529
+ "data-ui-choice-option": "",
530
+ "data-multiple": __props.multiple ? "" : void 0,
524
531
  id: `${uid.value}-option-${row.index}`,
525
532
  "aria-selected": row.selected,
526
533
  "aria-disabled": row.disabled,
@@ -548,7 +555,9 @@ var UiCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
548
555
  key: 0,
549
556
  class: normalizeClass(["option", { active: createIndex.value === active.value }]),
550
557
  role: "option",
558
+ "data-ui-choice-option": "",
551
559
  "aria-selected": "false",
560
+ "data-multiple": __props.multiple ? "" : void 0,
552
561
  id: `${uid.value}-option-${createIndex.value}`,
553
562
  "data-index": createIndex.value
554
563
  }, toDisplayString(`Create “${raw.value}”`), 11, _hoisted_24)) : createCommentVNode("v-if", true),
@@ -567,6 +576,6 @@ var UiCombobox_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
567
576
  ], 16, _hoisted_1);
568
577
  };
569
578
  }
570
- }), [["__scopeId", "data-v-87a4808b"]]);
579
+ }), [["__scopeId", "data-v-f90db7fa"]]);
571
580
  //#endregion
572
581
  export { UiCombobox_default as t };
@@ -95,6 +95,6 @@ var UiIconButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
95
95
  })) : createCommentVNode("v-if", true), createElementVNode("span", _hoisted_2, [renderSlot(_ctx.$slots, "default")])], 16, _hoisted_1);
96
96
  };
97
97
  }
98
- }), [["__scopeId", "data-v-e99fb642"]]);
98
+ }), [["__scopeId", "data-v-ae1ec9d2"]]);
99
99
  //#endregion
100
100
  export { UiIconButton_default as t };
@@ -66,6 +66,6 @@ var UiInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
66
66
  }), null, 16, _hoisted_1)), [[vModelDynamic, model.value]]);
67
67
  };
68
68
  }
69
- }), [["__scopeId", "data-v-aa3c35f4"]]);
69
+ }), [["__scopeId", "data-v-0d457505"]]);
70
70
  //#endregion
71
71
  export { UiInput_default as t };
@@ -41,6 +41,6 @@ var UiInputGroup_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @_
41
41
  ], 16, _hoisted_1);
42
42
  };
43
43
  }
44
- }), [["__scopeId", "data-v-8627fd48"]]);
44
+ }), [["__scopeId", "data-v-5ed34845"]]);
45
45
  //#endregion
46
46
  export { UiInputGroup_default as t };