@threadlabs/looma 0.12.2 → 0.12.4

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.
@@ -0,0 +1,180 @@
1
+ <!-- Generated by HTML Next 1.0.0-alpha.5 for Vue 3.5. Do not edit. -->
2
+ <script setup lang="ts">
3
+ defineOptions({ inheritAttrs: false })
4
+
5
+ withDefaults(
6
+ defineProps<{
7
+ as?: 'button' | 'a'
8
+ current?: boolean | 'page' | 'step' | 'location'
9
+ href?: string
10
+ rel?: string
11
+ target?: string
12
+ }>(),
13
+ {
14
+ as: 'button',
15
+ current: false,
16
+ },
17
+ )
18
+
19
+ function text(value: unknown): string {
20
+ if (Array.isArray(value)) return value.map(text).join(' ')
21
+ return value === null || value === undefined || typeof value === 'object' ? '' : String(value)
22
+ }
23
+
24
+ function attribute(value: unknown): any {
25
+ if (
26
+ value === null || value === undefined || value === false
27
+ || (typeof value === 'object' && !Array.isArray(value))
28
+ ) return undefined
29
+ return value === true ? '' : text(value)
30
+ }
31
+ </script>
32
+
33
+ <template>
34
+ <component
35
+ :is="as"
36
+ data-component="ui-nav-item"
37
+ v-bind="$attrs"
38
+ :type="attribute(({ true: 'button', false: null })[`${!href}`])"
39
+ :href="href"
40
+ :target="target"
41
+ :rel="rel"
42
+ :aria-current="typeof (({ true: 'page', false: null, page: 'page', step: 'step', location: 'location' })[
43
+ `${current}`
44
+ ]) === 'boolean'
45
+ ? String(
46
+ ({ true: 'page', false: null, page: 'page', step: 'step', location: 'location' })[`${current}`],
47
+ )
48
+ : attribute(
49
+ ({ true: 'page', false: null, page: 'page', step: 'step', location: 'location' })[`${current}`],
50
+ )"
51
+ >
52
+ <span class="indicator" aria-hidden="true"></span>
53
+ <span class="leading"><slot name="leading" /></span>
54
+ <span class="content"><span class="label"><slot /></span>
55
+ <span class="description"><slot name="description" /></span></span>
56
+ </component>
57
+ </template>
58
+
59
+ <style scoped>
60
+ /* One destination in a side or rail navigation: an icon to find it by (leading), its name (the
61
+ default slot), and an optional line under it (description), such as the record a section
62
+ belongs to. Label and description are one line each and end in an ellipsis, so every item in a
63
+ navigation has the same height and the rail never grows sideways. */
64
+ [data-component~="ui-nav-item"] {
65
+ --_indicator-width: var(--ui-nav-item-indicator-width, 3px);
66
+ --_indicator-color: var(--ui-nav-item-indicator-color, var(--ui-accent));
67
+ position: relative;
68
+ box-sizing: border-box;
69
+ display: flex;
70
+ align-items: center;
71
+ gap: var(--ui-space-3);
72
+ inline-size: 100%;
73
+ min-inline-size: 0;
74
+ min-block-size: var(--ui-control-size, 2.5rem);
75
+ margin: 0;
76
+ padding-block: var(--ui-space-2);
77
+ padding-inline: var(--ui-space-3);
78
+ border: 0;
79
+ border-radius: var(--ui-radius-md);
80
+ background: transparent;
81
+ color: var(--ui-text-secondary);
82
+ font: inherit;
83
+ font-weight: var(--ui-font-medium);
84
+ text-align: start;
85
+ text-decoration: none;
86
+ cursor: pointer;
87
+ appearance: none;
88
+ transition:
89
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
90
+ color var(--ui-motion-fast) var(--ui-motion-ease);
91
+ }
92
+
93
+ [data-component~="ui-nav-item"]:hover:not([aria-current]) {
94
+ background: var(--ui-surface-hover);
95
+ color: var(--ui-text-primary);
96
+ }
97
+
98
+ /* The ring is an outline, drawn inside the item: forced colors keep an outline where they drop a
99
+ box shadow, and a scrolling rail cannot clip a ring that stays within the item. */
100
+ [data-component~="ui-nav-item"]:focus-visible {
101
+ outline: 2px solid var(--ui-focus-ring);
102
+ outline-offset: -2px;
103
+ }
104
+
105
+ [data-component~="ui-nav-item"][aria-current] {
106
+ background: var(--ui-nav-item-current-surface, var(--ui-accent-soft));
107
+ color: var(--ui-accent-subtle-text, var(--ui-text-primary));
108
+ font-weight: var(--ui-font-semibold);
109
+ }
110
+
111
+ /* The bar on the start edge is a border, not a fill: forced colors replace backgrounds but keep a
112
+ border, so the current item stays marked in high contrast. Logical edges mirror it in a
113
+ right-to-left page. */
114
+ .indicator {
115
+ position: absolute;
116
+ inset-block: var(--ui-space-2);
117
+ inset-inline-start: 0;
118
+ display: none;
119
+ border-inline-start: var(--_indicator-width) solid var(--_indicator-color);
120
+ border-radius: var(--ui-radius-round);
121
+ }
122
+
123
+ [data-component~="ui-nav-item"][aria-current] .indicator {
124
+ display: block;
125
+ }
126
+
127
+ @media (forced-colors: active) {
128
+ .indicator {
129
+ border-inline-start-color: Highlight;
130
+ }
131
+ }
132
+
133
+ .leading {
134
+ display: inline-flex;
135
+ flex: none;
136
+ align-items: center;
137
+ color: inherit;
138
+ font-size: var(--ui-font-size-lg);
139
+ }
140
+
141
+ .content {
142
+ display: flex;
143
+ flex: 1;
144
+ flex-direction: column;
145
+ gap: var(--ui-space-0-5, 2px);
146
+ min-inline-size: 0;
147
+ }
148
+
149
+ .label,
150
+ .description {
151
+ display: block;
152
+ min-inline-size: 0;
153
+ overflow: hidden;
154
+ text-overflow: ellipsis;
155
+ white-space: nowrap;
156
+ }
157
+
158
+ .label {
159
+ font-size: var(--ui-font-size-md);
160
+ line-height: var(--ui-line-height-tight);
161
+ }
162
+
163
+ .description {
164
+ color: var(--ui-text-muted);
165
+ font-size: var(--ui-font-size-sm);
166
+ font-weight: var(--ui-font-normal);
167
+ line-height: var(--ui-line-height-tight);
168
+ }
169
+
170
+ /* An unused region takes no space. */
171
+ .leading:empty,
172
+ .description:empty {
173
+ display: none;
174
+ }
175
+
176
+ /* A component that sets its display still honours the hidden attribute on its root. */
177
+ [data-component~="ui-nav-item"][hidden] {
178
+ display: none;
179
+ }
180
+ </style>
@@ -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-0dbc98f0"]]);
27
+ }), [["__scopeId", "data-v-4fe703f2"]]);
28
28
  //#endregion
