mcr-design-systems 1.0.211 → 1.0.212

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.
@@ -11,10 +11,10 @@ const a = e({
11
11
  ],
12
12
  variants: {
13
13
  size: {
14
- "x-small": ["px-xs-3 py-xs-3", "text-xs leading-4", "gap-xs-3", "h-5"],
15
- small: ["px-xs-3 py-xs-3", "text-sm leading-5", "gap-xs-3", "h-6"],
16
- medium: ["px-sm py-xs-3", "text-sm leading-5", "gap-xs-3", "h-8"],
17
- large: ["px-sm", "text-base leading-6", "gap-xs-3", "h-12"]
14
+ "x-small": ["px-xs", "text-base-sm leading-4", "gap-xs-3", "h-md-2"],
15
+ small: ["px-sm-2", "text-sm leading-5", "gap-xs-3", "h-lg"],
16
+ medium: ["px-sm-2", "text-base-md leading-5", "gap-xs-3", "h-10"],
17
+ large: ["px-sm", "text-base-lg leading-6", "gap-xs-3", "h-12"]
18
18
  },
19
19
  variant: {
20
20
  neutral: "",
@@ -1,19 +1,19 @@
1
- import { jsx as m, jsxs as v } from "react/jsx-runtime";
1
+ import { jsx as l, jsxs as v } from "react/jsx-runtime";
2
2
  import h, { useCallback as f } from "react";
3
3
  import { cn as S } from "../../shared/utils/cn.js";
4
4
  import { dataTestId as V } from "../../shared/utils/dataTestId.js";
5
5
  import { Typography as _ } from "../Typography/index.js";
6
6
  import c from "../Icon/Icon.js";
7
- import { chipIconVariants as x, chipVariants as I } from "./helper/variants.js";
8
- const b = h.memo(({ icon: i, size: e, position: l }) => {
7
+ import { chipIconVariants as b, chipVariants as I } from "./helper/variants.js";
8
+ const x = h.memo(({ icon: i, size: e, position: m }) => {
9
9
  const { name: n, node: p, "aria-label": r } = i;
10
- return /* @__PURE__ */ m(
10
+ return /* @__PURE__ */ l(
11
11
  "span",
12
12
  {
13
- className: x({ size: e, position: l }),
13
+ className: b({ size: e, position: m }),
14
14
  "aria-label": r,
15
15
  role: r ? "img" : void 0,
16
- children: p || n && /* @__PURE__ */ m(
16
+ children: p || n && /* @__PURE__ */ l(
17
17
  c,
18
18
  {
19
19
  name: n,
@@ -23,34 +23,34 @@ const b = h.memo(({ icon: i, size: e, position: l }) => {
23
23
  }
24
24
  );
25
25
  });
26
- b.displayName = "ChipIcon";
26
+ x.displayName = "ChipIcon";
27
27
  const L = h.forwardRef(
28
28
  ({
29
29
  children: i,
30
30
  leadingIcon: e,
31
- trailingIcon: l,
31
+ trailingIcon: m,
32
32
  variant: n = "warning",
33
33
  selected: p = !0,
34
34
  state: r = "default",
35
35
  size: a = "large",
36
36
  className: C,
37
- disabled: s = !1,
37
+ disabled: t = !1,
38
38
  onClick: d,
39
- onRemove: t,
40
- dataTestIdName: N = "chip",
41
- ...g
39
+ onRemove: s,
40
+ dataTestIdName: g = "chip",
41
+ ...N
42
42
  }, w) => {
43
43
  const y = f(
44
44
  (o) => {
45
- !s && r !== "disabled" && d?.(o);
45
+ !t && r !== "disabled" && d?.(o);
46
46
  },
47
- [s, r, d]
47
+ [t, r, d]
48
48
  ), k = f(
49
49
  (o) => {
50
- o.stopPropagation(), !s && r !== "disabled" && t?.();
50
+ o.stopPropagation(), !t && r !== "disabled" && s?.();
51
51
  },
52
- [s, r, t]
53
- ), u = s ? "disabled" : r, T = S(
52
+ [t, r, s]
53
+ ), u = t ? "disabled" : r, T = S(
54
54
  I({
55
55
  size: a,
56
56
  variant: n,
@@ -61,7 +61,7 @@ const L = h.forwardRef(
61
61
  ), j = (o) => {
62
62
  switch (o) {
63
63
  case "x-small":
64
- return "xs";
64
+ return "sm";
65
65
  case "small":
66
66
  return "sm";
67
67
  case "medium":
@@ -78,14 +78,14 @@ const L = h.forwardRef(
78
78
  ref: w,
79
79
  type: "button",
80
80
  className: T,
81
- disabled: s || u === "disabled",
81
+ disabled: t || u === "disabled",
82
82
  onClick: y,
83
- ...V(N),
83
+ ...V(g),
84
84
  "aria-pressed": p,
85
- ...g,
85
+ ...N,
86
86
  children: [
87
- e && /* @__PURE__ */ m(b, { icon: e, size: a, position: "leading" }),
88
- i && /* @__PURE__ */ m(
87
+ e && /* @__PURE__ */ l(x, { icon: e, size: a, position: "leading" }),
88
+ i && /* @__PURE__ */ l(
89
89
  _,
90
90
  {
91
91
  variants: "action-emphasize",
@@ -95,21 +95,22 @@ const L = h.forwardRef(
95
95
  children: i
96
96
  }
97
97
  ),
98
- l && /* @__PURE__ */ m(
98
+ m && /* @__PURE__ */ l(
99
99
  "span",
100
100
  {
101
- className: x({ size: a, position: "trailing" }),
102
- onClick: t ? k : void 0,
103
- role: t ? "button" : void 0,
104
- tabIndex: t ? 0 : void 0,
105
- "aria-label": l["aria-label"] || "Remove",
106
- children: l.node || l.name && /* @__PURE__ */ m(
101
+ className: b({ size: a, position: "trailing" }),
102
+ onClick: s ? k : void 0,
103
+ role: s ? "button" : void 0,
104
+ tabIndex: s ? 0 : void 0,
105
+ "aria-label": m["aria-label"] || "Remove",
106
+ "data-no-trigger": "true",
107
+ children: m.node || m.name && /* @__PURE__ */ l(
107
108
  c,
108
109
  {
109
- name: l.name,
110
- size: a === "x-small" ? 12 : a === "small" || a === "medium" ? 16 : 24
110
+ name: m.name,
111
+ size: a === "x-small" || a === "small" || a === "medium" ? 16 : 24
111
112
  }
112
- ) || t && /* @__PURE__ */ m(
113
+ ) || s && /* @__PURE__ */ l(
113
114
  c,
114
115
  {
115
116
  name: "x-close",
@@ -10,10 +10,7 @@ const n = e({
10
10
  // 4px gap
11
11
  "w-full",
12
12
  "min-h-8",
13
- "px-sm-2",
14
- // 12px horizontal padding
15
- "py-xs-2",
16
- // 6px vertical padding
13
+ // Padding removed from base - defined in size variants
17
14
  "text-sm",
18
15
  // 14px font size
19
16
  "font-normal",
@@ -98,12 +95,8 @@ const n = e({
98
95
  "min-h-10",
99
96
  "px-sm-2",
100
97
  // 12px horizontal padding
101
- "py-sm-2",
98
+ "py-xs"
102
99
  // 8px vertical padding
103
- "text-base",
104
- // 16px font size
105
- "leading-6"
106
- // 24px line height
107
100
  ],
108
101
  leadingIcon: ["w-5", "h-5"],
109
102
  // 20px
@@ -82,6 +82,7 @@ export interface SelectProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
82
82
  displayType?: 'chip' | 'default';
83
83
  /**
84
84
  * Maximum number of selected items to display as chips (multiple mode only)
85
+ * If not specified, will auto-calculate based on available width
85
86
  */
86
87
  maxDisplayChips?: number;
87
88
  /**
@@ -1,119 +1,142 @@
1
- import { jsxs as d, jsx as t, Fragment as te } from "react/jsx-runtime";
2
- import { forwardRef as ke, useState as re, useRef as Ee, useEffect as je, useCallback as z, useMemo as B, memo as Fe } from "react";
1
+ import { jsxs as d, jsx as r, Fragment as Se } from "react/jsx-runtime";
2
+ import { forwardRef as $e, useState as Re, useRef as Te, useCallback as R, useMemo as E, memo as ke } from "react";
3
3
  import { cn as h } from "../../shared/utils/cn.js";
4
- import { dataTestId as Ve } from "../../shared/utils/dataTestId.js";
5
- import { Typography as D } from "../Typography/index.js";
6
- import y from "../Icon/Icon.js";
7
- import { Dropdown as ne } from "../Dropdown/index.js";
8
- import { selectVariants as ze } from "./helper/variants.js";
9
- import se from "../Chip/index.js";
10
- import Be from "../TextField/HelperText.js";
11
- const ae = ke(
4
+ import { dataTestId as je } from "../../shared/utils/dataTestId.js";
5
+ import { Typography as F } from "../Typography/index.js";
6
+ import C from "../Icon/Icon.js";
7
+ import { Dropdown as re } from "../Dropdown/index.js";
8
+ import { selectVariants as De } from "./helper/variants.js";
9
+ import te from "../Chip/index.js";
10
+ import Pe from "../TextField/HelperText.js";
11
+ import { useChipOverflow as Ee } from "../../shared/hooks/useChipOverflow.js";
12
+ const ae = $e(
12
13
  ({
13
- items: S = [],
14
- value: r,
15
- onChange: N,
16
- placeholder: g = "Select an option...",
17
- disabled: n = !1,
18
- readOnly: s = !1,
19
- loading: q = !1,
20
- showCheckmark: G = !1,
21
- emptyText: J = "No options available",
22
- state: w,
23
- label: K,
24
- helpText: ce,
25
- required: oe = !1,
26
- leadingIcon: c,
27
- trailingIcon: l,
28
- mode: m = "single",
29
- displayType: ie = "chip",
30
- maxDisplayChips: M = 3,
14
+ items: M = [],
15
+ value: t,
16
+ onChange: y,
17
+ placeholder: b = "Select an option...",
18
+ disabled: a = !1,
19
+ readOnly: n = !1,
20
+ loading: V = !1,
21
+ showCheckmark: z = !1,
22
+ emptyText: q = "No options available",
23
+ state: T,
24
+ label: G,
25
+ helpText: ne,
26
+ required: se = !1,
27
+ leadingIcon: m,
28
+ trailingIcon: p,
29
+ mode: o = "single",
30
+ displayType: oe = "chip",
31
+ maxDisplayChips: Fe,
32
+ // eslint-disable-line @typescript-eslint/no-unused-vars -- kept for backward compatibility
31
33
  moreItemsText: le = "+{count}",
32
- trigger: me,
33
- side: L = "bottom",
34
- align: P = "start",
35
- sideOffset: Q = 4,
36
- enableVirtualization: U,
37
- itemHeight: X = 32,
38
- maxHeight: Y = 300,
39
- size: a = "md",
40
- variant: R = "default",
41
- fullWidth: $ = !1,
42
- className: fe,
43
- iconsSize: pe,
44
- "data-testid": u,
45
- width: v,
46
- error: Z,
47
- haveIcon: he,
34
+ trigger: ie,
35
+ side: J = "bottom",
36
+ align: K = "start",
37
+ sideOffset: L = 4,
38
+ enableVirtualization: Q,
39
+ itemHeight: U = 32,
40
+ maxHeight: W = 300,
41
+ size: s = "md",
42
+ variant: k = "default",
43
+ fullWidth: j = !1,
44
+ className: ce,
45
+ iconsSize: me,
46
+ "data-testid": l,
47
+ width: w,
48
+ error: X,
49
+ haveIcon: pe,
48
50
  iconsCustom: ue,
49
- onBlur: _,
50
- dropdownProps: H,
51
- allowSearch: de,
52
- title: T,
53
- onSearchChange: Ne,
54
- searchValue: ge,
55
- showClearButton: ve = !1,
51
+ onBlur: Y,
52
+ dropdownProps: Z,
53
+ allowSearch: fe,
54
+ title: D,
55
+ onSearchChange: he,
56
+ searchValue: de,
57
+ showClearButton: ge = !1,
56
58
  searchPlaceholder: xe = "Search...",
57
- ...Ce
58
- }, Ae) => {
59
- const [o, b] = re(!1), [k, ye] = re(0), E = Ee(null), i = ze({
60
- size: a,
61
- variant: R,
62
- fullWidth: $,
63
- state: w,
64
- disabled: n,
65
- readOnly: s
66
- });
67
- je(() => {
68
- if (E.current) {
69
- const e = new ResizeObserver((f) => {
70
- for (const p of f)
71
- ye(p.contentRect.width);
72
- });
73
- return e.observe(E.current), () => e.disconnect();
74
- }
75
- }, []);
76
- const O = z(() => {
77
- if (k === 0) return M;
78
- const e = a === "sm" ? 100 : a === "lg" ? 140 : 120, f = 4, p = 32, F = 32, A = c ? 24 : 0, Re = p + F + A + 16, $e = k - Re, Te = Math.floor(
79
- $e / (e + f)
80
- );
81
- return Math.max(1, Math.min(Te, M));
82
- }, [k, M, a, c]), be = z(
59
+ ...Ne
60
+ }, ve) => {
61
+ const [u, S] = Re(!1), Ce = Te(null), i = De({
62
+ size: s,
63
+ variant: k,
64
+ fullWidth: j,
65
+ state: T,
66
+ disabled: a,
67
+ readOnly: n
68
+ }), ye = R(
83
69
  (e) => {
84
- if (m === "multiple" && Array.isArray(r) && !n && !s) {
85
- const f = r.filter((p) => p !== e);
86
- N?.(f);
70
+ if (o === "multiple" && Array.isArray(t) && !a && !n) {
71
+ const c = t.filter((A) => A !== e);
72
+ y?.(c);
87
73
  }
88
74
  },
89
- [m, r, N, n, s]
90
- ), Se = z(() => {
91
- m === "multiple" && Array.isArray(r) && r.length > 0 && !n && !s && N?.([]);
92
- }, [m, r, N, n, s]), x = B(() => {
93
- if (!r) return [];
94
- const e = [], f = Array.isArray(r) ? r : [r];
95
- return ((F) => {
96
- F.forEach((A) => {
97
- "items" in A ? A.items.forEach((V) => {
98
- f.includes(V.value) && e.push(V);
99
- }) : f.includes(A.value) && e.push(A);
75
+ [o, t, y, a, n]
76
+ ), _ = R(() => {
77
+ o === "multiple" && Array.isArray(t) && t.length > 0 && !a && !n && y?.([]);
78
+ }, [o, t, y, a, n]), f = E(() => {
79
+ if (!t) return [];
80
+ const e = Array.isArray(t) ? t : [t], c = /* @__PURE__ */ new Map();
81
+ return ((N) => {
82
+ N.forEach((v) => {
83
+ "items" in v ? v.items.forEach((ee) => {
84
+ c.set(ee.value, ee);
85
+ }) : c.set(v.value, v);
100
86
  });
101
- })(S), e;
102
- }, [r, S]), j = B(() => {
103
- if (m === "single") {
104
- const e = x[0];
105
- return e ? e.label : g;
87
+ })(M), e.map((N) => {
88
+ const v = c.get(N);
89
+ return v || {
90
+ value: N,
91
+ label: N
92
+ };
93
+ });
94
+ }, [t, M]), P = E(() => {
95
+ if (o === "single") {
96
+ const e = f[0];
97
+ return e ? e.label : b;
106
98
  }
107
- return m === "multiple" ? r?.length === 0 ? g : T ? `${T} ` : "" : "";
108
- }, [m, x, g, T, r]), W = B(() => {
109
- if (m !== "multiple" || !Array.isArray(r)) return [];
110
- const e = O(), f = x.slice(0, e), p = x.length - e;
111
- return {
112
- displayItems: f,
113
- remainingCount: p,
114
- hasMore: p > 0
99
+ return o === "multiple" ? t?.length === 0 ? b : D ? `${D} ` : "" : "";
100
+ }, [o, f, b, D, t]), g = Ee({
101
+ items: o === "multiple" && Array.isArray(t) ? f.map((e) => ({
102
+ value: e.value,
103
+ label: e.label
104
+ })) : [],
105
+ gap: 8,
106
+ // 8px gap between chips (matches gap-2 in Tailwind)
107
+ minChipsToShow: 1,
108
+ moreChipWidth: 60
109
+ // Estimated width for "+X more" chip
110
+ }), $ = E(() => {
111
+ if (o !== "multiple" || !Array.isArray(t))
112
+ return {
113
+ displayItems: [],
114
+ remainingCount: 0,
115
+ hasMore: !1
116
+ };
117
+ const c = {
118
+ displayItems: g.displayItems.map((A) => f.find(
119
+ (N) => N.value === A.value
120
+ ) || {
121
+ value: A.value,
122
+ label: A.label
123
+ }),
124
+ remainingCount: g.remainingCount,
125
+ hasMore: g.hasMore
115
126
  };
116
- }, [m, r, x, O]), We = v ? { width: typeof v == "number" ? `${v}px` : v } : {}, we = h(i.container(), fe), C = (e) => {
127
+ return f.length > 0 && c.displayItems.length === 0 && !c.hasMore ? {
128
+ displayItems: [f[0]],
129
+ remainingCount: Math.max(0, f.length - 1),
130
+ hasMore: f.length > 1
131
+ } : c;
132
+ }, [
133
+ o,
134
+ t,
135
+ g.displayItems,
136
+ g.remainingCount,
137
+ g.hasMore,
138
+ f
139
+ ]), be = w ? { width: typeof w == "number" ? `${w}px` : w } : {}, we = h(i.container(), ce), x = (e) => {
117
140
  switch (e) {
118
141
  case "sm":
119
142
  return 16;
@@ -124,58 +147,64 @@ const ae = ke(
124
147
  default:
125
148
  return 16;
126
149
  }
127
- }, I = (e) => {
150
+ }, B = (e) => {
128
151
  switch (e) {
129
152
  case "sm":
130
153
  return "small";
131
154
  case "md":
132
155
  return "medium";
133
156
  case "lg":
134
- return "large";
157
+ return "x-small";
135
158
  default:
136
159
  return "medium";
137
160
  }
138
- }, ee = (e) => {
139
- b(e), !e && _ && _(
161
+ }, H = R((e) => !!(e.closest('[data-testid*="chip"]') || e.closest('[data-testid*="clear-all"]') || e.closest('[data-no-trigger="true"]') || e.closest('[role="button"]') && e.closest('[data-testid*="chip"]')), []), I = R(
162
+ (e) => {
163
+ const c = e.target;
164
+ return H(c) ? (e.preventDefault(), e.stopPropagation(), !0) : !1;
165
+ },
166
+ [H]
167
+ ), O = (e) => {
168
+ S(e), !e && Y && Y(
140
169
  new FocusEvent("blur")
141
170
  );
142
- }, Me = () => /* @__PURE__ */ d(
171
+ }, Ae = () => /* @__PURE__ */ d(
143
172
  "div",
144
173
  {
145
174
  className: i.trigger(),
146
- "data-state": o ? "open" : "closed",
175
+ "data-state": u ? "open" : "closed",
147
176
  children: [
148
- c && /* @__PURE__ */ t("span", { className: i.leadingIcon(), children: c.node || c.name && /* @__PURE__ */ t(
149
- y,
177
+ m && /* @__PURE__ */ r("span", { className: i.leadingIcon(), children: m.node || m.name && /* @__PURE__ */ r(
178
+ C,
150
179
  {
151
- name: c.name,
152
- size: C(a),
153
- "aria-label": c["aria-label"]
180
+ name: m.name,
181
+ size: x(s),
182
+ "aria-label": m["aria-label"]
154
183
  }
155
184
  ) }),
156
- /* @__PURE__ */ t(
185
+ /* @__PURE__ */ r(
157
186
  "span",
158
187
  {
159
188
  className: h(
160
189
  "flex-1 truncate text-left",
161
- x.length > 0 ? "text-fg-neutral-main" : i.placeholder()
190
+ f.length > 0 ? "text-fg-neutral-main" : i.placeholder()
162
191
  ),
163
- children: j
192
+ children: P
164
193
  }
165
194
  ),
166
- l ? /* @__PURE__ */ t("span", { className: i.trailingIcon(), children: l.node || l.name && /* @__PURE__ */ t(
167
- y,
195
+ p ? /* @__PURE__ */ r("span", { className: i.trailingIcon(), children: p.node || p.name && /* @__PURE__ */ r(
196
+ C,
168
197
  {
169
- name: l.name,
170
- size: C(a),
171
- "aria-label": l["aria-label"]
198
+ name: p.name,
199
+ size: x(s),
200
+ "aria-label": p["aria-label"]
172
201
  }
173
- ) }) : /* @__PURE__ */ t(
174
- y,
202
+ ) }) : /* @__PURE__ */ r(
203
+ C,
175
204
  {
176
- name: o ? "chevron-up" : "chevron-down",
177
- size: C(a),
178
- className: h(i.chevron(), o && "rotate-180")
205
+ name: u ? "chevron-up" : "chevron-down",
206
+ size: x(s),
207
+ className: h(i.chevron(), u && "rotate-180")
179
208
  }
180
209
  )
181
210
  ]
@@ -184,234 +213,264 @@ const ae = ke(
184
213
  return /* @__PURE__ */ d(
185
214
  "div",
186
215
  {
187
- ref: Ae,
216
+ ref: ve,
188
217
  className: we,
189
- style: We,
190
- ...Ve(u || "select"),
191
- ...Ce,
218
+ style: be,
219
+ ...je(l || "select"),
220
+ ...Ne,
192
221
  children: [
193
- K && /* @__PURE__ */ d("div", { className: "mb-1 flex items-center gap-[2px]", children: [
194
- /* @__PURE__ */ t(D, { variants: "action", size: "sm", color: "fg-neutral-subtle", children: K }),
195
- oe && /* @__PURE__ */ t(D, { variants: "action", size: "sm", color: "fg-accent-error", children: "*" })
222
+ G && /* @__PURE__ */ d("div", { className: "mb-1 flex items-center gap-[2px]", children: [
223
+ /* @__PURE__ */ r(F, { variants: "action", size: "sm", color: "fg-neutral-subtle", children: G }),
224
+ se && /* @__PURE__ */ r(F, { variants: "action", size: "sm", color: "fg-accent-error", children: "*" })
196
225
  ] }),
197
- /* @__PURE__ */ t("div", { className: "relative h-11", children: m === "multiple" ? /* @__PURE__ */ t(
198
- ne,
226
+ /* @__PURE__ */ r("div", { className: "relative h-11", children: o === "multiple" ? /* @__PURE__ */ r(
227
+ re,
199
228
  {
200
- ...H,
201
- items: S,
202
- value: r,
229
+ ...Z,
230
+ items: M,
231
+ value: t,
203
232
  onValueChange: (e) => {
204
- n || s || N?.(Array.isArray(e) ? e : [e]);
233
+ a || n || y?.(Array.isArray(e) ? e : [e]);
205
234
  },
206
235
  fullWidthContent: !0,
207
- placeholder: g,
208
- disabled: n,
209
- loading: q,
210
- showCheckmark: G,
211
- emptyText: J,
212
- state: w,
213
- open: o,
214
- onOpenChange: ee,
215
- side: L,
216
- align: P,
217
- search: de,
218
- sideOffset: Q,
219
- enableVirtualization: U,
236
+ placeholder: b,
237
+ disabled: a,
238
+ loading: V,
239
+ showCheckmark: z,
240
+ emptyText: q,
241
+ state: T,
242
+ open: u,
243
+ onOpenChange: O,
244
+ side: J,
245
+ align: K,
246
+ search: fe,
247
+ sideOffset: L,
248
+ enableVirtualization: Q,
220
249
  selectionMode: "separated",
221
250
  multiSelect: !0,
222
- itemHeight: X,
223
- maxHeight: Y,
224
- size: a,
225
- variant: R,
226
- fullWidth: $,
251
+ itemHeight: U,
252
+ maxHeight: W,
253
+ size: s,
254
+ variant: k,
255
+ fullWidth: j,
227
256
  searchPlaceholder: xe,
228
- width: v,
229
- "data-testid": u ? `${u}-dropdown` : void 0,
230
- showClearButton: ve,
231
- onClear: Se,
232
- searchValue: ge,
233
- onSearchChange: Ne,
257
+ width: w,
258
+ "data-testid": l ? `${l}-dropdown` : void 0,
259
+ showClearButton: ge,
260
+ onClear: _,
261
+ searchValue: de,
262
+ onSearchChange: he,
234
263
  className: "flex items-center",
235
264
  children: /* @__PURE__ */ d(
236
265
  "div",
237
266
  {
238
- ref: E,
267
+ ref: Ce,
239
268
  className: h(
240
269
  i.trigger({
241
- state: Z ? "error" : void 0
270
+ state: X ? "error" : void 0
242
271
  }),
243
272
  "flex"
244
273
  ),
245
- "data-state": o ? "open" : "closed",
246
- onClick: () => b(!o),
274
+ "data-state": u ? "open" : "closed",
275
+ onPointerDown: I,
276
+ onClick: (e) => {
277
+ a || n || I(e) || S(!u);
278
+ },
247
279
  children: [
248
- c && /* @__PURE__ */ t("span", { className: i.leadingIcon(), children: c.node || c.name && /* @__PURE__ */ t(
249
- y,
280
+ m && /* @__PURE__ */ r("span", { className: i.leadingIcon(), children: m.node || m.name && /* @__PURE__ */ r(
281
+ C,
250
282
  {
251
- name: c.name,
252
- size: C(a),
253
- "aria-label": c["aria-label"],
283
+ name: m.name,
284
+ size: x(s),
285
+ "aria-label": m["aria-label"],
254
286
  className: "cursor-pointer"
255
287
  }
256
288
  ) }),
257
- /* @__PURE__ */ t(
289
+ /* @__PURE__ */ r(
258
290
  "div",
259
291
  {
260
292
  className: h(
261
293
  "flex-1 flex flex-nowrap gap-1 min-h-0 overflow-hidden",
262
- !n && !s && "cursor-pointer"
294
+ !a && !n && "cursor-pointer"
263
295
  ),
264
- onClick: (e) => {
265
- n || s || e.target.closest('[data-testid*="chip"]') || b(!o);
266
- },
267
- children: Array.isArray(W) ? null : /* @__PURE__ */ t(te, { children: ie === "chip" ? (
268
- // Chip display mode - render individual chips
269
- /* @__PURE__ */ d(te, { children: [
270
- W.displayItems.map((e) => /* @__PURE__ */ t("div", { className: "flex-shrink-0", children: /* @__PURE__ */ t(
271
- se,
272
- {
273
- size: I(a),
274
- onRemove: !n && !s ? () => {
275
- be(e.value);
276
- } : void 0,
277
- className: "bg-bg-surface-level-3",
278
- variant: "neutral",
279
- trailingIcon: !n && !s ? {
280
- name: "x-close",
281
- "aria-label": "Remove option"
282
- } : void 0,
283
- dataTestIdName: `${u || "select"}-chip-${e.value}`,
284
- children: e.label
285
- }
286
- ) }, e.value)),
287
- W.hasMore && /* @__PURE__ */ t(
288
- "div",
289
- {
290
- onClick: (e) => e.stopPropagation(),
291
- className: "flex-shrink-0",
292
- children: /* @__PURE__ */ t(
293
- se,
294
- {
295
- size: I(a),
296
- variant: "neutral",
297
- className: "self-center bg-bg-surface-level-3",
298
- dataTestIdName: `${u || "select"}-chip-more`,
299
- children: le.replace(
300
- "{count}",
301
- W.remainingCount.toString()
302
- )
303
- }
304
- )
305
- }
306
- )
307
- ] })
296
+ children: Array.isArray($) ? null : /* @__PURE__ */ r(Se, { children: oe === "chip" ? /* @__PURE__ */ d(
297
+ "div",
298
+ {
299
+ ref: g.containerRef,
300
+ className: "flex items-center gap-2 flex-nowrap w-full max-w-full overflow-hidden",
301
+ children: [
302
+ $.displayItems.map((e) => /* @__PURE__ */ r(
303
+ te,
304
+ {
305
+ size: B(s),
306
+ onRemove: !a && !n ? () => {
307
+ ye(e.value);
308
+ } : void 0,
309
+ className: "bg-bg-surface-level-3 flex-shrink-0",
310
+ variant: "neutral",
311
+ trailingIcon: !a && !n ? {
312
+ name: "x-close",
313
+ "aria-label": "Remove option"
314
+ } : void 0,
315
+ dataTestIdName: `${l || "select"}-chip-${e.value}`,
316
+ "data-no-trigger": "true",
317
+ children: e.label
318
+ },
319
+ e.value
320
+ )),
321
+ $.hasMore && /* @__PURE__ */ r(
322
+ te,
323
+ {
324
+ size: B(s),
325
+ variant: "neutral",
326
+ className: "bg-bg-surface-level-3 flex-shrink-0",
327
+ dataTestIdName: `${l || "select"}-chip-more`,
328
+ onClick: (e) => e.stopPropagation(),
329
+ children: le.replace(
330
+ "{count}",
331
+ $.remainingCount.toString()
332
+ )
333
+ }
334
+ )
335
+ ]
336
+ }
308
337
  ) : (
309
338
  // Default display mode - show summary text
310
- /* @__PURE__ */ t(
339
+ /* @__PURE__ */ r(
311
340
  "div",
312
341
  {
313
342
  className: h(
314
343
  i.placeholder(),
315
- !n && !s && "cursor-pointer"
344
+ !a && !n && "cursor-pointer"
316
345
  ),
317
- children: Array.isArray(r) ? r?.length > 0 ? /* @__PURE__ */ d(
318
- D,
346
+ children: Array.isArray(t) ? t?.length > 0 ? /* @__PURE__ */ d(
347
+ F,
319
348
  {
320
349
  variants: "body",
321
350
  size: "md",
322
351
  color: "fg-neutral-main",
323
352
  children: [
324
- j,
353
+ P,
325
354
  /* @__PURE__ */ d("span", { className: "text-fg-brand-rest", children: [
326
355
  "(",
327
- r?.length,
356
+ t?.length,
328
357
  ")"
329
358
  ] })
330
359
  ]
331
360
  }
332
- ) : g : j
361
+ ) : b : P
333
362
  }
334
363
  )
335
364
  ) })
336
365
  }
337
366
  ),
338
- /* @__PURE__ */ t("div", { className: "flex items-center gap-xs", children: /* @__PURE__ */ t(
339
- "button",
340
- {
341
- type: "button",
342
- onClick: () => {
343
- !n && !s && b(!o);
344
- },
345
- className: h(
346
- "flex items-center justify-center p-1",
347
- !n && !s && "cursor-pointer"
348
- ),
349
- children: l ? /* @__PURE__ */ t("span", { className: i.trailingIcon(), children: l.node || l.name && /* @__PURE__ */ t(
350
- y,
351
- {
352
- name: l.name,
353
- size: C(a),
354
- "aria-label": l["aria-label"]
355
- }
356
- ) }) : /* @__PURE__ */ t(
357
- y,
358
- {
359
- name: o ? "chevron-up" : "chevron-down",
360
- size: C(a),
361
- className: h(
362
- i.chevron(),
363
- o && "rotate-180"
364
- )
365
- }
366
- )
367
- }
368
- ) })
367
+ /* @__PURE__ */ d("div", { className: "flex items-center gap-xs", children: [
368
+ Array.isArray(t) && t.length > 0 && /* @__PURE__ */ r(
369
+ "button",
370
+ {
371
+ type: "button",
372
+ onClick: (e) => {
373
+ e.stopPropagation(), _();
374
+ },
375
+ className: h(
376
+ "flex items-center justify-center rounded-sm transition-colors",
377
+ !a && !n && "cursor-pointer hover:bg-bg-neutral-subtle",
378
+ a || n ? "opacity-50 cursor-not-allowed" : ""
379
+ ),
380
+ disabled: a || n,
381
+ "aria-label": "Clear all selections",
382
+ "data-testid": l ? `${l}-clear-all` : void 0,
383
+ "data-no-trigger": "true",
384
+ children: /* @__PURE__ */ r(
385
+ C,
386
+ {
387
+ name: "x-circle",
388
+ variant: "solid",
389
+ size: x(s),
390
+ className: "text-fg-neutral-subtle"
391
+ }
392
+ )
393
+ }
394
+ ),
395
+ /* @__PURE__ */ r(
396
+ "button",
397
+ {
398
+ type: "button",
399
+ onClick: (e) => {
400
+ e.stopPropagation(), !a && !n && S(!u);
401
+ },
402
+ className: h(
403
+ "flex items-center justify-center dropdown-toggle-btn",
404
+ !a && !n && "cursor-pointer"
405
+ ),
406
+ "data-testid": l ? `${l}-dropdown-toggle` : "dropdown-toggle",
407
+ children: p ? /* @__PURE__ */ r("span", { className: i.trailingIcon(), children: p.node || p.name && /* @__PURE__ */ r(
408
+ C,
409
+ {
410
+ name: p.name,
411
+ size: x(s),
412
+ "aria-label": p["aria-label"]
413
+ }
414
+ ) }) : /* @__PURE__ */ r(
415
+ C,
416
+ {
417
+ name: u ? "chevron-up" : "chevron-down",
418
+ size: x(s),
419
+ className: h(
420
+ i.chevron(),
421
+ u && "rotate-180"
422
+ )
423
+ }
424
+ )
425
+ }
426
+ )
427
+ ] })
369
428
  ]
370
429
  }
371
430
  )
372
431
  }
373
432
  ) : (
374
433
  /* Single mode - use Dropdown normally */
375
- /* @__PURE__ */ t(
376
- ne,
434
+ /* @__PURE__ */ r(
435
+ re,
377
436
  {
378
- ...H,
379
- items: S,
380
- value: r,
437
+ ...Z,
438
+ items: M,
439
+ value: t,
381
440
  onValueChange: (e) => {
382
- n || s || (N?.(e), b(!1));
441
+ a || n || (y?.(e), S(!1));
383
442
  },
384
- placeholder: g,
385
- disabled: n,
386
- loading: q,
387
- showCheckmark: G,
388
- emptyText: J,
389
- state: w,
390
- open: o,
391
- onOpenChange: ee,
392
- side: L,
393
- align: P,
394
- sideOffset: Q,
395
- enableVirtualization: U,
396
- itemHeight: X,
397
- maxHeight: Y,
398
- size: a,
399
- variant: R,
400
- fullWidth: $,
401
- width: v,
402
- "data-testid": u ? `${u}-dropdown` : void 0,
403
- children: me || Me()
443
+ placeholder: b,
444
+ disabled: a,
445
+ loading: V,
446
+ showCheckmark: z,
447
+ emptyText: q,
448
+ state: T,
449
+ open: u,
450
+ onOpenChange: O,
451
+ side: J,
452
+ align: K,
453
+ sideOffset: L,
454
+ enableVirtualization: Q,
455
+ itemHeight: U,
456
+ maxHeight: W,
457
+ size: s,
458
+ variant: k,
459
+ fullWidth: j,
460
+ width: w,
461
+ "data-testid": l ? `${l}-dropdown` : void 0,
462
+ children: ie || Ae()
404
463
  }
405
464
  )
406
465
  ) }),
407
- /* @__PURE__ */ t(
408
- Be,
466
+ /* @__PURE__ */ r(
467
+ Pe,
409
468
  {
410
469
  className: "mt-1",
411
- text: ce,
412
- error: Z,
413
- haveIcon: he,
414
- iconsSize: pe,
470
+ text: ne,
471
+ error: X,
472
+ haveIcon: pe,
473
+ iconsSize: me,
415
474
  iconsCustom: ue
416
475
  }
417
476
  )
@@ -421,7 +480,7 @@ const ae = ke(
421
480
  }
422
481
  );
423
482
  ae.displayName = "Select";
424
- const Ye = Fe(ae);
483
+ const Ye = ke(ae);
425
484
  export {
426
485
  Ye as default
427
486
  };
@@ -1,3 +1,5 @@
1
1
  export { useTruncateTooltip } from './useTruncateTooltip';
2
2
  export { useSeparatedMode } from './useSeparatedMode';
3
+ export { useChipOverflow } from './useChipOverflow';
3
4
  export type { UseSeparatedModeProps, UseSeparatedModeReturn, SeparatedModeItem, SeparatedModeGroup } from './useSeparatedMode';
5
+ export type { UseChipOverflowProps, UseChipOverflowReturn, ChipOverflowItem } from './useChipOverflow';
@@ -0,0 +1,24 @@
1
+ export interface ChipOverflowItem {
2
+ value: string;
3
+ label: string;
4
+ [key: string]: unknown;
5
+ }
6
+ export interface UseChipOverflowProps {
7
+ items: ChipOverflowItem[];
8
+ gap?: number;
9
+ minChipsToShow?: number;
10
+ moreChipWidth?: number;
11
+ }
12
+ export interface UseChipOverflowReturn {
13
+ containerRef: React.RefObject<HTMLDivElement | null>;
14
+ displayItems: ChipOverflowItem[];
15
+ remainingCount: number;
16
+ hasMore: boolean;
17
+ recalculate: () => void;
18
+ }
19
+ /**
20
+ * Custom hook to handle chip overflow detection and dynamic truncation
21
+ * Uses ResizeObserver to detect when chips would overflow and automatically
22
+ * calculates how many chips can be displayed
23
+ */
24
+ export declare const useChipOverflow: ({ items, gap, minChipsToShow, moreChipWidth, }: UseChipOverflowProps) => UseChipOverflowReturn;
@@ -0,0 +1,99 @@
1
+ import { useRef as w, useState as k, useCallback as q, useEffect as g } from "react";
2
+ const O = ({
3
+ items: t,
4
+ gap: a = 8,
5
+ minChipsToShow: C = 1,
6
+ moreChipWidth: W = 60
7
+ }) => {
8
+ const f = w(null), [x, o] = k(t.length), n = q(() => {
9
+ if (!f.current || t.length === 0) {
10
+ o(t.length);
11
+ return;
12
+ }
13
+ const i = f.current, h = i.clientWidth;
14
+ if (h === 0) {
15
+ o(t.length);
16
+ return;
17
+ }
18
+ if (t.length <= 4) {
19
+ const e = i.querySelectorAll(
20
+ '[data-testid*="chip"]:not([data-testid*="chip-more"])'
21
+ );
22
+ let r = 75;
23
+ e.length > 0 && (r = e[0].offsetWidth);
24
+ const s = Math.max(0, t.length - 1) * a;
25
+ if (t.length * r + s <= h) {
26
+ o(t.length);
27
+ return;
28
+ }
29
+ }
30
+ const l = i.querySelectorAll(
31
+ '[data-testid*="chip"]:not([data-testid*="chip-more"])'
32
+ );
33
+ if (l.length === 0) {
34
+ o(t.length);
35
+ return;
36
+ }
37
+ let u = 0;
38
+ l.length > 0 && (u = Array.from(l).reduce((r, s) => r + s.offsetWidth, 0) / l.length), u === 0 && (u = 80);
39
+ let M = 0, c = 0;
40
+ for (let e = 0; e < t.length; e++) {
41
+ const r = e < l.length ? l[e].offsetWidth : u;
42
+ if (r === 0)
43
+ break;
44
+ const s = e === t.length - 1, p = M + r + (e > 0 ? a : 0);
45
+ let d;
46
+ if (s)
47
+ d = h;
48
+ else {
49
+ const b = r;
50
+ p + a + b > h ? d = h - W - a : d = h;
51
+ }
52
+ if (p <= d)
53
+ M = p, c = e + 1;
54
+ else
55
+ break;
56
+ }
57
+ c = Math.max(c, Math.min(C, t.length));
58
+ const y = c >= t.length ? t.length : c, A = t.length > 0 ? Math.max(1, y) : 0;
59
+ o(A);
60
+ }, [t.length, a, C, W]);
61
+ g(() => {
62
+ const i = f.current;
63
+ if (!i) return;
64
+ const h = setTimeout(n, 0), l = new ResizeObserver(() => {
65
+ n();
66
+ });
67
+ return l.observe(i), () => {
68
+ clearTimeout(h), l.disconnect();
69
+ };
70
+ }, [n]), g(() => {
71
+ n();
72
+ const i = setTimeout(() => {
73
+ n();
74
+ }, 10), h = setTimeout(() => {
75
+ n();
76
+ }, 50);
77
+ return () => {
78
+ clearTimeout(i), clearTimeout(h);
79
+ };
80
+ }, [t, n]), g(() => {
81
+ if (t.length > 0) {
82
+ const i = requestAnimationFrame(() => {
83
+ n();
84
+ });
85
+ return () => cancelAnimationFrame(i);
86
+ }
87
+ }, [t.length, n]);
88
+ const T = t.slice(0, x), m = Math.max(0, t.length - x), v = m > 0;
89
+ return {
90
+ containerRef: f,
91
+ displayItems: T,
92
+ remainingCount: m,
93
+ hasMore: v,
94
+ recalculate: n
95
+ };
96
+ };
97
+ export {
98
+ O as useChipOverflow
99
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mcr-design-systems",
3
3
  "private": false,
4
- "version": "1.0.211",
4
+ "version": "1.0.212",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",