haze-ui 1.34.1 → 1.35.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 (98) hide show
  1. package/README.md +26 -0
  2. package/dist/THIRD-PARTY-NOTICES.md +2 -1
  3. package/dist/components/Anchor/Anchor.js +84 -65
  4. package/dist/components/BackToTop/BackToTop.js +18 -12
  5. package/dist/components/Combobox/Combobox.js +109 -99
  6. package/dist/components/CopyButton/CopyButton.js +13 -12
  7. package/dist/components/DataTable/DataTable.js +16 -16
  8. package/dist/components/FloatButton/FloatButton.js +11 -19
  9. package/dist/components/FollowUpSuggestions/FollowUpSuggestions.js +45 -0
  10. package/dist/components/FollowUpSuggestions/index.js +3 -0
  11. package/dist/components/LocaleProvider/ar-sa.js +9 -0
  12. package/dist/components/LocaleProvider/de-de.js +9 -0
  13. package/dist/components/LocaleProvider/es-es.js +9 -0
  14. package/dist/components/LocaleProvider/fr-fr.js +9 -0
  15. package/dist/components/LocaleProvider/it-it.js +9 -0
  16. package/dist/components/LocaleProvider/ja-jp.js +9 -0
  17. package/dist/components/LocaleProvider/ko-kr.js +9 -0
  18. package/dist/components/LocaleProvider/locale.js +9 -0
  19. package/dist/components/LocaleProvider/pt-br.js +9 -0
  20. package/dist/components/LocaleProvider/ru-ru.js +9 -0
  21. package/dist/components/LocaleProvider/zh-cn.js +9 -0
  22. package/dist/components/NavigationBar/NavLink.js +15 -16
  23. package/dist/components/NotificationCenter/NotificationCenter.js +294 -0
  24. package/dist/components/NotificationCenter/index.js +3 -0
  25. package/dist/components/Tabs/Tab.js +58 -50
  26. package/dist/components/TaskList/TaskList.js +96 -0
  27. package/dist/components/TaskList/index.js +3 -0
  28. package/dist/components/Toggle/Toggle.js +8 -8
  29. package/dist/components/Toggle/ToggleCore.js +4 -5
  30. package/dist/components/Toolbar/ToolbarButton.js +7 -7
  31. package/dist/components/Toolbar/ToolbarToggle.js +9 -9
  32. package/dist/components/Tree/Tree.js +159 -137
  33. package/dist/components/Tree/index.js +2 -1
  34. package/dist/components/Tree/useTree.js +32 -0
  35. package/dist/components/Tree/utils.js +21 -11
  36. package/dist/css/anchor.css +1 -1
  37. package/dist/css/combobox.css +1 -1
  38. package/dist/css/data-table.css +1 -1
  39. package/dist/css/follow-up-suggestions.css +4 -0
  40. package/dist/css/notification-center.css +5 -0
  41. package/dist/css/task-list.css +4 -0
  42. package/dist/css/tokens.css +1 -0
  43. package/dist/css-manifest.json +21 -0
  44. package/dist/haze-ui.css +17 -3
  45. package/dist/headless/index.js +2 -1
  46. package/dist/hooks/index.js +25 -0
  47. package/dist/hooks/useAnchorSpy.js +49 -0
  48. package/dist/hooks/useElementSize.js +31 -0
  49. package/dist/hooks/useIdle.js +45 -0
  50. package/dist/hooks/useMutationObserver.js +31 -0
  51. package/dist/hooks/useNetwork.js +28 -0
  52. package/dist/hooks/useOrientation.js +27 -0
  53. package/dist/hooks/useResizeObserver.js +16 -0
  54. package/dist/icons/index.js +9 -0
  55. package/dist/index.js +323 -318
  56. package/dist/mcp-docs.json +535 -13
  57. package/dist/registry.json +387 -7
  58. package/dist/sitemap.xml +6 -0
  59. package/dist/tokens/index.js +2 -1
  60. package/dist/tokens/zoom.js +6 -0
  61. package/dist/types/components/Anchor/Anchor.d.ts +5 -1
  62. package/dist/types/components/BackToTop/BackToTop.d.ts +23 -5
  63. package/dist/types/components/Combobox/Combobox.d.ts +17 -1
  64. package/dist/types/components/ConfigProvider/ConfigContext.d.ts +6 -0
  65. package/dist/types/components/CopyButton/CopyButton.d.ts +16 -4
  66. package/dist/types/components/DataTable/DataTable.bench.d.ts +1 -0
  67. package/dist/types/components/FloatButton/FloatButton.d.ts +25 -5
  68. package/dist/types/components/FollowUpSuggestions/FollowUpSuggestions.d.ts +27 -0
  69. package/dist/types/components/FollowUpSuggestions/index.d.ts +2 -0
  70. package/dist/types/components/LocaleProvider/locale.d.ts +9 -0
  71. package/dist/types/components/NavigationBar/NavLink.d.ts +24 -32
  72. package/dist/types/components/NotificationCenter/NotificationCenter.d.ts +111 -0
  73. package/dist/types/components/NotificationCenter/index.d.ts +2 -0
  74. package/dist/types/components/Select/Select.bench.d.ts +1 -0
  75. package/dist/types/components/Tabs/Tab.d.ts +26 -4
  76. package/dist/types/components/TaskList/TaskList.d.ts +50 -0
  77. package/dist/types/components/TaskList/index.d.ts +2 -0
  78. package/dist/types/components/Toggle/Toggle.d.ts +15 -8
  79. package/dist/types/components/Toggle/ToggleCore.d.ts +16 -7
  80. package/dist/types/components/Toolbar/ToolbarButton.d.ts +17 -5
  81. package/dist/types/components/Toolbar/ToolbarToggle.d.ts +22 -5
  82. package/dist/types/components/Tree/Tree.d.ts +1 -1
  83. package/dist/types/components/Tree/index.d.ts +4 -1
  84. package/dist/types/components/Tree/types.d.ts +20 -0
  85. package/dist/types/components/Tree/useTree.d.ts +96 -0
  86. package/dist/types/components/Tree/utils.d.ts +7 -0
  87. package/dist/types/components/VirtualList/VirtualList.bench.d.ts +1 -0
  88. package/dist/types/headless/index.d.ts +16 -0
  89. package/dist/types/hooks/index.d.ts +4 -0
  90. package/dist/types/hooks/useAnchorSpy.d.ts +62 -0
  91. package/dist/types/icons/index.d.ts +138 -0
  92. package/dist/types/index.d.ts +10 -2
  93. package/dist/types/tokens/index.d.ts +1 -0
  94. package/dist/types/tokens/zoom.d.ts +33 -0
  95. package/dist/types/utils/deprecate.d.ts +13 -0
  96. package/dist/types/utils/portal.d.ts +29 -0
  97. package/dist/utils/portal.js +13 -0
  98. package/package.json +40 -8
