@kanso-labs/kanso-ui 0.40.8 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/color-scheme.d.ts +6 -0
  2. package/dist/color-scheme.js +9 -2
  3. package/dist/color-scheme.js.map +1 -1
  4. package/dist/components/app-bar/index.d.ts +11 -2
  5. package/dist/components/app-bar/index.js +53 -46
  6. package/dist/components/app-bar/index.js.map +1 -1
  7. package/dist/components/avatar/index.d.ts +7 -0
  8. package/dist/components/avatar/index.js.map +1 -1
  9. package/dist/components/badge/index.js +7 -3
  10. package/dist/components/badge/index.js.map +1 -1
  11. package/dist/components/card/index.d.ts +12 -1
  12. package/dist/components/card/index.js +136 -66
  13. package/dist/components/card/index.js.map +1 -1
  14. package/dist/components/dialog/index.js +3 -2
  15. package/dist/components/dialog/index.js.map +1 -1
  16. package/dist/components/popover/index.d.ts +4 -1
  17. package/dist/components/popover/index.js +241 -138
  18. package/dist/components/popover/index.js.map +1 -1
  19. package/dist/components/product-icon/index.d.ts +3 -1
  20. package/dist/components/product-icon/index.js.map +1 -1
  21. package/dist/components/progress-indicator/index.js +1 -1
  22. package/dist/components/progress-indicator/index.js.map +1 -1
  23. package/dist/components/search-field/index.js +7 -3
  24. package/dist/components/search-field/index.js.map +1 -1
  25. package/dist/components/segmented-button/index.d.ts +20 -1
  26. package/dist/components/segmented-button/index.js +253 -114
  27. package/dist/components/segmented-button/index.js.map +1 -1
  28. package/dist/components/separator/index.js +2 -2
  29. package/dist/components/separator/index.js.map +1 -1
  30. package/dist/components/sheet/index.js +17 -16
  31. package/dist/components/sheet/index.js.map +1 -1
  32. package/dist/components/snackbar/index.d.ts +10 -3
  33. package/dist/components/snackbar/index.js +32 -12
  34. package/dist/components/snackbar/index.js.map +1 -1
  35. package/dist/components/switch/index.js +12 -3
  36. package/dist/components/switch/index.js.map +1 -1
  37. package/dist/components/toolbar/index.d.ts +3 -2
  38. package/dist/components/toolbar/index.js +3 -2
  39. package/dist/components/toolbar/index.js.map +1 -1
  40. package/dist/field/index.js +67 -61
  41. package/dist/field/index.js.map +1 -1
  42. package/dist/field/press.js +27 -0
  43. package/dist/field/press.js.map +1 -0
  44. package/dist/mark/initials.js +41 -26
  45. package/dist/mark/initials.js.map +1 -1
  46. package/dist/overlay/index.js +24 -0
  47. package/dist/overlay/index.js.map +1 -0
  48. package/dist/styles/scheme.js +19 -0
  49. package/dist/styles/scheme.js.map +1 -0
  50. package/dist/styles.css +106 -34
  51. package/dist/theme-scope.d.ts +5 -2
  52. package/dist/theme-scope.js +2 -1
  53. package/dist/theme-scope.js.map +1 -1
  54. package/package.json +1 -1