29
29
  export { UiBadge_default as t };
@@ -25,6 +25,12 @@ var _hoisted_4 = [
25
25
  "height",
26
26
  "rx"
27
27
  ];
28
+ var _hoisted_5 = [
29
+ "x1",
30
+ "x2",
31
+ "y1",
32
+ "y2"
33
+ ];
28
34
  //#endregion
29
35
  //#region .build/vue/UiIcon.vue
30
36
  var UiIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -68,11 +74,18 @@ var UiIcon_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
68
74
  width: shape.width,
69
75
  height: shape.height,
70
76
  rx: shape.rx
71
- }, null, 8, _hoisted_4)) : createCommentVNode("v-if", true)
77
+ }, null, 8, _hoisted_4)) : createCommentVNode("v-if", true),
78
+ shape.tag === "line" ? (openBlock(), createElementBlock("line", {
79
+ key: 3,
80
+ x1: shape.x1,
81
+ x2: shape.x2,
82
+ y1: shape.y1,
83
+ y2: shape.y2
84
+ }, null, 8, _hoisted_5)) : createCommentVNode("v-if", true)
72
85
  ]);
73
86
  }), 128))]))], 16);
74
87
  };
75
88
  }
76
- }), [["__scopeId", "data-v-3d48bd86"]]);
89
+ }), [["__scopeId", "data-v-6c3d73c1"]]);
77
90
  //#endregion
