@threadlabs/looma 0.26.15 → 0.26.16

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.26.15",
3
+ "version": "0.26.16",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",
@@ -38,6 +38,12 @@
38
38
  line-height: var(--ui-line-height-relaxed);
39
39
  }
40
40
 
41
+ /* Opt in at the text owner; trimming does not inherit from a surrounding layout. */
42
+ :scope[data-ui-text-state~="trim"] {
43
+ text-box-trim: trim-both;
44
+ text-box-edge: cap alphabetic;
45
+ }
46
+
41
47
  :scope[data-ui-text-state~="tone=secondary"] {
42
48
  color: var(--ui-text-secondary);
43
49
  }
@@ -91,6 +97,12 @@
91
97
  white-space: nowrap;
92
98
  }
93
99
 
100
+ /* Trim ends the layout box at the baseline; preserve descending ink while clipping long labels. */
101
+ :scope[data-ui-text-state~="trim"][data-ui-text-state~="truncate"] {
102
+ overflow-x: clip;
103
+ overflow-y: visible;
104
+ }
105
+
94
106
  :scope[data-ui-text-state~="align=center"] {
95
107
  text-align: center;
96
108
  }
@@ -115,6 +127,8 @@
115
127
 
116
128
  /* A heading drops the browser's heading size and weight, so size and weight set it as they set
117
129
  any text, and inherit keeps the text around it. */
130
+
131
+ /* Opt in at the text owner; trimming does not inherit from a surrounding layout. */
118
132
  /* Every status tone uses the text-safe token a subtle badge sets its words in, so text and badges
119
133
  in one tone match, and each holds 4.5:1 on sunken surfaces where some base colours fall short. */
120
134
 
@@ -127,5 +141,7 @@
127
141
  text-underline-offset: 0.18em;
128
142
  }
129
143
 
144
+ /* Trim ends the layout box at the baseline; preserve descending ink while clipping long labels. */
145
+
130
146
  /* A component that sets its display still honours the hidden attribute on its root. */
131
147
  }