@@ -5,6 +5,15 @@ import { ToggleButtonGroupProps, ToggleButtonProps } from "react-aria-components
5
5
  type SegmentedButtonProps = LabelledByAttribute & Omit<ToggleButtonGroupProps, 'className' | 'orientation' | 'style'> & {
6
6
  /** A function may compute the class from the set's render state. */
7
7
  className?: ToggleButtonGroupProps['className'];
8
+ /**
9
+ * Whether the chosen segment stays chosen when it is pressed again. On
10
+ * by default while one is chosen, since a radio group always holds a
11
+ * choice; `false` lets a press clear it, as React Aria's own default
12
+ * does. Off by default while several may be, where any of them can be
13
+ * turned off.
14
+ * @default true while one is chosen, false while several may be
15
+ */
16
+ disallowEmptySelection?: boolean;
8
17
  /**
9
18
  * Whether a chosen segment draws a check before its label, as the page
10
19
  * has it. `false` leaves the segment's own icon in place while selected,
@@ -31,6 +40,9 @@ type SegmentedButtonSegmentProps = Omit<ToggleButtonProps, 'children' | 'classNa
31
40
  * An icon before the label, in the page's 18dp size. Replaced by the check
32
41
  * while the segment is chosen, unless the set turns that off. An icon drawn
33
42
  * in `em` takes that size from the slot.
43
+ *
44
+ * Given with no label, the icon is the segment, centred in it and kept
45
+ * while chosen; name the segment with `aria-label` then.
34
46
  */
35
47
  icon?: ReactNode;
36
48
  /** A function may compute the style from the segment's render state. */
@@ -57,10 +69,17 @@ type SegmentedButtonSegmentProps = Omit<ToggleButtonProps, 'children' | 'classNa
57
69
  * how the chosen container moves: it slides between segments while one is
58
70
  * chosen, and fades in place while several may be.
59
71
  *
72
+ * Choosing one behaves as a radio group too, which React Aria's
73
+ * `ToggleButtonGroup` does not. The chosen segment stays chosen when it is
74
+ * pressed again, unless `disallowEmptySelection` is `false`. The arrow keys
75
+ * move to a segment and choose it, wrapping at either end, and Home and End
76
+ * choose the first and last. Choosing several keeps React Aria's keys: the
77
+ * arrows move between segments, and Space or Enter toggles the focused one.
78
+ *
60
79
  * The call site's `className` and `style` land on the track, which is the
61
80
  * element a layout positions.
62
81
  */
63
- declare function SegmentedButton({ selectionMode, showSelectedIcon, ...props }: RefAttributes<HTMLDivElement> & SegmentedButtonProps): import("react").JSX.Element;
82
+ declare function SegmentedButton({ disallowEmptySelection, render, selectionMode, showSelectedIcon, ...props }: RefAttributes<HTMLDivElement> & SegmentedButtonProps): import("react").JSX.Element;
64
83
  declare namespace SegmentedButton {
65
84
  var Segment: typeof SegmentedButtonSegment;
66
85
  }
@@ -8,40 +8,61 @@ import { focus } from "../../styles/focus.js";
8
8
  import { useToggleGroupDisabled } from "../../hooks/useToggleGroupDisabled.js";
9
9
  import { useRipple } from "../../hooks/useRipple.js";
10
10
  import { c } from "react/compiler-runtime";
11
- import { createContext, useContext } from "react";
11
+ import { createContext, createElement, useContext, useLayoutEffect, useState } from "react";
12
12
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
13
  import { SelectionIndicator, ToggleButton, ToggleButtonGroup } from "react-aria-components";
14
14
  //#region src/components/segmented-button/index.tsx
15
15
  const ShowSelectedIconContext = createContext(true);
16
16
  const SelectionModeContext = createContext("single");
17
+ function keyOf(segment) {
18
+ const written = segment.dataset.key;
19
+ if (written === void 0) return null;
20
+ const key = JSON.parse(written);
21
+ return typeof key === "string" || typeof key === "number" ? key : null;
22
+ }
23
+ function radioGroupRenderer(render) {
24
+ return (domProps, renderProps) => {
25
+ const merged = {
26
+ ...domProps,
27
+ onKeyDownCapture: radioKeys(renderProps.state, domProps.onKeyDownCapture)
28
+ };
29
+ return render === void 0 ? createElement("div", merged) : render(merged, renderProps);
30
+ };
31
+ }
32
+ function radioKeys(state, toolbar) {
33
+ return (event) => {
34
+ const group = event.currentTarget;
35
+ const segments = [...group.querySelectorAll("[data-key]:not([data-disabled])")].filter((segment) => segment.closest("[role=\"radiogroup\"]") === group);
36
+ const from = segments.findIndex((segment) => segment === event.target);
37
+ const step = event.altKey || event.ctrlKey || event.metaKey ? null : stepOf(event.key, getComputedStyle(group).direction === "rtl");
38
+ if (from === -1 || step === null) {
39
+ toolbar?.(event);
40
+ return;
41
+ }
42
+ event.preventDefault();
43
+ event.stopPropagation();
44
+ const segment = segments[step === "first" ? 0 : step === "last" ? segments.length - 1 : (from + step + segments.length) % segments.length];
45
+ const key = keyOf(segment);
46
+ if (key === null) return;
47
+ segment.focus();
48
+ state.setSelected(key, true);
49
+ };
50
+ }
51
+ function stepOf(key, rtl) {
52
+ switch (key) {
53
+ case "ArrowDown": return 1;
54
+ case "ArrowLeft": return rtl ? 1 : -1;
55
+ case "ArrowRight": return rtl ? -1 : 1;
56
+ case "ArrowUp": return -1;
57
+ case "End": return "last";
58
+ case "Home": return "first";
59
+ default: return null;
60
+ }
61
+ }
17
62
  `${spacing.sm}`;
18
63
  `${spacing.sm}`;
64
+ `${spacing.md}${spacing.sm}`;
19
65
  const styles = {
20
- label: {
21
- k6CgDc: "x12w9bfk",
22
- k7Eaqz: "xeuugli",
23
- kVQacm: "xb3r6kr",
24
- kg5iWk: "xlyipyv",
25
- kIyJzY: "x1qno0dh",
26
- k1ekBW: "x1ve1rmq",
27
- kAMwcw: "xpc4ca7",
28
- khDVqt: "xuxw1ft",
29
- $$css: true
30
- },
31
- labelChosen: {
32
- kAXs8y: "x1g12otp",
33
- $$css: true
34
- },
35
- labelReserved: {
36
- k71WvV: "x184gv5z",
37
- keTefX: "x1mjqfaz",
38
- $$css: true
39
- },
40
- labelShifted: {
41
- k71WvV: "x14z9mp",
42
- keTefX: "x1c5lys2",
43
- $$css: true
44
- },
45
66
  segment: {
46
67
  "--segment-indicator-radius-end": "x32u3vw x111hk5a",
47
68
  "--segment-indicator-radius-start": "xatjrgw x1syycwj",
@@ -72,7 +93,7 @@ const styles = {
72
93
  kLWn49: "x1lz68p4",
73
94
  k7Eaqz: "xeuugli",
74
95
  k8WAf4: "xt970qd",
75
- kg3NbH: "x18fpw6u",
96
+ kg3NbH: "xn60lsn",
76
97
  kVAEAm: "x1n2onr6",
77
98
  kIyJzY: "x1qno0dh",
78
99
  k1ekBW: "xt3l3uh",
@@ -96,6 +117,34 @@ const styles = {
96
117
  segmentUnselected: {
97
118
  kMwMTN: "x139gbkf",
98
119
  $$css: true
120
+ },
121
+ spacer: {
122
+ k6CgDc: "x12w9bfk",
123
+ kGNEyG: "x6s0dn4",
124
+ kB7OPa: "x9f619",
125
+ k1xSpc: "x78zum5",
126
+ kmuXW: "xs83m0k",
127
+ kzqmXN: "xbraz1g",
128
+ kjj79g: "x13a6bvl",
129
+ k7Eaqz: "xeuugli",
130
+ kIyJzY: "x1qno0dh",
131
+ k1ekBW: "x1pha8k4",
132
+ kAMwcw: "xpc4ca7",
133
+ $$css: true
134
+ },
135
+ spacerHalf: {
136
+ kzqmXN: "x154zo0h",
137
+ $$css: true
138
+ },
139
+ spacerHolding: {
140
+ kzqmXN: "x1n85vuq",
141
+ k7Eaqz: "x36sgg7",
142
+ $$css: true
143
+ },
144
+ spacerIcon: {
145
+ kzqmXN: "x1iuy3mw",
146
+ k7Eaqz: "x16xo4sp",
147
+ $$css: true
99
148
  }
100
149
  };
101
150
  /**
@@ -105,11 +154,14 @@ const styles = {
105
154
  * type be inferred, since `ReactNode` is a union that includes a promise and
106
155
  * an inferred one has to be `async`.
107
156
  */
108
- function glyphFor(state, icon, showSelectedIcon) {
109
- if (state.isSelected && showSelectedIcon) return /* @__PURE__ */ jsx(CheckGlyph, { className: "x5yr21d x2lah0s x1xp8n7a" });
157
+ function glyphFor(state, icon, marked) {
158
+ if (state.isSelected && marked) return /* @__PURE__ */ jsx(CheckGlyph, { className: "x5yr21d x2lah0s x1xp8n7a" });
110
159
  return icon ?? null;
111
160
  }
112
- function indicatorClassName(isDisabled, selectionMode, showSelectedIcon) {
161
+ function hasLabel(children) {
162
+ return children !== void 0 && children !== null && children !== false && children !== "";
163
+ }
164
+ function indicatorClassName(isDisabled, selectionMode, marked) {
113
165
  return (state) => ({
114
166
  0: { className: "x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd" },
115
167
  8: { className: "x15dekr4 x1jzqe4 xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7" },
@@ -127,14 +179,16 @@ function indicatorClassName(isDisabled, selectionMode, showSelectedIcon) {
127
179
  11: { className: "xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk" },
128
180
  7: { className: "xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk xioksi3 x1c42kcb x1seskgd xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk" },
129
181
  15: { className: "xrldhhw x12tjb6f x1g25zgg xleywy5 x9f619 x1jz8bvi x47corl x10l6tqk x8knxv4 x12w9bfk x1qno0dh x19991ni xpc4ca7 xepofeg x9yvj25 xmnqt3w xx61lck x2h6xq1 xg01cxk" }
130
- })[!!(selectionMode === "multiple") << 3 | !!!showSelectedIcon << 2 | !!isDisabled << 1 | !!(state.isEntering || state.isExiting) << 0].className ?? "";
182
+ })[!!(selectionMode === "multiple") << 3 | !!!marked << 2 | !!isDisabled << 1 | !!(state.isEntering || state.isExiting) << 0].className ?? "";
131
183
  }
132
- function segmentContent(children, icon, ripple, selectionMode, showSelectedIcon) {
133
- const reserves = showSelectedIcon || icon !== void 0;
184
+ function segmentContent(children, icon, ripple, selectionMode, marked, labelRef, labelTitle) {
185
+ const labelled = hasLabel(children);
186
+ const reserves = marked || icon !== void 0;
134
187
  return (state) => {
135
- const glyph = glyphFor(state, icon, showSelectedIcon);
188
+ const glyph = glyphFor(state, icon, marked);
189
+ const drawn = glyph !== null;
136
190
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
137
- /* @__PURE__ */ jsx(SelectionIndicator, { className: indicatorClassName(state.isDisabled, selectionMode, showSelectedIcon) }),
191
+ /* @__PURE__ */ jsx(SelectionIndicator, { className: indicatorClassName(state.isDisabled, selectionMode, marked) }),
138
192
  /* @__PURE__ */ jsx("span", { ...{
139
193
  0: { className: "x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi xg01cxk x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4" },
140
194
  4: { className: "x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xe2qvxb" },
@@ -145,17 +199,33 @@ function segmentContent(children, icon, ripple, selectionMode, showSelectedIcon)
145
199
  3: { className: "x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g" },
146
200
  7: { className: "x12w9bfk xtwfq29 x1pjcqnp x9f619 x1jz8bvi x47corl x10l6tqk x1qno0dh x19991ni xpc4ca7 x8knxv4 xjg27g" }
147
201
  }[!!state.isHovered << 2 | !!state.isFocusVisible << 1 | !!state.isPressed << 0] }),
148
- reserves && /* @__PURE__ */ jsx("span", {
149
- ...{
150
- 0: { className: "x12w9bfk x6s0dn4 xmix8c7 x3nfvp2 xosj86m xnalus7 xwa60dl x2xyl1b xl56j7k xb3r6kr x47corl x10l6tqk xmzmy3r x1qno0dh x1j4rzew xpc4ca7" },
151
- 1: { className: "x12w9bfk x6s0dn4 xmix8c7 x3nfvp2 xosj86m xwa60dl x2xyl1b xl56j7k xb3r6kr x47corl x10l6tqk xmzmy3r x1qno0dh x1j4rzew xpc4ca7 x1xp8n7a" }
152
- }[!!(glyph !== null) << 0],
153
- children: glyph
154
- }),
155
202
  /* @__PURE__ */ jsx("span", {
156
- ...props(styles.label, reserves && (glyph === null ? styles.labelReserved : styles.labelShifted), state.isSelected && !state.isDisabled && styles.labelChosen),
203
+ ...props(styles.spacer, reserves && (drawn ? labelled ? styles.spacerHolding : styles.spacerIcon : styles.spacerHalf)),
204
+ children: reserves && /* @__PURE__ */ jsx("span", {
205
+ ...{
206
+ 0: { className: "x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xnalus7 xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7" },
207
+ 2: { className: "x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1xp8n7a" },
208
+ 1: { className: "x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xnalus7 xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1nsf9p3" },
209
+ 3: { className: "x12w9bfk x6s0dn4 xmix8c7 x9f619 x3nfvp2 x2lah0s xosj86m xl56j7k xb3r6kr x47corl x1qno0dh x1gcwfje xpc4ca7 x1xp8n7a x1nsf9p3" }
210
+ }[!!drawn << 1 | !!(drawn && labelled) << 0],
211
+ children: glyph
212
+ })
213
+ }),
214
+ labelled && /* @__PURE__ */ jsx("span", {
215
+ ref: labelRef,
216
+ title: labelTitle,
217
+ ...{
218
+ 0: { className: "x12w9bfk x2lah0s x193iq5w xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft" },
219
+ 2: { className: "x12w9bfk x2lah0s xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1tpxo8" },
220
+ 1: { className: "x12w9bfk x2lah0s x193iq5w xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1g12otp" },
221
+ 3: { className: "x12w9bfk x2lah0s xeuugli xb3r6kr xlyipyv x1qno0dh xrtqwew xpc4ca7 xuxw1ft x1tpxo8 x1g12otp" }
222
+ }[!!drawn << 1 | !!(state.isSelected && !state.isDisabled) << 0],
157
223
  children
158
224
  }),
225
+ /* @__PURE__ */ jsx("span", { ...{
226
+ 0: { className: "x12w9bfk x6s0dn4 x9f619 x78zum5 xs83m0k xbraz1g x13a6bvl xeuugli x1qno0dh x1pha8k4 xpc4ca7" },
227
+ 1: { className: "x12w9bfk x6s0dn4 x9f619 x78zum5 xs83m0k x13a6bvl xeuugli x1qno0dh x1pha8k4 xpc4ca7 x154zo0h" }
228
+ }[!!(reserves && !drawn) << 0] }),
159
229
  ripple.surface
160
230
  ] });
161
231
  };
@@ -181,11 +251,18 @@ function segmentContent(children, icon, ripple, selectionMode, showSelectedIcon)
181
251
  * how the chosen container moves: it slides between segments while one is
182
252
  * chosen, and fades in place while several may be.
183
253
  *
254
+ * Choosing one behaves as a radio group too, which React Aria's
255
+ * `ToggleButtonGroup` does not. The chosen segment stays chosen when it is
256
+ * pressed again, unless `disallowEmptySelection` is `false`. The arrow keys
257
+ * move to a segment and choose it, wrapping at either end, and Home and End
258
+ * choose the first and last. Choosing several keeps React Aria's keys: the
259
+ * arrows move between segments, and Space or Enter toggles the focused one.
260
+ *
184
261
  * The call site's `className` and `style` land on the track, which is the
185
262
  * element a layout positions.
186
263
  */
187
264
  function SegmentedButton(t0) {
188
- const $ = c(22);
265
+ const $ = c(29);
189
266
  let T0;
190
267
  let T1;
191
268
  let T2;
@@ -194,18 +271,28 @@ function SegmentedButton(t0) {
194
271
  let t3;
195
272
  let t4;
196
273
  let t5;
274
+ let t6;
275
+ let t7;
197
276
  if ($[0] !== t0) {
198
- const { selectionMode: t6, showSelectedIcon: t7, ...props } = t0;
199
- const selectionMode = t6 === void 0 ? "single" : t6;
200
- const showSelectedIcon = t7 === void 0 ? true : t7;
277
+ const { disallowEmptySelection, render, selectionMode: t8, showSelectedIcon: t9, ...props } = t0;
278
+ const selectionMode = t8 === void 0 ? "single" : t8;
279
+ const showSelectedIcon = t9 === void 0 ? true : t9;
280
+ const single = selectionMode === "single";
201
281
  T2 = ShowSelectedIconContext;
202
- t5 = showSelectedIcon;
282
+ t7 = showSelectedIcon;
203
283
  T1 = SelectionModeContext;
204
- t4 = selectionMode;
284
+ t6 = selectionMode;
205
285
  T0 = ToggleButtonGroup;
206
286
  t1 = props;
207
- t2 = selectionMode;
208
- t3 = mergeStatefulStyles({ className: "x9f619 xwz0xwf xu6a5m6 x1mt1orb xc8icb0" }, props);
287
+ t2 = disallowEmptySelection ?? single;
288
+ if ($[11] !== render || $[12] !== single) {
289
+ t3 = single ? radioGroupRenderer(render) : render;
290
+ $[11] = render;
291
+ $[12] = single;
292
+ $[13] = t3;
293
+ } else t3 = $[13];
294
+ t4 = selectionMode;
295
+ t5 = mergeStatefulStyles({ className: "x9f619 xwz0xwf xu6a5m6 x1mt1orb xc8icb0" }, props);
209
296
  $[0] = t0;
210
297
  $[1] = T0;
211
298
  $[2] = T1;
@@ -215,6 +302,8 @@ function SegmentedButton(t0) {
215
302
  $[6] = t3;
216
303
  $[7] = t4;
217
304
  $[8] = t5;
305
+ $[9] = t6;
306
+ $[10] = t7;
218
307
  } else {
219
308
  T0 = $[1];
220
309
  T1 = $[2];
@@ -224,43 +313,49 @@ function SegmentedButton(t0) {
224
313
  t3 = $[6];
225
314
  t4 = $[7];
226
315
  t5 = $[8];
316
+ t6 = $[9];
317
+ t7 = $[10];
227
318
  }
228
- let t6;
229
- if ($[9] !== T0 || $[10] !== t1 || $[11] !== t2 || $[12] !== t3) {
230
- t6 = /* @__PURE__ */ jsx(T0, {
319
+ let t8;
320
+ if ($[14] !== T0 || $[15] !== t1 || $[16] !== t2 || $[17] !== t3 || $[18] !== t4 || $[19] !== t5) {
321
+ t8 = /* @__PURE__ */ jsx(T0, {
231
322
  ...t1,
232
- selectionMode: t2,
233
- ...t3
323
+ disallowEmptySelection: t2,
324
+ render: t3,
325
+ selectionMode: t4,
326
+ ...t5
234
327
  });
235
- $[9] = T0;
236
- $[10] = t1;
237
- $[11] = t2;
238
- $[12] = t3;
239
- $[13] = t6;
240
- } else t6 = $[13];
241
- let t7;
242
- if ($[14] !== T1 || $[15] !== t4 || $[16] !== t6) {
243
- t7 = /* @__PURE__ */ jsx(T1, {
244
- value: t4,
245
- children: t6
328
+ $[14] = T0;
329
+ $[15] = t1;
330
+ $[16] = t2;
331
+ $[17] = t3;
332
+ $[18] = t4;
333
+ $[19] = t5;
334
+ $[20] = t8;
335
+ } else t8 = $[20];
336
+ let t9;
337
+ if ($[21] !== T1 || $[22] !== t6 || $[23] !== t8) {
338
+ t9 = /* @__PURE__ */ jsx(T1, {
339
+ value: t6,
340
+ children: t8
246
341
  });
247
- $[14] = T1;
248
- $[15] = t4;
249
- $[16] = t6;
250
- $[17] = t7;
251
- } else t7 = $[17];
252
- let t8;
253
- if ($[18] !== T2 || $[19] !== t5 || $[20] !== t7) {
254
- t8 = /* @__PURE__ */ jsx(T2, {
255
- value: t5,
256
- children: t7
342
+ $[21] = T1;
343
+ $[22] = t6;
344
+ $[23] = t8;
345
+ $[24] = t9;
346
+ } else t9 = $[24];
347
+ let t10;
348
+ if ($[25] !== T2 || $[26] !== t7 || $[27] !== t9) {
349
+ t10 = /* @__PURE__ */ jsx(T2, {
350
+ value: t7,
351
+ children: t9
257
352
  });
258
- $[18] = T2;
259
- $[19] = t5;
260
- $[20] = t7;
261
- $[21] = t8;
262
- } else t8 = $[21];
263
- return t8;
353
+ $[25] = T2;
354
+ $[26] = t7;
355
+ $[27] = t9;
356
+ $[28] = t10;
357
+ } else t10 = $[28];
358
+ return t10;
264
359
  }
265
360
  /**
266
361
  * One segment. Its `id` is what selection is reported by, and its label is
@@ -268,11 +363,13 @@ function SegmentedButton(t0) {
268
363
  * unchosen one draws whatever `icon` holds, if anything.
269
364
  */
270
365
  function SegmentedButtonSegment(t0) {
271
- const $ = c(20);
366
+ const $ = c(23);
272
367
  const { children, disableRipple: t1, icon, onClick, onContextMenu, onKeyDown, onKeyUp, onPointerCancel, onPointerDown, onPointerLeave, onPointerUp, render, ...props } = t0;
273
368
  const disableRipple = t1 === void 0 ? false : t1;
274
369
  const selectionMode = useContext(SelectionModeContext);
275
- const showSelectedIcon = useContext(ShowSelectedIconContext);
370
+ const marked = useContext(ShowSelectedIconContext) && hasLabel(children);
371
+ const [label, setLabel] = useState(null);
372
+ const labelTitle = useTruncatedText(label);
276
373
  const element = {
277
374
  aria: ariaAttributesOf(props),
278
375
  onKeyDown,
@@ -299,40 +396,82 @@ function SegmentedButtonSegment(t0) {
299
396
  } else t2 = $[6];
300
397
  const ripple = useRipple(!disableRipple && props.isDisabled !== true && !disabledByGroup, t2);
301
398
  const T0 = ToggleButton;
302
- const t3 = toggleButtonRenderer(element, render);
303
- const t4 = ripple.handlers;
304
- const t5 = mergeStatefulStyles(segmentStyles(showSelectedIcon), props);
305
- let t6;
306
- if ($[7] !== children || $[8] !== icon || $[9] !== ripple || $[10] !== selectionMode || $[11] !== showSelectedIcon) {
307
- t6 = segmentContent(children, icon, ripple, selectionMode, showSelectedIcon);
399
+ const t3 = selectionMode === "single" && props.id !== void 0 ? JSON.stringify(props.id) : void 0;
400
+ const t4 = toggleButtonRenderer(element, render);
401
+ const t5 = ripple.handlers;
402
+ const t6 = mergeStatefulStyles(segmentStyles(marked), props);
403
+ let t7;
404
+ if ($[7] !== children || $[8] !== icon || $[9] !== labelTitle || $[10] !== marked || $[11] !== ripple || $[12] !== selectionMode || $[13] !== setLabel) {
405
+ t7 = segmentContent(children, icon, ripple, selectionMode, marked, setLabel, labelTitle);
308
406
  $[7] = children;
309
407
  $[8] = icon;
310
- $[9] = ripple;
311
- $[10] = selectionMode;
312
- $[11] = showSelectedIcon;
313
- $[12] = t6;
314
- } else t6 = $[12];
315
- let t7;
316
- if ($[13] !== T0 || $[14] !== props || $[15] !== ripple.handlers || $[16] !== t3 || $[17] !== t5 || $[18] !== t6) {
317
- t7 = /* @__PURE__ */ jsx(T0, {
318
- render: t3,
319
- ...t4,
320
- ...props,
408
+ $[9] = labelTitle;
409
+ $[10] = marked;
410
+ $[11] = ripple;
411
+ $[12] = selectionMode;
412
+ $[13] = setLabel;
413
+ $[14] = t7;
414
+ } else t7 = $[14];
415
+ let t8;
416
+ if ($[15] !== T0 || $[16] !== props || $[17] !== ripple.handlers || $[18] !== t3 || $[19] !== t4 || $[20] !== t6 || $[21] !== t7) {
417
+ t8 = /* @__PURE__ */ jsx(T0, {
418
+ "data-key": t3,
419
+ render: t4,
321
420
  ...t5,
322
- children: t6
421
+ ...props,
422
+ ...t6,
423
+ children: t7
323
424
  });
324
- $[13] = T0;
325
- $[14] = props;
326
- $[15] = ripple.handlers;
327
- $[16] = t3;
328
- $[17] = t5;
329
- $[18] = t6;
330
- $[19] = t7;
331
- } else t7 = $[19];
332
- return t7;
425
+ $[15] = T0;
426
+ $[16] = props;
427
+ $[17] = ripple.handlers;
428
+ $[18] = t3;
429
+ $[19] = t4;
430
+ $[20] = t6;
431
+ $[21] = t7;
432
+ $[22] = t8;
433
+ } else t8 = $[22];
434
+ return t8;
435
+ }
436
+ function segmentStyles(marked) {
437
+ return (state) => props(styles.segment, focus.ring, state.isSelected ? styles.segmentSelected : styles.segmentUnselected, state.isSelected && !marked && styles.segmentSelectedUnmarked, state.isDisabled && styles.segmentDisabled);
333
438
  }
334
- function segmentStyles(showSelectedIcon) {
335
- return (state) => props(styles.segment, focus.ring, state.isSelected ? styles.segmentSelected : styles.segmentUnselected, state.isSelected && !showSelectedIcon && styles.segmentSelectedUnmarked, state.isDisabled && styles.segmentDisabled);
439
+ function useTruncatedText(label) {
440
+ const $ = c(3);
441
+ const [text, setText] = useState(void 0);
442
+ let t0;
443
+ let t1;
444
+ if ($[0] !== label) {
445
+ t0 = () => {
446
+ if (label === null) return;
447
+ const measure = () => {
448
+ const cut = label.scrollWidth > label.clientWidth;
449
+ setText(cut && label.textContent !== "" ? label.textContent : void 0);
450
+ };
451
+ measure();
452
+ const resize = new ResizeObserver(measure);
453
+ resize.observe(label);
454
+ const relabel = new MutationObserver(measure);
455
+ relabel.observe(label, {
456
+ characterData: true,
457
+ childList: true,
458
+ subtree: true
459
+ });
460
+ return () => {
461
+ resize.disconnect();
462
+ relabel.disconnect();
463
+ };
464
+ };
465
+ t1 = [label];
466
+ $[0] = label;
467
+ $[1] = t0;
468
+ $[2] = t1;
469
+ } else {
470
+ t0 = $[1];
471
+ t1 = $[2];
472
+ }
473
+ useLayoutEffect(t0, t1);
474
+ return text;
336
475
  }
337
476
  SegmentedButton.Segment = SegmentedButtonSegment;
338
477
  //#endregion