package/README.md CHANGED
@@ -7,6 +7,7 @@ English | [简体中文](./README-zh_CN.md)
7
7
  [![npm](https://img.shields.io/npm/v/haze-ui)](https://www.npmjs.com/package/haze-ui)
8
8
  [![downloads](https://img.shields.io/npm/dm/haze-ui.svg)](https://www.npmjs.com/package/haze-ui)
9
9
  [![CI](https://github.com/wmzy/haze-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/wmzy/haze-ui/actions/workflows/ci.yml)
10
+ [![Scorecard](https://api.scorecard.dev/projects/github.com/wmzy/haze-ui/badge)](https://scorecard.dev/viewer/?uri=github.com/wmzy/haze-ui)
10
11
 
11
12
  haze-ui is a React 19 component library styled with Linaria (zero-runtime
12
13
  CSS-in-JS) against `--haze-*` design tokens: 148 components in 9 groups,
@@ -97,6 +98,11 @@ with no polyfills or fallbacks — the same four engines are the hard CSS floor.
97
98
  powered by [react-use-control](https://github.com/wmzy/react-use-control);
98
99
  no `defaultXxx`/`xxx` dual API to keep in sync.
99
100
  → [Getting started](https://wmzy.github.io/haze-ui/getting-started)
101
+ - **Curated icons, zero cost** — `haze-ui/icons` re-exports the ~100 most
102
+ common [lucide-react](https://lucide.dev) glyphs to pair with the `Icon`
103
+ component, plus the matching `hazeIconSize` scale; `lucide-react` is a
104
+ regular dependency with `sideEffects: false`, so unused icons — or the
105
+ whole set — tree-shake away.
100
106
  - **AI / chat component family** — `ChatContainer`, `ChatMessage`,
101
107
  `StreamingText`, `ToolCallCard`, `ThinkingIndicator` and `ChatInput` cover
102
108
  the agent chat surface; `Plan`, `Queue`, `InlineCitation` and the
@@ -107,6 +113,14 @@ with no polyfills or fallbacks — the same four engines are the hard CSS floor.
107
113
  - **React Compiler verified** — the whole suite runs green with
108
114
  babel-plugin-react-compiler enabled (`pnpm test:compiler`): auto-memoization
109
115
  is part of the release gate, not a hope.
116
+ - **Runtime benchmarks** — `pnpm bench` (vitest bench, jsdom) measures pure
117
+ JS-side costs of the heaviest components — 1000-row DataTable render and
118
+ sort flips, a 5000-item VirtualList scroll window, and Select panel
119
+ open/close cycles. Informational numbers for trend spotting; CI runs the
120
+ job non-blocking.
121
+ - **Codemod upgrade toolchain** — `pnpm codemod <transform> <path>` runs the
122
+ jscodeshift-powered migrations in [scripts/codemods](./scripts/codemods);
123
+ every future major ships a codemod for its breaking changes.
110
124
  - **Native-form ready** — value-holding components (Select, Switch, Rating,
111
125
  Slider, TagInput, OTPInput, Segmented, ColorPicker, RichTextEditor) accept
112
126
  a `name` and submit into `FormData`, so `<form action={serverAction}>`
@@ -138,12 +152,24 @@ with no polyfills or fallbacks — the same four engines are the hard CSS floor.
138
152
  Every styled export is also installable through the shadcn CLI as a thin
139
153
  wrapper over the npm package — see [registry/README.md](./registry/README.md).
140
154
 
155
+ ## Release channels
156
+
157
+ | Channel | Install | Version shape | Who it's for |
158
+ | --- | --- | --- | --- |
159
+ | stable (`latest`) | `npm i haze-ui` | `1.34.1` | Production. Cut from `main` by semantic-release whenever a relevant commit (feat/fix/perf…) lands. |
160
+ | beta | `npm i haze-ui@beta` | `1.35.0-beta.1` | Trying upcoming changes early. Cut from the `beta` branch through semantic-release's prerelease flow — same commit analysis, changelog and GitHub Release as stable, published to the `beta` dist-tag so `latest` never moves. |
161
+ | canary | `npm i haze-ui@canary` | `0.0.0-canary.a1b2c3d4.123` | Verifying a fix against one exact commit. Manually dispatched from any ref, stamped with the commit SHA + run number, and fully bypasses semantic-release — no commit analysis, no changelog, no git tag. |
162
+
163
+ Beta vs canary in one line: **beta** is an ordered prerelease line (`x.y.z-beta.n`) that graduates to stable when its commits merge into `main`; **canary** is a disposable per-commit snapshot (`0.0.0-canary.<sha>.<run>`) that the next dispatch supersedes and nothing ever promotes.
164
+
141
165
  ## Community
142
166
 
143
167
  - 🐛 [Report a bug](https://github.com/wmzy/haze-ui/issues/new?template=bug_report.yml)
144
168
  - ✨ [Request a feature](https://github.com/wmzy/haze-ui/issues/new?template=feature_request.yml)
145
169
  - 📖 [Contribute to the project](./CONTRIBUTING.md)
146
170
  - 🔒 [Security policy](./SECURITY.md)
171
+ - 🤝 [Code of Conduct](./CODE_OF_CONDUCT.md)
172
+ - 💬 [Discussions & Q&A](https://github.com/wmzy/haze-ui/discussions)
147
173
 
148
174
  **Building with haze-ui?** We would love to feature you. Open an issue
149
175
  titled `used by: <your project>` with the project name, a link and (optionally)
@@ -15,7 +15,7 @@ must be verified manually before redistribution.
15
15
  ## License summary
16
16
 
17
17
  - MIT: 103 packages
18
- - ISC: 19 packages
18
+ - ISC: 20 packages
19
19
  - 0BSD: 1 package
20
20
  - BSD-3-Clause: 1 package
21
21
  - MIT AND ISC: 1 package
@@ -106,6 +106,7 @@ must be verified manually before redistribution.
106
106
  | `libphonenumber-js` | 1.13.15 | MIT | [gitlab.com/catamphetamine/libphonenumber-js](https://gitlab.com/catamphetamine/libphonenumber-js) |
107
107
  | `linkifyjs` | 4.3.3 | MIT | [github.com/nfrasser/linkifyjs](https://github.com/nfrasser/linkifyjs) |
108
108
  | `locate-path` | 5.0.0 | MIT | [github.com/sindresorhus/locate-path](https://github.com/sindresorhus/locate-path) |
109
+ | `lucide-react` | 1.44.0 | ISC | [github.com/lucide-icons/lucide](https://github.com/lucide-icons/lucide) |
109
110
  | `orderedmap` | 2.1.1 | MIT | [github.com/marijnh/orderedmap](https://github.com/marijnh/orderedmap) |
110
111
  | `p-limit` | 2.3.0 | MIT | [github.com/sindresorhus/p-limit](https://github.com/sindresorhus/p-limit) |
111
112
  | `p-locate` | 4.1.0 | MIT | [github.com/sindresorhus/p-locate](https://github.com/sindresorhus/p-locate) |
@@ -1,84 +1,103 @@
1
1
 
2
2
  "use client";
3
3
  import { classnames as e } from "../../utils/classnames.js";
4
+ import { useAnchorSpy as t } from "../../hooks/useAnchorSpy.js";
5
+ import { useElementSize as n } from "../../hooks/useElementSize.js";
4
6
  /* empty css */
5
- import { useEffect as t } from "react";
6
- import { jsx as n } from "react/jsx-runtime";
7
- import { useControl as r } from "react-use-control";
7
+ import { useCallback as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
8
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
9
  //#region src/lib/components/Anchor/Anchor.tsx
9
- var i = "haze-Anchor__nav", a = "haze-Anchor__list", o = "haze-Anchor__link", s = "haze-Anchor__linkActive";
10
- function c({ items: c, activeId: l, onClick: u, offsetTop: d = 0, bounds: f = 5, getContainer: p, className: m, ...h }) {
11
- let [g, _] = r(l, () => c[0]?.id ?? ""), v = (e) => {
10
+ var u = "haze-Anchor__nav", d = "haze-Anchor__list", f = "haze-Anchor__sublist", p = "haze-Anchor__link", m = "haze-Anchor__linkActive", h = "haze-Anchor__linkActiveBar", g = "haze-Anchor__indicatorBar", _ = "haze-Anchor__indicatorHidden";
11
+ function v(e) {
12
+ return e.flatMap((e) => {
13
+ let t = e.children?.length ? v(e.children) : [];
14
+ return [e.id, ...t];
15
+ });
16
+ }
17
+ function y({ items: y, activeId: b, onClick: x, indicator: S = !1, offsetTop: C = 0, bounds: w = 5, getContainer: T, className: E, ...D }) {
18
+ let O = a(() => v(y), [y]), { activeId: k, setActiveId: A } = t({
19
+ ids: O,
20
+ getContainer: T,
21
+ offsetTop: C,
22
+ bounds: w,
23
+ activeId: b
24
+ }), j = o(null), [M, N] = s(null), [P, F] = n({ enabled: S }), I = r((e) => {
25
+ j.current = e, P(e);
26
+ }, [P]), L = r(() => {
27
+ let e = j.current?.querySelector("a[aria-current=\"true\"]");
28
+ if (!e) {
29
+ N(null);
30
+ return;
31
+ }
32
+ N({
33
+ top: e.offsetTop,
34
+ height: e.offsetHeight
35
+ });
36
+ }, []);
37
+ i(() => {
38
+ S && L();
39
+ }, [
40
+ S,
41
+ k,
42
+ y,
43
+ F,
44
+ L
45
+ ]);
46
+ let R = (e) => {
12
47
  let t = document.getElementById(e);
13
48
  if (!t) return;
14
- let n = p?.() ?? window;
49
+ let n = T?.() ?? window;
15
50
  if (n instanceof HTMLElement) {
16
- n.scrollTop = t.getBoundingClientRect().top - n.getBoundingClientRect().top + n.scrollTop - d;
51
+ n.scrollTop = t.getBoundingClientRect().top - n.getBoundingClientRect().top + n.scrollTop - C;
17
52
  return;
18
53
  }
19
54
  n.scrollTo({
20
- top: t.getBoundingClientRect().top + window.scrollY - d,
55
+ top: t.getBoundingClientRect().top + window.scrollY - C,
21
56
  behavior: "smooth"
22
57
  });
58
+ }, z = (t) => {
59
+ let n = k === t.id;
60
+ return /* @__PURE__ */ l("li", {
61
+ "data-slot": "item",
62
+ children: [/* @__PURE__ */ c("a", {
63
+ "data-slot": "link",
64
+ href: `#${t.id}`,
65
+ "aria-current": n ? "true" : void 0,
66
+ onClick: (e) => {
67
+ e.preventDefault(), A(t.id), x?.(t.id), R(t.id);
68
+ },
69
+ className: e([
70
+ p,
71
+ n && m,
72
+ n && !S && h
73
+ ]),
74
+ children: t.label
75
+ }), t.children?.length ? /* @__PURE__ */ c("ul", {
76
+ "data-slot": "sublist",
77
+ className: e([f]),
78
+ children: t.children.map(z)
79
+ }) : null]
80
+ }, t.id);
23
81
  };
24
- return t(() => {
25
- if (typeof IntersectionObserver > "u") return;
26
- let e = /* @__PURE__ */ new Set(), t = p?.() ?? window, n = new IntersectionObserver((t) => {
27
- for (let n of t) n.isIntersecting ? e.add(n.target.id) : e.delete(n.target.id);
28
- let n = c.find((t) => e.has(t.id));
29
- n && _(n.id);
30
- }, {
31
- root: t instanceof HTMLElement ? t : null,
32
- rootMargin: `${-d}px 0px 0px 0px`
33
- });
34
- for (let e of c) {
35
- let t = document.getElementById(e.id);
36
- t && n.observe(t);
37
- }
38
- return () => n.disconnect();
39
- }, [
40
- c,
41
- d,
42
- p,
43
- _
44
- ]), t(() => {
45
- if (typeof IntersectionObserver < "u") return;
46
- let e = p?.() ?? window, t = e instanceof HTMLElement ? e : window, n = e instanceof HTMLElement ? e.getBoundingClientRect().top : 0, r = () => {
47
- let e;
48
- for (let t of c) {
49
- let r = document.getElementById(t.id);
50
- r && r.getBoundingClientRect().top - n <= f && (e = t.id);
51
- }
52
- e && _(e);
53
- };
54
- return t.addEventListener("scroll", r, { passive: !0 }), () => t.removeEventListener("scroll", r);
55
- }, [
56
- c,
57
- f,
58
- p,
59
- _
60
- ]), /* @__PURE__ */ n("nav", {
82
+ return /* @__PURE__ */ l("nav", {
61
83
  "data-slot": "anchor",
62
- ...h,
63
- className: e([i, m]),
64
- children: n("ul", {
84
+ ref: I,
85
+ ...D,
86
+ className: e([u, E]),
87
+ children: [S ? /* @__PURE__ */ c("span", {
88
+ "aria-hidden": "true",
89
+ "data-slot": "indicator",
90
+ style: M === null ? void 0 : {
91
+ transform: `translateY(${M.top}px)`,
92
+ height: `${M.height}px`
93
+ },
94
+ className: e([g, M === null && _])
95
+ }) : null, /* @__PURE__ */ c("ul", {
65
96
  "data-slot": "list",
66
- className: e([a]),
67
- children: c.map((t) => /* @__PURE__ */ n("li", {
68
- "data-slot": "item",
69
- children: /* @__PURE__ */ n("a", {
70
- "data-slot": "link",
71
- href: `#${t.id}`,
72
- "aria-current": g === t.id ? "true" : void 0,
73
- onClick: (e) => {
74
- e.preventDefault(), _(t.id), u?.(t.id), v(t.id);
75
- },
76
- className: e([o, g === t.id && s]),
77
- children: t.label
78
- })
79
- }, t.id))
80
- })
97
+ className: e([d]),
98
+ children: y.map(z)
99
+ })]
81
100
  });
82
101
  }
83
102
  //#endregion
84
- export { c as default };
103
+ export { y as default };
@@ -7,25 +7,31 @@ import { useCallback as n, useEffect as r, useState as i } from "react";
7
7
  import { jsx as a } from "react/jsx-runtime";
8
8
  //#region src/lib/components/BackToTop/BackToTop.tsx
9
9
  var o = "haze-BackToTop__button", s = "haze-BackToTop__hidden";
10
- function c({ threshold: c = 300, children: l = "↑", className: u }) {
11
- let [d, f] = i(!1), p = t("backToTop"), m = n(() => {
12
- f(window.scrollY > c);
10
+ function c({ threshold: c = 300, as: l, className: u, children: d = "↑", onClick: f, ...p }) {
11
+ let [m, h] = i(!1), g = t("backToTop"), _ = n(() => {
12
+ h(window.scrollY > c);
13
13
  }, [c]);
14
- return r(() => (window.addEventListener("scroll", m, { passive: !0 }), () => window.removeEventListener("scroll", m)), [m]), /* @__PURE__ */ a("button", {
14
+ r(() => (window.addEventListener("scroll", _, { passive: !0 }), () => window.removeEventListener("scroll", _)), [_]);
15
+ let v = () => {
16
+ window.scrollTo({
17
+ top: 0,
18
+ behavior: "smooth"
19
+ });
20
+ };
21
+ return /* @__PURE__ */ a(l ?? "button", {
22
+ ...l === void 0 || l === "button" ? { type: "button" } : {},
15
23
  "data-slot": "back-to-top",
16
- onClick: () => {
17
- window.scrollTo({
18
- top: 0,
19
- behavior: "smooth"
20
- });
24
+ "aria-label": g.label,
25
+ ...p,
26
+ onClick: (e) => {
27
+ f?.(e), v();
21
28
  },
22
- "aria-label": p.label,
23
29
  className: e([
24
30
  o,
25
- !d && s,
31
+ !m && s,
26
32
  u
27
33
  ]),
28
- children: l
34
+ children: d
29
35
  });
30
36
  }
31
37
  //#endregion
@@ -17,8 +17,8 @@ import { useCallback as le, useEffect as i, useId as ue, useMemo as a, useRef as
17
17
  import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
18
18
  import { useControl as d } from "react-use-control";
19
19
  //#region src/lib/components/Combobox/Combobox.tsx
20
- var de = "haze-Combobox__wrapper", fe = "haze-Combobox__input", pe = "haze-Combobox__multiBox", me = "haze-Combobox__multiInput", f = "haze-Combobox__matchMark", p = "haze-Combobox__stateRow", he = "haze-Combobox__groupHeadingText", ge = "haze-Combobox__listbox", _e = "haze-Combobox__listboxVirtual", ve = 200, ye = 37, be = "haze-Combobox__virtualRow";
21
- function xe(t, n) {
20
+ var de = "haze-Combobox__wrapper", fe = "haze-Combobox__input", pe = "haze-Combobox__multiBox", me = "haze-Combobox__multiInput", he = "haze-Combobox__overflowBadge", f = "haze-Combobox__matchMark", p = "haze-Combobox__stateRow", ge = "haze-Combobox__groupHeadingText", _e = "haze-Combobox__listbox", ve = "haze-Combobox__listboxVirtual", ye = 200, be = 37, xe = "haze-Combobox__virtualRow";
21
+ function Se(t, n) {
22
22
  if (n === "") return t;
23
23
  let r = t.toLowerCase().indexOf(n.toLowerCase());
24
24
  return r < 0 ? t : /* @__PURE__ */ u(c, { children: [
@@ -31,27 +31,27 @@ function xe(t, n) {
31
31
  t.slice(r + n.length)
32
32
  ] });
33
33
  }
34
- function m({ value: c, open: f, options: m, children: Se, multiple: h = !1, onValuesChange: g, creatable: Ce = !1, onCreate: we, onSearch: _, loading: v = !1, empty: Te, highlightMatches: Ee = !1, maxHeight: y, placeholder: De, virtualThreshold: b = 100, virtualized: x, className: Oe, classNames: S, ref: C }) {
35
- let w = ee("Combobox"), T = w.classNames ? {
36
- ...w.classNames,
37
- ...S
38
- } : S, E = n("combobox"), [D, O] = d(c, h ? [] : ""), [k, ke] = s([]), [A, j] = s(""), [M, N] = d(f, !1), [P, F] = s(-1), [Ae, je] = s(A), I = ue(), L = o(null), Me = le((e) => te(L, C)(e), [L, C]), R = o(null), z = o(null), B = o(null), V = o(null), H = re({
39
- open: M,
40
- setOpen: N,
41
- triggerRef: h ? R : L,
42
- panelRef: z,
34
+ function m({ value: c, open: f, options: m, children: Ce, multiple: h = !1, maxCount: we, maxTagCount: g, onValuesChange: _, creatable: Te = !1, onCreate: Ee, onSearch: v, loading: y = !1, empty: De, highlightMatches: Oe = !1, maxHeight: b, placeholder: ke, virtualThreshold: x = 100, virtualized: S, className: Ae, classNames: C, ref: w }) {
35
+ let T = ee("Combobox"), E = T.classNames ? {
36
+ ...T.classNames,
37
+ ...C
38
+ } : C, D = n("combobox"), je = n("select"), [O, k] = d(c, h ? [] : ""), [A, Me] = s([]), [j, M] = s(""), [N, P] = d(f, !1), [F, I] = s(-1), [Ne, Pe] = s(j), L = ue(), R = o(null), Fe = le((e) => te(R, w)(e), [R, w]), z = o(null), B = o(null), Ie = o(null), Le = o(null), V = re({
39
+ open: N,
40
+ setOpen: P,
41
+ triggerRef: h ? z : R,
42
+ panelRef: B,
43
43
  animated: !0
44
- }), U = Array.isArray(D) ? D : [], W = a(() => [...m ?? [], ...ce(Se)], [m, Se]), G = a(() => {
45
- if (k.length === 0) return W;
46
- let e = new Set(W.map((e) => e.value)), t = k.filter((t) => !e.has(t)).map((e) => ({
44
+ }), H = Array.isArray(O) ? O : [], U = h && we !== void 0 && H.length >= we, W = a(() => [...m ?? [], ...ce(Ce)], [m, Ce]), G = a(() => {
45
+ if (A.length === 0) return W;
46
+ let e = new Set(W.map((e) => e.value)), t = A.filter((t) => !e.has(t)).map((e) => ({
47
47
  value: e,
48
48
  label: e
49
49
  }));
50
50
  return t.length > 0 ? [...W, ...t] : W;
51
- }, [W, k]), K = _ ? G : G.filter((e) => e.label.toLowerCase().includes(A.toLowerCase())), q = Ce && !v && A.trim() !== "" && K.length === 0, J = A.trim(), Ne = t(E.create, { query: J }), Y = q ? [{
51
+ }, [W, A]), K = v ? G : G.filter((e) => e.label.toLowerCase().includes(j.toLowerCase())), q = Te && !y && !U && j.trim() !== "" && K.length === 0, J = j.trim(), Re = t(D.create, { query: J }), Y = q ? [{
52
52
  value: J,
53
53
  label: J
54
- }, ...K] : K, Pe = typeof x == "object" ? x : void 0, X = (x === void 0 ? void 0 : !!x) ?? (b > 0 && Y.length > b), Fe = Pe?.itemHeight ?? ye, Ie = Pe?.overscan, Le = (e) => `${I}-option-${e}`, Re = M && Y[P] ? Le(P) : void 0, Z = [];
54
+ }, ...K] : K, ze = typeof S == "object" ? S : void 0, X = (S === void 0 ? void 0 : !!S) ?? (x > 0 && Y.length > x), Be = ze?.itemHeight ?? be, Ve = ze?.overscan, He = (e) => `${L}-option-${e}`, Ue = N && Y[F] ? He(F) : void 0, Z = [];
55
55
  for (let e = 0; e < Y.length; e++) {
56
56
  let t = Y[e];
57
57
  if (t === void 0) continue;
@@ -79,123 +79,133 @@ function m({ value: c, open: f, options: m, children: Se, multiple: h = !1, onVa
79
79
  }]
80
80
  });
81
81
  }
82
- let ze = Z.some((e) => e.label !== void 0);
82
+ let We = Z.some((e) => e.label !== void 0);
83
83
  i(() => {
84
- if (!H.shown || P < 0) return;
84
+ if (!V.shown || F < 0) return;
85
85
  if (X) {
86
- B.current?.scrollToIndex(P, "auto");
86
+ Ie.current?.scrollToIndex(F, "auto");
87
87
  return;
88
88
  }
89
- let e = V.current;
89
+ let e = Le.current;
90
90
  e && typeof e.scrollIntoView == "function" && e.scrollIntoView({ block: "nearest" });
91
91
  }, [
92
92
  X,
93
- H.shown,
94
- P
93
+ V.shown,
94
+ F
95
95
  ]);
96
- let Be = o(_);
96
+ let Ge = o(v);
97
97
  i(() => {
98
- Be.current = _;
99
- }, [_]);
100
- let Ve = o(A);
98
+ Ge.current = v;
99
+ }, [v]);
100
+ let Ke = o(j);
101
101
  i(() => {
102
- Ve.current !== A && (Ve.current = A, Be.current?.(A));
103
- }, [A]), A !== Ae && (je(A), F(-1));
104
- let He = (e) => h ? U.includes(e) : D === e, Ue = (e) => G.find((t) => t.value === e)?.label ?? e, We = (e, t) => {
102
+ Ke.current !== j && (Ke.current = j, Ge.current?.(j));
103
+ }, [j]), j !== Ne && (Pe(j), I(-1));
104
+ let qe = (e) => h ? H.includes(e) : O === e, Je = (e) => G.find((t) => t.value === e)?.label ?? String(e), Ye = (e, t) => {
105
105
  let n = t ?? G.find((t) => t.value === e)?.label ?? String(e);
106
106
  if (h) {
107
- let t = U.includes(e) ? U.filter((t) => t !== e) : [...U, e];
108
- O(t), g?.(t), j("");
109
- } else O(e), g?.(e), j(n), N(!1);
110
- L.current?.focus();
111
- }, Ge = () => {
112
- we?.(J), ke((e) => e.includes(J) ? e : [...e, J]), We(J, J);
113
- }, Ke = (e) => {
107
+ if (U && !H.includes(e)) return;
108
+ let t = H.includes(e) ? H.filter((t) => t !== e) : [...H, e];
109
+ k(t), _?.(t), M("");
110
+ } else k(e), _?.(e), M(n), P(!1);
111
+ R.current?.focus();
112
+ }, Xe = () => {
113
+ Ee?.(J), Me((e) => e.includes(J) ? e : [...e, J]), Ye(J, J);
114
+ }, Ze = (e) => {
114
115
  if (q && e === J) {
115
- Ge();
116
+ Xe();
116
117
  return;
117
118
  }
118
- G.find((t) => t.value === e)?.disabled || We(e);
119
- }, qe = (e) => {
120
- if (e.key === "ArrowDown") e.preventDefault(), N(!0), F((e) => Math.min(e + 1, Y.length - 1));
121
- else if (e.key === "ArrowUp") e.preventDefault(), N(!0), F((e) => Math.max(e - 1, 0));
122
- else if (e.key === "Enter" && P >= 0 && Y[P]) e.preventDefault(), Ke(Y[P].value);
123
- else if (e.key === "Escape") N(!1);
124
- else if (e.key === "Backspace" && h && A === "" && U.length > 0) {
119
+ G.find((t) => t.value === e)?.disabled || Ye(e);
120
+ }, Qe = (e) => {
121
+ if (e.key === "ArrowDown") e.preventDefault(), P(!0), I((e) => Math.min(e + 1, Y.length - 1));
122
+ else if (e.key === "ArrowUp") e.preventDefault(), P(!0), I((e) => Math.max(e - 1, 0));
123
+ else if (e.key === "Enter" && F >= 0 && Y[F]) e.preventDefault(), Ze(Y[F].value);
124
+ else if (e.key === "Escape") P(!1);
125
+ else if (e.key === "Backspace" && h && j === "" && H.length > 0) {
125
126
  e.preventDefault();
126
- let t = U.slice(0, -1);
127
- O(t), g?.(t);
127
+ let t = H.slice(0, -1);
128
+ k(t), _?.(t);
128
129
  }
129
130
  }, Q = (t, n, r) => /* @__PURE__ */ l(se, {
130
- ref: !r && n === P ? V : void 0,
131
+ ref: !r && n === F ? Le : void 0,
131
132
  value: t.value,
132
- disabled: t.disabled === !0,
133
- id: Le(n),
133
+ disabled: t.disabled === !0 || h && U && !qe(t.value),
134
+ id: He(n),
134
135
  setSize: Y.length,
135
136
  posInSet: n + 1,
136
- highlighted: n === P,
137
- selected: He(t.value),
138
- onSelect: Ke,
139
- className: e([r && be, T?.item]),
140
- children: q && n === 0 ? Ne : Ee ? xe(t.label, A) : t.label
137
+ highlighted: n === F,
138
+ selected: qe(t.value),
139
+ onSelect: Ze,
140
+ className: e([r && xe, E?.item]),
141
+ children: q && n === 0 ? Re : Oe ? Se(t.label, j) : t.label
141
142
  }, t.value), $ = /* @__PURE__ */ l("input", {
142
- ref: Me,
143
+ ref: Fe,
143
144
  "data-slot": "input",
144
145
  role: "combobox",
145
- style: h ? void 0 : H.triggerStyle,
146
- "aria-expanded": M,
147
- "aria-controls": I,
146
+ style: h ? void 0 : V.triggerStyle,
147
+ "aria-expanded": N,
148
+ "aria-controls": L,
148
149
  "aria-autocomplete": "list",
149
- "aria-activedescendant": Re,
150
- "aria-busy": v || void 0,
151
- value: A,
152
- placeholder: De,
150
+ "aria-activedescendant": Ue,
151
+ "aria-busy": y || void 0,
152
+ value: j,
153
+ placeholder: ke,
153
154
  onChange: (e) => {
154
- j(e.target.value), N(!0);
155
+ M(e.target.value), P(!0);
155
156
  },
156
- onPointerDown: h ? void 0 : H.onTriggerPointerDown,
157
- onClick: h ? void 0 : H.onTriggerClick,
158
- onKeyDown: qe,
159
- className: e([h ? me : fe, T?.input])
157
+ onPointerDown: h ? void 0 : V.onTriggerPointerDown,
158
+ onClick: h ? void 0 : V.onTriggerClick,
159
+ onKeyDown: Qe,
160
+ className: e([h ? me : fe, E?.input])
160
161
  });
161
162
  return /* @__PURE__ */ u("div", {
162
163
  "data-slot": "combobox",
163
164
  className: e([
164
165
  de,
165
- Oe,
166
- T?.root
166
+ Ae,
167
+ E?.root
167
168
  ]),
168
169
  children: [h ? /* @__PURE__ */ u("div", {
169
- ref: R,
170
+ ref: z,
170
171
  "data-slot": "trigger",
171
- style: H.triggerStyle,
172
- onPointerDown: H.onTriggerPointerDown,
172
+ style: V.triggerStyle,
173
+ onPointerDown: V.onTriggerPointerDown,
173
174
  onClick: () => {
174
- H.onTriggerClick(), L.current?.focus();
175
+ V.onTriggerClick(), R.current?.focus();
175
176
  },
176
177
  className: e(pe),
177
- children: [U.map((e) => /* @__PURE__ */ l("span", {
178
- "data-slot": "item",
179
- onClick: (e) => e.stopPropagation(),
180
- children: /* @__PURE__ */ l(ie, {
181
- color: "primary",
182
- onClose: () => {
183
- let t = U.filter((t) => t !== e);
184
- O(t), g?.(t);
185
- },
186
- children: Ue(e)
187
- })
188
- }, e)), $]
178
+ children: [
179
+ (g === void 0 ? H : H.slice(0, Math.max(g, 0))).map((e) => /* @__PURE__ */ l("span", {
180
+ "data-slot": "item",
181
+ onClick: (e) => e.stopPropagation(),
182
+ children: /* @__PURE__ */ l(ie, {
183
+ color: "primary",
184
+ onClose: () => {
185
+ let t = H.filter((t) => t !== e);
186
+ k(t), _?.(t);
187
+ },
188
+ children: Je(e)
189
+ })
190
+ }, e)),
191
+ g !== void 0 && H.length > Math.max(g, 0) && /* @__PURE__ */ l("span", {
192
+ "data-slot": "overflow-badge",
193
+ title: H.slice(Math.max(g, 0)).map((e) => Je(e)).join(", "),
194
+ className: e(he),
195
+ children: t(je.moreTags, { count: H.length - Math.max(g, 0) })
196
+ }),
197
+ $
198
+ ]
189
199
  }) : $, /* @__PURE__ */ l(ne, {
190
- ref: z,
191
- behavior: H,
200
+ ref: B,
201
+ behavior: V,
192
202
  placement: "bottom-span",
193
- id: I,
203
+ id: L,
194
204
  role: "listbox",
195
205
  "aria-multiselectable": h ? "true" : void 0,
196
- visualClass: X ? _e : ge,
197
- style: y !== void 0 && !X ? { maxHeight: `${y}px` } : void 0,
198
- children: v ? /* @__PURE__ */ l("div", {
206
+ visualClass: X ? ve : _e,
207
+ style: b !== void 0 && !X ? { maxHeight: `${b}px` } : void 0,
208
+ children: y ? /* @__PURE__ */ l("div", {
199
209
  role: "option",
200
210
  "data-slot": "loading",
201
211
  "aria-selected": !1,
@@ -207,21 +217,21 @@ function m({ value: c, open: f, options: m, children: Se, multiple: h = !1, onVa
207
217
  "data-slot": "empty",
208
218
  "aria-selected": !1,
209
219
  "aria-disabled": "true",
210
- className: e([p, T?.empty]),
211
- children: Te ?? E.noResults
220
+ className: e([p, E?.empty]),
221
+ children: De ?? D.noResults
212
222
  }) : X ? /* @__PURE__ */ l(ae, {
213
- ref: B,
223
+ ref: Ie,
214
224
  "data-virtualized": !0,
215
225
  items: Y,
216
- height: Math.min(y ?? ve, Y.length * Fe),
217
- itemHeight: Fe,
218
- overscan: Ie,
219
- groups: ze ? Z.filter((e) => e.label !== void 0).map((t) => ({
226
+ height: Math.min(b ?? ye, Y.length * Be),
227
+ itemHeight: Be,
228
+ overscan: Ve,
229
+ groups: We ? Z.filter((e) => e.label !== void 0).map((t) => ({
220
230
  startIndex: t.rows[0]?.index ?? 0,
221
231
  key: t.key,
222
232
  render: () => /* @__PURE__ */ l("div", {
223
233
  "data-slot": "group-label",
224
- className: e([he]),
234
+ className: e([ge]),
225
235
  children: t.label
226
236
  })
227
237
  })) : void 0,
@@ -53,29 +53,30 @@ function u(e) {
53
53
  children: n
54
54
  }), t[1] = e, t[2] = r), r;
55
55
  }
56
- function d({ value: o, getValue: d, copiedTimeout: f = 2e3, copyLabel: p = "Copy", copiedLabel: m = "Copied", variant: h = "outline", square: g = !0, size: _, classNames: v, className: y, children: b, onClick: x, ...S }) {
57
- let { copied: C, copy: w } = i(f), T = t("Button"), E = _ ?? T.size ?? "md", D = a[E];
58
- function O(e) {
56
+ function d({ value: o, getValue: d, copiedTimeout: f = 2e3, copyLabel: p = "Copy", copiedLabel: m = "Copied", variant: h = "outline", square: g = !0, size: _, classNames: v, className: y, as: b, children: x, onClick: S, ...C }) {
57
+ let { copied: w, copy: T } = i(f), E = t("Button"), D = _ ?? E.size ?? "md", O = a[D];
58
+ function k(e) {
59
59
  let t = d?.() ?? o;
60
- t !== void 0 && w(t), x?.(e);
60
+ t !== void 0 && T(t), S?.(e);
61
61
  }
62
- let k = C ? u : l;
62
+ let A = w ? u : l;
63
63
  return /* @__PURE__ */ c(n, {
64
64
  variant: h,
65
65
  size: _,
66
66
  square: g,
67
- "data-copied": C || void 0,
68
- "aria-label": C ? m : p,
67
+ as: b,
68
+ "data-copied": w || void 0,
69
+ "aria-label": w ? m : p,
69
70
  className: [
70
71
  y,
71
72
  v?.root,
72
- C && h !== "solid" && "haze-copy-button-styles__copiedSkin"
73
+ w && h !== "solid" && "haze-copy-button-styles__copiedSkin"
73
74
  ].filter(Boolean).join(" ") || void 0,
74
- onClick: O,
75
- ...S,
76
- children: [typeof b == "function" ? b(C) : b ?? /* @__PURE__ */ s(k, { className: e([D, v?.icon]) }), /* @__PURE__ */ s(r, {
75
+ onClick: k,
76
+ ...C,
77
+ children: [typeof x == "function" ? x(w) : x ?? /* @__PURE__ */ s(A, { className: e([O, v?.icon]) }), /* @__PURE__ */ s(r, {
77
78
  role: "status",
78
- children: C ? m : ""
79
+ children: w ? m : ""
79
80
  })]
80
81
  });
81
82
  }