@threadlabs/looma 0.11.1 → 0.11.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.11.1",
3
+ "version": "0.11.3",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -0,0 +1,87 @@
1
+ /* Generated by HTML Next 1.0.0-alpha.5. Do not edit. */
2
+ @scope ([data-component~="ui-input-group"]) to ([data-component], [data-slotted]) {
3
+ /* An input with fixed text before or after it, such as a domain after a site's name
4
+ ("acme" + ".example.com") or slashes around a path. The group draws the field's border and
5
+ focus ring around the input and its affixes together; the input inside drops its own through
6
+ its custom properties, so it is still the one ui-input, with its form behaviour intact. The
7
+ affixes are plain text beside the input, so name the input with a label that says what the
8
+ whole value is. */
9
+ :scope {
10
+ --ui-input-border: transparent;
11
+ --ui-input-border-hover: transparent;
12
+ --ui-input-focus-border: transparent;
13
+ --ui-input-shadow: none;
14
+ --ui-input-focus-shadow: none;
15
+ --ui-input-radius: 0;
16
+ --ui-input-surface: transparent;
17
+
18
+ display: flex;
19
+ align-items: stretch;
20
+ box-sizing: border-box;
21
+ inline-size: 100%;
22
+ min-inline-size: 0;
23
+ min-block-size: var(--ui-control-size-md);
24
+ border: 1px solid var(--ui-border-strong);
25
+ border-radius: var(--ui-radius-md);
26
+ background: var(--ui-surface-elevated);
27
+ box-shadow: var(--ui-control-inset);
28
+ overflow: hidden;
29
+ transition: border-color var(--ui-motion-fast) var(--ui-motion-ease), box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
30
+ }
31
+
32
+ :scope:hover:not(:focus-within) {
33
+ border-color: var(--ui-text-secondary);
34
+ }
35
+
36
+ :scope:focus-within {
37
+ border-color: var(--ui-accent-solid);
38
+ box-shadow:
39
+ var(--ui-control-inset),
40
+ var(--ui-control-focus-halo-shadow);
41
+ }
42
+
43
+ :scope:has([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])) {
44
+ border-color: var(--ui-danger-solid);
45
+ }
46
+
47
+ :scope[data-ui-input-group-state~="disabled"] {
48
+ background: var(--ui-surface-muted);
49
+ box-shadow: none;
50
+ }
51
+
52
+ .field {
53
+ display: flex;
54
+ flex: 1;
55
+ min-inline-size: 0;
56
+ }
57
+
58
+ .affix {
59
+ display: inline-flex;
60
+ flex: none;
61
+ align-items: center;
62
+ padding-inline: var(--ui-space-2);
63
+ color: var(--ui-text-secondary);
64
+ font-family: var(--ui-font-family-mono);
65
+ font-size: var(--ui-font-size-sm);
66
+ white-space: nowrap;
67
+ }
68
+
69
+ .affix:empty {
70
+ display: none;
71
+ }
72
+
73
+ /* A component that sets its display still honours the hidden attribute on its root. */
74
+ :scope[hidden] {
75
+ display: none;
76
+ }
77
+ }
78
+ @scope ([data-component~="ui-input-group"]) to ([data-component]) {
79
+ /* An input with fixed text before or after it, such as a domain after a site's name
80
+ ("acme" + ".example.com") or slashes around a path. The group draws the field's border and
81
+ focus ring around the input and its affixes together; the input inside drops its own through
82
+ its custom properties, so it is still the one ui-input, with its form behaviour intact. The
83
+ affixes are plain text beside the input, so name the input with a label that says what the
84
+ whole value is. */
85
+
86
+ /* A component that sets its display still honours the hidden attribute on its root. */
87
+ }
@@ -9,9 +9,9 @@
9
9
  margin: 0;
10
10
  padding: var(--ui-space-2) var(--ui-space-3);
11
11
  appearance: none;
12
- border: 1px solid var(--ui-control-border, var(--ui-border-strong));
12
+ border: 1px solid var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
13
13
  border-radius: var(--ui-input-radius, var(--ui-radius-md));