78
91
  export { UiIcon_default as t };
@@ -0,0 +1,81 @@
1
+ import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
2
+ import { createBlock, createElementVNode, defineComponent, mergeProps, openBlock, renderSlot, resolveDynamicComponent, withCtx } from "vue";
3
+ //#region .build/vue/UiNavItem.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = { class: "leading" };
5
+ var _hoisted_2 = { class: "content" };
6
+ var _hoisted_3 = { class: "label" };
7
+ var _hoisted_4 = { class: "description" };
8
+ //#endregion
9
+ //#region .build/vue/UiNavItem.vue
10
+ var UiNavItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
11
+ inheritAttrs: false,
12
+ __name: "UiNavItem",
13
+ props: {
14
+ as: { default: "button" },
15
+ current: {
16
+ type: [Boolean, String],
17
+ default: false
18
+ },
19
+ href: {},
20
+ rel: {},
21
+ target: {}
22
+ },
23
+ setup(__props) {
24
+ function text(value) {
25
+ if (Array.isArray(value)) return value.map(text).join(" ");
26
+ return value === null || value === void 0 || typeof value === "object" ? "" : String(value);
27
+ }
28
+ function attribute(value) {
29
+ if (value === null || value === void 0 || value === false || typeof value === "object" && !Array.isArray(value)) return void 0;
30
+ return value === true ? "" : text(value);
31
+ }
32
+ return (_ctx, _cache) => {
33
+ return openBlock(), createBlock(resolveDynamicComponent(__props.as), mergeProps({ "data-component": "ui-nav-item" }, _ctx.$attrs, {
34
+ type: attribute({
35
+ true: "button",
36
+ false: null
37
+ }[`${!__props.href}`]),
38
+ href: __props.href,
39
+ target: __props.target,
40
+ rel: __props.rel,
41
+ "aria-current": typeof {
42
+ true: "page",
43
+ false: null,
44
+ page: "page",
45
+ step: "step",
46
+ location: "location"
47
+ }[`${__props.current}`] === "boolean" ? String({
48
+ true: "page",
49
+ false: null,
50
+ page: "page",
51
+ step: "step",
52
+ location: "location"
53
+ }[`${__props.current}`]) : attribute({
54
+ true: "page",
55
+ false: null,
56
+ page: "page",
57
+ step: "step",
58
+ location: "location"
59
+ }[`${__props.current}`])
60
+ }), {
61
+ default: withCtx(() => [
62
+ _cache[0] || (_cache[0] = createElementVNode("span", {
63
+ class: "indicator",
64
+ "aria-hidden": "true"
65
+ }, null, -1)),
66
+ createElementVNode("span", _hoisted_1, [renderSlot(_ctx.$slots, "leading", {}, void 0, true)]),
67
+ createElementVNode("span", _hoisted_2, [createElementVNode("span", _hoisted_3, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]), createElementVNode("span", _hoisted_4, [renderSlot(_ctx.$slots, "description", {}, void 0, true)])])
68
+ ]),
69
+ _: 3
70
+ }, 16, [
71
+ "type",
72
+ "href",
73
+ "target",
74
+ "rel",
75
+ "aria-current"
76
+ ]);
77
+ };
78
+ }
79
+ }), [["__scopeId", "data-v-aa140273"]]);
80
+ //#endregion
81
+ export { UiNavItem_default as t };
@@ -169,10 +169,11 @@
169
169
  display: none;
