dishui 0.0.55 → 0.0.57

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 (29) hide show
  1. package/dist/components/Select/index.js +90 -72
  2. package/dist/components/Select/index.js.map +1 -1
  3. package/dist/components/pro/Flow/Flow.js +656 -568
  4. package/dist/components/pro/Flow/Flow.js.map +1 -1
  5. package/dist/components/pro/Flow/FlowCanvas.js +1027 -970
  6. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  7. package/dist/components/pro/Flow/canvas/ViewportContainer.d.ts +6 -0
  8. package/dist/components/pro/Flow/canvas/ViewportContainer.js +20 -15
  9. package/dist/components/pro/Flow/canvas/ViewportContainer.js.map +1 -1
  10. package/dist/components/pro/Flow/context/FlowUIContext.d.ts +12 -3
  11. package/dist/components/pro/Flow/context/FlowUIContext.js +89 -81
  12. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  13. package/dist/components/pro/Flow/hooks/useCompactMode.d.ts +13 -0
  14. package/dist/components/pro/Flow/hooks/useCompactMode.js +20 -0
  15. package/dist/components/pro/Flow/hooks/useCompactMode.js.map +1 -0
  16. package/dist/components/pro/Flow/hooks/useDraggablePanel.d.ts +19 -4
  17. package/dist/components/pro/Flow/hooks/useDraggablePanel.js +31 -24
  18. package/dist/components/pro/Flow/hooks/useDraggablePanel.js.map +1 -1
  19. package/dist/components/pro/Flow/hooks/useMindMap.js +16 -22
  20. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  21. package/dist/components/pro/Flow/hooks/usePixiApp.js +16 -16
  22. package/dist/components/pro/Flow/hooks/usePixiApp.js.map +1 -1
  23. package/dist/components/pro/Flow/panels/FlowPanelGroup.d.ts +10 -5
  24. package/dist/components/pro/Flow/panels/FlowPanelGroup.js +95 -67
  25. package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
  26. package/dist/dishui.css +1 -1
  27. package/dist/utils/i18n.js +20 -0
  28. package/dist/utils/i18n.js.map +1 -1
  29. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
- import { useClickOutside as W } from "../../hooks/useClickOutside.js";
2
- import { useCallback as y, useEffect as w, useRef as k, useState as p } from "react";
3
- import { jsx as o, jsxs as E } from "react/jsx-runtime";
4
- import { createPortal as z } from "react-dom";
5
- var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
1
+ import { useClickOutside as K } from "../../hooks/useClickOutside.js";
2
+ import { useCallback as L, useEffect as p, useRef as v, useState as w } from "react";
3
+ import { jsx as o, jsxs as P } from "react/jsx-runtime";
4
+ import { createPortal as U } from "react-dom";
5
+ var Y = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
6
6
  xmlns: "http://www.w3.org/2000/svg",
7
7
  fill: "none",
8
8
  viewBox: "0 0 24 24",
@@ -20,7 +20,7 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
20
20
  strokeLinejoin: "round",
21
21
  d: "M19 9l-7 7-7-7"
22
22
  })
23
- }), H = () => /* @__PURE__ */ o("svg", {
23
+ }), X = () => /* @__PURE__ */ o("svg", {
24
24
  xmlns: "http://www.w3.org/2000/svg",
25
25
  className: "h-3 w-3",
26
26
  fill: "none",
@@ -32,10 +32,10 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
32
32
  strokeLinejoin: "round",
33
33
  d: "M6 18L18 6M6 6l12 12"
34
34
  })