14
- background: var(--ui-control-surface, var(--ui-surface-elevated));
14
+ background: var(--ui-input-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
15
15
  color: var(--ui-text-primary);
16
16
  font: inherit;
17
17
  line-height: var(--ui-line-height-md);
@@ -34,11 +34,11 @@
34
34
  }
35
35
 
36
36
  :scope:hover:not(:focus):not(:disabled) {
37
- border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
37
+ border-color: var(--ui-input-border-hover, var(--ui-control-border-hover, var(--ui-text-secondary)));
38
38
  }
39
39
 
40
40
  :scope:focus-visible {
41
- border-color: var(--ui-control-focus, var(--ui-accent-solid));
41
+ border-color: var(--ui-input-focus-border, var(--ui-control-focus, var(--ui-accent-solid)));
42
42
  outline: none;
43
43
  box-shadow: var(--ui-input-focus-shadow, var(--ui-control-inset), var(--ui-control-focus-halo-shadow));
44
44
  }
@@ -16,9 +16,9 @@
16
16
  align-items: center;
17
17
  gap: var(--ui-list-item-gap, var(--ui-space-3));
18
18
  min-inline-size: 0;
19
- min-block-size: var(--ui-control-size, 2.5rem);
20
- padding-block: var(--ui-list-item-padding-block, var(--ui-space-2));
21
- padding-inline: var(--ui-list-item-padding-inline, var(--ui-space-3));
19
+ min-block-size: var(--_ui-list-item-min-size, var(--ui-control-size, 2.5rem));
20
+ padding-block: var(--ui-list-item-padding-block, var(--_ui-list-item-padding-block, var(--ui-space-2)));
21
+ padding-inline: var(--ui-list-item-padding-inline, var(--_ui-list-item-padding-inline, var(--ui-space-3)));
22
22
  border-radius: var(--ui-radius-md);
23
23
  color: var(--ui-text-primary);
24
24
  transition: background-color var(--ui-motion-fast) var(--ui-motion-ease), border-color var(--ui-motion-fast) var(--ui-motion-ease);
@@ -88,7 +88,7 @@
88
88
 
89
89
  .title {
90
90
  font-size: var(--ui-font-size-md);
91
- font-weight: var(--ui-font-medium);
91
+ font-weight: var(--_ui-list-item-title-weight, var(--ui-font-medium));
92
92
  line-height: var(--ui-line-height-tight);
93
93
  }
94
94
 
@@ -13,6 +13,15 @@
13
13
  list-style: none;
14
14
  }
15
15
 
16
+ /* Compact passes its size to the items through private properties, which cross into each item. */
17
+ :scope[data-ui-list-state~="density=compact"] {
18
+ --_ui-list-item-min-size: 0;
19
+ --_ui-list-item-padding-block: 0;
20
+ --_ui-list-item-padding-inline: 0;
21
+ --_ui-list-item-title-weight: var(--ui-font-normal);
22
+ gap: var(--ui-list-gap, var(--ui-space-2));
23
+ }
24
+
16
25
  :scope[data-ui-list-state~="layout=grid"] {
17
26
  display: grid;
18
27
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--ui-list-min-item-width, 14rem)), 1fr));
@@ -29,5 +38,7 @@
29
38
  explicit list role keeps the list announced as one: some browsers drop it from a list with no
30
39
  markers. */
31
40
 
41
+ /* Compact passes its size to the items through private properties, which cross into each item. */
42
+
32
43
  /* A component that sets its display still honours the hidden attribute on its root. */
33
44
  }