170
170
  }
171
171
 
172
- [data-component~="ui-badge"][data-v-0dbc98f0] {
172
+ [data-component~="ui-badge"][data-v-4fe703f2] {
173
173
  --_badge-surface: var(--ui-surface-subtle);
174
174
  --_badge-text: var(--ui-text-secondary);
175
- --_badge-border: color-mix(in srgb, var(--ui-text-secondary) 30%, transparent);
175
+ /* Every tone's edge is its fill, so it is unseen until forced colors draw it. */
176
+ --_badge-border: var(--ui-surface-subtle);
176
177
 
177
178
  display: inline-flex;
178
179
  align-items: center;
@@ -191,12 +192,12 @@
191
192
  white-space: nowrap;
192
193
  }
193
194
 
194
- /* Centre the glyphs, not the line box: a label without descenders otherwise reads high. */
195
195
  /* Centre the glyphs, not the line box: a label without descenders otherwise reads high.
196
- * Trimming applies to block containers, so the box is a block with centred content. */
196
+ * Trimming applies to block containers; an inline-block is one and, like the inline-flex it
197
+ * replaces, still sizes to its label rather than filling its container. */
197
198
  @supports (text-box-trim: trim-both) {
198
- [data-component~="ui-badge"][data-v-0dbc98f0] {
199
- display: block;
199
+ [data-component~="ui-badge"][data-v-4fe703f2] {
200
+ display: inline-block;
200
201
  min-block-size: var(--ui-badge-min-block-size, 1.5rem);
201
202
  text-align: center;
202
203
  align-content: center;
@@ -204,52 +205,52 @@
204
205
  text-box-edge: cap alphabetic;
205
206
  }
206
207
  }
207
- [data-component~="ui-badge"][data-ui-badge-state~="tone=accent"][data-v-0dbc98f0] {
208
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=accent"][data-v-4fe703f2] {
208
209
  --_badge-surface: var(--ui-accent-strong-surface, var(--ui-accent-solid));
209
210
  --_badge-border: var(--ui-accent-strong-surface, var(--ui-accent-solid));
210
211
  --_badge-text: var(--ui-accent-on-strong, var(--ui-text-on-accent));
211
212
  }
212
- [data-component~="ui-badge"][data-ui-badge-state~="tone=danger"][data-v-0dbc98f0] {
213
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=danger"][data-v-4fe703f2] {
213
214
  --_badge-surface: var(--ui-danger-strong-surface, var(--ui-danger-solid));
214
215
  --_badge-border: var(--ui-danger-strong-surface, var(--ui-danger-solid));
215
216
  --_badge-text: var(--ui-danger-on-strong, var(--ui-text-on-accent));
216
217
  }
217
- [data-component~="ui-badge"][data-ui-badge-state~="tone=success"][data-v-0dbc98f0] {
218
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=success"][data-v-4fe703f2] {
218
219
  --_badge-surface: var(--ui-success-strong-surface, var(--ui-success-solid));
219
220
  --_badge-border: var(--ui-success-strong-surface, var(--ui-success-solid));
220
221
  --_badge-text: var(--ui-success-on-strong, var(--ui-text-on-accent));
221
222
  }
222
- [data-component~="ui-badge"][data-ui-badge-state~="tone=warning"][data-v-0dbc98f0] {
223
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=warning"][data-v-4fe703f2] {
223
224
  --_badge-surface: var(--ui-warning-strong-surface, var(--ui-warning-solid));
224
225
  --_badge-border: var(--ui-warning-strong-surface, var(--ui-warning-solid));
225
226
  --_badge-text: var(--ui-warning-on-strong, var(--ui-text-on-accent));
226
227
  }
227
- [data-component~="ui-badge"][data-ui-badge-state~="tone=info"][data-v-0dbc98f0] {
228
+ [data-component~="ui-badge"][data-ui-badge-state~="tone=info"][data-v-4fe703f2] {
228
229
  --_badge-surface: var(--ui-info-strong-surface, var(--ui-info-solid));
229
230
  --_badge-border: var(--ui-info-strong-surface, var(--ui-info-solid));
230
231
  --_badge-text: var(--ui-info-on-strong, var(--ui-text-on-accent));
231
232
  }
232
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=accent"][data-v-0dbc98f0] {
233
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=accent"][data-v-4fe703f2] {
233
234
  --_badge-surface: var(--ui-accent-soft);
234
235
  --_badge-border: var(--ui-accent-soft);
235
236
  --_badge-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
236
237
  }
237
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=danger"][data-v-0dbc98f0] {
238
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=danger"][data-v-4fe703f2] {
238
239
  --_badge-surface: var(--ui-danger-soft);
239
240
  --_badge-border: var(--ui-danger-soft);
240
241
  --_badge-text: var(--ui-danger-subtle-text, var(--ui-danger-solid));
241
242
  }
242
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=success"][data-v-0dbc98f0] {
243
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=success"][data-v-4fe703f2] {
243
244
  --_badge-surface: var(--ui-success-soft);
244
245
  --_badge-border: var(--ui-success-soft);
245
246
  --_badge-text: var(--ui-success-subtle-text, var(--ui-success-solid));
246
247
  }
