dishui 0.0.84 → 0.0.91
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.
- package/dist/components/Input/index.js +52 -62
- package/dist/components/Input/index.js.map +1 -1
- package/dist/components/LayoutSuite/index.d.ts +10 -0
- package/dist/components/LayoutSuite/index.js +27 -18
- package/dist/components/LayoutSuite/index.js.map +1 -1
- package/dist/components/Markdown/markdownComponents.js +1 -0
- package/dist/components/Markdown/markdownComponents.js.map +1 -1
- package/dist/components/Markdown/useMarkdownSource.js +46 -31
- package/dist/components/Markdown/useMarkdownSource.js.map +1 -1
- package/dist/components/Markdown/useMarkmapRenderer.js +44 -31
- package/dist/components/Markdown/useMarkmapRenderer.js.map +1 -1
- package/dist/components/Markdown/useMermaidRenderer.js +49 -31
- package/dist/components/Markdown/useMermaidRenderer.js.map +1 -1
- package/dist/components/ProtectedRoute/index.d.ts +2 -1
- package/dist/components/ProtectedRoute/index.js +16 -6
- package/dist/components/ProtectedRoute/index.js.map +1 -1
- package/dist/components/Select/index.d.ts +6 -0
- package/dist/components/Select/index.js +166 -136
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/Table/index.d.ts +23 -2
- package/dist/components/Table/index.js +153 -101
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/Tabs/index.d.ts +12 -1
- package/dist/components/Tabs/index.js +42 -17
- package/dist/components/Tabs/index.js.map +1 -1
- package/dist/components/pro/ArticleContextMenu/index.js +7 -7
- package/dist/components/pro/CodeEditor/editors/CodeEditor.js +200 -189
- package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
- package/dist/components/pro/CodeEditor/types.d.ts +3 -0
- package/dist/components/pro/DataTable/DataTable.d.ts +1 -1
- package/dist/components/pro/DataTable/DataTable.js +124 -247
- package/dist/components/pro/DataTable/DataTable.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableBody.d.ts +3 -1
- package/dist/components/pro/DataTable/components/TableBody.js +41 -41
- package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
- package/dist/components/pro/DataTable/components/TablePagination.d.ts +3 -9
- package/dist/components/pro/DataTable/components/TablePagination.js +29 -25
- package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableToolbar.d.ts +2 -1
- package/dist/components/pro/DataTable/components/TableToolbar.js +25 -19
- package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
- package/dist/components/pro/DataTable/index.d.ts +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
- package/dist/components/pro/DataTable/tanstack-table.d.ts +2 -2
- package/dist/components/pro/DataTable/tanstack-table.js +29 -21
- package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
- package/dist/components/pro/DataTable/treeDataUtils.d.ts +2 -0
- package/dist/components/pro/DataTable/treeDataUtils.js +18 -19
- package/dist/components/pro/DataTable/treeDataUtils.js.map +1 -1
- package/dist/components/pro/DataTable/types.d.ts +43 -0
- package/dist/components/pro/DataTable/useDataTableModel.d.ts +16 -0
- package/dist/components/pro/DataTable/useDataTableModel.js +148 -0
- package/dist/components/pro/DataTable/useDataTableModel.js.map +1 -0
- package/dist/components/pro/FileExplorer/Breadcrumb.js +12 -12
- package/dist/components/pro/Flow/nodes/DataNodeView.js +87 -82
- package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/Model3DView.js +69 -63
- package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.d.ts +14 -0
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.js +76 -0
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.js.map +1 -0
- package/dist/components/pro/Flow/nodes/demandRender.d.ts +11 -0
- package/dist/components/pro/Flow/nodes/demandRender.js +26 -0
- package/dist/components/pro/Flow/nodes/demandRender.js.map +1 -0
- package/dist/components/pro/RichTextEditor/SlashMenu.js +68 -58
- package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
- package/dist/contexts/AppContext.d.ts +1 -0
- package/dist/contexts/AppContext.js +144 -145
- package/dist/contexts/AppContext.js.map +1 -1
- package/dist/contexts/authentication.d.ts +7 -0
- package/dist/contexts/authentication.js +22 -0
- package/dist/contexts/authentication.js.map +1 -0
- package/dist/data-table.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/hooks/useControllableState.d.ts +6 -14
- package/dist/hooks/useControllableState.js +21 -15
- package/dist/hooks/useControllableState.js.map +1 -1
- package/dist/hooks/useTableColumns.d.ts +3 -3
- package/dist/hooks/useTableColumns.js +2 -2
- package/dist/hooks/useTableColumns.js.map +1 -1
- package/dist/hooks/useTableData.d.ts +11 -4
- package/dist/hooks/useTableData.js +44 -26
- package/dist/hooks/useTableData.js.map +1 -1
- package/dist/index-nostyled.d.ts +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +97 -97
- package/dist/lite.d.ts +2 -0
- package/dist/lite.js +22 -21
- package/dist/utils/i18n.js +1 -1
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/routerBuilder.d.ts +7 -5
- package/dist/utils/routerBuilder.js +11 -15
- package/dist/utils/routerBuilder.js.map +1 -1
- package/dist/utils/safeStorage.d.ts +8 -0
- package/dist/utils/safeStorage.js +45 -0
- package/dist/utils/safeStorage.js.map +1 -0
- package/package.json +22 -5
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { createPortal as s } from "react-dom";
|
|
1
|
+
import { useCallback as e, useEffect as t, useId as n, useMemo as r, useRef as i, useState as a } from "react";
|
|
2
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
3
|
+
import { createPortal as c } from "react-dom";
|
|
5
4
|
//#region src/components/Select/index.tsx
|
|
6
|
-
var
|
|
5
|
+
var l = ({ isOpen: e }) => /* @__PURE__ */ o("svg", {
|
|
7
6
|
xmlns: "http://www.w3.org/2000/svg",
|
|
8
7
|
fill: "none",
|
|
9
8
|
viewBox: "0 0 24 24",
|
|
@@ -16,200 +15,225 @@ var c = ({ isOpen: e }) => /* @__PURE__ */ a("svg", {
|
|
|
16
15
|
transform: e ? "rotate(180deg)" : "rotate(0deg)",
|
|
17
16
|
transition: "transform 200ms ease-in-out"
|
|
18
17
|
},
|
|
19
|
-
children: /* @__PURE__ */
|
|
18
|
+
children: /* @__PURE__ */ o("path", {
|
|
20
19
|
strokeLinecap: "round",
|
|
21
20
|
strokeLinejoin: "round",
|
|
22
21
|
d: "M19 9l-7 7-7-7"
|
|
23
22
|
})
|
|
24
|
-
}),
|
|
23
|
+
}), u = () => /* @__PURE__ */ o("svg", {
|
|
25
24
|
xmlns: "http://www.w3.org/2000/svg",
|
|
26
25
|
className: "h-3 w-3",
|
|
27
26
|
fill: "none",
|
|
28
27
|
viewBox: "0 0 24 24",
|
|
29
28
|
stroke: "currentColor",
|
|
30
29
|
strokeWidth: 3,
|
|
31
|
-
children: /* @__PURE__ */
|
|
30
|
+
children: /* @__PURE__ */ o("path", {
|
|
32
31
|
strokeLinecap: "round",
|
|
33
32
|
strokeLinejoin: "round",
|
|
34
33
|
d: "M6 18L18 6M6 6l12 12"
|
|
35
34
|
})
|
|
36
|
-
}),
|
|
37
|
-
let
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
}), d = ({ options: d, value: f, onChange: p, "aria-label": m, "aria-labelledby": h, "aria-describedby": g, id: _, disabled: v = !1, placeholder: y = "Select...", multiple: b = !1, fixedHeight: x = !1, style: S, className: C }) => {
|
|
36
|
+
let w = n(), T = _ ?? `select-${w}`, E = `${T}-listbox`, D = (e) => `${E}-${typeof e.value}-${encodeURIComponent(String(e.value))}`, [O, k] = a(!1), A = O && !v;
|
|
37
|
+
v && O && k(!1);
|
|
38
|
+
let [j, M] = a(null), [N, P] = a(""), [F, I] = a(!0), [L, R] = a({}), z = i(null), B = i(null), V = i(null), H = i(null), U = i(null), W = i(!1);
|
|
39
|
+
t(() => {
|
|
40
|
+
if (!A) return;
|
|
40
41
|
let e = (e) => {
|
|
41
42
|
let t = e.target;
|
|
42
|
-
|
|
43
|
+
z.current?.contains(t) || H.current?.contains(t) || k(!1);
|
|
43
44
|
};
|
|
44
|
-
return document.addEventListener("pointerdown", e),
|
|
45
|
-
document.removeEventListener("pointerdown", e)
|
|
45
|
+
return document.addEventListener("pointerdown", e), () => {
|
|
46
|
+
document.removeEventListener("pointerdown", e);
|
|
46
47
|
};
|
|
47
|
-
}, [
|
|
48
|
-
let
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
}, [A]);
|
|
49
|
+
let G = r(() => Array.isArray(f) ? f : f == null ? [] : [f], [f]), K = d.flatMap((e, t) => e.disabled ? [] : [t]), q = d.findIndex((e) => !e.disabled && G.includes(e.value)), J = d.findIndex((e) => !e.disabled && e.value === j), Y = J >= 0 ? J : q >= 0 ? q : K[0] ?? -1, X = (e) => {
|
|
50
|
+
let t = e.relatedTarget;
|
|
51
|
+
(!t || !z.current?.contains(t) && !H.current?.contains(t)) && k(!1);
|
|
52
|
+
}, Z = e(() => {
|
|
53
|
+
let e = z.current;
|
|
52
54
|
if (!e) return;
|
|
53
|
-
let t = e.getBoundingClientRect(), n = Math.min(
|
|
54
|
-
|
|
55
|
+
let t = e.getBoundingClientRect(), n = Math.min(d.length, 8) * 36 + 8, r = t.bottom + 4 + n <= window.innerHeight;
|
|
56
|
+
R({
|
|
55
57
|
position: "fixed",
|
|
56
58
|
left: t.left,
|
|
57
59
|
top: r ? t.bottom + 4 : Math.max(8, t.top - n - 4),
|
|
58
60
|
width: t.width,
|
|
59
61
|
zIndex: 1e4
|
|
60
62
|
});
|
|
61
|
-
}, [
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
window.removeEventListener("resize",
|
|
63
|
+
}, [d.length]);
|
|
64
|
+
t(() => {
|
|
65
|
+
if (A) return Z(), window.addEventListener("resize", Z), window.addEventListener("scroll", Z, !0), () => {
|
|
66
|
+
window.removeEventListener("resize", Z), window.removeEventListener("scroll", Z, !0);
|
|
65
67
|
};
|
|
66
|
-
}, [
|
|
67
|
-
let e =
|
|
68
|
+
}, [A, Z]), t(() => {
|
|
69
|
+
let e = z.current;
|
|
68
70
|
if (!e) return;
|
|
69
|
-
let t = () =>
|
|
71
|
+
let t = () => I(e.clientWidth >= 88);
|
|
70
72
|
t();
|
|
71
73
|
let n = new ResizeObserver(t);
|
|
72
74
|
return n.observe(e), () => n.disconnect();
|
|
73
|
-
}, []),
|
|
74
|
-
if (
|
|
75
|
-
|
|
75
|
+
}, []), t(() => {
|
|
76
|
+
if (A && H.current && Y >= 0) {
|
|
77
|
+
let e = H.current, t = e.children[Y];
|
|
78
|
+
if (t) {
|
|
79
|
+
let n = e.getBoundingClientRect(), r = t.getBoundingClientRect();
|
|
80
|
+
r.bottom > n.bottom ? e.scrollTop += r.bottom - n.bottom : r.top < n.top && (e.scrollTop -= n.top - r.top);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, [A, Y]);
|
|
84
|
+
let Q = (e = "first") => {
|
|
85
|
+
if (v) return;
|
|
86
|
+
let t = q >= 0 ? q : e === "last" ? K.at(-1) : K[0];
|
|
87
|
+
M(t !== void 0 && t >= 0 ? d[t].value : null), k(!0), Z();
|
|
88
|
+
}, ee = () => {
|
|
89
|
+
v || (B.current?.focus({ preventScroll: !0 }), A ? k(!1) : Q());
|
|
90
|
+
}, te = (e) => {
|
|
91
|
+
if (e.key === "Tab") {
|
|
92
|
+
k(!1);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!(e.target !== B.current || v || e.defaultPrevented || e.nativeEvent.isComposing || e.altKey || e.ctrlKey || e.metaKey)) {
|
|
76
96
|
switch (e.key) {
|
|
77
97
|
case "ArrowDown":
|
|
78
|
-
e.preventDefault(), S((e) => e < u.length - 1 ? e + 1 : 0), F();
|
|
79
|
-
break;
|
|
80
98
|
case "ArrowUp":
|
|
81
|
-
|
|
99
|
+
if (!A) Q(e.key === "ArrowUp" ? "last" : "first");
|
|
100
|
+
else if (K.length) {
|
|
101
|
+
let t = K.indexOf(Y), n = e.key === "ArrowDown" ? 1 : -1, r = K[(t + n + K.length) % K.length];
|
|
102
|
+
M(d[r].value);
|
|
103
|
+
}
|
|
82
104
|
break;
|
|
105
|
+
case "Home":
|
|
106
|
+
case "End": {
|
|
107
|
+
A || Q();
|
|
108
|
+
let t = e.key === "Home" ? K[0] : K.at(-1);
|
|
109
|
+
M(t === void 0 ? null : d[t].value);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
83
112
|
case "Enter":
|
|
84
113
|
case " ":
|
|
85
|
-
|
|
114
|
+
A ? Y >= 0 && $(d[Y]) : Q();
|
|
86
115
|
break;
|
|
87
|
-
case "Escape":
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
};
|
|
93
|
-
}, [
|
|
94
|
-
y,
|
|
95
|
-
x,
|
|
96
|
-
u,
|
|
97
|
-
h
|
|
98
|
-
]);
|
|
99
|
-
let F = t(() => {
|
|
100
|
-
if (j.current && x >= 0) {
|
|
101
|
-
let e = j.current, t = e.children[x];
|
|
102
|
-
if (t) {
|
|
103
|
-
let n = e.getBoundingClientRect(), r = t.getBoundingClientRect();
|
|
104
|
-
r.bottom > n.bottom ? e.scrollTop += r.bottom - n.bottom : r.top < n.top && (e.scrollTop -= n.top - r.top);
|
|
116
|
+
case "Escape":
|
|
117
|
+
if (!A) return;
|
|
118
|
+
k(!1);
|
|
119
|
+
break;
|
|
120
|
+
default: return;
|
|
105
121
|
}
|
|
122
|
+
e.preventDefault(), e.stopPropagation();
|
|
123
|
+
}
|
|
124
|
+
}, $ = (e) => {
|
|
125
|
+
if (!(v || e.disabled)) {
|
|
126
|
+
if (M(e.value), B.current?.focus({ preventScroll: !0 }), b) {
|
|
127
|
+
let t = Array.isArray(f) ? f : [], n;
|
|
128
|
+
n = t.includes(e.value) ? t.filter((t) => t !== e.value) : [...t, e.value], p(n);
|
|
129
|
+
} else p(e.value), k(!1);
|
|
106
130
|
}
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}, L = (e) => {
|
|
111
|
-
if (h) {
|
|
112
|
-
let t = Array.isArray(d) ? d : [], n;
|
|
113
|
-
n = t.includes(e.value) ? t.filter((t) => t !== e.value) : [...t, e.value], f(n);
|
|
114
|
-
} else f(e.value), b(!1);
|
|
115
|
-
}, R = (e, t) => {
|
|
116
|
-
if (e.pointerType === "mouse") {
|
|
117
|
-
e.preventDefault(), e.stopPropagation(), L(t);
|
|
131
|
+
}, ne = (e, t) => {
|
|
132
|
+
if (W.current = !1, e.pointerType === "mouse") {
|
|
133
|
+
e.preventDefault(), e.stopPropagation(), $(t);
|
|
118
134
|
return;
|
|
119
135
|
}
|
|
120
|
-
e.stopPropagation(),
|
|
136
|
+
e.stopPropagation(), U.current = {
|
|
121
137
|
pointerId: e.pointerId,
|
|
122
138
|
x: e.clientX,
|
|
123
139
|
y: e.clientY
|
|
124
140
|
};
|
|
125
|
-
},
|
|
126
|
-
let
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
},
|
|
131
|
-
|
|
141
|
+
}, re = (e) => {
|
|
142
|
+
let t = U.current;
|
|
143
|
+
if (U.current = null, !t || e.pointerId !== t.pointerId) return;
|
|
144
|
+
let n = Math.hypot(e.clientX - t.x, e.clientY - t.y);
|
|
145
|
+
W.current = n < 10, e.stopPropagation();
|
|
146
|
+
}, ie = () => {
|
|
147
|
+
U.current = null, W.current = !1;
|
|
148
|
+
}, ae = (e, t) => {
|
|
149
|
+
e.stopPropagation(), !(v || d.find((e) => e.value === t)?.disabled) && (B.current?.focus({ preventScroll: !0 }), p((Array.isArray(f) ? f : []).filter((e) => e !== t)));
|
|
132
150
|
};
|
|
133
|
-
|
|
134
|
-
if (
|
|
135
|
-
let e =
|
|
136
|
-
|
|
137
|
-
} else
|
|
151
|
+
t(() => {
|
|
152
|
+
if (b && V.current) {
|
|
153
|
+
let e = V.current, t = d.filter((e) => G.includes(e.value)).map((e) => e.label).join(", "), n = e.scrollWidth > e.clientWidth;
|
|
154
|
+
P(n ? t : "");
|
|
155
|
+
} else P("");
|
|
138
156
|
}, [
|
|
157
|
+
b,
|
|
139
158
|
d,
|
|
140
|
-
|
|
141
|
-
u,
|
|
142
|
-
N
|
|
159
|
+
G
|
|
143
160
|
]);
|
|
144
|
-
let
|
|
145
|
-
if (
|
|
161
|
+
let oe = () => {
|
|
162
|
+
if (G.length === 0) return /* @__PURE__ */ o("span", {
|
|
146
163
|
className: "text-base-content/60 italic",
|
|
147
|
-
children:
|
|
164
|
+
children: y
|
|
148
165
|
});
|
|
149
|
-
let e =
|
|
150
|
-
if (
|
|
151
|
-
let t =
|
|
152
|
-
return /* @__PURE__ */
|
|
153
|
-
ref:
|
|
166
|
+
let e = d.filter((e) => G.includes(e.value));
|
|
167
|
+
if (b) {
|
|
168
|
+
let t = x;
|
|
169
|
+
return /* @__PURE__ */ o("div", {
|
|
170
|
+
ref: V,
|
|
154
171
|
className: `
|
|
155
172
|
flex gap-1
|
|
156
173
|
${t ? "flex-nowrap overflow-x-auto overflow-y-hidden" : "flex-wrap overflow-hidden"} // Enable horizontal scroll, hide vertical scrollbar if any
|
|
157
|
-
${
|
|
174
|
+
${N ? "tooltip tooltip-bottom" : ""} // Keep tooltip for overflow
|
|
158
175
|
`,
|
|
159
|
-
"data-tip":
|
|
176
|
+
"data-tip": N || void 0,
|
|
160
177
|
style: {
|
|
161
178
|
scrollbarWidth: "thin",
|
|
162
179
|
...t ? { paddingRight: "1.75rem" } : {}
|
|
163
180
|
},
|
|
164
|
-
children: e.map((e) => /* @__PURE__ */
|
|
181
|
+
children: e.map((e) => /* @__PURE__ */ s("span", {
|
|
165
182
|
className: "badge badge-ghost gap-1 text-xs items-center whitespace-nowrap flex-shrink-0",
|
|
166
|
-
children: [e.label, /* @__PURE__ */
|
|
183
|
+
children: [e.label, /* @__PURE__ */ o("button", {
|
|
167
184
|
type: "button",
|
|
168
|
-
|
|
185
|
+
disabled: v || e.disabled,
|
|
186
|
+
onClick: (t) => ae(t, e.value),
|
|
169
187
|
className: "btn btn-xs btn-ghost btn-circle p-0 m-0 hover:bg-error hover:text-error-content",
|
|
170
188
|
"aria-label": `Remove ${e.label}`,
|
|
171
|
-
children: /* @__PURE__ */
|
|
189
|
+
children: /* @__PURE__ */ o(u, {})
|
|
172
190
|
})]
|
|
173
|
-
}, e
|
|
191
|
+
}, D(e)))
|
|
174
192
|
});
|
|
175
193
|
}
|
|
176
194
|
{
|
|
177
|
-
let e =
|
|
178
|
-
return e ? /* @__PURE__ */
|
|
195
|
+
let e = d.find((e) => e.value === G[0]);
|
|
196
|
+
return e ? /* @__PURE__ */ o("span", {
|
|
179
197
|
className: "truncate",
|
|
180
198
|
children: e.label
|
|
181
|
-
}) : /* @__PURE__ */
|
|
199
|
+
}) : /* @__PURE__ */ o("span", {
|
|
182
200
|
className: "text-base-content/60 italic",
|
|
183
|
-
children:
|
|
201
|
+
children: y
|
|
184
202
|
});
|
|
185
203
|
}
|
|
186
|
-
},
|
|
204
|
+
}, se = `
|
|
187
205
|
relative border border-base-300 rounded-lg bg-base-100 w-full
|
|
188
206
|
flex justify-between items-center cursor-pointer px-3 text-sm
|
|
189
207
|
focus:outline-none focus:ring-2 focus:ring-primary focus:ring-opacity-50
|
|
190
208
|
hover:border-base-content/30
|
|
191
|
-
${
|
|
209
|
+
${b ? x ? "h-8" : "min-h-8 h-auto py-1" : "h-8"}
|
|
192
210
|
`;
|
|
193
|
-
return /* @__PURE__ */
|
|
194
|
-
ref:
|
|
195
|
-
style:
|
|
196
|
-
className: `relative w-full font-sans select-none ${
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
211
|
+
return /* @__PURE__ */ s("div", {
|
|
212
|
+
ref: z,
|
|
213
|
+
style: S,
|
|
214
|
+
className: `relative w-full font-sans select-none ${C || ""}`,
|
|
215
|
+
onBlur: X,
|
|
216
|
+
onKeyDown: te,
|
|
217
|
+
children: [/* @__PURE__ */ s("div", {
|
|
218
|
+
ref: B,
|
|
219
|
+
id: T,
|
|
220
|
+
tabIndex: v ? -1 : 0,
|
|
221
|
+
className: `${se} ${v ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
222
|
+
onClick: ee,
|
|
204
223
|
role: "combobox",
|
|
205
|
-
"aria-label":
|
|
224
|
+
"aria-label": m ?? (h ? void 0 : y),
|
|
225
|
+
"aria-labelledby": h,
|
|
226
|
+
"aria-describedby": g,
|
|
206
227
|
"aria-haspopup": "listbox",
|
|
207
|
-
"aria-expanded":
|
|
208
|
-
|
|
228
|
+
"aria-expanded": A,
|
|
229
|
+
"aria-disabled": v || void 0,
|
|
230
|
+
"aria-controls": A ? E : void 0,
|
|
231
|
+
"aria-activedescendant": A && Y >= 0 ? D(d[Y]) : void 0,
|
|
232
|
+
children: [/* @__PURE__ */ o("div", {
|
|
209
233
|
className: "flex-1 min-w-0 overflow-hidden",
|
|
210
|
-
style: { paddingRight:
|
|
211
|
-
children:
|
|
212
|
-
}),
|
|
234
|
+
style: { paddingRight: F ? 28 : 0 },
|
|
235
|
+
children: oe()
|
|
236
|
+
}), F && /* @__PURE__ */ o("div", {
|
|
213
237
|
"aria-hidden": "true",
|
|
214
238
|
style: {
|
|
215
239
|
position: "absolute",
|
|
@@ -223,33 +247,39 @@ var c = ({ isOpen: e }) => /* @__PURE__ */ a("svg", {
|
|
|
223
247
|
width: 16,
|
|
224
248
|
height: 16
|
|
225
249
|
},
|
|
226
|
-
children: /* @__PURE__ */
|
|
250
|
+
children: /* @__PURE__ */ o(l, { isOpen: A })
|
|
227
251
|
})]
|
|
228
|
-
}),
|
|
229
|
-
ref:
|
|
252
|
+
}), A && typeof document < "u" && c(/* @__PURE__ */ o("ul", {
|
|
253
|
+
ref: H,
|
|
254
|
+
id: E,
|
|
230
255
|
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",
|
|
231
256
|
style: {
|
|
232
|
-
...
|
|
257
|
+
...L,
|
|
233
258
|
touchAction: "pan-y"
|
|
234
259
|
},
|
|
235
260
|
onPointerDown: (e) => e.stopPropagation(),
|
|
236
261
|
role: "listbox",
|
|
237
|
-
"aria-
|
|
262
|
+
"aria-labelledby": h ?? T,
|
|
263
|
+
"aria-multiselectable": b || void 0,
|
|
264
|
+
onFocus: () => B.current?.focus({ preventScroll: !0 }),
|
|
238
265
|
tabIndex: -1,
|
|
239
|
-
children:
|
|
240
|
-
id:
|
|
241
|
-
className: `p-2 cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis
|
|
242
|
-
onPointerDown: (t) =>
|
|
243
|
-
onPointerUp:
|
|
244
|
-
onPointerCancel:
|
|
245
|
-
onClick: (
|
|
246
|
-
|
|
266
|
+
children: d.length > 0 ? d.map((e, t) => /* @__PURE__ */ o("li", {
|
|
267
|
+
id: D(e),
|
|
268
|
+
className: `p-2 ${e.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-base-200"} whitespace-nowrap overflow-hidden text-ellipsis ${t === Y ? "bg-base-300" : ""} ${G.includes(e.value) && !b ? "font-semibold bg-base-200" : ""} ${G.includes(e.value) && b ? "font-semibold" : ""}`,
|
|
269
|
+
onPointerDown: (t) => ne(t, e),
|
|
270
|
+
onPointerUp: re,
|
|
271
|
+
onPointerCancel: ie,
|
|
272
|
+
onClick: (t) => {
|
|
273
|
+
t.preventDefault(), t.stopPropagation(), (W.current || t.detail === 0) && $(e), W.current = !1;
|
|
274
|
+
},
|
|
275
|
+
onPointerMove: (t) => {
|
|
276
|
+
t.pointerType === "mouse" && (t.movementX || t.movementY) && !e.disabled && M(e.value);
|
|
247
277
|
},
|
|
248
|
-
onMouseEnter: () => S(t),
|
|
249
278
|
role: "option",
|
|
250
|
-
"aria-
|
|
279
|
+
"aria-disabled": e.disabled || void 0,
|
|
280
|
+
"aria-selected": G.includes(e.value),
|
|
251
281
|
children: e.label
|
|
252
|
-
}, e
|
|
282
|
+
}, D(e))) : /* @__PURE__ */ o("li", {
|
|
253
283
|
className: "p-2 text-base-content/60 italic",
|
|
254
284
|
children: "No options available"
|
|
255
285
|
})
|
|
@@ -257,6 +287,6 @@ var c = ({ isOpen: e }) => /* @__PURE__ */ a("svg", {
|
|
|
257
287
|
});
|
|
258
288
|
};
|
|
259
289
|
//#endregion
|
|
260
|
-
export {
|
|
290
|
+
export { d as default };
|
|
261
291
|
|
|
262
292
|
//# 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 /** Accessible name for the combobox. */\n 'aria-label'?: string;\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 'aria-label': ariaLabel,\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-label={ariaLabel}\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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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useId, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport interface Option {\n value: string | number;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SelectProps {\n /** Accessible name for the combobox. */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n /** Optional ID for the combobox; generated per instance when omitted. */\n id?: string;\n disabled?: boolean;\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 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n 'aria-describedby': ariaDescribedby,\n id,\n disabled = false,\n placeholder = 'Select...',\n multiple = false,\n fixedHeight = false,\n style,\n className // This className applies to the wrapper\n}) => {\n const generatedId = useId();\n const comboboxId = id ?? `select-${generatedId}`;\n const listboxId = `${comboboxId}-listbox`;\n const optionId = (option: Option) => `${listboxId}-${typeof option.value}-${encodeURIComponent(String(option.value))}`;\n const [open, setIsOpen] = useState(false);\n const isOpen = open && !disabled;\n if (disabled && open) setIsOpen(false);\n const [highlightedValue, setHighlightedValue] = useState<Option['value'] | null>(null);\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 comboboxRef = 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 const touchTapRef = useRef(false);\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\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown);\n };\n }, [isOpen]);\n\n const selectedValuesArray = useMemo(() => Array.isArray(value) ? value : (value !== undefined && value !== null ? [value] : []), [value]);\n\n const enabledIndices = options.flatMap((option, index) => option.disabled ? [] : [index]);\n const selectedIndex = options.findIndex(option => !option.disabled && selectedValuesArray.includes(option.value));\n const storedIndex = options.findIndex(option => !option.disabled && option.value === highlightedValue);\n // Derive a valid active option even when options are removed, reordered or disabled.\n const highlightedIndex = storedIndex >= 0 ? storedIndex : selectedIndex >= 0 ? selectedIndex : enabledIndices[0] ?? -1;\n\n\n const handleBlur = (event: React.FocusEvent) => {\n const next = event.relatedTarget as Node | null;\n if (!next || (!wrapperRef.current?.contains(next) && !optionsListRef.current?.contains(next))) {\n setIsOpen(false);\n }\n };\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 // Scroll after React commits the new active option, not using the previous index.\n useEffect(() => {\n if (isOpen && 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 }, [isOpen, highlightedIndex]);\n\n const openDropdown = (edge: 'first' | 'last' = 'first') => {\n if (disabled) return;\n const index = selectedIndex >= 0 ? selectedIndex : edge === 'last' ? enabledIndices.at(-1) : enabledIndices[0];\n setHighlightedValue(index !== undefined && index >= 0 ? options[index].value : null);\n setIsOpen(true);\n updateDropdownPosition();\n };\n\n const toggleDropdown = () => {\n if (disabled) return;\n comboboxRef.current?.focus({ preventScroll: true });\n if (isOpen) setIsOpen(false);\n else openDropdown();\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Tab') {\n setIsOpen(false); // Preserve native Tab / Shift+Tab focus traversal, including tag buttons.\n return;\n }\n if (event.target !== comboboxRef.current || disabled || event.defaultPrevented || event.nativeEvent.isComposing || event.altKey || event.ctrlKey || event.metaKey) return;\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n if (!isOpen) openDropdown(event.key === 'ArrowUp' ? 'last' : 'first');\n else if (enabledIndices.length) {\n const current = enabledIndices.indexOf(highlightedIndex);\n const step = event.key === 'ArrowDown' ? 1 : -1;\n const next = enabledIndices[(current + step + enabledIndices.length) % enabledIndices.length];\n setHighlightedValue(options[next].value);\n }\n break;\n }\n case 'Home':\n case 'End': {\n if (!isOpen) openDropdown();\n const next = event.key === 'Home' ? enabledIndices[0] : enabledIndices.at(-1);\n setHighlightedValue(next === undefined ? null : options[next].value);\n break;\n }\n case 'Enter':\n case ' ':\n if (!isOpen) openDropdown();\n else if (highlightedIndex >= 0) handleOptionClick(options[highlightedIndex]);\n break;\n case 'Escape':\n if (!isOpen) return;\n setIsOpen(false);\n break;\n default:\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n };\n\n const handleOptionClick = (option: Option) => {\n if (disabled || option.disabled) return;\n setHighlightedValue(option.value);\n comboboxRef.current?.focus({ preventScroll: true });\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 };\n\n // Mouse: select immediately on press (existing desktop behavior).\n // Touch/pen: confirm a tap on pointerup, then select on click. Unmounting the\n // option on pointerup would send compatibility mouse events to the page behind\n // the portal, stealing focus. 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 touchTapRef.current = false;\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>) => {\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 touchTapRef.current = moved < 10;\n event.stopPropagation();\n };\n\n const handleOptionPointerCancel = () => {\n touchPressRef.current = null;\n touchTapRef.current = false;\n };\n\n const handleRemoveItem = (e: React.MouseEvent, itemValue: string | number) => {\n e.stopPropagation(); // Prevent dropdown from opening/closing\n if (disabled || options.find(option => option.value === itemValue)?.disabled) return;\n comboboxRef.current?.focus({ preventScroll: true });\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 }, [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={optionId(option)} className=\"badge badge-ghost gap-1 text-xs items-center whitespace-nowrap flex-shrink-0\">\n {option.label}\n <button\n type=\"button\"\n disabled={disabled || option.disabled}\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 onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n >\n {/* Header */}\n <div\n ref={comboboxRef}\n id={comboboxId}\n tabIndex={disabled ? -1 : 0}\n className={`${selectClasses} ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}\n onClick={toggleDropdown}\n\n role=\"combobox\"\n aria-label={ariaLabel ?? (ariaLabelledby ? undefined : placeholder)}\n aria-labelledby={ariaLabelledby}\n aria-describedby={ariaDescribedby}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-disabled={disabled || undefined}\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={isOpen && highlightedIndex >= 0 ? optionId(options[highlightedIndex]) : undefined}\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 id={listboxId}\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\"\n aria-labelledby={ariaLabelledby ?? comboboxId}\n aria-multiselectable={multiple || undefined}\n // Keep DOM focus on the combobox even when touch focuses the portal.\n onFocus={() => comboboxRef.current?.focus({ preventScroll: true })}\n tabIndex={-1}\n >\n {options.length > 0 ? (\n options.map((option, index) => (\n <li\n key={optionId(option)}\n id={optionId(option)}\n className={`p-2 ${option.disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer hover:bg-base-200'} whitespace-nowrap overflow-hidden text-ellipsis ${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={handleOptionPointerUp}\n onPointerCancel={handleOptionPointerCancel}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n if (touchTapRef.current || event.detail === 0) handleOptionClick(option);\n touchTapRef.current = false;\n }}\n onPointerMove={event => {\n // Scrolling under a stationary pointer must not undo keyboard navigation.\n if (event.pointerType === 'mouse' && (event.movementX || event.movementY) && !option.disabled) {\n setHighlightedValue(option.value);\n }\n }}\n role=\"option\"\n aria-disabled={option.disabled || undefined}\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,11 +1,26 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
export type TableCardOptions = {
|
|
3
|
+
/** Applied to each Table.Body grid. */
|
|
4
|
+
gridClassName?: string;
|
|
5
|
+
gridStyle?: React.CSSProperties;
|
|
6
|
+
/** Applied to each body row card. */
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: React.CSSProperties;
|
|
9
|
+
fieldClassName?: string;
|
|
10
|
+
fieldStyle?: React.CSSProperties;
|
|
11
|
+
labelClassName?: string;
|
|
12
|
+
labelStyle?: React.CSSProperties;
|
|
13
|
+
};
|
|
2
14
|
export type TableProps = {
|
|
3
15
|
children: React.ReactNode;
|
|
16
|
+
card?: boolean;
|
|
17
|
+
cardOptions?: TableCardOptions;
|
|
4
18
|
className?: string;
|
|
5
19
|
onClick?: (e: React.MouseEvent) => void;
|
|
6
20
|
onMouseEnter?: (e: React.MouseEvent) => void;
|
|
7
21
|
onMouseLeave?: (e: React.MouseEvent) => void;
|
|
8
22
|
} & React.TableHTMLAttributes<HTMLTableElement>;
|
|
23
|
+
declare const Table: ({ children, className, card, cardOptions, onClick, onMouseEnter, onMouseLeave, ...rest }: TableProps) => React.JSX.Element;
|
|
9
24
|
export type TableHeadProps = React.HTMLAttributes<HTMLTableSectionElement>;
|
|
10
25
|
export type TableBodyProps = React.HTMLAttributes<HTMLTableSectionElement>;
|
|
11
26
|
export type TableRowProps = {
|
|
@@ -19,6 +34,8 @@ export type TableRowProps = {
|
|
|
19
34
|
} & Omit<React.HTMLAttributes<HTMLTableRowElement>, 'className' | 'onClick' | 'onDoubleClick' | 'onMouseEnter' | 'onMouseLeave'>;
|
|
20
35
|
export type TableCellProps = {
|
|
21
36
|
children?: React.ReactNode;
|
|
37
|
+
/** Visible field label in card body cells only. */
|
|
38
|
+
label?: React.ReactNode;
|
|
22
39
|
className?: string;
|
|
23
40
|
onClick?: (e: React.MouseEvent) => void;
|
|
24
41
|
colSpan?: number;
|
|
@@ -42,7 +59,8 @@ export type TableHeaderCellProps = {
|
|
|
42
59
|
} & React.ThHTMLAttributes<HTMLTableCellElement>;
|
|
43
60
|
export type TableCaptionProps = React.HTMLAttributes<HTMLTableCaptionElement>;
|
|
44
61
|
export type TableFooterProps = React.HTMLAttributes<HTMLTableSectionElement>;
|
|
45
|
-
|
|
62
|
+
export type TableCardProps = Omit<TableProps, 'card'>;
|
|
63
|
+
interface TableSubcomponents {
|
|
46
64
|
Caption: React.FC<TableCaptionProps>;
|
|
47
65
|
Footer: React.FC<TableFooterProps>;
|
|
48
66
|
Head: React.FC<TableHeadProps>;
|
|
@@ -51,5 +69,8 @@ interface TableCompound extends React.FC<TableProps> {
|
|
|
51
69
|
Cell: React.FC<TableCellProps>;
|
|
52
70
|
HeaderCell: React.FC<TableHeaderCellProps>;
|
|
53
71
|
}
|
|
54
|
-
declare const
|
|
72
|
+
declare const TableCard: (props: TableCardProps) => React.JSX.Element;
|
|
73
|
+
declare const TableWithCompounds: typeof Table & TableSubcomponents & {
|
|
74
|
+
Card: typeof TableCard & TableSubcomponents;
|
|
75
|
+
};
|
|
55
76
|
export default TableWithCompounds;
|