@@ -201,7 +201,7 @@
201
201
  /* A hovered row reads its whole name: the label slides far enough to show the end, waits
202
202
  there, and comes back. Only when it actually overflows — the controller measures by how
203
203
  much — after the controls have taken their place over its end — and hands over the distance
204
- and a duration from it, so a longer name travels no faster. */
204
+ and a duration from it, so every name moves at the same speed. */
205
205
  .row[data-ui-marquee] > .label > .label-text {
206
206
  /* Once, and it stays at the end while the pointer is there: a name that keeps sliding back
207
207
  and forth under the pointer is harder to read than one that arrives and holds. */
@@ -424,7 +424,7 @@
424
424
  /* A hovered row reads its whole name: the label slides far enough to show the end, waits
425
425
  there, and comes back. Only when it actually overflows — the controller measures by how
426
426
  much — after the controls have taken their place over its end — and hands over the distance
427
- and a duration from it, so a longer name travels no faster. */
427
+ and a duration from it, so every name moves at the same speed. */
428
428
 
429
429
  /* This comes after the hover fade, which it replaces at the same specificity. While the name
430
430
  slides, the label reaches back under the icon (the controller measures how far) with its text
@@ -0,0 +1,14 @@
1
+ // Generated by HTML Next 1.0.0-alpha.5 for Vanilla DOM. Do not edit.
2
+ export interface UiInputGroupEventMap {
3
+ }
4
+ export interface UiInputGroupElement extends HTMLDivElement {
5
+ addEventListener<K extends keyof UiInputGroupEventMap>(type: K, listener: (this: UiInputGroupElement, event: UiInputGroupEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
6
+ removeEventListener<K extends keyof UiInputGroupEventMap>(type: K, listener: (this: UiInputGroupElement, event: UiInputGroupEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
7
+ }
8
+ export interface UiInputGroupProps {
9
+ disabled?: boolean | null;
10
+ attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
11
+ children?: readonly (string | Node)[];
12
+ slots?: Readonly<Record<string, readonly (string | Node)[]>>;
13
+ }
14
+ export declare function createUiInputGroup(props?: UiInputGroupProps): UiInputGroupElement;
@@ -0,0 +1,53 @@
1
+ // Generated by HTML Next 1.0.0-alpha.5 for Vanilla DOM. Do not edit.
2
+ import { manageGeneratedProps } from "@nextwebwg/html-next/generated-runtime";
3
+ import "../styles/ui-input-group.css";
4
+
5
+ export function createUiInputGroup(options = {}) {
6
+ const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
7
+ const projected = [];
8
+ const prop0 = componentProps["disabled"] === undefined ? false : componentProps["disabled"];
9
+ const element = document.createElement("div");
10
+ for (const [name, value] of Object.entries(attributes)) {
11
+ if (value === null || value === undefined || value === false) continue;
12
+ element.setAttribute(name, value === true ? "" : String(value));
13
+ }
14
+ element.setAttribute("data-component", "ui-input-group");
15
+ const element0 = document.createElement("span");
16
+ element0.setAttribute("class", "affix");
17
+ if (slots["prefix"] ?? [].length > 0) {
18
+ for (const child of slots["prefix"] ?? []) {
19
+ const node = typeof child === "string" ? document.createTextNode(child) : child;
20
+ projected.push([node, "prefix"]);
21
+ element0.append(node);
22
+ }
23
+ } else {
24
+ }
25
+ element.append(element0);
26
+ const element1 = document.createElement("span");
27
+ element1.setAttribute("class", "field");
28
+ if (children.length > 0) {
29
+ for (const child of children) {
30
+ const node = typeof child === "string" ? document.createTextNode(child) : child;
31
+ projected.push([node, ""]);
32
+ element1.append(node);
33
+ }
34
+ } else {
35
+ }
36
+ element.append(element1);
37
+ const element2 = document.createElement("span");
38
+ element2.setAttribute("class", "affix");
39
+ if (slots["suffix"] ?? [].length > 0) {
40
+ for (const child of slots["suffix"] ?? []) {
41
+ const node = typeof child === "string" ? document.createTextNode(child) : child;
42
+ projected.push([node, "suffix"]);
43
+ element2.append(node);
44
+ }
45
+ } else {
46
+ }
47
+ element.append(element2);
48
+ manageGeneratedProps(element, [
49
+ { name: "disabled", attribute: "data-disabled", value: componentProps["disabled"], default: false, type: "boolean", required: false },
50
+ ]);
51
+ return element;
52
+ }
53
+
@@ -6,6 +6,7 @@ export interface UiListElement extends HTMLUListElement {
6
6
  removeEventListener<K extends keyof UiListEventMap>(type: K, listener: (this: UiListElement, event: UiListEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
7
7
  }
8
8
  export interface UiListProps {
9
+ density?: "comfortable" | "compact" | null;
9
10
  layout?: "rows" | "grid" | null;
10
11
  attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
11
12
  children?: readonly (string | Node)[];
package/vanilla/UiList.js CHANGED
@@ -5,7 +5,8 @@ import "../styles/ui-list.css";
5
5
  export function createUiList(options = {}) {
6
6
  const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
7
7
  const projected = [];
8
- const prop0 = componentProps["layout"] === undefined ? "rows" : componentProps["layout"];
8
+ const prop0 = componentProps["density"] === undefined ? "comfortable" : componentProps["density"];
9
+ const prop1 = componentProps["layout"] === undefined ? "rows" : componentProps["layout"];
9
10
  const element = document.createElement("ul");
10
11
  for (const [name, value] of Object.entries(attributes)) {
11
12
  if (value === null || value === undefined || value === false) continue;
@@ -22,6 +23,7 @@ export function createUiList(options = {}) {
22
23
  } else {
23
24
  }
24
25
  manageGeneratedProps(element, [
26
+ { name: "density", attribute: "data-density", value: componentProps["density"], default: "comfortable", type: ["comfortable","compact"], required: false },
25
27
  { name: "layout", attribute: "data-layout", value: componentProps["layout"], default: "rows", type: ["rows","grid"], required: false },
26
28
  ]);
27
29
  return element;
package/vanilla/index.js CHANGED
@@ -32,6 +32,7 @@ export * from "./UiGrid.js";
32
32
  export * from "./UiIcon.js";
33
33
  export * from "./UiIconButton.js";
34
34
  export * from "./UiInput.js";
35
+ export * from "./UiInputGroup.js";
35
36
  export * from "./UiList.js";
36
37
  export * from "./UiListItem.js";
37
38
  export * from "./UiMenu.js";
package/vue/UiInput.vue CHANGED
@@ -64,9 +64,9 @@ useComponentHost(controllerModule.default, {
64
64
  margin: 0;
65
65
  padding: var(--ui-space-2) var(--ui-space-3);
66
66
  appearance: none;
67
- border: 1px solid var(--ui-control-border, var(--ui-border-strong));
67
+ border: 1px solid var(--ui-input-border, var(--ui-control-border, var(--ui-border-strong)));
68
68
  border-radius: var(--ui-input-radius, var(--ui-radius-md));
69
- background: var(--ui-control-surface, var(--ui-surface-elevated));
69
+ background: var(--ui-input-surface, var(--ui-control-surface, var(--ui-surface-elevated)));
70
70
  color: var(--ui-text-primary);
71
71
  font: inherit;
72
72
  line-height: var(--ui-line-height-md);
@@ -89,11 +89,14 @@ useComponentHost(controllerModule.default, {
89
89
  }
90
90
 
91
91
  [data-component~="ui-input"]:hover:not(:focus):not(:disabled) {
92
- border-color: var(--ui-control-border-hover, var(--ui-text-secondary));
92
+ border-color: var(
93
+ --ui-input-border-hover,
94
+ var(--ui-control-border-hover, var(--ui-text-secondary))
95
+ );
93
96
  }
94
97
 
95
98
  [data-component~="ui-input"]:focus-visible {
96
- border-color: var(--ui-control-focus, var(--ui-accent-solid));
99
+ border-color: var(--ui-input-focus-border, var(--ui-control-focus, var(--ui-accent-solid)));
97
100
  outline: none;
98
101
  box-shadow: var(
99
102
  --ui-input-focus-shadow,
@@ -0,0 +1,22 @@
1
+ type __VLS_Props = {
2
+ disabled?: boolean;
3
+ };
4
+ declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
5
+ type __VLS_Slots = {} & {
6
+ prefix?: (props: typeof __VLS_1) => any;
7
+ } & {
8
+ default?: (props: typeof __VLS_3) => any;
9
+ } & {
10
+ suffix?: (props: typeof __VLS_5) => any;
11
+ };
12
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
13
+ disabled: boolean;
14
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
18
+ type __VLS_WithSlots<T, S> = T & {
19
+ new (): {
20
+ $slots: S;
21
+ };
22
+ };
@@ -0,0 +1,2 @@
1
+ import { t as UiInputGroup_default } from "./chunks/UiInputGroup.js";
2
+ export { UiInputGroup_default as default };
@@ -0,0 +1,113 @@
1
+ <!-- Generated by HTML Next 1.0.0-alpha.5 for Vue 3.5. Do not edit. -->
2
+ <script setup lang="ts">
3
+ import { computed } from 'vue'
4
+
5
+ defineOptions({ inheritAttrs: false })
6
+
7
+ const props = withDefaults(
8
+ defineProps<{
9
+ disabled?: boolean
10
+ }>(),
11
+ {
12
+ disabled: false,
13
+ },
14
+ )
15
+
16
+ /** The values the styles' :host-state() rules test. */
17
+ const hostState = computed(() =>
18
+ [
19
+ props.disabled && 'disabled',
20
+ ].filter(Boolean).join(' ')
21
+ )
22
+ </script>
23
+
24
+ <template>
25
+ <div
26
+ data-component="ui-input-group"
27
+ v-bind="$attrs"
28
+ :data-ui-input-group-state="hostState || undefined"
29
+ >
30
+ <span class="affix"><slot name="prefix" /></span>
31
+ <span class="field"><slot /></span>
32
+ <span class="affix"><slot name="suffix" /></span>
33
+ </div>
34
+ </template>
35
+
36
+ <style scoped>
37
+ /* An input with fixed text before or after it, such as a domain after a site's name
38
+ ("acme" + ".example.com") or slashes around a path. The group draws the field's border and
39
+ focus ring around the input and its affixes together; the input inside drops its own through
40
+ its custom properties, so it is still the one ui-input, with its form behaviour intact. The
41
+ affixes are plain text beside the input, so name the input with a label that says what the
42
+ whole value is. */
43
+ [data-component~="ui-input-group"] {
44
+ --ui-input-border: transparent;
45
+ --ui-input-border-hover: transparent;
46
+ --ui-input-focus-border: transparent;
47
+ --ui-input-shadow: none;
48
+ --ui-input-focus-shadow: none;
49
+ --ui-input-radius: 0;
50
+ --ui-input-surface: transparent;
51
+
52
+ display: flex;
53
+ align-items: stretch;
54
+ box-sizing: border-box;
55
+ inline-size: 100%;
56
+ min-inline-size: 0;
57
+ min-block-size: var(--ui-control-size-md);
58
+ border: 1px solid var(--ui-border-strong);
59
+ border-radius: var(--ui-radius-md);
60
+ background: var(--ui-surface-elevated);
61
+ box-shadow: var(--ui-control-inset);
62
+ overflow: hidden;
63
+ transition:
64
+ border-color var(--ui-motion-fast) var(--ui-motion-ease),
65
+ box-shadow var(--ui-motion-fast) var(--ui-motion-ease);
66
+ }
67
+
68
+ [data-component~="ui-input-group"]:hover:not(:focus-within) {
69
+ border-color: var(--ui-text-secondary);
70
+ }
71
+
72
+ [data-component~="ui-input-group"]:focus-within {
73
+ border-color: var(--ui-accent-solid);
74
+ box-shadow:
75
+ var(--ui-control-inset),
76
+ var(--ui-control-focus-halo-shadow);
77
+ }
78
+
79
+ [data-component~="ui-input-group"]:has([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])) {
80
+ border-color: var(--ui-danger-solid);
81
+ }
82
+
83
+ [data-component~="ui-input-group"][data-ui-input-group-state~="disabled"] {
84
+ background: var(--ui-surface-muted);
85
+ box-shadow: none;
86
+ }
87
+
88
+ .field {
89
+ display: flex;
90
+ flex: 1;
91
+ min-inline-size: 0;
92
+ }
93
+
94
+ .affix {
95
+ display: inline-flex;
96
+ flex: none;
97
+ align-items: center;
98
+ padding-inline: var(--ui-space-2);
99
+ color: var(--ui-text-secondary);
100
+ font-family: var(--ui-font-family-mono);
101
+ font-size: var(--ui-font-size-sm);
102
+ white-space: nowrap;
103
+ }
104
+
105
+ .affix:empty {
106
+ display: none;
107
+ }
108
+
109
+ /* A component that sets its display still honours the hidden attribute on its root. */
110
+ [data-component~="ui-input-group"][hidden] {
111
+ display: none;
112
+ }
113
+ </style>
package/vue/UiList.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  type __VLS_Props = {
2
+ density?: 'comfortable' | 'compact';
2
3
  layout?: 'rows' | 'grid';
3
4
  };