247
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=warning"][data-v-0dbc98f0] {
248
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=warning"][data-v-4fe703f2] {
248
249
  --_badge-surface: var(--ui-warning-soft);
249
250
  --_badge-border: var(--ui-warning-soft);
250
251
  --_badge-text: var(--ui-warning-subtle-text, var(--ui-warning-solid));
251
252
  }
252
- [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=info"][data-v-0dbc98f0] {
253
+ [data-component~="ui-badge"][data-ui-badge-state~="variant=subtle"][data-ui-badge-state~="tone=info"][data-v-4fe703f2] {
253
254
  --_badge-surface: var(--ui-info-soft);
254
255
  --_badge-border: var(--ui-info-soft);
255
256
  --_badge-text: var(--ui-info-subtle-text, var(--ui-info-solid));
@@ -258,7 +259,7 @@
258
259
  /* A tag is flat at the start and points at the end. The point is cut from the box, so it has no
259
260
  outline to follow: the edge is the fill. The end padding grows by the point's depth so the
260
261
  label never runs into it. */
261
- [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-0dbc98f0] {
262
+ [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-4fe703f2] {
262
263
  --_badge-point: var(--ui-badge-point, var(--ui-space-2));
263
264
 
264
265
  border-color: transparent;
@@ -272,7 +273,7 @@
272
273
  0 100%
273
274
  );
274
275
  }
275
- [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-0dbc98f0]:dir(rtl) {
276
+ [data-component~="ui-badge"][data-ui-badge-state~="shape=tag"][data-v-4fe703f2]:dir(rtl) {
276
277
  padding-inline-end: var(--ui-badge-padding-inline, var(--ui-space-2));
277
278
  padding-inline-start: calc(
278
279
  var(--ui-badge-padding-inline, var(--ui-space-2)) + var(--_badge-point)
@@ -281,24 +282,24 @@
281
282
  }
282
283
 
283
284
  /* A component that sets its display still honours the hidden attribute on its root. */
284
- [data-component~="ui-badge"][hidden][data-v-0dbc98f0] {
285
+ [data-component~="ui-badge"][hidden][data-v-4fe703f2] {
285
286
  display: none;
286
287
  }
287
288
 
288
- [data-component~="ui-icon"][data-v-3d48bd86] {
289
+ [data-component~="ui-icon"][data-v-6c3d73c1] {
289
290
  display: inline-flex;
290
291
  flex: none;
291
292
  inline-size: var(--ui-icon-size, 1em);
292
293
  block-size: var(--ui-icon-size, 1em);
293
294
  }
294
- svg[data-v-3d48bd86] {
295
+ svg[data-v-6c3d73c1] {
295
296
  inline-size: 100%;
296
297
  block-size: 100%;
297
298
  stroke-width: var(--ui-icon-stroke-width, 2);
298
299
  }
299
300
 
300
301
  /* A component that sets its display still honours the hidden attribute on its root. */
301
- [data-component~="ui-icon"][hidden][data-v-3d48bd86] {
302
+ [data-component~="ui-icon"][hidden][data-v-6c3d73c1] {
302
303
  display: none;
303
304
  }
304
305
 
@@ -3609,6 +3610,118 @@ svg[data-v-c322b7ed-s] {
3609
3610
  display: none;
3610
3611
  }
3611
3612
 
3613
+ /* One destination in a side or rail navigation: an icon to find it by (leading), its name (the
3614
+ default slot), and an optional line under it (description), such as the record a section
3615
+ belongs to. Label and description are one line each and end in an ellipsis, so every item in a
3616
+ navigation has the same height and the rail never grows sideways. */
3617
+ [data-component~="ui-nav-item"][data-v-aa140273] {
3618
+ --_indicator-width: var(--ui-nav-item-indicator-width, 3px);
3619
+ --_indicator-color: var(--ui-nav-item-indicator-color, var(--ui-accent));
3620
+ position: relative;
3621
+ box-sizing: border-box;
3622
+ display: flex;
3623
+ align-items: center;
3624
+ gap: var(--ui-space-3);
3625
+ inline-size: 100%;
3626
+ min-inline-size: 0;
3627
+ min-block-size: var(--ui-control-size, 2.5rem);
3628
+ margin: 0;
3629
+ padding-block: var(--ui-space-2);
3630
+ padding-inline: var(--ui-space-3);
3631
+ border: 0;
3632
+ border-radius: var(--ui-radius-md);
3633
+ background: transparent;
3634
+ color: var(--ui-text-secondary);
3635
+ font: inherit;
3636
+ font-weight: var(--ui-font-medium);
3637
+ text-align: start;
3638
+ text-decoration: none;
3639
+ cursor: pointer;
3640
+ appearance: none;
3641
+ transition:
3642
+ background-color var(--ui-motion-fast) var(--ui-motion-ease),
3643
+ color var(--ui-motion-fast) var(--ui-motion-ease);
3644
+ }
3645
+ [data-component~="ui-nav-item"][data-v-aa140273]:hover:not([aria-current]) {
3646
+ background: var(--ui-surface-hover);
3647
+ color: var(--ui-text-primary);
3648
+ }
3649
+
3650
+ /* The ring is an outline, drawn inside the item: forced colors keep an outline where they drop a
3651
+ box shadow, and a scrolling rail cannot clip a ring that stays within the item. */
3652
+ [data-component~="ui-nav-item"][data-v-aa140273]:focus-visible {
3653
+ outline: 2px solid var(--ui-focus-ring);
3654
+ outline-offset: -2px;
3655
+ }
3656
+ [data-component~="ui-nav-item"][aria-current][data-v-aa140273] {
3657
+ background: var(--ui-nav-item-current-surface, var(--ui-accent-soft));
3658
+ color: var(--ui-accent-subtle-text, var(--ui-text-primary));
3659
+ font-weight: var(--ui-font-semibold);
3660
+ }
3661
+
3662
+ /* The bar on the start edge is a border, not a fill: forced colors replace backgrounds but keep a
3663
+ border, so the current item stays marked in high contrast. Logical edges mirror it in a
3664
+ right-to-left page. */
3665
+ .indicator[data-v-aa140273] {
3666
+ position: absolute;
3667
+ inset-block: var(--ui-space-2);
3668
+ inset-inline-start: 0;
3669
+ display: none;
3670
+ border-inline-start: var(--_indicator-width) solid var(--_indicator-color);
3671
+ border-radius: var(--ui-radius-round);
3672
+ }
3673
+ [data-component~="ui-nav-item"][aria-current] .indicator[data-v-aa140273] {
3674
+ display: block;
3675
+ }
3676
+ @media (forced-colors: active) {
3677
+ .indicator[data-v-aa140273] {
3678
+ border-inline-start-color: Highlight;
3679
+ }
3680
+ }
3681
+ .leading[data-v-aa140273] {
3682
+ display: inline-flex;
3683
+ flex: none;
3684
+ align-items: center;
3685
+ color: inherit;
3686
+ font-size: var(--ui-font-size-lg);
3687
+ }
3688
+ .content[data-v-aa140273] {
3689
+ display: flex;
3690
+ flex: 1;
3691
+ flex-direction: column;
3692
+ gap: var(--ui-space-0-5, 2px);
3693
+ min-inline-size: 0;
3694
+ }
3695
+ .label[data-v-aa140273],
3696
+ .description[data-v-aa140273] {
3697
+ display: block;
3698
+ min-inline-size: 0;
3699
+ overflow: hidden;
3700
+ text-overflow: ellipsis;
3701
+ white-space: nowrap;
3702
+ }
3703
+ .label[data-v-aa140273] {
3704
+ font-size: var(--ui-font-size-md);
3705
+ line-height: var(--ui-line-height-tight);
3706
+ }
3707
+ .description[data-v-aa140273] {
3708
+ color: var(--ui-text-muted);
3709
+ font-size: var(--ui-font-size-sm);
3710
+ font-weight: var(--ui-font-normal);
3711
+ line-height: var(--ui-line-height-tight);
3712
+ }
3713
+
3714
+ /* An unused region takes no space. */
3715
+ .leading[data-v-aa140273]:empty,
3716
+ .description[data-v-aa140273]:empty {
3717
+ display: none;
3718
+ }
3719
+
3720
+ /* A component that sets its display still honours the hidden attribute on its root. */
3721
+ [data-component~="ui-nav-item"][hidden][data-v-aa140273] {
3722
+ display: none;
3723
+ }
3724
+
3612
3725
  /* The top of a view: its title (the page's one h1), with an optional icon or mark before it, a
3613
3726
  short eyebrow above it, a line or two of description under it, and the view's own actions at
3614
3727
  the end. Every view titles itself the same way, at the same size. */
package/vue/index.d.ts CHANGED
@@ -37,6 +37,7 @@ export { default as List } from "./UiList.js";
37
37
  export { default as ListItem } from "./UiListItem.js";
38
38
  export { default as Menu } from "./UiMenu.js";
39
39
  export { default as MenuItem } from "./UiMenuItem.js";
40
+ export { default as NavItem } from "./UiNavItem.js";
40
41
  export { default as PageHeader } from "./UiPageHeader.js";
41
42
  export { default as Popover } from "./UiPopover.js";
42
43
  export { default as Radio } from "./UiRadio.js";
package/vue/index.js CHANGED
@@ -38,6 +38,7 @@ import { t as UiList_default } from "./chunks/UiList.js";
38
38
  import { t as UiListItem_default } from "./chunks/UiListItem.js";
39
39
  import { t as UiMenu_default } from "./chunks/UiMenu.js";
40
40
  import { t as UiMenuItem_default } from "./chunks/UiMenuItem.js";
41
+ import { t as UiNavItem_default } from "./chunks/UiNavItem.js";
41
42
  import { t as UiPageHeader_default } from "./chunks/UiPageHeader.js";
42
43
  import { t as UiPopover_default } from "./chunks/UiPopover.js";
43
44
  import { t as UiRadio_default } from "./chunks/UiRadio.js";
@@ -63,4 +64,4 @@ import { t as UiTopBar_default } from "./chunks/UiTopBar.js";
63
64
  import { t as UiTree_default } from "./chunks/UiTree.js";
64
65
  import { t as UiTreeItem_default } from "./chunks/UiTreeItem.js";
65
66
  import { trackInputModality } from "@threadlabs/looma/components/shared/input-modality.js";
66
- export { UiActionBar_default as ActionBar, UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiBreadcrumbItem_default as BreadcrumbItem, UiBreadcrumbs_default as Breadcrumbs, UiButton_default as Button, UiCallout_default as Callout, UiCard_default as Card, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiCover_default as Cover, UiDescriptionItem_default as DescriptionItem, UiDescriptionList_default as DescriptionList, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiInput_default as Input, UiInputGroup_default as InputGroup, UiList_default as List, UiListItem_default as ListItem, UiMenu_default as Menu, UiMenuItem_default as MenuItem, UiPageHeader_default as PageHeader, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiScrollArea_default as ScrollArea, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSection_default as Section, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiSpinner_default as Spinner, UiStack_default as Stack, UiStatusMessage_default as StatusMessage, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTabs_default as Tabs, UiText_default as Text, UiTextarea_default as Textarea, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem, trackInputModality };
67
+ export { UiActionBar_default as ActionBar, UiAffordanceScope_default as AffordanceScope, UiAvatar_default as Avatar, UiAvatarGroup_default as AvatarGroup, UiBadge_default as Badge, UiBreadcrumbItem_default as BreadcrumbItem, UiBreadcrumbs_default as Breadcrumbs, UiButton_default as Button, UiCallout_default as Callout, UiCard_default as Card, UiCheckbox_default as Checkbox, UiCluster_default as Cluster, UiCombobox_default as Combobox, UiContainer_default as Container, UiContextMenu_default as ContextMenu, UiCover_default as Cover, UiDescriptionItem_default as DescriptionItem, UiDescriptionList_default as DescriptionList, UiDialog_default as Dialog, UiDisclosure_default as Disclosure, UiEditable_default as Editable, UiEditorInsertTableGrid_default as EditorInsertTableGrid, UiEditorMentionMenu_default as EditorMentionMenu, UiEditorSlashMenu_default as EditorSlashMenu, UiEditorTableContextMenu_default as EditorTableContextMenu, UiEditorTableOverlay_default as EditorTableOverlay, UiEditorTableToolbar_default as EditorTableToolbar, UiEditorToolbar_default as EditorToolbar, UiFloatingActionButton_default as FloatingActionButton, UiFormField_default as FormField, UiGrid_default as Grid, UiIcon_default as Icon, UiIconButton_default as IconButton, UiInput_default as Input, UiInputGroup_default as InputGroup, UiList_default as List, UiListItem_default as ListItem, UiMenu_default as Menu, UiMenuItem_default as MenuItem, UiNavItem_default as NavItem, UiPageHeader_default as PageHeader, UiPopover_default as Popover, UiRadio_default as Radio, UiRadioGroup_default as RadioGroup, UiReel_default as Reel, UiScrollArea_default as ScrollArea, UiSearchResultRow_default as SearchResultRow, UiSearchShell_default as SearchShell, UiSection_default as Section, UiSelect_default as Select, UiSeparator_default as Separator, UiSidebar_default as Sidebar, UiSpinner_default as Spinner, UiStack_default as Stack, UiStatusMessage_default as StatusMessage, UiSwitch_default as Switch, UiSwitcher_default as Switcher, UiTabs_default as Tabs, UiText_default as Text, UiTextarea_default as Textarea, UiToastRegion_default as ToastRegion, UiTooltip_default as Tooltip, UiTopBar_default as TopBar, UiTree_default as Tree, UiTreeItem_default as TreeItem, trackInputModality };