@threadlabs/looma 0.25.3 → 0.25.5

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 (69) hide show
  1. package/components/ui-badge/ui-badge.html +59 -3
  2. package/components/ui-button/ui-button.html +1 -1
  3. package/components/ui-card/ui-card.html +27 -2
  4. package/components/ui-cluster/ui-cluster.html +30 -0
  5. package/components/ui-editor-surface/ui-editor-surface.html +23 -0
  6. package/components/ui-scroll-area/ui-scroll-area.html +5 -0
  7. package/components/ui-stack/ui-stack.html +17 -1
  8. package/components/ui-text/ui-text.html +5 -0
  9. package/components/ui-textarea/ui-textarea.html +7 -0
  10. package/dist/index.js +1 -1
  11. package/package.json +1 -1
  12. package/styles/ui-badge.css +61 -4
  13. package/styles/ui-button.css +1 -1
  14. package/styles/ui-card.css +24 -0
  15. package/styles/ui-cluster.css +25 -0
  16. package/styles/ui-editor-surface.css +19 -0
  17. package/styles/ui-scroll-area.css +4 -0
  18. package/styles/ui-stack.css +13 -0
  19. package/styles/ui-text.css +4 -0
  20. package/styles/ui-textarea.css +4 -0
  21. package/vanilla/UiBadge.js +16 -3
  22. package/vanilla/UiCard.d.ts +1 -1
  23. package/vanilla/UiCard.js +1 -1
  24. package/vanilla/UiCluster.d.ts +3 -0
  25. package/vanilla/UiCluster.js +9 -3
  26. package/vanilla/UiEditorSurface.d.ts +14 -0
  27. package/vanilla/UiEditorSurface.js +27 -0
  28. package/vanilla/UiScrollArea.d.ts +1 -0
  29. package/vanilla/UiScrollArea.js +1 -1
  30. package/vanilla/UiStack.d.ts +2 -0
  31. package/vanilla/UiStack.js +8 -9
  32. package/vanilla/UiText.d.ts +1 -0
  33. package/vanilla/UiText.js +1 -1
  34. package/vanilla/UiTextarea.d.ts +1 -0
  35. package/vanilla/UiTextarea.js +4 -1
  36. package/vanilla/index.js +1 -0
  37. package/vue/UiBadge.d.ts +4 -2
  38. package/vue/UiBadge.vue +57 -3
  39. package/vue/UiButton.vue +1 -1
  40. package/vue/UiCard.d.ts +3 -3
  41. package/vue/UiCard.vue +34 -5
  42. package/vue/UiCluster.d.ts +27 -0
  43. package/vue/UiCluster.vue +95 -1
  44. package/vue/UiEditorSlashMenuItem.d.ts +1 -1
  45. package/vue/UiEditorSurface.d.ts +26 -0
  46. package/vue/UiEditorSurface.js +2 -0
  47. package/vue/UiEditorSurface.vue +129 -0
  48. package/vue/UiScrollArea.d.ts +9 -0
  49. package/vue/UiScrollArea.vue +28 -2
  50. package/vue/UiStack.d.ts +18 -0
  51. package/vue/UiStack.vue +58 -1
  52. package/vue/UiText.d.ts +9 -0
  53. package/vue/UiText.vue +33 -0
  54. package/vue/UiTextarea.d.ts +9 -0
  55. package/vue/UiTextarea.vue +37 -2
  56. package/vue/chunks/UiBadge.js +7 -3
  57. package/vue/chunks/UiButton.js +1 -1
  58. package/vue/chunks/UiCard.js +10 -3
  59. package/vue/chunks/UiCluster.js +82 -1
  60. package/vue/chunks/UiEditorSurface.js +71 -0
  61. package/vue/chunks/UiScrollArea.js +28 -2
  62. package/vue/chunks/UiStack.js +46 -1
  63. package/vue/chunks/UiText.js +43 -1
  64. package/vue/chunks/UiTextarea.js +28 -2
  65. package/vue/components.css +321 -190
  66. package/vue/editor/LoomaEditor.d.ts +12 -0
  67. package/vue/editor/index.js +7 -2
  68. package/vue/index.d.ts +1 -0
  69. package/vue/index.js +2 -1