35
- }), G = ({ options: r, value: l, onChange: g, placeholder: L = "Select...", multiple: a = !1, fixedHeight: R = !1, style: I, className: O }) => {
36
- const [i, u] = p(!1), [c, b] = p(-1), [v, D] = p(""), [N, P] = p(!0), [j, S] = p({}), h = k(null), x = k(null), m = k(null);
37
- w(() => {
38
- if (!i) return;
35
+ }), Z = ({ options: r, value: i, onChange: x, placeholder: R = "Select...", multiple: l = !1, fixedHeight: D = !1, style: O, className: $ }) => {
36
+ const [a, u] = w(!1), [c, b] = w(-1), [y, N] = w(""), [A, j] = w(!0), [M, S] = w({}), h = v(null), k = v(null), m = v(null), g = v(null);
37
+ p(() => {
38
+ if (!a) return;
39
39
  const e = (n) => {
40
40
  const t = n.target;
41
41
  h.current?.contains(t) || m.current?.contains(t) || u(!1);
@@ -43,10 +43,10 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
43
43
  return document.addEventListener("pointerdown", e), document.addEventListener("mousedown", e), () => {
44
44
  document.removeEventListener("pointerdown", e), document.removeEventListener("mousedown", e);
45
45
  };
46
- }, [i]);
47
- const d = Array.isArray(l) ? l : l != null ? [l] : [];
48
- W(h, y(() => u(!1), []));
49
- const f = y(() => {
46
+ }, [a]);
47
+ const d = Array.isArray(i) ? i : i != null ? [i] : [];
48
+ K(h, L(() => u(!1), []));
49
+ const f = L(() => {
50
50
  const e = h.current;
51
51
  if (!e) return;
52
52
  const n = e.getBoundingClientRect(), t = Math.min(r.length, 8) * 36 + 8, s = n.bottom + 4 + t <= window.innerHeight;
@@ -58,31 +58,31 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
58
58
  zIndex: 1e4
59
59
  });
60
60
  }, [r.length]);
61
- w(() => {
62
- if (i)
61
+ p(() => {
62
+ if (a)
63
63
  return f(), window.addEventListener("resize", f), window.addEventListener("scroll", f, !0), () => {
64
64
  window.removeEventListener("resize", f), window.removeEventListener("scroll", f, !0);
65
65
  };
66
- }, [i, f]), w(() => {
66
+ }, [a, f]), p(() => {
67
67
  const e = h.current;
68
68
  if (!e) return;
69
- const n = () => P(e.clientWidth >= 88);
69
+ const n = () => j(e.clientWidth >= 88);
70
70
  n();
71
71
  const t = new ResizeObserver(n);
72
72
  return t.observe(e), () => t.disconnect();
73
- }, []), w(() => {
74
- if (!i) return;
73
+ }, []), p(() => {
74
+ if (!a) return;
75
75
  const e = (n) => {
76
76
  switch (n.key) {
77
77
  case "ArrowDown":
78
- n.preventDefault(), b((t) => t < r.length - 1 ? t + 1 : 0), A();
78
+ n.preventDefault(), b((t) => t < r.length - 1 ? t + 1 : 0), C();
79
79
  break;
80
80
  case "ArrowUp":
81
- n.preventDefault(), b((t) => t > 0 ? t - 1 : r.length - 1), A();
81
+ n.preventDefault(), b((t) => t > 0 ? t - 1 : r.length - 1), C();
82
82
  break;
83
83
  case "Enter":
84
84
  case " ":
85
- n.preventDefault(), c >= 0 && c < r.length && $(r[c]), a || u(!1);
85
+ n.preventDefault(), c >= 0 && c < r.length && E(r[c]), l || u(!1);
86
86
  break;
87
87
  case "Escape":
88
88
  u(!1);
@@ -95,12 +95,12 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
95
95
  document.removeEventListener("keydown", e);
96
96
  };
97
97
  }, [
98
- i,
98
+ a,
99
99
  c,
100
100
  r,
101
- a
101
+ l
102
102
  ]);
103
- const A = y(() => {
103
+ const C = L(() => {
104
104
  if (m.current && c >= 0) {
105
105
  const e = m.current, n = e.children[c];
106
106
  if (n) {
@@ -108,58 +108,73 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
108
108
  s.bottom > t.bottom ? e.scrollTop += s.bottom - t.bottom : s.top < t.top && (e.scrollTop -= t.top - s.top);
109
109
  }
110
110
  }
111
- }, [c]), C = () => {
112
- const e = !i;
111
+ }, [c]), I = () => {
112
+ const e = !a;
113
113
  u(e), b(e ? 0 : -1), e && f();
114
- }, $ = (e) => {
115
- if (a) {
116
- const n = Array.isArray(l) ? l : [];
114
+ }, E = (e) => {
115
+ if (l) {
116
+ const n = Array.isArray(i) ? i : [];
117
117
  let t;
118
- n.includes(e.value) ? t = n.filter((s) => s !== e.value) : t = [...n, e.value], g(t);
118
+ n.includes(e.value) ? t = n.filter((s) => s !== e.value) : t = [...n, e.value], x(t);
119
119
  } else
120
- g(e.value), u(!1);
120
+ x(e.value), u(!1);
121
+ }, T = (e, n) => {
122
+ if (e.pointerType === "mouse") {
123
+ e.preventDefault(), e.stopPropagation(), E(n);
124
+ return;
125
+ }
126
+ e.stopPropagation(), g.current = {
127
+ pointerId: e.pointerId,
128
+ x: e.clientX,
129
+ y: e.clientY
130
+ };
121
131
  }, B = (e, n) => {
122
- e.stopPropagation(), g((Array.isArray(l) ? l : []).filter((t) => t !== n));
132
+ const t = g.current;
133
+ g.current = null, !(!t || e.pointerId !== t.pointerId) && Math.hypot(e.clientX - t.x, e.clientY - t.y) < 10 && (e.stopPropagation(), E(n));
134
+ }, W = () => {
135
+ g.current = null;
136
+ }, z = (e, n) => {
137
+ e.stopPropagation(), x((Array.isArray(i) ? i : []).filter((t) => t !== n));
123
138
  };
124
- w(() => {
125
- if (a && x.current) {
126
- const e = x.current, n = r.filter((s) => d.includes(s.value)).map((s) => s.label).join(", "), t = e.scrollWidth > e.clientWidth;
127
- D(t ? n : "");
128
- } else D("");
139
+ p(() => {
140
+ if (l && k.current) {
141
+ const e = k.current, n = r.filter((s) => d.includes(s.value)).map((s) => s.label).join(", "), t = e.scrollWidth > e.clientWidth;
142
+ N(t ? n : "");
143
+ } else N("");
129
144
  }, [
145
+ i,
130
146
  l,
131
- a,
132
147
  r,
133
148
  d
134
149
  ]);
135
- const M = () => {
150
+ const V = () => {
136
151
  if (d.length === 0) return /* @__PURE__ */ o("span", {
137
152
  className: "text-base-content/60 italic",
138
- children: L
153
+ children: R
139
154
  });
140
155
  const e = r.filter((n) => d.includes(n.value));
141
- if (a) {
142
- const n = R;
156
+ if (l) {
157
+ const n = D;
143
158
  return /* @__PURE__ */ o("div", {
144
- ref: x,
159
+ ref: k,
145
160
  className: `
146
161
  flex gap-1
147
162
  ${n ? "flex-nowrap overflow-x-auto overflow-y-hidden" : "flex-wrap overflow-hidden"} // Enable horizontal scroll, hide vertical scrollbar if any
148
- ${v ? "tooltip tooltip-bottom" : ""} // Keep tooltip for overflow
163
+ ${y ? "tooltip tooltip-bottom" : ""} // Keep tooltip for overflow
149
164
  `,
150
- "data-tip": v || void 0,
165
+ "data-tip": y || void 0,
151
166
  style: {
152
167
  scrollbarWidth: "thin",
153
168
  ...n ? { paddingRight: "1.75rem" } : {}
154
169
  },
155
- children: e.map((t) => /* @__PURE__ */ E("span", {
170
+ children: e.map((t) => /* @__PURE__ */ P("span", {
156
171
  className: "badge badge-ghost gap-1 text-xs items-center whitespace-nowrap flex-shrink-0",
157
172
  children: [t.label, /* @__PURE__ */ o("button", {
158
173
  type: "button",
159
- onClick: (s) => B(s, t.value),
174
+ onClick: (s) => z(s, t.value),
160
175
  className: "btn btn-xs btn-ghost btn-circle p-0 m-0 hover:bg-error hover:text-error-content",
161
176
  "aria-label": `Remove ${t.label}`,
162
- children: /* @__PURE__ */ o(H, {})
177
+ children: /* @__PURE__ */ o(X, {})
163
178
  })]
164
179
  }, t.value))
165
180
  });
@@ -170,35 +185,35 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
170
185
  children: n.label
171
186
  }) : /* @__PURE__ */ o("span", {
172
187
  className: "text-base-content/60 italic",
173
- children: L
188
+ children: R
174
189
  });
175
190
  }
176
- }, T = `
191
+ }, H = `
177
192
  relative border border-base-300 rounded-lg bg-base-100 w-full
178
193
  flex justify-between items-center cursor-pointer px-3 text-sm
179
194
  focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50
180
195
  hover:border-base-content/30
181
- ${a ? R ? "h-8" : "min-h-8 h-auto py-1" : "h-8"}
196
+ ${l ? D ? "h-8" : "min-h-8 h-auto py-1" : "h-8"}
182
197
  `;
183
- return /* @__PURE__ */ E("div", {
198
+ return /* @__PURE__ */ P("div", {
184
199
  ref: h,
185
- style: I,
186
- className: `relative w-full font-sans select-none ${O || ""}`,
187
- children: [/* @__PURE__ */ E("div", {
200
+ style: O,
201
+ className: `relative w-full font-sans select-none ${$ || ""}`,
202
+ children: [/* @__PURE__ */ P("div", {
188
203
  tabIndex: 0,
189
- className: T,
190
- onClick: C,
204
+ className: H,
205
+ onClick: I,
191
206
  onKeyDown: (e) => {
192
- (e.key === "Enter" || e.key === " ") && C();
207
+ (e.key === "Enter" || e.key === " ") && I();
193
208
  },
194
209
  role: "combobox",
195
210
  "aria-haspopup": "listbox",
196
- "aria-expanded": i,
211
+ "aria-expanded": a,
197
212
  children: [/* @__PURE__ */ o("div", {
198
213
  className: "flex-1 min-w-0 overflow-hidden",
199
- style: { paddingRight: N ? 28 : 0 },
200
- children: M()
201
- }), N && /* @__PURE__ */ o("div", {
214
+ style: { paddingRight: A ? 28 : 0 },
215
+ children: V()
216
+ }), A && /* @__PURE__ */ o("div", {
202
217
  "aria-hidden": "true",
203
218
  style: {
204
219
  position: "absolute",
@@ -212,22 +227,25 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
212
227
  width: 16,
213
228
  height: 16
214
229
  },
215
- children: /* @__PURE__ */ o(V, { isOpen: i })
230
+ children: /* @__PURE__ */ o(Y, { isOpen: a })
216
231
  })]
217
- }), i && typeof document < "u" && z(/* @__PURE__ */ o("ul", {
232
+ }), a && typeof document < "u" && U(/* @__PURE__ */ o("ul", {
218
233
  ref: m,
219
234
  className: "bg-base-100 border border-base-300 rounded-md shadow-lg list-none p-0 m-0 max-h-60 overflow-y-auto focus:outline-none",
220
- style: j,
235
+ style: {
236
+ ...M,
237
+ touchAction: "pan-y"
238
+ },
221
239
  onPointerDown: (e) => e.stopPropagation(),
222
240
  role: "listbox",
223
241
  "aria-activedescendant": c >= 0 ? `option-${r[c]?.value}` : void 0,
224
242
  tabIndex: -1,
225
243
  children: r.length > 0 ? r.map((e, n) => /* @__PURE__ */ o("li", {
226
244
  id: `option-${e.value}`,
227
- className: `p-2 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis hover:bg-base-200 ${n === c ? "bg-base-300" : ""} ${d.includes(e.value) && !a ? "font-semibold bg-base-200" : ""} ${d.includes(e.value) && a ? "font-semibold" : ""}`,
228
- onPointerDown: (t) => {
229
- t.preventDefault(), t.stopPropagation(), $(e);
230
- },
245
+ className: `p-2 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis hover:bg-base-200 ${n === c ? "bg-base-300" : ""} ${d.includes(e.value) && !l ? "font-semibold bg-base-200" : ""} ${d.includes(e.value) && l ? "font-semibold" : ""}`,
246
+ onPointerDown: (t) => T(t, e),
247
+ onPointerUp: (t) => B(t, e),
248
+ onPointerCancel: W,
231
249
  onClick: (t) => {
232
250
  t.preventDefault(), t.stopPropagation();
233
251
  },
@@ -243,7 +261,7 @@ var V = ({ isOpen: r }) => /* @__PURE__ */ o("svg", {
243
261
  });
244
262
  };
245
263
  export {
246
- G as default
264
+ Z as default
247
265
  };
248
266
 
249
267
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useClickOutside } from '../../hooks/useClickOutside';\n\nexport interface Option {\n value: string | number;\n label: string;\n}\n\nexport interface SelectProps {\n options: Option[];\n value?: string | number | (string | number)[];\n onChange: (value: string | number | (string | number)[]) => void;\n placeholder?: string;\n multiple?: boolean;\n fixedHeight?: boolean;\n style?: React.CSSProperties; // Allow passing inline styles\n className?: string; // Allow passing CSS classes for the wrapper\n}\n\n// SVG component for the dropdown arrow\nconst DropdownArrow: React.FC<{ isOpen: boolean }> = ({ isOpen }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n style={{\n display: 'block',\n width: 16,\n height: 16,\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 200ms ease-in-out',\n }}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\n// SVG component for the remove button 'x'\nconst RemoveIcon: React.FC = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n);\n\n// Select Component Implementation using daisyUI/Tailwind\nconst Select: React.FC<SelectProps> = ({\n options,\n value,\n onChange,\n placeholder = 'Select...',\n multiple = false,\n fixedHeight = false,\n style,\n className // This className applies to the wrapper\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const [tooltipText, setTooltipText] = useState('');\n const [showArrow, setShowArrow] = useState(true);\n const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});\n const wrapperRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null); // Ref for the header div\n const optionsListRef = useRef<HTMLUListElement>(null);\n\n useEffect(() => {\n if (!isOpen) return;\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (wrapperRef.current?.contains(target) || optionsListRef.current?.contains(target)) return;\n setIsOpen(false);\n };\n document.addEventListener('pointerdown', handlePointerDown);\n document.addEventListener('mousedown', handlePointerDown);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n document.removeEventListener('mousedown', handlePointerDown);\n };\n }, [isOpen]);\n\n const selectedValuesArray = Array.isArray(value) ? value : (value !== undefined && value !== null ? [value] : []);\n\n // Close dropdown when clicking outside\n useClickOutside(wrapperRef, useCallback(() => setIsOpen(false), []));\n\n const updateDropdownPosition = useCallback(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n const estimatedHeight = Math.min(options.length, 8) * 36 + 8;\n const fitsBelow = rect.bottom + 4 + estimatedHeight <= window.innerHeight;\n setDropdownStyle({\n position: 'fixed',\n left: rect.left,\n top: fitsBelow ? rect.bottom + 4 : Math.max(8, rect.top - estimatedHeight - 4),\n width: rect.width,\n zIndex: 10000,\n });\n }, [options.length]);\n\n useEffect(() => {\n if (!isOpen) return;\n updateDropdownPosition();\n window.addEventListener('resize', updateDropdownPosition);\n window.addEventListener('scroll', updateDropdownPosition, true);\n return () => {\n window.removeEventListener('resize', updateDropdownPosition);\n window.removeEventListener('scroll', updateDropdownPosition, true);\n };\n }, [isOpen, updateDropdownPosition]);\n\n // Hide the decorative arrow when the control becomes too narrow to reserve\n // space for both it and a useful amount of label text.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const update = () => setShowArrow(wrapper.clientWidth >= 88);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(wrapper);\n return () => observer.disconnect();\n }, []);\n\n // Keyboard navigation\n useEffect(() => {\n if (!isOpen) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setHighlightedIndex(prev => (prev < options.length - 1 ? prev + 1 : 0));\n scrollToHighlightedOption();\n break;\n case 'ArrowUp':\n event.preventDefault();\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : options.length - 1));\n scrollToHighlightedOption();\n break;\n case 'Enter':\n case ' ': // Space key\n event.preventDefault();\n if (highlightedIndex >= 0 && highlightedIndex < options.length) {\n handleOptionClick(options[highlightedIndex]);\n if (!multiple) setIsOpen(false); // Close dropdown on selection if single mode\n } else if (!multiple) {\n setIsOpen(false); // Close dropdown if Enter/Space is pressed without a highlighted option in single mode\n }\n break;\n case 'Escape':\n setIsOpen(false);\n break;\n default:\n // Optional: Implement type-ahead find\n break;\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, highlightedIndex, options, multiple]); // Added multiple to dependencies\n\n const scrollToHighlightedOption = useCallback(() => {\n if (optionsListRef.current && highlightedIndex >= 0) {\n const list = optionsListRef.current;\n const optionElement = list.children[highlightedIndex] as HTMLLIElement;\n if (optionElement) {\n const listRect = list.getBoundingClientRect();\n const optionRect = optionElement.getBoundingClientRect();\n\n if (optionRect.bottom > listRect.bottom) {\n list.scrollTop += optionRect.bottom - listRect.bottom;\n } else if (optionRect.top < listRect.top) {\n list.scrollTop -= listRect.top - optionRect.top;\n }\n }\n }\n }, [highlightedIndex]);\n\n const toggleDropdown = () => {\n const next = !isOpen;\n setIsOpen(next);\n setHighlightedIndex(next ? 0 : -1); // Reset or set initial highlight\n if (next) updateDropdownPosition();\n };\n\n const handleOptionClick = (option: Option) => {\n if (multiple) {\n const currentValues = Array.isArray(value) ? value : [];\n let newValue;\n if (currentValues.includes(option.value)) {\n newValue = currentValues.filter(v => v !== option.value);\n } else {\n newValue = [...currentValues, option.value];\n }\n onChange(newValue);\n } else {\n onChange(option.value);\n setIsOpen(false); // Close dropdown on single select\n }\n // Keep highlight on the selected item in multi-select? Maybe not.\n // setHighlightedIndex(options.findIndex(o => o.value === option.value));\n };\n\n const handleRemoveItem = (e: React.MouseEvent, itemValue: string | number) => {\n e.stopPropagation(); // Prevent dropdown from opening/closing\n const currentValues = Array.isArray(value) ? value : [];\n onChange(currentValues.filter(v => v !== itemValue));\n };\n\n // Update tooltip text and check for overflow\n useEffect(() => {\n if (multiple && headerRef.current) {\n const header = headerRef.current;\n const selectedLabels = options\n .filter(opt => selectedValuesArray.includes(opt.value))\n .map(opt => opt.label)\n .join(', ');\n\n // Check if the content (scrollWidth) exceeds the visible area (clientWidth)\n const isOverflowing = header.scrollWidth > header.clientWidth;\n setTooltipText(isOverflowing ? selectedLabels : ''); // Only set text if overflowing\n } else {\n setTooltipText(''); // Clear tooltip for single select or empty multi-select\n }\n }, [value, multiple, options, selectedValuesArray]);\n\n\n const renderSelectedValue = () => {\n if (selectedValuesArray.length === 0) {\n return <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n\n const selectedOptions = options.filter(opt => selectedValuesArray.includes(opt.value));\n\n if (multiple) {\n const isFixed = fixedHeight;\n // Apply overflow-x-auto for horizontal scrolling in fixedHeight mode\n const containerClasses = `\n flex gap-1 \n ${isFixed ? 'flex-nowrap overflow-x-auto overflow-y-hidden' : 'flex-wrap overflow-hidden'} // Enable horizontal scroll, hide vertical scrollbar if any\n ${tooltipText ? 'tooltip tooltip-bottom' : ''} // Keep tooltip for overflow\n `;\n // Removed showEllipsisPrefix\n\n return (\n <div\n ref={headerRef}\n className={containerClasses}\n data-tip={tooltipText ? tooltipText : undefined} // Keep tooltip logic\n // Add scrollbar styling if desired (e.g., using ::-webkit-scrollbar pseudo-element via CSS or a utility)\n style={{\n scrollbarWidth: 'thin',\n // 为固定高度模式添加右侧内边距,避免与下拉图标重叠\n ...(isFixed ? { paddingRight: '1.75rem' } : {})\n }}\n >\n {/* Removed wrapper for ellipsis and its popup */}\n\n {/* Render the badges */}\n {selectedOptions.map(option => (\n <span key={option.value} className=\"badge badge-ghost gap-1 text-xs items-center whitespace-nowrap flex-shrink-0\">\n {option.label}\n <button\n type=\"button\"\n onClick={(e) => handleRemoveItem(e, option.value)}\n className=\"btn btn-xs btn-ghost btn-circle p-0 m-0 hover:bg-error hover:text-error-content\"\n aria-label={`Remove ${option.label}`}\n >\n <RemoveIcon />\n </button>\n </span>\n ))}\n </div>\n );\n } else {\n const selectedOption = options.find(opt => opt.value === selectedValuesArray[0]);\n return selectedOption ? <span className=\"truncate\">{selectedOption.label}</span> : <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n };\n\n // Match the default control height to a normal line of form text. Multi-select\n // may still grow when wrapping tags unless fixedHeight is requested.\n const selectClasses = `\n relative border border-base-300 rounded-lg bg-base-100 w-full\n flex justify-between items-center cursor-pointer px-3 text-sm\n focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50\n hover:border-base-content/30\n ${multiple\n ? (fixedHeight ? 'h-8' : 'min-h-8 h-auto py-1')\n : 'h-8'}\n `;\n\n return (\n <div\n ref={wrapperRef}\n style={style}\n className={`relative w-full font-sans select-none ${className || ''}`}\n >\n {/* Header */}\n <div\n tabIndex={0}\n className={selectClasses}\n onClick={toggleDropdown}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') toggleDropdown(); }}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <div\n className=\"flex-1 min-w-0 overflow-hidden\"\n style={{ paddingRight: showArrow ? 28 : 0 }}\n >\n {renderSelectedValue()}\n </div>\n {/* Inline positioning avoids utility CSS/theme overrides moving the icon. */}\n {showArrow && (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n right: 10,\n top: '50%',\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n }}\n >\n <DropdownArrow isOpen={isOpen} />\n </div>\n )}\n </div>\n\n {/* Dropdown Options */}\n {isOpen && typeof document !== 'undefined' && createPortal(\n <ul\n ref={optionsListRef}\n className=\"bg-base-100 border border-base-300 rounded-md shadow-lg list-none p-0 m-0 max-h-60 overflow-y-auto focus:outline-none\"\n style={dropdownStyle}\n onPointerDown={(event) => event.stopPropagation()}\n role=\"listbox\" // ARIA role\n aria-activedescendant={highlightedIndex >= 0 ? `option-${options[highlightedIndex]?.value}` : undefined} // For screen readers\n tabIndex={-1} // Allows focus programmatically but not via tab\n >\n {options.length > 0 ? (\n options.map((option, index) => (\n <li\n key={option.value}\n id={`option-${option.value}`} // ID for aria-activedescendant\n className={`p-2 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis hover:bg-base-200 ${index === highlightedIndex ? 'bg-base-300' : '' // Highlight style\n } ${selectedValuesArray.includes(option.value) && !multiple ? 'font-semibold bg-base-200' : '' // Style for selected single item\n } ${selectedValuesArray.includes(option.value) && multiple ? 'font-semibold' : '' // Style for selected multi items (less prominent background)\n }`}\n onPointerDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleOptionClick(option);\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onMouseEnter={() => setHighlightedIndex(index)} // Highlight on hover\n role=\"option\" // ARIA role\n aria-selected={selectedValuesArray.includes(option.value)}\n >\n {/* Optional: Add a checkmark or similar for selected items, especially in multi-select */}\n {option.label}\n </li>\n ))\n ) : (\n <li className=\"p-2 text-base-content/60 italic\">\n No options available\n </li>\n )}\n </ul>,\n document.body,\n )}\n </div>\n );\n};\n\nexport default Select; "],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useClickOutside } from '../../hooks/useClickOutside';\n\nexport interface Option {\n value: string | number;\n label: string;\n}\n\nexport interface SelectProps {\n options: Option[];\n value?: string | number | (string | number)[];\n onChange: (value: string | number | (string | number)[]) => void;\n placeholder?: string;\n multiple?: boolean;\n fixedHeight?: boolean;\n style?: React.CSSProperties; // Allow passing inline styles\n className?: string; // Allow passing CSS classes for the wrapper\n}\n\n// SVG component for the dropdown arrow\nconst DropdownArrow: React.FC<{ isOpen: boolean }> = ({ isOpen }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n style={{\n display: 'block',\n width: 16,\n height: 16,\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 200ms ease-in-out',\n }}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\n// SVG component for the remove button 'x'\nconst RemoveIcon: React.FC = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n);\n\n// Select Component Implementation using daisyUI/Tailwind\nconst Select: React.FC<SelectProps> = ({\n options,\n value,\n onChange,\n placeholder = 'Select...',\n multiple = false,\n fixedHeight = false,\n style,\n className // This className applies to the wrapper\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const [tooltipText, setTooltipText] = useState('');\n const [showArrow, setShowArrow] = useState(true);\n const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});\n const wrapperRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null); // Ref for the header div\n const optionsListRef = useRef<HTMLUListElement>(null);\n // Tracks a touch/pen press on an option so a tap selects while a drag scrolls.\n // (pointerdown on touch must NOT preventDefault — that blocks native scrolling.)\n const touchPressRef = useRef<{ pointerId: number; x: number; y: number } | null>(null);\n\n useEffect(() => {\n if (!isOpen) return;\n const handlePointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (wrapperRef.current?.contains(target) || optionsListRef.current?.contains(target)) return;\n setIsOpen(false);\n };\n document.addEventListener('pointerdown', handlePointerDown);\n document.addEventListener('mousedown', handlePointerDown);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n document.removeEventListener('mousedown', handlePointerDown);\n };\n }, [isOpen]);\n\n const selectedValuesArray = Array.isArray(value) ? value : (value !== undefined && value !== null ? [value] : []);\n\n // Close dropdown when clicking outside\n useClickOutside(wrapperRef, useCallback(() => setIsOpen(false), []));\n\n const updateDropdownPosition = useCallback(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const rect = wrapper.getBoundingClientRect();\n const estimatedHeight = Math.min(options.length, 8) * 36 + 8;\n const fitsBelow = rect.bottom + 4 + estimatedHeight <= window.innerHeight;\n setDropdownStyle({\n position: 'fixed',\n left: rect.left,\n top: fitsBelow ? rect.bottom + 4 : Math.max(8, rect.top - estimatedHeight - 4),\n width: rect.width,\n zIndex: 10000,\n });\n }, [options.length]);\n\n useEffect(() => {\n if (!isOpen) return;\n updateDropdownPosition();\n window.addEventListener('resize', updateDropdownPosition);\n window.addEventListener('scroll', updateDropdownPosition, true);\n return () => {\n window.removeEventListener('resize', updateDropdownPosition);\n window.removeEventListener('scroll', updateDropdownPosition, true);\n };\n }, [isOpen, updateDropdownPosition]);\n\n // Hide the decorative arrow when the control becomes too narrow to reserve\n // space for both it and a useful amount of label text.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return;\n const update = () => setShowArrow(wrapper.clientWidth >= 88);\n update();\n const observer = new ResizeObserver(update);\n observer.observe(wrapper);\n return () => observer.disconnect();\n }, []);\n\n // Keyboard navigation\n useEffect(() => {\n if (!isOpen) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n setHighlightedIndex(prev => (prev < options.length - 1 ? prev + 1 : 0));\n scrollToHighlightedOption();\n break;\n case 'ArrowUp':\n event.preventDefault();\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : options.length - 1));\n scrollToHighlightedOption();\n break;\n case 'Enter':\n case ' ': // Space key\n event.preventDefault();\n if (highlightedIndex >= 0 && highlightedIndex < options.length) {\n handleOptionClick(options[highlightedIndex]);\n if (!multiple) setIsOpen(false); // Close dropdown on selection if single mode\n } else if (!multiple) {\n setIsOpen(false); // Close dropdown if Enter/Space is pressed without a highlighted option in single mode\n }\n break;\n case 'Escape':\n setIsOpen(false);\n break;\n default:\n // Optional: Implement type-ahead find\n break;\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen, highlightedIndex, options, multiple]); // Added multiple to dependencies\n\n const scrollToHighlightedOption = useCallback(() => {\n if (optionsListRef.current && highlightedIndex >= 0) {\n const list = optionsListRef.current;\n const optionElement = list.children[highlightedIndex] as HTMLLIElement;\n if (optionElement) {\n const listRect = list.getBoundingClientRect();\n const optionRect = optionElement.getBoundingClientRect();\n\n if (optionRect.bottom > listRect.bottom) {\n list.scrollTop += optionRect.bottom - listRect.bottom;\n } else if (optionRect.top < listRect.top) {\n list.scrollTop -= listRect.top - optionRect.top;\n }\n }\n }\n }, [highlightedIndex]);\n\n const toggleDropdown = () => {\n const next = !isOpen;\n setIsOpen(next);\n setHighlightedIndex(next ? 0 : -1); // Reset or set initial highlight\n if (next) updateDropdownPosition();\n };\n\n const handleOptionClick = (option: Option) => {\n if (multiple) {\n const currentValues = Array.isArray(value) ? value : [];\n let newValue;\n if (currentValues.includes(option.value)) {\n newValue = currentValues.filter(v => v !== option.value);\n } else {\n newValue = [...currentValues, option.value];\n }\n onChange(newValue);\n } else {\n onChange(option.value);\n setIsOpen(false); // Close dropdown on single select\n }\n // Keep highlight on the selected item in multi-select? Maybe not.\n // setHighlightedIndex(options.findIndex(o => o.value === option.value));\n };\n\n // Mouse: select immediately on press (existing desktop behavior).\n // Touch/pen: only record the press — selection happens on pointerup if the\n // gesture turned out to be a tap rather than a scroll. preventDefault() on a\n // touch pointerdown suppresses the browser's native pan gesture, which made\n // long dropdowns impossible to scroll on mobile (and every scroll attempt\n // selected an option instead).\n const handleOptionPointerDown = (event: React.PointerEvent<HTMLLIElement>, option: Option) => {\n if (event.pointerType === 'mouse') {\n event.preventDefault();\n event.stopPropagation();\n handleOptionClick(option);\n return;\n }\n event.stopPropagation();\n touchPressRef.current = { pointerId: event.pointerId, x: event.clientX, y: event.clientY };\n };\n\n const handleOptionPointerUp = (event: React.PointerEvent<HTMLLIElement>, option: Option) => {\n const press = touchPressRef.current;\n touchPressRef.current = null;\n if (!press || event.pointerId !== press.pointerId) return;\n // Select only if the finger did not move much — otherwise it was a scroll.\n const moved = Math.hypot(event.clientX - press.x, event.clientY - press.y);\n if (moved < 10) {\n event.stopPropagation();\n handleOptionClick(option);\n }\n };\n\n const handleOptionPointerCancel = () => {\n touchPressRef.current = null;\n };\n\n const handleRemoveItem = (e: React.MouseEvent, itemValue: string | number) => {\n e.stopPropagation(); // Prevent dropdown from opening/closing\n const currentValues = Array.isArray(value) ? value : [];\n onChange(currentValues.filter(v => v !== itemValue));\n };\n\n // Update tooltip text and check for overflow\n useEffect(() => {\n if (multiple && headerRef.current) {\n const header = headerRef.current;\n const selectedLabels = options\n .filter(opt => selectedValuesArray.includes(opt.value))\n .map(opt => opt.label)\n .join(', ');\n\n // Check if the content (scrollWidth) exceeds the visible area (clientWidth)\n const isOverflowing = header.scrollWidth > header.clientWidth;\n setTooltipText(isOverflowing ? selectedLabels : ''); // Only set text if overflowing\n } else {\n setTooltipText(''); // Clear tooltip for single select or empty multi-select\n }\n }, [value, multiple, options, selectedValuesArray]);\n\n\n const renderSelectedValue = () => {\n if (selectedValuesArray.length === 0) {\n return <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n\n const selectedOptions = options.filter(opt => selectedValuesArray.includes(opt.value));\n\n if (multiple) {\n const isFixed = fixedHeight;\n // Apply overflow-x-auto for horizontal scrolling in fixedHeight mode\n const containerClasses = `\n flex gap-1 \n ${isFixed ? 'flex-nowrap overflow-x-auto overflow-y-hidden' : 'flex-wrap overflow-hidden'} // Enable horizontal scroll, hide vertical scrollbar if any\n ${tooltipText ? 'tooltip tooltip-bottom' : ''} // Keep tooltip for overflow\n `;\n // Removed showEllipsisPrefix\n\n return (\n <div\n ref={headerRef}\n className={containerClasses}\n data-tip={tooltipText ? tooltipText : undefined} // Keep tooltip logic\n // Add scrollbar styling if desired (e.g., using ::-webkit-scrollbar pseudo-element via CSS or a utility)\n style={{\n scrollbarWidth: 'thin',\n // 为固定高度模式添加右侧内边距,避免与下拉图标重叠\n ...(isFixed ? { paddingRight: '1.75rem' } : {})\n }}\n >\n {/* Removed wrapper for ellipsis and its popup */}\n\n {/* Render the badges */}\n {selectedOptions.map(option => (\n <span key={option.value} className=\"badge badge-ghost gap-1 text-xs items-center whitespace-nowrap flex-shrink-0\">\n {option.label}\n <button\n type=\"button\"\n onClick={(e) => handleRemoveItem(e, option.value)}\n className=\"btn btn-xs btn-ghost btn-circle p-0 m-0 hover:bg-error hover:text-error-content\"\n aria-label={`Remove ${option.label}`}\n >\n <RemoveIcon />\n </button>\n </span>\n ))}\n </div>\n );\n } else {\n const selectedOption = options.find(opt => opt.value === selectedValuesArray[0]);\n return selectedOption ? <span className=\"truncate\">{selectedOption.label}</span> : <span className=\"text-base-content/60 italic\">{placeholder}</span>;\n }\n };\n\n // Match the default control height to a normal line of form text. Multi-select\n // may still grow when wrapping tags unless fixedHeight is requested.\n const selectClasses = `\n relative border border-base-300 rounded-lg bg-base-100 w-full\n flex justify-between items-center cursor-pointer px-3 text-sm\n focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50\n hover:border-base-content/30\n ${multiple\n ? (fixedHeight ? 'h-8' : 'min-h-8 h-auto py-1')\n : 'h-8'}\n `;\n\n return (\n <div\n ref={wrapperRef}\n style={style}\n className={`relative w-full font-sans select-none ${className || ''}`}\n >\n {/* Header */}\n <div\n tabIndex={0}\n className={selectClasses}\n onClick={toggleDropdown}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') toggleDropdown(); }}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n >\n <div\n className=\"flex-1 min-w-0 overflow-hidden\"\n style={{ paddingRight: showArrow ? 28 : 0 }}\n >\n {renderSelectedValue()}\n </div>\n {/* Inline positioning avoids utility CSS/theme overrides moving the icon. */}\n {showArrow && (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n right: 10,\n top: '50%',\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 16,\n height: 16,\n }}\n >\n <DropdownArrow isOpen={isOpen} />\n </div>\n )}\n </div>\n\n {/* Dropdown Options */}\n {isOpen && typeof document !== 'undefined' && createPortal(\n <ul\n ref={optionsListRef}\n className=\"bg-base-100 border border-base-300 rounded-md shadow-lg list-none p-0 m-0 max-h-60 overflow-y-auto focus:outline-none\"\n style={{ ...dropdownStyle, touchAction: 'pan-y' }}\n onPointerDown={(event) => event.stopPropagation()}\n role=\"listbox\" // ARIA role\n aria-activedescendant={highlightedIndex >= 0 ? `option-${options[highlightedIndex]?.value}` : undefined} // For screen readers\n tabIndex={-1} // Allows focus programmatically but not via tab\n >\n {options.length > 0 ? (\n options.map((option, index) => (\n <li\n key={option.value}\n id={`option-${option.value}`} // ID for aria-activedescendant\n className={`p-2 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis hover:bg-base-200 ${index === highlightedIndex ? 'bg-base-300' : '' // Highlight style\n } ${selectedValuesArray.includes(option.value) && !multiple ? 'font-semibold bg-base-200' : '' // Style for selected single item\n } ${selectedValuesArray.includes(option.value) && multiple ? 'font-semibold' : '' // Style for selected multi items (less prominent background)\n }`}\n onPointerDown={(event) => handleOptionPointerDown(event, option)}\n onPointerUp={(event) => handleOptionPointerUp(event, option)}\n onPointerCancel={handleOptionPointerCancel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onMouseEnter={() => setHighlightedIndex(index)} // Highlight on hover\n role=\"option\" // ARIA role\n aria-selected={selectedValuesArray.includes(option.value)}\n >\n {/* Optional: Add a checkmark or similar for selected items, especially in multi-select */}\n {option.label}\n </li>\n ))\n ) : (\n <li className=\"p-2 text-base-content/60 italic\">\n No options available\n </li>\n )}\n </ul>,\n document.body,\n )}\n </div>\n );\n};\n\nexport default Select; "],"mappings":"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"}