@@ -12,6 +12,7 @@ export interface UiTextProps {
12
12
  grow?: boolean | null;
13
13
  size?: "inherit" | "xs" | "sm" | "md" | "lg" | null;
14
14
  tone?: "default" | "secondary" | "muted" | "accent" | "danger" | "success" | "info" | "warning" | null;
15
+ trim?: boolean | null;
15
16
  truncate?: boolean | null;
16
17
  variant?: "body" | "eyebrow" | "code" | null;
17
18
  weight?: "inherit" | "normal" | "medium" | "semibold" | null;
package/vanilla/UiText.js CHANGED
@@ -26,13 +26,13 @@ const T20 = ["",[],4];
26
26
  const T21 = ["",[]];
27
27
  let P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21;
28
28
  const S = { n: [], t: [], f: import.meta.url, g: "ui-text" };
29
- const A = [["span",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["div",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["small",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["strong",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["label",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["h2",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["h3",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["h4",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["h5",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["h6",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]],["p",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-truncate","data-variant","data-weight","data-wrap"]]];
29
+ const A = [["span",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["div",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["small",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["strong",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["label",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["h2",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["h3",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["h4",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["h5",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["h6",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]],["p",{},[],"",[],["data-ui-text-state","data-align","data-as","data-font","data-grow","data-size","data-tone","data-trim","data-truncate","data-variant","data-weight","data-wrap"]]];
30
30
  const Q = [[],[],[],[],[],[],[],[],[],[],[]];
31
- const D = { props: { "align": { "required":false,"values":["start","center"],"default":"start", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "as": { "required":false,"values":["p","span","div","small","strong","label","h2","h3","h4","h5","h6"],"default":"p", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "font": { "required":false,"values":["inherit","sans"],"default":"inherit", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "grow": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "size": { "required":false,"values":["inherit","xs","sm","md","lg"],"default":"inherit", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "tone": { "required":false,"values":["default","secondary","muted","accent","danger","success","info","warning"],"default":"default", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "truncate": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "variant": { "required":false,"values":["body","eyebrow","code"],"default":"body", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "weight": { "required":false,"values":["inherit","normal","medium","semibold"],"default":"inherit", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "wrap": { "required":false,"values":["normal","anywhere"],"default":"normal", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
31
+ const D = { props: { "align": { "required":false,"values":["start","center"],"default":"start", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "as": { "required":false,"values":["p","span","div","small","strong","label","h2","h3","h4","h5","h6"],"default":"p", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "font": { "required":false,"values":["inherit","sans"],"default":"inherit", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "grow": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "size": { "required":false,"values":["inherit","xs","sm","md","lg"],"default":"inherit", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "tone": { "required":false,"values":["default","secondary","muted","accent","danger","success","info","warning"],"default":"default", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "trim": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "truncate": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "variant": { "required":false,"values":["body","eyebrow","code"],"default":"body", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "weight": { "required":false,"values":["inherit","normal","medium","semibold"],"default":"inherit", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "wrap": { "required":false,"values":["normal","anywhere"],"default":"normal", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] } } };
32
32
 
33
33
  export function createUiText(options = {}, html) {
34
34
  const { attributes = {}, children = [], slots = {}, ...componentProps } = options;
35
- const v = [null, null, null, null, null, null, null, null, null, null];
35
+ const v = [null, null, null, null, null, null, null, null, null, null, null];
36
36
  acceptProps(undefined, D, S.n, v, componentProps, [], html);
37
37
  let a = ((v[1] === "span") ? 0 : (v[1] === "div") ? 1 : (v[1] === "small") ? 2 : (v[1] === "strong") ? 3 : (v[1] === "label") ? 4 : (v[1] === "h2") ? 5 : (v[1] === "h3") ? 6 : (v[1] === "h4") ? 7 : (v[1] === "h5") ? 8 : (v[1] === "h6") ? 9 : 10);
38
38
  let element;
@@ -211,8 +211,8 @@ export function createUiText(options = {}, html) {
211
211
  return r;
212
212
  };
213
213
  const p0 = (r, c, d) => {
214
- if (c & 1021) {
215
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
214
+ if (c & 2045) {
215
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
216
216
  const s0 = x0;
217
217
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
218
218
  }
@@ -228,8 +228,8 @@ export function createUiText(options = {}, html) {
228
228
  return r;
229
229
  };
230
230
  const p2 = (r, c, d) => {
231
- if (c & 1021) {
232
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
231
+ if (c & 2045) {
232
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
233
233
  const s0 = x0;
234
234
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
235
235
  }
@@ -245,8 +245,8 @@ export function createUiText(options = {}, html) {
245
245
  return r;
246
246
  };
247
247
  const p4 = (r, c, d) => {
248
- if (c & 1021) {
249
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
248
+ if (c & 2045) {
249
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
250
250
  const s0 = x0;
251
251
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
252
252
  }
@@ -262,8 +262,8 @@ export function createUiText(options = {}, html) {
262
262
  return r;
263
263
  };
264
264
  const p6 = (r, c, d) => {
265
- if (c & 1021) {
266
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
265
+ if (c & 2045) {
266
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
267
267
  const s0 = x0;
268
268
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
269
269
  }
@@ -279,8 +279,8 @@ export function createUiText(options = {}, html) {
279
279
  return r;
280
280
  };
281
281
  const p8 = (r, c, d) => {
282
- if (c & 1021) {
283
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
282
+ if (c & 2045) {
283
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
284
284
  const s0 = x0;
285
285
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
286
286
  }
@@ -296,8 +296,8 @@ export function createUiText(options = {}, html) {
296
296
  return r;
297
297
  };
298
298
  const p10 = (r, c, d) => {
299
- if (c & 1021) {
300
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
299
+ if (c & 2045) {
300
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
301
301
  const s0 = x0;
302
302
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
303
303
  }
@@ -313,8 +313,8 @@ export function createUiText(options = {}, html) {
313
313
  return r;
314
314
  };
315
315
  const p12 = (r, c, d) => {
316
- if (c & 1021) {
317
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
316
+ if (c & 2045) {
317
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
318
318
  const s0 = x0;
319
319
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
320
320
  }
@@ -330,8 +330,8 @@ export function createUiText(options = {}, html) {
330
330
  return r;
331
331
  };
332
332
  const p14 = (r, c, d) => {
333
- if (c & 1021) {
334
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
333
+ if (c & 2045) {
334
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
335
335
  const s0 = x0;
336
336
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
337
337
  }
@@ -347,8 +347,8 @@ export function createUiText(options = {}, html) {
347
347
  return r;
348
348
  };
349
349
  const p16 = (r, c, d) => {
350
- if (c & 1021) {
351
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
350
+ if (c & 2045) {
351
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
352
352
  const s0 = x0;
353
353
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
354
354
  }
@@ -364,8 +364,8 @@ export function createUiText(options = {}, html) {
364
364
  return r;
365
365
  };
366
366
  const p18 = (r, c, d) => {
367
- if (c & 1021) {
368
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
367
+ if (c & 2045) {
368
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
369
369
  const s0 = x0;
370
370
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
371
371
  }
@@ -381,8 +381,8 @@ export function createUiText(options = {}, html) {
381
381
  return r;
382
382
  };
383
383
  const p20 = (r, c, d) => {
384
- if (c & 1021) {
385
- const x0 = hostState(["grow","size","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[5], v[8], v[7], v[6], v[0], v[2], v[9]]);
384
+ if (c & 2045) {
385
+ const x0 = hostState(["grow","size","trim","tone","weight","variant","truncate","align","font","wrap"], [v[3], v[4], v[6], v[5], v[9], v[8], v[7], v[0], v[2], v[10]]);
386
386
  const s0 = x0;
387
387
  if (s0 !== r.v0) writeAttribute(r.n, "data-ui-text-state", (r.v0 = s0) === "" ? null : s0);
388
388
  }
package/vue/UiText.d.ts CHANGED
@@ -48,6 +48,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
48
48
  type: PropType<"default" | "secondary" | "muted" | "accent" | "danger" | "success" | "info" | "warning" | null>;
49
49
  default: string;
50
50
  };
51
+ trim: {
52
+ type: PropType<boolean | null>;
53
+ default: boolean;
54
+ };
51
55
  truncate: {
52
56
  type: PropType<boolean | null>;
53
57
  default: boolean;
@@ -89,6 +93,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
89
93
  type: PropType<"default" | "secondary" | "muted" | "accent" | "danger" | "success" | "info" | "warning" | null>;
90
94
  default: string;
91
95
  };
96
+ trim: {
97
+ type: PropType<boolean | null>;
98
+ default: boolean;
99
+ };
92
100
  truncate: {
93
101
  type: PropType<boolean | null>;
94
102
  default: boolean;
@@ -113,6 +121,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
113
121
  align: "center" | "start" | null;
114
122
  as: "div" | "h2" | "h3" | "h4" | "h5" | "h6" | "label" | "p" | "small" | "span" | "strong" | null;
115
123
  wrap: "normal" | "anywhere" | null;
124
+ trim: boolean | null;
116
125
  grow: boolean | null;
117
126
  truncate: boolean | null;
118
127
  weight: "inherit" | "medium" | "normal" | "semibold" | null;
package/vue/UiText.vue CHANGED
@@ -61,6 +61,14 @@ const propValidityContract = {
61
61
  values: ['default', 'secondary', 'muted', 'accent', 'danger', 'success', 'info', 'warning'],
62
62
  default: 'default',
63
63
  },
64
+ trim: {
65
+ type: { kind: 'terminal', name: 'boolean' },
66
+ required: false,
67
+ target: { attribute: 'trim' },
68
+ description:
69
+ 'Removes extra font space above the capital height and below the baseline, for compact headings and labels. Prose keeps its existing line-edge space by\n default. Browsers without text-box-trim retain normal font metrics.',
70
+ default: false,
71
+ },
64
72
  truncate: {
65
73
  type: { kind: 'terminal', name: 'boolean' },
66
74
  required: false,
@@ -125,6 +133,7 @@ const props = defineProps({
125
133
  >,
126
134
  default: 'default',
127
135
  },
136
+ trim: { type: null as unknown as PropType<boolean | null>, default: false },
128
137
  truncate: { type: null as unknown as PropType<boolean | null>, default: false },
129
138
  variant: {
130
139
  type: null as unknown as PropType<'body' | 'eyebrow' | 'code' | null>,
@@ -143,6 +152,7 @@ const acceptedProps: Record<string, unknown> = {
143
152
  grow: false,
144
153
  size: 'inherit',
145
154
  tone: 'default',
155
+ trim: false,
146
156
  truncate: false,
147
157
  variant: 'body',
148
158
  weight: 'inherit',
@@ -202,6 +212,13 @@ const checkedProps = computed(() => ({
202
212
  | 'success'
203
213
  | 'info'
204
214
  | 'warning',
215
+ trim: checkedProp<boolean>(
216
+ props['trim'],
217
+ { kind: 'terminal', name: 'boolean' },
218
+ false,
219
+ 'trim',
220
+ acceptedProps,
221
+ ) as boolean,
205
222
  truncate: checkedProp<boolean>(
206
223
  props['truncate'],
207
224
  { kind: 'terminal', name: 'boolean' },
@@ -311,6 +328,7 @@ const hostState = computed(() =>
311
328
  checkedProps.value.grow && 'grow',
312
329
  checkedProps.value.size && 'size',
313
330
  checkedProps.value.size != null && `size=${encodeURIComponent(checkedProps.value.size)}`,
331
+ checkedProps.value.trim && 'trim',
314
332
  checkedProps.value.tone && 'tone',
315
333
  checkedProps.value.tone != null && `tone=${encodeURIComponent(checkedProps.value.tone)}`,
316
334
  checkedProps.value.weight && 'weight',
@@ -341,6 +359,7 @@ const hostState = computed(() =>
341
359
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
342
360
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
343
361
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
362
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
344
363
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
345
364
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
346
365
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -359,6 +378,7 @@ const hostState = computed(() =>
359
378
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
360
379
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
361
380
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
381
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
362
382
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
363
383
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
364
384
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -379,6 +399,7 @@ const hostState = computed(() =>
379
399
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
380
400
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
381
401
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
402
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
382
403
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
383
404
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
384
405
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -397,6 +418,7 @@ const hostState = computed(() =>
397
418
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
398
419
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
399
420
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
421
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
400
422
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
401
423
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
402
424
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -415,6 +437,7 @@ const hostState = computed(() =>
415
437
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
416
438
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
417
439
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
440
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
418
441
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
419
442
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
420
443
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -433,6 +456,7 @@ const hostState = computed(() =>
433
456
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
434
457
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
435
458
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
459
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
436
460
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
437
461
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
438
462
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -453,6 +477,7 @@ const hostState = computed(() =>
453
477
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
454
478
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
455
479
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
480
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
456
481
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
457
482
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
458
483
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -473,6 +498,7 @@ const hostState = computed(() =>
473
498
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
474
499
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
475
500
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
501
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
476
502
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
477
503
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
478
504
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -493,6 +519,7 @@ const hostState = computed(() =>
493
519
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
494
520
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
495
521
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
522
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
496
523
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
497
524
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
498
525
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -513,6 +540,7 @@ const hostState = computed(() =>
513
540
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
514
541
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
515
542
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
543
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
516
544
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
517
545
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
518
546
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -533,6 +561,7 @@ const hostState = computed(() =>
533
561
  :data-grow="reflectedProp('grow', 'grow', checkedProps.grow, undefined, false)"
534
562
  :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
535
563
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
564
+ :data-trim="reflectedProp('trim', 'trim', checkedProps.trim, undefined, false)"
536
565
  :data-truncate="reflectedProp('truncate', 'truncate', checkedProps.truncate, undefined, false)"
537
566
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
538
567
  :data-weight="reflectedProp('weight', 'weight', checkedProps.weight, undefined, false)"
@@ -583,6 +612,12 @@ const hostState = computed(() =>
583
612
  line-height: var(--ui-line-height-relaxed);
584
613
  }
585
614
 
615
+ /* Opt in at the text owner; trimming does not inherit from a surrounding layout. */
616
+ [data-component~="ui-text"][data-ui-text-state~="trim"] {
617
+ text-box-trim: trim-both;
618
+ text-box-edge: cap alphabetic;
619
+ }
620
+
586
621
  [data-component~="ui-text"][data-ui-text-state~="tone=secondary"] {
587
622
  color: var(--ui-text-secondary);
588
623
  }
@@ -642,6 +677,12 @@ const hostState = computed(() =>
642
677
  white-space: nowrap;
643
678
  }
644
679
 
680
+ /* Trim ends the layout box at the baseline; preserve descending ink while clipping long labels. */
681
+ [data-component~="ui-text"][data-ui-text-state~="trim"][data-ui-text-state~="truncate"] {
682
+ overflow-x: clip;
683
+ overflow-y: visible;
684
+ }
685
+
645
686
  [data-component~="ui-text"][data-ui-text-state~="align=center"] {
646
687
  text-align: center;
647
688
  }