@devalok/shilp-sutra 0.27.1 → 0.27.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select-popover.d.ts","sourceRoot":"","sources":["../../src/composed/multi-select-popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAgB9B,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACtG,8DAA8D;IAC9D,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,yCAAyC;IACzC,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,oCAAoC;IACpC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACtC,2BAA2B;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IACxD,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;IAC1E,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAClC,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,sBAAsB;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAMD,QAAA,MAAM,kBAAkB,gGAyOvB,CAAA;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
1
+ {"version":3,"file":"multi-select-popover.d.ts","sourceRoot":"","sources":["../../src/composed/multi-select-popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAgB9B,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACtG,8DAA8D;IAC9D,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,yCAAyC;IACzC,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,oCAAoC;IACpC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACtC,2BAA2B;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IACxD,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;IAC1E,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAClC,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,sBAAsB;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAMD,QAAA,MAAM,kBAAkB,gGA6OvB,CAAA;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
@@ -2,17 +2,17 @@
2
2
  import { jsxs as l, jsx as n, Fragment as H } from "react/jsx-runtime";
3
3
  import * as r from "react";
4
4
  import { cn as L } from "../ui/lib/utils.js";
5
- import { Popover as J, PopoverTrigger as Q, PopoverContent as V } from "../ui/popover.js";
6
- import { IconSearch as W, IconCheck as X } from "@tabler/icons-react";
5
+ import { Popover as J, PopoverTrigger as Q, PopoverContent as W } from "../ui/popover.js";
6
+ import { IconSearch as X, IconCheck as Y } from "@tabler/icons-react";
7
7
  import { springs as P } from "../ui/lib/motion.js";
8
- import { Spinner as Y } from "../ui/spinner.js";
8
+ import { Spinner as Z } from "../ui/spinner.js";
9
9
  import { m as A } from "../_chunks/framer.js";
10
- const Z = r.forwardRef(
10
+ const _ = r.forwardRef(
11
11
  ({
12
- items: g,
12
+ items: w,
13
13
  groups: o,
14
14
  value: d,
15
- onValueChange: w,
15
+ onValueChange: h,
16
16
  searchPlaceholder: T = "Search...",
17
17
  onSearch: c,
18
18
  searchDebounce: v = 300,
@@ -25,49 +25,44 @@ const Z = r.forwardRef(
25
25
  className: K,
26
26
  ...$
27
27
  }, z) => {
28
- const [f, G] = r.useState(!1), [a, C] = r.useState(""), [u, m] = r.useState(null), [S, h] = r.useState(!1), [i, p] = r.useState(-1), y = r.useRef(), I = r.useRef(null);
28
+ const [f, G] = r.useState(!1), [i, S] = r.useState(""), [u, m] = r.useState(null), [C, y] = r.useState(!1), [a, p] = r.useState(-1), g = r.useRef(), I = r.useRef(null);
29
29
  r.useEffect(() => {
30
- f || (C(""), m(null), p(-1));
30
+ f || (S(""), m(null), p(-1));
31
31
  }, [f]), r.useEffect(() => {
32
32
  if (!(!c || !f)) {
33
- if (!a.trim()) {
34
- m(null), h(!1);
33
+ if (!i.trim()) {
34
+ m(null), y(!1);
35
35
  return;
36
36
  }
37
- return h(!0), clearTimeout(y.current), y.current = setTimeout(() => {
38
- c(a).then((e) => m(e)).catch(() => m([])).finally(() => h(!1));
39
- }, v), () => clearTimeout(y.current);
37
+ return y(!0), clearTimeout(g.current), g.current = setTimeout(() => {
38
+ c(i).then((e) => m(e)).catch(() => m([])).finally(() => y(!1));
39
+ }, v), () => clearTimeout(g.current);
40
40
  }
41
- }, [a, c, v, f]);
42
- const b = r.useMemo(() => u || (o ? o.flatMap((e) => e.items) : g ?? []), [g, o, u]), x = r.useMemo(() => {
41
+ }, [i, c, v, f]);
42
+ const b = r.useMemo(() => u || (o ? o.flatMap((e) => e.items) : w ?? []), [w, o, u]), x = r.useMemo(() => {
43
43
  if (c) return b;
44
- const e = a.toLowerCase();
44
+ const e = i.toLowerCase();
45
45
  return e ? b.filter((s) => s.label.toLowerCase().includes(e)) : b;
46
- }, [b, a, c]), R = r.useMemo(() => {
46
+ }, [b, i, c]), R = r.useMemo(() => {
47
47
  if (!o || c || u) return null;
48
- const e = a.toLowerCase();
48
+ const e = i.toLowerCase();
49
49
  return o.map((s) => ({
50
50
  ...s,
51
51
  items: e ? s.items.filter((t) => t.label.toLowerCase().includes(e)) : s.items
52
52
  })).filter((s) => s.items.length > 0);
53
- }, [o, a, c, u]);
53
+ }, [o, i, c, u]);
54
54
  function M(e) {
55
- if (d.includes(e))
56
- w(d.filter((t) => t !== e));
57
- else {
58
- if (k && d.length >= k) return;
59
- w([...d, e]);
60
- }
55
+ d.includes(e) ? h(d.filter((t) => t !== e)) : k && d.length >= k ? h([...d.slice(1), e]) : h([...d, e]);
61
56
  }
62
57
  r.useEffect(() => {
63
58
  p(-1);
64
- }, [a]), r.useEffect(() => {
59
+ }, [i]), r.useEffect(() => {
65
60
  var t;
66
- if (i < 0) return;
61
+ if (a < 0) return;
67
62
  const e = I.current;
68
63
  if (!e) return;
69
- (t = e.querySelectorAll("[data-multiselect-item]")[i]) == null || t.scrollIntoView({ block: "nearest" });
70
- }, [i]);
64
+ (t = e.querySelectorAll("[data-multiselect-item]")[a]) == null || t.scrollIntoView({ block: "nearest" });
65
+ }, [a]);
71
66
  function U(e) {
72
67
  const s = x.length;
73
68
  if (s !== 0) {
@@ -75,16 +70,16 @@ const Z = r.forwardRef(
75
70
  e.preventDefault(), p((t) => t < s - 1 ? t + 1 : 0);
76
71
  else if (e.key === "ArrowUp")
77
72
  e.preventDefault(), p((t) => t <= 0 ? s - 1 : t - 1);
78
- else if (e.key === "Enter" && i >= 0) {
73
+ else if (e.key === "Enter" && a >= 0) {
79
74
  e.preventDefault();
80
- const t = x[i];
75
+ const t = x[a];
81
76
  t && !t.disabled && M(t.id);
82
77
  }
83
78
  }
84
79
  }
85
80
  let B = 0;
86
81
  function D(e) {
87
- const s = d.includes(e.id), t = B++, E = t === i;
82
+ const s = d.includes(e.id), t = B++, E = t === a;
88
83
  return /* @__PURE__ */ l(
89
84
  A.button,
90
85
  {
@@ -126,7 +121,7 @@ const Z = r.forwardRef(
126
121
  animate: { scale: 1 },
127
122
  transition: P.bouncy,
128
123
  className: "inline-flex shrink-0",
129
- children: /* @__PURE__ */ n(X, { className: "h-ico-sm w-ico-sm text-accent-11" })
124
+ children: /* @__PURE__ */ n(Y, { className: "h-ico-sm w-ico-sm text-accent-11" })
130
125
  }
131
126
  )
132
127
  ]
@@ -137,7 +132,7 @@ const Z = r.forwardRef(
137
132
  return /* @__PURE__ */ l(J, { open: f, onOpenChange: G, children: [
138
133
  /* @__PURE__ */ n(Q, { asChild: !0, children: O }),
139
134
  /* @__PURE__ */ l(
140
- V,
135
+ W,
141
136
  {
142
137
  ref: z,
143
138
  ...$,
@@ -150,28 +145,28 @@ const Z = r.forwardRef(
150
145
  sideOffset: 4,
151
146
  children: [
152
147
  /* @__PURE__ */ l("div", { className: "flex items-center gap-ds-03 border-b border-surface-border-strong px-ds-04 py-ds-03", children: [
153
- /* @__PURE__ */ n(W, { className: "h-ico-sm w-ico-sm shrink-0 text-surface-fg-subtle", stroke: 1.5 }),
148
+ /* @__PURE__ */ n(X, { className: "h-ico-sm w-ico-sm shrink-0 text-surface-fg-subtle", stroke: 1.5 }),
154
149
  /* @__PURE__ */ n(
155
150
  "input",
156
151
  {
157
152
  type: "text",
158
153
  placeholder: T,
159
- value: a,
160
- onChange: (e) => C(e.target.value),
154
+ value: i,
155
+ onChange: (e) => S(e.target.value),
161
156
  onKeyDown: U,
162
157
  "aria-label": "Search",
163
- "aria-activedescendant": i >= 0 ? `msp-item-${i}` : void 0,
158
+ "aria-activedescendant": a >= 0 ? `msp-item-${a}` : void 0,
164
159
  className: "w-full bg-transparent text-ds-md font-body text-surface-fg placeholder:text-surface-fg-subtle outline-none"
165
160
  }
166
161
  ),
167
- S && /* @__PURE__ */ n(Y, { size: "sm" })
162
+ C && /* @__PURE__ */ n(Z, { size: "sm" })
168
163
  ] }),
169
164
  /* @__PURE__ */ l("div", { ref: I, className: "max-h-[240px] overflow-y-auto py-ds-02", children: [
170
165
  R ? R.map((e) => /* @__PURE__ */ l("div", { children: [
171
166
  /* @__PURE__ */ n("div", { className: "px-ds-04 py-ds-02 text-ds-xs font-semibold uppercase tracking-wider text-surface-fg-subtle", children: e.label }),
172
167
  e.items.map(D)
173
168
  ] }, e.label)) : x.map(D),
174
- !S && x.length === 0 && /* @__PURE__ */ n("p", { className: "px-ds-04 py-ds-05 text-center text-ds-sm font-body text-surface-fg-subtle", children: j })
169
+ !C && x.length === 0 && /* @__PURE__ */ n("p", { className: "px-ds-04 py-ds-05 text-center text-ds-sm font-body text-surface-fg-subtle", children: j })
175
170
  ] })
176
171
  ]
177
172
  }
@@ -179,7 +174,7 @@ const Z = r.forwardRef(
179
174
  ] });
180
175
  }
181
176
  );
182
- Z.displayName = "MultiSelectPopover";
177
+ _.displayName = "MultiSelectPopover";
183
178
  export {
184
- Z as MultiSelectPopover
179
+ _ as MultiSelectPopover
185
180
  };
@@ -141,7 +141,7 @@ const k = l.forwardRef(
141
141
  children: [
142
142
  /* @__PURE__ */ d("div", { className: "border-b border-surface-border-strong px-ds-05 py-ds-04", children: [
143
143
  /* @__PURE__ */ e("p", { className: "text-ds-md text-surface-fg", children: r.name }),
144
- r.email && /* @__PURE__ */ e("p", { className: "text-ds-sm text-surface-fg-subtle", children: r.email })
144
+ r.email && /* @__PURE__ */ e("p", { className: "text-ds-sm text-surface-fg-subtle truncate", children: r.email })
145
145
  ] }),
146
146
  /* @__PURE__ */ d(
147
147
  f,
@@ -51,3 +51,12 @@
51
51
  - Supply either `items` (flat) or `groups` (sectioned), not both
52
52
  - When `onSearch` is provided, local filtering is disabled — the callback must return results
53
53
  - Search state resets when the popover closes
54
+ - `maxSelections: 1` acts as single-select — clicking a new item replaces the current one
55
+
56
+ ## Changes
57
+
58
+ ### v0.27.2
59
+ - **Fixed** `maxSelections` at limit now replaces oldest selection instead of blocking. Single-select (`maxSelections: 1`) swaps in the new value.
60
+
61
+ ### v0.26.0
62
+ - **Added** Initial release
@@ -128,6 +128,9 @@ UserMenuItem fields:
128
128
  - **Added** Auto grid/flex layout detection based on Center zone presence
129
129
  - **Changed** Background elevated from `bg-surface-1` to `bg-surface-2`
130
130
 
131
+ ### v0.27.2
132
+ - **Fixed** UserMenu email truncation — long emails now truncate instead of overflowing the dropdown
133
+
131
134
  ### v0.7.0
132
135
  - **Added** `userMenuItems` prop for custom dropdown items
133
136
 
package/llms-full.txt CHANGED
@@ -5,7 +5,7 @@
5
5
  > All variant values and props verified from source CVA definitions.
6
6
  >
7
7
  > Package: @devalok/shilp-sutra
8
- > Version: 0.27.1
8
+ > Version: 0.27.2
9
9
 
10
10
  ---
11
11
 
@@ -4003,6 +4003,15 @@ MasterDetail (root), MasterDetail.List, MasterDetail.Detail, MasterDetail.ListIt
4003
4003
  - Supply either `items` (flat) or `groups` (sectioned), not both
4004
4004
  - When `onSearch` is provided, local filtering is disabled — the callback must return results
4005
4005
  - Search state resets when the popover closes
4006
+ - `maxSelections: 1` acts as single-select — clicking a new item replaces the current one
4007
+
4008
+ ## Changes
4009
+
4010
+ ### v0.27.2
4011
+ - **Fixed** `maxSelections` at limit now replaces oldest selection instead of blocking. Single-select (`maxSelections: 1`) swaps in the new value.
4012
+
4013
+ ### v0.26.0
4014
+ - **Added** Initial release
4006
4015
  # PageHeader
4007
4016
 
4008
4017
  - Import: @devalok/shilp-sutra/composed/page-header
@@ -4848,6 +4857,9 @@ UserMenuItem fields:
4848
4857
  - **Added** Auto grid/flex layout detection based on Center zone presence
4849
4858
  - **Changed** Background elevated from `bg-surface-1` to `bg-surface-2`
4850
4859
 
4860
+ ### v0.27.2
4861
+ - **Fixed** UserMenu email truncation — long emails now truncate instead of overflowing the dropdown
4862
+
4851
4863
  ### v0.7.0
4852
4864
  - **Added** `userMenuItems` prop for custom dropdown items
4853
4865
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devalok/shilp-sutra",
3
- "version": "0.27.1",
3
+ "version": "0.27.2",
4
4
  "description": "Devalok Design System — tokens, components, and patterns for Next.js",
5
5
  "license": "MIT",
6
6
  "type": "module",