@@ -9,6 +9,14 @@ defineOptions({ inheritAttrs: false })
9
9
 
10
10
  const propValidityContract = {
11
11
  props: {
12
+ fill: {
13
+ type: { kind: 'terminal', name: 'boolean' },
14
+ required: false,
15
+ target: { attribute: 'fill' },
16
+ description:
17
+ 'Grows into remaining space within a flex layout while keeping content independently scrollable.',
18
+ default: false,
19
+ },
12
20
  orientation: {
13
21
  type: { kind: 'terminal', name: 'keyword' },
14
22
  required: false,
@@ -30,6 +38,7 @@ const propValidityContract = {
30
38
  },
31
39
  } as const
32
40
  const props = defineProps({
41
+ fill: { type: null as unknown as PropType<boolean | null>, default: false },
33
42
  orientation: {
34
43
  type: null as unknown as PropType<'vertical' | 'horizontal' | null>,
35
44
  default: 'vertical',
@@ -39,8 +48,19 @@ const props = defineProps({
39
48
  default: 'content',
40
49
  },
41
50
  })
42
- const acceptedProps: Record<string, unknown> = { orientation: 'vertical', size: 'content' }
51
+ const acceptedProps: Record<string, unknown> = {
52
+ fill: false,
53
+ orientation: 'vertical',
54
+ size: 'content',
55
+ }
43
56
  const checkedProps = computed(() => ({
57
+ fill: checkedProp<boolean>(
58
+ props['fill'],
59
+ { kind: 'terminal', name: 'boolean' },
60
+ false,
61
+ 'fill',
62
+ acceptedProps,
63
+ ) as boolean,
44
64
  orientation: checkedProp<'vertical' | 'horizontal'>(
45
65
  props['orientation'],
46
66
  { kind: 'terminal', name: 'keyword' },
@@ -116,6 +136,7 @@ if (
116
136
  /** The values the styles' :host-state() rules test. */
117
137
  const hostState = computed(() =>
118
138
  [
139
+ checkedProps.value.fill && 'fill',
119
140
  checkedProps.value.orientation && 'orientation',
120
141
  checkedProps.value.orientation != null
121
142
  && `orientation=${encodeURIComponent(checkedProps.value.orientation)}`,
@@ -141,7 +162,7 @@ useComponentHost(() => import('../components/ui-scroll-area/ui-scroll-area.js'),
141
162
  ? (incoming[name] ?? incoming[kebab] ?? null)
142
163
  : null
143
164
  },
144
- propNames: ['orientation', 'size'],
165
+ propNames: ['fill', 'orientation', 'size'],
145
166
  propValidity: (name: string) =>
146
167
  propValidityState({ contract: propValidityContract, values: { ...props } }, name),
147
168
  refs: { content: contentElement },
@@ -153,6 +174,7 @@ useComponentHost(() => import('../components/ui-scroll-area/ui-scroll-area.js'),
153
174
  data-component="ui-scroll-area"
154
175
  v-bind="nativeAttrs($attrs)"
155
176
  v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
177
+ :data-fill="reflectedProp('fill', 'fill', checkedProps.fill, undefined, false)"
156
178
  :data-orientation="reflectedProp('orientation', 'orientation', checkedProps.orientation, undefined, false)"
157
179
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
158
180
  :data-ui-scroll-area-state="hostState || undefined"
@@ -166,6 +188,10 @@ useComponentHost(() => import('../components/ui-scroll-area/ui-scroll-area.js'),
166
188
  /* The controller sets each fade length from overflow and scroll position. The mask blends
167
189
  into whatever is behind the area without needing to know its colour. Before upgrade, its
168
190
  zero-length defaults leave the authored scroll area fully visible. */
191
+ [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="fill"] {
192
+ flex: 1;
193
+ }
194
+
169
195
  [data-component~="ui-scroll-area"] {
170
196
  display: block;
171
197
  box-sizing: border-box;
package/vue/UiStack.d.ts CHANGED
@@ -8,10 +8,18 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
8
8
  type: PropType<"start" | "center" | "end" | "stretch" | null>;
9
9
  default: null;
10
10
  };
11
+ fill: {
12
+ type: PropType<boolean | null>;
13
+ default: boolean;
14
+ };
11
15
  gap: {
12
16
  type: PropType<"none" | "xs" | "s" | "m" | "l" | "xl" | null>;
13
17
  default: null;
14
18
  };
19
+ height: {
20
+ type: PropType<number | null>;
21
+ default: null;
22
+ };
15
23
  justify: {
16
24
  type: PropType<"start" | "center" | "end" | "between" | null>;
17
25
  default: null;
@@ -21,15 +29,25 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
21
29
  type: PropType<"start" | "center" | "end" | "stretch" | null>;
22
30
  default: null;
23
31
  };
32
+ fill: {
33
+ type: PropType<boolean | null>;
34
+ default: boolean;
35
+ };
24
36
  gap: {
25
37
  type: PropType<"none" | "xs" | "s" | "m" | "l" | "xl" | null>;
26
38
  default: null;
27
39
  };
40
+ height: {
41
+ type: PropType<number | null>;
42
+ default: null;
43
+ };
28
44
  justify: {
29
45
  type: PropType<"start" | "center" | "end" | "between" | null>;
30
46
  default: null;
31
47
  };
32
48
  }>> & Readonly<{}>, {
49
+ fill: boolean | null;
50
+ height: number | null;
33
51
  align: "center" | "start" | "stretch" | "end" | null;
34
52
  gap: "s" | "none" | "xs" | "m" | "l" | "xl" | null;
35
53
  justify: "center" | "start" | "end" | "between" | null;
package/vue/UiStack.vue CHANGED
@@ -16,6 +16,14 @@ const propValidityContract = {
16
16
  'How items sit across the stack: stretch (the default) makes each fill the stack\'s width; start, center, and end keep each at its own width, against the\n start, in the middle, or against the end.',
17
17
  values: ['start', 'center', 'end', 'stretch'],
18
18
  },
19
+ fill: {
20
+ type: { kind: 'terminal', name: 'boolean' },
21
+ required: false,
22
+ target: { attribute: 'fill' },
23
+ description:
24
+ 'Grows into the remaining space of a flex layout and allows its scrolling children to shrink.',
25
+ default: false,
26
+ },
19
27
  gap: {
20
28
  type: { kind: 'terminal', name: 'keyword' },
21
29
  required: false,
@@ -24,6 +32,13 @@ const propValidityContract = {
24
32
  'Space between items, on the spacing scale: none is zero, xs is 0.5rem, s 0.75rem, m 1rem (also the default), l 1.5rem, and xl 2rem. The --ui-stack-gap\n custom property, set on the stack itself, overrides it; set on an ancestor, it does nothing.',
25
33
  values: ['none', 'xs', 's', 'm', 'l', 'xl'],
26
34
  },
35
+ height: {
36
+ type: { kind: 'terminal', name: 'number' },
37
+ required: false,
38
+ target: { attribute: 'height' },
39
+ description:
40
+ 'An optional measured height in CSS pixels, for a viewport-bounded composition. Omit it to retain intrinsic sizing.',
41
+ },
27
42
  justify: {
28
43
  type: { kind: 'terminal', name: 'keyword' },
29
44
  required: false,
@@ -39,16 +54,24 @@ const props = defineProps({
39
54
  type: null as unknown as PropType<'start' | 'center' | 'end' | 'stretch' | null>,
40
55
  default: null,
41
56
  },
57
+ fill: { type: null as unknown as PropType<boolean | null>, default: false },
42
58
  gap: {
43
59
  type: null as unknown as PropType<'none' | 'xs' | 's' | 'm' | 'l' | 'xl' | null>,
44
60
  default: null,
45
61
  },
62
+ height: { type: null as unknown as PropType<number | null>, default: null },
46
63
  justify: {
47
64
  type: null as unknown as PropType<'start' | 'center' | 'end' | 'between' | null>,
48
65
  default: null,
49
66
  },
50
67
  })
51
- const acceptedProps: Record<string, unknown> = { align: null, gap: null, justify: null }
68
+ const acceptedProps: Record<string, unknown> = {
69
+ align: null,
70
+ fill: false,
71
+ gap: null,
72
+ height: null,
73
+ justify: null,
74
+ }
52
75
  const checkedProps = computed(() => ({
53
76
  align: checkedProp<'start' | 'center' | 'end' | 'stretch'>(
54
77
  props['align'],
@@ -57,6 +80,13 @@ const checkedProps = computed(() => ({
57
80
  'align',
58
81
  acceptedProps,
59
82
  ),
83
+ fill: checkedProp<boolean>(
84
+ props['fill'],
85
+ { kind: 'terminal', name: 'boolean' },
86
+ false,
87
+ 'fill',
88
+ acceptedProps,
89
+ ) as boolean,
60
90
  gap: checkedProp<'none' | 'xs' | 's' | 'm' | 'l' | 'xl'>(
61
91
  props['gap'],
62
92
  { kind: 'terminal', name: 'keyword' },
@@ -64,6 +94,13 @@ const checkedProps = computed(() => ({
64
94
  'gap',
65
95
  acceptedProps,
66
96
  ),
97
+ height: checkedProp<number>(
98
+ props['height'],
99
+ { kind: 'terminal', name: 'number' },
100
+ false,
101
+ 'height',
102
+ acceptedProps,
103
+ ),
67
104
  justify: checkedProp<'start' | 'center' | 'end' | 'between'>(
68
105
  props['justify'],
69
106
  { kind: 'terminal', name: 'keyword' },
@@ -127,6 +164,9 @@ if (
127
164
  /** The values the styles' :host-state() rules test. */
128
165
  const hostState = computed(() =>
129
166
  [
167
+ checkedProps.value.fill && 'fill',
168
+ checkedProps.value.height && 'height',
169
+ checkedProps.value.height != null && `height=${checkedProps.value.height}`,
130
170
  checkedProps.value.gap && 'gap',
131
171
  checkedProps.value.gap != null && `gap=${encodeURIComponent(checkedProps.value.gap)}`,
132
172
  checkedProps.value.align && 'align',
@@ -142,9 +182,12 @@ const hostState = computed(() =>
142
182
  <div
143
183
  data-component="ui-stack"
144
184
  v-bind="nativeAttrs($attrs)"
185
+ :style="{ '--ui-stack-height': checkedProps.height ?? undefined }"
145
186
  v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
146
187
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
188
+ :data-fill="reflectedProp('fill', 'fill', checkedProps.fill, undefined, false)"
147
189
  :data-gap="reflectedProp('gap', 'gap', checkedProps.gap, undefined, false)"
190
+ :data-height="reflectedProp('height', 'height', checkedProps.height, undefined, false)"
148
191
  :data-justify="reflectedProp('justify', 'justify', checkedProps.justify, undefined, false)"
149
192
  :data-ui-stack-state="hostState || undefined"
150
193
  >
@@ -154,6 +197,11 @@ const hostState = computed(() =>
154
197
 
155
198
  <style scoped>
156
199
  /* This component's hooks style the element they are set on, and never a nested one. */
200
+ @property --ui-stack-height {
201
+ syntax: "*";
202
+ inherits: false;
203
+ }
204
+
157
205
  @property --ui-stack-gap {
158
206
  syntax: "*";
159
207
  inherits: false;
@@ -170,6 +218,15 @@ const hostState = computed(() =>
170
218
  margin: 0;
171
219
  }
172
220
 
221
+ [data-component~="ui-stack"][data-ui-stack-state~="fill"] {
222
+ flex: 1;
223
+ min-block-size: 0;
224
+ }
225
+ [data-component~="ui-stack"][data-ui-stack-state~="height"] {
226
+ block-size: calc(var(--ui-stack-height, 0) * 1px);
227
+ min-block-size: 0;
228
+ }
229
+
173
230
  [data-component~="ui-stack"][data-ui-stack-state~="gap=none"] {
174
231
  --_layout-gap: 0px;
175
232
  }
package/vue/UiText.d.ts CHANGED
@@ -36,6 +36,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
36
36
  type: PropType<"inherit" | "sans" | null>;
37
37
  default: string;
38
38
  };
39
+ grow: {
40
+ type: PropType<boolean | null>;
41
+ default: boolean;
42
+ };
39
43
  size: {
40
44
  type: PropType<"inherit" | "xs" | "sm" | "md" | "lg" | null>;
41
45
  default: string;
@@ -73,6 +77,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
73
77
  type: PropType<"inherit" | "sans" | null>;
74
78
  default: string;
75
79
  };
80
+ grow: {
81
+ type: PropType<boolean | null>;
82
+ default: boolean;
83
+ };
76
84
  size: {
77
85
  type: PropType<"inherit" | "xs" | "sm" | "md" | "lg" | null>;
78
86
  default: string;
@@ -105,6 +113,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
105
113
  align: "center" | "start" | null;
106
114
  as: "div" | "h2" | "h3" | "h4" | "h5" | "h6" | "label" | "p" | "small" | "span" | "strong" | null;
107
115
  wrap: "normal" | "anywhere" | null;
116
+ grow: boolean | null;
108
117
  truncate: boolean | null;
109
118
  weight: "inherit" | "medium" | "normal" | "semibold" | null;
110
119
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
package/vue/UiText.vue CHANGED
@@ -35,6 +35,14 @@ const propValidityContract = {
35
35
  values: ['inherit', 'sans'],
36
36
  default: 'inherit',
37
37
  },
38
+ grow: {
39
+ type: { kind: 'terminal', name: 'boolean' },
40
+ required: false,
41
+ target: { attribute: 'grow' },
42
+ description:
43
+ 'Lets this text use remaining inline space in a flex row, including when truncated.',
44
+ default: false,
45
+ },
38
46
  size: {
39
47
  type: { kind: 'terminal', name: 'keyword' },
40
48
  required: false,
@@ -98,6 +106,7 @@ const props = defineProps({
98
106
  default: 'p',
99
107
  },
100
108
  font: { type: null as unknown as PropType<'inherit' | 'sans' | null>, default: 'inherit' },
109
+ grow: { type: null as unknown as PropType<boolean | null>, default: false },
101
110
  size: {
102
111
  type: null as unknown as PropType<'inherit' | 'xs' | 'sm' | 'md' | 'lg' | null>,
103
112
  default: 'inherit',
@@ -131,6 +140,7 @@ const acceptedProps: Record<string, unknown> = {
131
140
  align: 'start',
132
141
  as: 'p',
133
142
  font: 'inherit',
143
+ grow: false,
134
144
  size: 'inherit',
135
145
  tone: 'default',
136
146
  truncate: false,
@@ -167,6 +177,13 @@ const checkedProps = computed(() => ({
167
177
  'font',
168
178
  acceptedProps,
169
179
  ) as 'inherit' | 'sans',
180
+ grow: checkedProp<boolean>(
181
+ props['grow'],
182
+ { kind: 'terminal', name: 'boolean' },
183
+ false,
184
+ 'grow',
185
+ acceptedProps,
186
+ ) as boolean,
170
187
  size: checkedProp<'inherit' | 'xs' | 'sm' | 'md' | 'lg'>(
171
188
  props['size'],
172
189
  { kind: 'terminal', name: 'keyword' },
@@ -291,6 +308,7 @@ if (
291
308
  /** The values the styles' :host-state() rules test. */
292
309
  const hostState = computed(() =>
293
310
  [
311
+ checkedProps.value.grow && 'grow',
294
312
  checkedProps.value.size && 'size',
295
313
  checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
296
314
  checkedProps.value.tone && 'tone',
@@ -320,6 +338,7 @@ const hostState = computed(() =>
320
338
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
321
339
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
322
340
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
341
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
323
342
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
324
343
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
325
344
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -337,6 +356,7 @@ const hostState = computed(() =>
337
356
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
338
357
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
339
358
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
359
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
340
360
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
341
361
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
342
362
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -356,6 +376,7 @@ const hostState = computed(() =>
356
376
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
357
377
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
358
378
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
379
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
359
380
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
360
381
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
361
382
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -373,6 +394,7 @@ const hostState = computed(() =>
373
394
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
374
395
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
375
396
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
397
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
376
398
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
377
399
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
378
400
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -390,6 +412,7 @@ const hostState = computed(() =>
390
412
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
391
413
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
392
414
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
415
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
393
416
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
394
417
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
395
418
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -407,6 +430,7 @@ const hostState = computed(() =>
407
430
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
408
431
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
409
432
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
433
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
410
434
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
411
435
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
412
436
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -426,6 +450,7 @@ const hostState = computed(() =>
426
450
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
427
451
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
428
452
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
453
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
429
454
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
430
455
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
431
456
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -445,6 +470,7 @@ const hostState = computed(() =>
445
470
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
446
471
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
447
472
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
473
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
448
474
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
449
475
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
450
476
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -464,6 +490,7 @@ const hostState = computed(() =>
464
490
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
465
491
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
466
492
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
493
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
467
494
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
468
495
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
469
496
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -483,6 +510,7 @@ const hostState = computed(() =>
483
510
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
484
511
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
485
512
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
513
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
486
514
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
487
515
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
488
516
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -502,6 +530,7 @@ const hostState = computed(() =>
502
530
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
503
531
  :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
504
532
  :data-font="reflectedProp('font', 'font', checkedProps.font, undefined, false)"
533
+ :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
505
534
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
506
535
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
507
536
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
@@ -519,6 +548,10 @@ const hostState = computed(() =>
519
548
  /* Running text, set on the type scale and in a tone that says what it is, so a view never styles
520
549
  text of its own. The root is a paragraph unless as= names a span, div, small, strong, label, or
521
550
  heading. */
551
+ [data-component~="ui-text"][data-ui-text-state~="grow"] {
552
+ flex: 1;
553
+ }
554
+
522
555
  [data-component~="ui-text"] {
523
556
  margin: 0;
524
557
  min-inline-size: 0;
@@ -12,6 +12,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
12
12
  type: PropType<boolean | null>;
13
13
  default: boolean;
14
14
  };
15
+ maxRows: {
16
+ type: PropType<number | null>;
17
+ default: null;
18
+ };
15
19
  readonly: {
16
20
  type: PropType<boolean | null>;
17
21
  default: boolean;
@@ -50,6 +54,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
50
54
  type: PropType<boolean | null>;
51
55
  default: boolean;
52
56
  };
57
+ maxRows: {
58
+ type: PropType<number | null>;
59
+ default: null;
60
+ };
53
61
  readonly: {
54
62
  type: PropType<boolean | null>;
55
63
  default: boolean;
@@ -83,6 +91,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
83
91
  disabled: boolean | null;
84
92
  required: boolean | null;
85
93
  readonly: boolean | null;
94
+ maxRows: number | null;
86
95
  autosize: boolean | null;
87
96
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
88
97
  declare const _default: typeof __VLS_export;
@@ -32,6 +32,13 @@ const propValidityContract = {
32
32
  description: 'Exposes invalid state to assistive technology and styling.',
33
33
  default: false,
34
34
  },
35
+ maxRows: {
36
+ type: { kind: 'terminal', name: 'integer' },
37
+ required: false,
38
+ target: { attribute: 'maxrows' },
39
+ description:
40
+ 'Optional maximum visible rows, for a growing field in a bounded layout. Extra text scrolls inside the field. Omit it to retain unbounded growth.',
41
+ },
35
42
  readonly: {
36
43
  type: { kind: 'terminal', name: 'boolean' },
37
44
  required: false,
@@ -75,6 +82,7 @@ const props = defineProps({
75
82
  autosize: { type: null as unknown as PropType<boolean | null>, default: false },
76
83
  disabled: { type: null as unknown as PropType<boolean | null>, default: false },
77
84
  invalid: { type: null as unknown as PropType<boolean | null>, default: false },
85
+ maxRows: { type: null as unknown as PropType<number | null>, default: null },
78
86
  readonly: { type: null as unknown as PropType<boolean | null>, default: false },
79
87
  required: { type: null as unknown as PropType<boolean | null>, default: false },
80
88
  rows: { type: null as unknown as PropType<number | null>, default: 4 },
@@ -86,6 +94,7 @@ const acceptedProps: Record<string, unknown> = {
86
94
  autosize: false,
87
95
  disabled: false,
88
96
  invalid: false,
97
+ maxRows: null,
89
98
  readonly: false,
90
99
  required: false,
91
100
  rows: 4,
@@ -114,6 +123,13 @@ const checkedProps = computed(() => ({
114
123
  'invalid',
115
124
  acceptedProps,
116
125
  ) as boolean,
126
+ maxRows: checkedProp<number>(
127
+ props['maxRows'],
128
+ { kind: 'terminal', name: 'integer' },
129
+ false,
130
+ 'maxRows',
131
+ acceptedProps,
132
+ ),
117
133
  readonly: checkedProp<boolean>(
118
134
  props['readonly'],
119
135
  { kind: 'terminal', name: 'boolean' },
@@ -225,6 +241,8 @@ const hostState = computed(() =>
225
241
  [
226
242
  checkedProps.value.size && 'size',
227
243
  checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
244
+ checkedProps.value.maxRows && 'maxRows',
245
+ checkedProps.value.maxRows != null && `maxRows=${checkedProps.value.maxRows}`,
228
246
  checkedProps.value.autosize && 'autosize',
229
247
  ].filter(Boolean).join(' ')
230
248
  )
@@ -246,7 +264,17 @@ useComponentHost(() => import('../components/ui-textarea/ui-textarea.js'), {
246
264
  ? (incoming[name] ?? incoming[kebab] ?? null)
247
265
  : null
248
266
  },
249
- propNames: ['autosize', 'disabled', 'invalid', 'readonly', 'required', 'rows', 'size', 'value'],
267
+ propNames: [
268
+ 'autosize',
269
+ 'disabled',
270
+ 'invalid',
271
+ 'maxRows',
272
+ 'readonly',
273
+ 'required',
274
+ 'rows',
275
+ 'size',
276
+ 'value',
277
+ ],
250
278
  propValidity: (name: string) =>
251
279
  propValidityState({ contract: propValidityContract, values: { ...props } }, name),
252
280
  })
@@ -261,11 +289,12 @@ useComponentHost(() => import('../components/ui-textarea/ui-textarea.js'), {
261
289
  :required="checkedProps.required ?? undefined"
262
290
  :aria-invalid="checkedProps.invalid ?? undefined"
263
291
  :rows="checkedProps.rows ?? undefined"
264
- :style="{ '--_rows': checkedProps.rows ?? undefined }"
292
+ :style="{ '--_rows': checkedProps.rows ?? undefined, '--_max-rows': checkedProps.maxRows ?? undefined }"
265
293
  v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
266
294
  :data-autosize="reflectedProp('autosize', 'autosize', checkedProps.autosize, undefined, false)"
267
295
  :data-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
268
296
  :data-invalid="reflectedProp('invalid', 'invalid', checkedProps.invalid, undefined, false)"
297
+ :data-max-rows="reflectedProp('maxRows', 'max-rows', checkedProps.maxRows, undefined, false)"
269
298
  :data-readonly="reflectedProp('readonly', 'readonly', checkedProps.readonly, undefined, false)"
270
299
  :data-required="reflectedProp('required', 'required', checkedProps.required, undefined, false)"
271
300
  :data-rows="reflectedProp('rows', 'rows', checkedProps.rows, undefined, false)"
@@ -466,6 +495,12 @@ useComponentHost(() => import('../components/ui-textarea/ui-textarea.js'), {
466
495
  font-size: var(--ui-font-size-md);
467
496
  }
468
497
 
498
+ [data-component~="ui-textarea"][data-ui-textarea-state~="maxRows"] {
499
+ max-block-size: calc(
500
+ max(var(--_rows), var(--_max-rows)) * 1lh + var(--_padding-block) + var(--_padding-block) + 2px
501
+ );
502
+ }
503
+
469
504
  @supports (field-sizing: content) {
470
505
  [data-component~="ui-textarea"][data-ui-textarea-state~="autosize"] {
471
506
  field-sizing: content;
@@ -9,7 +9,11 @@ var _hoisted_1 = [
9
9
  "data-variant",
10
10
  "data-ui-badge-state"
11
11
  ];
12
- var _hoisted_2 = { class: "label" };
12
+ var _hoisted_2 = {
13
+ class: "icon",
14
+ "aria-hidden": "true"
15
+ };
16
+ var _hoisted_3 = { class: "label" };
13
17
  //#endregion
14
18
  //#region .build/vue/UiBadge.vue
15
19
  var UiBadge_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -163,12 +167,12 @@ var UiBadge_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
163
167
  "data-tone": reflectedProp("tone", "tone", checkedProps.value.tone, void 0, false),
164
168
  "data-variant": reflectedProp("variant", "variant", checkedProps.value.variant, void 0, false),
165
169
  "data-ui-badge-state": hostState.value || void 0
166
- }), [createElementVNode("span", _hoisted_2, [renderSlot(_ctx.$slots, "default", {}, void 0, true)])], 16, _hoisted_1)), [[unref(vPropValidity), {
170
+ }), [createElementVNode("span", _hoisted_2, [renderSlot(_ctx.$slots, "icon")]), createElementVNode("span", _hoisted_3, [renderSlot(_ctx.$slots, "default")])], 16, _hoisted_1)), [[unref(vPropValidity), {
167
171
  contract: propValidityContract,
168
172
  values: { ...props }
169
173
  }]]);
170
174
  };
171
175
  }
172
- }), [["__scopeId", "data-v-b1009c5d"]]);
176
+ }), [["__scopeId", "data-v-5065fda2"]]);
173
177
  //#endregion
174
178
  export { UiBadge_default as t };
@@ -755,6 +755,6 @@ var UiButton_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PUR
755
755
  }]]);
756
756
  };
757
757
  }
758
- }), [["__scopeId", "data-v-5c174bca"]]);
758
+ }), [["__scopeId", "data-v-7c2bc2b4"]]);
759
759
  //#endregion
760
760
  export { UiButton_default as t };
@@ -119,8 +119,15 @@ var UiCard_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
119
119
  },
120
120
  required: false,
121
121
  target: { attribute: "tone" },
122
- description: "danger adds a soft danger surface and a strong leading edge for consequential content.",
123
- values: ["neutral", "danger"],
122
+ description: "accent, info, success and warning add a quiet semantic surface. danger retains its strong leading edge for consequential content. Tone never changes child\n controls.",
123
+ values: [
124
+ "neutral",
125
+ "accent",
126
+ "info",
127
+ "success",
128
+ "warning",
129
+ "danger"
130
+ ],
124
131
  default: "neutral"
125
132
  },
126
133
  variant: {
@@ -267,6 +274,6 @@ var UiCard_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
267
274
  }]]);
268
275
  };
269
276
  }
270
- }), [["__scopeId", "data-v-fa2ae386"]]);
277
+ }), [["__scopeId", "data-v-c589f774"]]);
271
278
  //#endregion
272
279
  export { UiCard_default as t };