4
5
  declare var __VLS_1: {};
@@ -7,6 +8,7 @@ type __VLS_Slots = {} & {
7
8
  };
8
9
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
9
10
  layout: "rows" | "grid";
11
+ density: "comfortable" | "compact";
10
12
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
13
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
14
  declare const _default: typeof __VLS_export;
package/vue/UiList.vue CHANGED
@@ -6,9 +6,11 @@ defineOptions({ inheritAttrs: false })
6
6
 
7
7
  const props = withDefaults(
8
8
  defineProps<{
9
+ density?: 'comfortable' | 'compact'
9
10
  layout?: 'rows' | 'grid'
10
11
  }>(),
11
12
  {
13
+ density: 'comfortable',
12
14
  layout: 'rows',
13
15
  },
14
16
  )
@@ -16,6 +18,7 @@ const props = withDefaults(
16
18
  /** The values the styles' :host-state() rules test. */
17
19
  const hostState = computed(() =>
18
20
  [
21
+ props.density && `density density=${props.density}`,
19
22
  props.layout && `layout layout=${props.layout}`,
20
23
  ].filter(Boolean).join(' ')
21
24
  )
@@ -46,6 +49,15 @@ const hostState = computed(() =>
46
49
  list-style: none;
47
50
  }
48
51
 
52
+ /* Compact passes its size to the items through private properties, which cross into each item. */
53
+ [data-component~="ui-list"][data-ui-list-state~="density=compact"] {
54
+ --_ui-list-item-min-size: 0;
55
+ --_ui-list-item-padding-block: 0;
56
+ --_ui-list-item-padding-inline: 0;
57
+ --_ui-list-item-title-weight: var(--ui-font-normal);
58
+ gap: var(--ui-list-gap, var(--ui-space-2));
59
+ }
60
+
49
61
  [data-component~="ui-list"][data-ui-list-state~="layout=grid"] {
50
62
  display: grid;
51
63
  grid-template-columns:
@@ -55,9 +55,15 @@ const hostState = computed(() =>
55
55
  align-items: center;
56
56
  gap: var(--ui-list-item-gap, var(--ui-space-3));
57
57
  min-inline-size: 0;
58
- min-block-size: var(--ui-control-size, 2.5rem);
59
- padding-block: var(--ui-list-item-padding-block, var(--ui-space-2));
60
- padding-inline: var(--ui-list-item-padding-inline, var(--ui-space-3));
58
+ min-block-size: var(--_ui-list-item-min-size, var(--ui-control-size, 2.5rem));
59
+ padding-block: var(
60
+ --ui-list-item-padding-block,
61
+ var(--_ui-list-item-padding-block, var(--ui-space-2))
62
+ );
63
+ padding-inline: var(
64
+ --ui-list-item-padding-inline,
65
+ var(--_ui-list-item-padding-inline, var(--ui-space-3))
66
+ );
61
67
  border-radius: var(--ui-radius-md);
62
68
  color: var(--ui-text-primary);
63
69
  transition:
@@ -130,7 +136,7 @@ const hostState = computed(() =>
130
136
 
131
137
  .title {
132
138
  font-size: var(--ui-font-size-md);
133
- font-weight: var(--ui-font-medium);
139
+ font-weight: var(--_ui-list-item-title-weight, var(--ui-font-medium));
134
140
  line-height: var(--ui-line-height-tight);
135
141
  }
136
142
 
@@ -378,7 +378,7 @@ useComponentHost(controllerModule.default, {
378
378
  /* A hovered row reads its whole name: the label slides far enough to show the end, waits
379
379
  there, and comes back. Only when it actually overflows — the controller measures by how
380
380
  much — after the controls have taken their place over its end — and hands over the distance
381
- and a duration from it, so a longer name travels no faster. */
381
+ and a duration from it, so every name moves at the same speed. */
382
382
  .row[data-ui-marquee] > .label > .label-text {
383
383
  /* Once, and it stays at the end while the pointer is there: a name that keeps sliding back
384
384
  and forth under the pointer is harder to read than one that arrives and holds. */
@@ -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-f84acfe8"]]);
64
+ }), [["__scopeId", "data-v-12ffae5a"]]);
65
65
  //#endregion
66
66
  export { UiInput_default as t };
@@ -0,0 +1,31 @@
1
+ import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
2
+ import { computed, createElementBlock, createElementVNode, defineComponent, mergeProps, openBlock, renderSlot } from "vue";
3
+ //#region .build/vue/UiInputGroup.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = ["data-ui-input-group-state"];
5
+ var _hoisted_2 = { class: "affix" };
6
+ var _hoisted_3 = { class: "field" };
7
+ var _hoisted_4 = { class: "affix" };
8
+ //#endregion
9
+ //#region .build/vue/UiInputGroup.vue
10
+ var UiInputGroup_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
11
+ inheritAttrs: false,
12
+ __name: "UiInputGroup",
13
+ props: { disabled: {
14
+ type: Boolean,
15
+ default: false
16
+ } },
17
+ setup(__props) {
18
+ const props = __props;
19
+ /** The values the styles' :host-state() rules test. */
20
+ const hostState = computed(() => [props.disabled && "disabled"].filter(Boolean).join(" "));
21
+ return (_ctx, _cache) => {
22
+ return openBlock(), createElementBlock("div", mergeProps({ "data-component": "ui-input-group" }, _ctx.$attrs, { "data-ui-input-group-state": hostState.value || void 0 }), [
23
+ createElementVNode("span", _hoisted_2, [renderSlot(_ctx.$slots, "prefix", {}, void 0, true)]),
24
+ createElementVNode("span", _hoisted_3, [renderSlot(_ctx.$slots, "default", {}, void 0, true)]),
25
+ createElementVNode("span", _hoisted_4, [renderSlot(_ctx.$slots, "suffix", {}, void 0, true)])
26
+ ], 16, _hoisted_1);
27
+ };
28
+ }
29
+ }), [["__scopeId", "data-v-0a135fc1"]]);
30
+ //#endregion
31
+ export { UiInputGroup_default as t };
@@ -7,11 +7,14 @@ var _hoisted_1 = ["data-ui-list-state"];
7
7
  var UiList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
8
8
  inheritAttrs: false,
9
9
  __name: "UiList",
10
- props: { layout: { default: "rows" } },
10
+ props: {
11
+ density: { default: "comfortable" },
12
+ layout: { default: "rows" }
13
+ },
11
14
  setup(__props) {
12
15
  const props = __props;
13
16
  /** The values the styles' :host-state() rules test. */
14
- const hostState = computed(() => [props.layout && `layout layout=${props.layout}`].filter(Boolean).join(" "));
17
+ const hostState = computed(() => [props.density && `density density=${props.density}`, props.layout && `layout layout=${props.layout}`].filter(Boolean).join(" "));
15
18
  return (_ctx, _cache) => {
16
19
  return openBlock(), createElementBlock("ul", mergeProps({
17
20
  "data-component": "ui-list",
@@ -19,6 +22,6 @@ var UiList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
19
22
  }, _ctx.$attrs, { "data-ui-list-state": hostState.value || void 0 }), [renderSlot(_ctx.$slots, "default", {}, void 0, true)], 16, _hoisted_1);
20
23
  };
21
24
  }
22
- }), [["__scopeId", "data-v-935b1197"]]);
25
+ }), [["__scopeId", "data-v-9e6cf63f"]]);
23
26
  //#endregion
24
27
  export { UiList_default as t };
@@ -34,6 +34,6 @@ var UiListItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
34
34
  ], 16, _hoisted_1);
35
35
  };
36
36
  }
37
- }), [["__scopeId", "data-v-d61daf46"]]);
37
+ }), [["__scopeId", "data-v-30896b18"]]);
38
38
  //#endregion
39
39
  export { UiListItem_default as t };
@@ -234,6 +234,6 @@ var UiTreeItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__P
234
234
  ], 16, _hoisted_1);
235
235
  };
236
236
  }
237
- }), [["__scopeId", "data-v-3778b642"]]);
237
+ }), [["__scopeId", "data-v-dab96891"]]);
238
238
  //#endregion
239
239
  export { UiTreeItem_default as t };