asterui 0.12.55 → 0.12.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.
- package/dist/components/DatePicker.d.ts +3 -1
- package/dist/components/DatePicker.js +85 -83
- package/dist/components/DatePicker.js.map +1 -1
- package/dist/components/Dropdown.d.ts +5 -4
- package/dist/components/Dropdown.js +228 -222
- package/dist/components/Dropdown.js.map +1 -1
- package/dist/components/InputNumber.d.ts +2 -0
- package/dist/components/InputNumber.js +92 -88
- package/dist/components/InputNumber.js.map +1 -1
- package/dist/components/Menu.d.ts +3 -1
- package/dist/components/Menu.js +38 -37
- package/dist/components/Menu.js.map +1 -1
- package/dist/components/Modal.d.ts +40 -18
- package/dist/components/Modal.js +180 -156
- package/dist/components/Modal.js.map +1 -1
- package/dist/components/OTPInput.d.ts +2 -0
- package/dist/components/OTPInput.js +55 -53
- package/dist/components/OTPInput.js.map +1 -1
- package/dist/components/Pagination.d.ts +3 -1
- package/dist/components/Pagination.js +104 -90
- package/dist/components/Pagination.js.map +1 -1
- package/dist/components/Popconfirm.d.ts +3 -1
- package/dist/components/Popconfirm.js +63 -59
- package/dist/components/Popconfirm.js.map +1 -1
- package/dist/components/Tabs.d.ts +3 -2
- package/dist/components/Tabs.js +74 -72
- package/dist/components/Tabs.js.map +1 -1
- package/dist/components/ThemeController.js +102 -88
- package/dist/components/ThemeController.js.map +1 -1
- package/dist/components/ThemeProvider.js +17 -15
- package/dist/components/ThemeProvider.js.map +1 -1
- package/dist/components/Transfer.d.ts +3 -1
- package/dist/components/Transfer.js +127 -120
- package/dist/components/Transfer.js.map +1 -1
- package/dist/components/Upload.d.ts +3 -1
- package/dist/components/Upload.js +144 -142
- package/dist/components/Upload.js.map +1 -1
- package/dist/hooks/useTheme.js +8 -6
- package/dist/hooks/useTheme.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
import { jsxs as p, jsx as t } from "react/jsx-runtime";
|
|
2
|
-
import { useState as
|
|
3
|
-
const
|
|
4
|
-
action:
|
|
5
|
-
accept:
|
|
6
|
-
multiple:
|
|
2
|
+
import { forwardRef as re, useState as O, useRef as N } from "react";
|
|
3
|
+
const ne = "loading", se = "loading-spinner", ae = "loading-sm", A = "btn", R = "btn-xs", oe = "btn-ghost", S = "btn-circle", ie = "btn-error", ue = re(function({
|
|
4
|
+
action: $,
|
|
5
|
+
accept: T,
|
|
6
|
+
multiple: z = !1,
|
|
7
7
|
maxCount: v,
|
|
8
8
|
maxSize: b,
|
|
9
9
|
listType: y = "text",
|
|
10
10
|
fileList: L,
|
|
11
|
-
defaultFileList:
|
|
12
|
-
beforeUpload:
|
|
13
|
-
onChange:
|
|
14
|
-
onRemove:
|
|
15
|
-
customRequest:
|
|
16
|
-
showUploadList:
|
|
11
|
+
defaultFileList: I = [],
|
|
12
|
+
beforeUpload: D,
|
|
13
|
+
onChange: f,
|
|
14
|
+
onRemove: F,
|
|
15
|
+
customRequest: k,
|
|
16
|
+
showUploadList: W = !0,
|
|
17
17
|
disabled: i = !1,
|
|
18
|
-
children:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
children: X,
|
|
19
|
+
"data-testid": w,
|
|
20
|
+
className: G = "",
|
|
21
|
+
...H
|
|
22
|
+
}, _) {
|
|
23
|
+
const [q, J] = O(I), E = (e) => w ? `${w}-${e}` : void 0, [j, x] = O(!1), P = N(null), B = N(0), h = N(0), c = L !== void 0 ? L : q, K = () => (B.current += 1, `upload-${Date.now()}-${B.current}`), m = (e) => {
|
|
24
|
+
L === void 0 && J(e);
|
|
25
|
+
}, C = (e) => {
|
|
25
26
|
const r = {
|
|
26
|
-
uid:
|
|
27
|
+
uid: K(),
|
|
27
28
|
name: e.name,
|
|
28
29
|
status: "uploading",
|
|
29
30
|
percent: 0,
|
|
30
31
|
originFileObj: e
|
|
31
32
|
}, s = [...c, r];
|
|
32
|
-
|
|
33
|
+
m(s), f?.({ file: r, fileList: s });
|
|
33
34
|
const l = (o) => {
|
|
34
35
|
const n = s.map(
|
|
35
36
|
(a) => a.uid === r.uid ? { ...a, percent: o } : a
|
|
36
37
|
);
|
|
37
|
-
|
|
38
|
+
m(n), f?.({ file: { ...r, percent: o }, fileList: n });
|
|
38
39
|
}, u = (o) => {
|
|
39
40
|
const n = {
|
|
40
41
|
...r,
|
|
@@ -44,7 +45,7 @@ const Y = "loading", Z = "loading-spinner", ee = "loading-sm", U = "btn", O = "b
|
|
|
44
45
|
}, a = s.map(
|
|
45
46
|
(d) => d.uid === r.uid ? n : d
|
|
46
47
|
);
|
|
47
|
-
|
|
48
|
+
m(a), f?.({ file: n, fileList: a });
|
|
48
49
|
}, g = (o) => {
|
|
49
50
|
const n = {
|
|
50
51
|
...r,
|
|
@@ -53,16 +54,16 @@ const Y = "loading", Z = "loading-spinner", ee = "loading-sm", U = "btn", O = "b
|
|
|
53
54
|
}, a = s.map(
|
|
54
55
|
(d) => d.uid === r.uid ? n : d
|
|
55
56
|
);
|
|
56
|
-
|
|
57
|
+
m(a), f?.({ file: n, fileList: a });
|
|
57
58
|
};
|
|
58
|
-
if (
|
|
59
|
-
|
|
59
|
+
if (k)
|
|
60
|
+
k({
|
|
60
61
|
file: e,
|
|
61
62
|
onProgress: l,
|
|
62
63
|
onSuccess: u,
|
|
63
64
|
onError: g
|
|
64
65
|
});
|
|
65
|
-
else if (
|
|
66
|
+
else if ($) {
|
|
66
67
|
const o = new FormData();
|
|
67
68
|
o.append("file", e);
|
|
68
69
|
const n = new XMLHttpRequest();
|
|
@@ -75,10 +76,10 @@ const Y = "loading", Z = "loading-spinner", ee = "loading-sm", U = "btn", O = "b
|
|
|
75
76
|
n.status >= 200 && n.status < 300 ? u(n.response) : g(new Error(`Upload failed with status ${n.status}`));
|
|
76
77
|
}), n.addEventListener("error", () => {
|
|
77
78
|
g(new Error("Upload failed"));
|
|
78
|
-
}), n.open("POST",
|
|
79
|
+
}), n.open("POST", $), n.send(o);
|
|
79
80
|
} else
|
|
80
81
|
u(null);
|
|
81
|
-
},
|
|
82
|
+
}, M = async (e) => {
|
|
82
83
|
if (i) return;
|
|
83
84
|
const r = Array.from(e);
|
|
84
85
|
if (v && c.length + r.length > v) {
|
|
@@ -95,44 +96,125 @@ const Y = "loading", Z = "loading-spinner", ee = "loading-sm", U = "btn", O = "b
|
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
|
-
if (
|
|
99
|
+
if (D) {
|
|
99
100
|
const s = await Promise.all(
|
|
100
|
-
r.map((u) =>
|
|
101
|
+
r.map((u) => D(u, r))
|
|
101
102
|
);
|
|
102
|
-
r.filter((u, g) => s[g] !== !1).forEach(
|
|
103
|
+
r.filter((u, g) => s[g] !== !1).forEach(C);
|
|
103
104
|
} else
|
|
104
|
-
r.forEach(
|
|
105
|
-
}, q = (e) => {
|
|
106
|
-
e.target.files && B(e.target.files), e.target.value = "";
|
|
107
|
-
}, J = (e) => {
|
|
108
|
-
e.preventDefault(), e.stopPropagation(), i || (h.current++, w(!0));
|
|
109
|
-
}, K = (e) => {
|
|
110
|
-
e.preventDefault(), e.stopPropagation(), i || (h.current--, h.current === 0 && w(!1));
|
|
105
|
+
r.forEach(C);
|
|
111
106
|
}, Q = (e) => {
|
|
112
|
-
e.
|
|
107
|
+
e.target.files && M(e.target.files), e.target.value = "";
|
|
113
108
|
}, V = (e) => {
|
|
114
|
-
e.preventDefault(), e.stopPropagation(), h.current
|
|
115
|
-
},
|
|
116
|
-
|
|
109
|
+
e.preventDefault(), e.stopPropagation(), i || (h.current++, x(!0));
|
|
110
|
+
}, Y = (e) => {
|
|
111
|
+
e.preventDefault(), e.stopPropagation(), i || (h.current--, h.current === 0 && x(!1));
|
|
112
|
+
}, Z = (e) => {
|
|
113
|
+
e.preventDefault(), e.stopPropagation();
|
|
114
|
+
}, ee = (e) => {
|
|
115
|
+
e.preventDefault(), e.stopPropagation(), h.current = 0, x(!1), !i && e.dataTransfer.files && M(e.dataTransfer.files);
|
|
116
|
+
}, U = async (e) => {
|
|
117
|
+
if (F && await F(e) === !1)
|
|
117
118
|
return;
|
|
118
119
|
const r = c.filter((s) => s.uid !== e.uid);
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
120
|
+
m(r), f?.({ file: e, fileList: r });
|
|
121
|
+
}, te = () => !W || c.length === 0 ? null : y === "picture-card" ? /* @__PURE__ */ t("div", { className: "flex flex-wrap gap-2 mt-2", children: c.map((e) => /* @__PURE__ */ p(
|
|
122
|
+
"div",
|
|
123
|
+
{
|
|
124
|
+
className: "relative w-24 h-24 border border-base-content/20 rounded-lg overflow-hidden",
|
|
125
|
+
children: [
|
|
126
|
+
e.status === "uploading" && /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-base-300/80 flex items-center justify-center", children: /* @__PURE__ */ t("span", { className: `${ne} ${se} ${ae}` }) }),
|
|
127
|
+
e.status === "done" && e.url && /* @__PURE__ */ t(
|
|
128
|
+
"img",
|
|
129
|
+
{
|
|
130
|
+
src: e.url,
|
|
131
|
+
alt: e.name,
|
|
132
|
+
className: "w-full h-full object-cover"
|
|
133
|
+
}
|
|
134
|
+
),
|
|
135
|
+
e.status === "error" && /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-error/10 flex items-center justify-center", children: /* @__PURE__ */ t(
|
|
136
|
+
"svg",
|
|
137
|
+
{
|
|
138
|
+
className: "w-8 h-8 text-error",
|
|
139
|
+
fill: "none",
|
|
140
|
+
viewBox: "0 0 24 24",
|
|
141
|
+
stroke: "currentColor",
|
|
142
|
+
children: /* @__PURE__ */ t(
|
|
143
|
+
"path",
|
|
144
|
+
{
|
|
145
|
+
strokeLinecap: "round",
|
|
146
|
+
strokeLinejoin: "round",
|
|
147
|
+
strokeWidth: 2,
|
|
148
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
) }),
|
|
153
|
+
/* @__PURE__ */ t(
|
|
154
|
+
"button",
|
|
155
|
+
{
|
|
156
|
+
onClick: () => U(e),
|
|
157
|
+
className: `absolute top-1 right-1 ${A} ${R} ${S} ${ie}`,
|
|
158
|
+
type: "button",
|
|
159
|
+
children: "✕"
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
e.uid
|
|
165
|
+
)) }) : /* @__PURE__ */ t("div", { className: "mt-2 space-y-2", children: c.map((e) => /* @__PURE__ */ p(
|
|
166
|
+
"div",
|
|
167
|
+
{
|
|
168
|
+
className: "flex items-center gap-2 p-2 border border-base-content/10 rounded-lg",
|
|
169
|
+
children: [
|
|
170
|
+
y === "picture" && e.url && /* @__PURE__ */ t(
|
|
171
|
+
"img",
|
|
172
|
+
{
|
|
173
|
+
src: e.url,
|
|
174
|
+
alt: e.name,
|
|
175
|
+
className: "w-12 h-12 object-cover rounded"
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
/* @__PURE__ */ p("div", { className: "flex-1 min-w-0", children: [
|
|
179
|
+
/* @__PURE__ */ t("div", { className: "truncate text-sm", children: e.name }),
|
|
180
|
+
e.status === "uploading" && e.percent !== void 0 && /* @__PURE__ */ t("div", { className: "w-full bg-base-200 rounded-full h-1.5 mt-1", children: /* @__PURE__ */ t(
|
|
181
|
+
"div",
|
|
182
|
+
{
|
|
183
|
+
className: "bg-primary h-1.5 rounded-full transition-all",
|
|
184
|
+
style: { width: `${e.percent}%` }
|
|
185
|
+
}
|
|
186
|
+
) }),
|
|
187
|
+
e.status === "error" && /* @__PURE__ */ t("div", { className: "text-xs text-error mt-1", children: "Upload failed" })
|
|
188
|
+
] }),
|
|
189
|
+
/* @__PURE__ */ t(
|
|
190
|
+
"button",
|
|
191
|
+
{
|
|
192
|
+
onClick: () => U(e),
|
|
193
|
+
className: `${A} ${R} ${oe} ${S}`,
|
|
194
|
+
type: "button",
|
|
195
|
+
children: "✕"
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
e.uid
|
|
201
|
+
)) });
|
|
202
|
+
return /* @__PURE__ */ p("div", { ref: _, className: G, "data-state": j ? "dragging" : "idle", "data-testid": w, ...H, children: [
|
|
122
203
|
/* @__PURE__ */ t(
|
|
123
204
|
"div",
|
|
124
205
|
{
|
|
125
|
-
onDragEnter:
|
|
126
|
-
onDragOver:
|
|
127
|
-
onDragLeave:
|
|
128
|
-
onDrop:
|
|
129
|
-
onClick: () => !i &&
|
|
206
|
+
onDragEnter: V,
|
|
207
|
+
onDragOver: Z,
|
|
208
|
+
onDragLeave: Y,
|
|
209
|
+
onDrop: ee,
|
|
210
|
+
onClick: () => !i && P.current?.click(),
|
|
130
211
|
className: `
|
|
131
212
|
border-2 border-dashed rounded-lg p-4 cursor-pointer transition-colors
|
|
132
|
-
${
|
|
213
|
+
${j ? "border-primary bg-primary/5" : "border-base-content/20"}
|
|
133
214
|
${i ? "opacity-50 cursor-not-allowed" : "hover:border-primary"}
|
|
134
215
|
`,
|
|
135
|
-
|
|
216
|
+
"data-testid": E("dropzone"),
|
|
217
|
+
children: X || /* @__PURE__ */ p("div", { className: "flex flex-col items-center gap-2 py-4", children: [
|
|
136
218
|
/* @__PURE__ */ t(
|
|
137
219
|
"svg",
|
|
138
220
|
{
|
|
@@ -161,101 +243,21 @@ const Y = "loading", Z = "loading-spinner", ee = "loading-sm", U = "btn", O = "b
|
|
|
161
243
|
/* @__PURE__ */ t(
|
|
162
244
|
"input",
|
|
163
245
|
{
|
|
164
|
-
ref:
|
|
246
|
+
ref: P,
|
|
165
247
|
type: "file",
|
|
166
|
-
accept:
|
|
167
|
-
multiple:
|
|
168
|
-
onChange:
|
|
248
|
+
accept: T,
|
|
249
|
+
multiple: z,
|
|
250
|
+
onChange: Q,
|
|
169
251
|
disabled: i,
|
|
170
|
-
className: "hidden"
|
|
252
|
+
className: "hidden",
|
|
253
|
+
"data-testid": E("input")
|
|
171
254
|
}
|
|
172
255
|
),
|
|
173
|
-
|
|
174
|
-
"div",
|
|
175
|
-
{
|
|
176
|
-
className: "relative w-24 h-24 border border-base-content/20 rounded-lg overflow-hidden",
|
|
177
|
-
children: [
|
|
178
|
-
e.status === "uploading" && /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-base-300/80 flex items-center justify-center", children: /* @__PURE__ */ t("span", { className: `${Y} ${Z} ${ee}` }) }),
|
|
179
|
-
e.status === "done" && e.url && /* @__PURE__ */ t(
|
|
180
|
-
"img",
|
|
181
|
-
{
|
|
182
|
-
src: e.url,
|
|
183
|
-
alt: e.name,
|
|
184
|
-
className: "w-full h-full object-cover"
|
|
185
|
-
}
|
|
186
|
-
),
|
|
187
|
-
e.status === "error" && /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-error/10 flex items-center justify-center", children: /* @__PURE__ */ t(
|
|
188
|
-
"svg",
|
|
189
|
-
{
|
|
190
|
-
className: "w-8 h-8 text-error",
|
|
191
|
-
fill: "none",
|
|
192
|
-
viewBox: "0 0 24 24",
|
|
193
|
-
stroke: "currentColor",
|
|
194
|
-
children: /* @__PURE__ */ t(
|
|
195
|
-
"path",
|
|
196
|
-
{
|
|
197
|
-
strokeLinecap: "round",
|
|
198
|
-
strokeLinejoin: "round",
|
|
199
|
-
strokeWidth: 2,
|
|
200
|
-
d: "M6 18L18 6M6 6l12 12"
|
|
201
|
-
}
|
|
202
|
-
)
|
|
203
|
-
}
|
|
204
|
-
) }),
|
|
205
|
-
/* @__PURE__ */ t(
|
|
206
|
-
"button",
|
|
207
|
-
{
|
|
208
|
-
onClick: () => C(e),
|
|
209
|
-
className: `absolute top-1 right-1 ${U} ${O} ${A} ${re}`,
|
|
210
|
-
type: "button",
|
|
211
|
-
children: "✕"
|
|
212
|
-
}
|
|
213
|
-
)
|
|
214
|
-
]
|
|
215
|
-
},
|
|
216
|
-
e.uid
|
|
217
|
-
)) }) : /* @__PURE__ */ t("div", { className: "mt-2 space-y-2", children: c.map((e) => /* @__PURE__ */ p(
|
|
218
|
-
"div",
|
|
219
|
-
{
|
|
220
|
-
className: "flex items-center gap-2 p-2 border border-base-content/10 rounded-lg",
|
|
221
|
-
children: [
|
|
222
|
-
y === "picture" && e.url && /* @__PURE__ */ t(
|
|
223
|
-
"img",
|
|
224
|
-
{
|
|
225
|
-
src: e.url,
|
|
226
|
-
alt: e.name,
|
|
227
|
-
className: "w-12 h-12 object-cover rounded"
|
|
228
|
-
}
|
|
229
|
-
),
|
|
230
|
-
/* @__PURE__ */ p("div", { className: "flex-1 min-w-0", children: [
|
|
231
|
-
/* @__PURE__ */ t("div", { className: "truncate text-sm", children: e.name }),
|
|
232
|
-
e.status === "uploading" && e.percent !== void 0 && /* @__PURE__ */ t("div", { className: "w-full bg-base-200 rounded-full h-1.5 mt-1", children: /* @__PURE__ */ t(
|
|
233
|
-
"div",
|
|
234
|
-
{
|
|
235
|
-
className: "bg-primary h-1.5 rounded-full transition-all",
|
|
236
|
-
style: { width: `${e.percent}%` }
|
|
237
|
-
}
|
|
238
|
-
) }),
|
|
239
|
-
e.status === "error" && /* @__PURE__ */ t("div", { className: "text-xs text-error mt-1", children: "Upload failed" })
|
|
240
|
-
] }),
|
|
241
|
-
/* @__PURE__ */ t(
|
|
242
|
-
"button",
|
|
243
|
-
{
|
|
244
|
-
onClick: () => C(e),
|
|
245
|
-
className: `${U} ${O} ${te} ${A}`,
|
|
246
|
-
type: "button",
|
|
247
|
-
children: "✕"
|
|
248
|
-
}
|
|
249
|
-
)
|
|
250
|
-
]
|
|
251
|
-
},
|
|
252
|
-
e.uid
|
|
253
|
-
)) })
|
|
256
|
+
te()
|
|
254
257
|
] });
|
|
255
|
-
};
|
|
256
|
-
ne.displayName = "Upload";
|
|
258
|
+
});
|
|
257
259
|
export {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
ue as Upload,
|
|
261
|
+
ue as default
|
|
260
262
|
};
|
|
261
263
|
//# sourceMappingURL=Upload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Upload.js","sources":["../../src/components/Upload.tsx"],"sourcesContent":["import React, { useState, useRef, DragEvent, ChangeEvent } from 'react'\n\n// DaisyUI classes\nconst dLoading = 'loading'\nconst dLoadingSpinner = 'loading-spinner'\nconst dLoadingSm = 'loading-sm'\nconst dBtn = 'btn'\nconst dBtnXs = 'btn-xs'\nconst dBtnGhost = 'btn-ghost'\nconst dBtnCircle = 'btn-circle'\nconst dBtnError = 'btn-error'\n\nexport interface UploadFile {\n uid: string\n name: string\n status: 'uploading' | 'done' | 'error'\n percent?: number\n url?: string\n response?: any\n error?: any\n originFileObj?: File\n}\n\nexport interface UploadProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n action?: string\n accept?: string\n multiple?: boolean\n maxCount?: number\n maxSize?: number // in bytes\n listType?: 'text' | 'picture' | 'picture-card'\n fileList?: UploadFile[]\n defaultFileList?: UploadFile[]\n beforeUpload?: (file: File, fileList: File[]) => boolean | Promise<boolean>\n onChange?: (info: { file: UploadFile; fileList: UploadFile[] }) => void\n onRemove?: (file: UploadFile) => void | boolean | Promise<void | boolean>\n customRequest?: (options: {\n file: File\n onProgress: (percent: number) => void\n onSuccess: (response: any) => void\n onError: (error: any) => void\n }) => void\n showUploadList?: boolean\n disabled?: boolean\n children?: React.ReactNode\n}\n\nexport const Upload: React.FC<UploadProps> = ({\n action,\n accept,\n multiple = false,\n maxCount,\n maxSize,\n listType = 'text',\n fileList: controlledFileList,\n defaultFileList = [],\n beforeUpload,\n onChange,\n onRemove,\n customRequest,\n showUploadList = true,\n disabled = false,\n children,\n className = '',\n ...rest\n}) => {\n const [internalFileList, setInternalFileList] = useState<UploadFile[]>(defaultFileList)\n const [isDragging, setIsDragging] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n const uidCounter = useRef(0)\n const dragCounter = useRef(0)\n\n const fileList = controlledFileList !== undefined ? controlledFileList : internalFileList\n\n const generateUid = () => {\n uidCounter.current += 1\n return `upload-${Date.now()}-${uidCounter.current}`\n }\n\n const updateFileList = (newFileList: UploadFile[]) => {\n if (controlledFileList === undefined) {\n setInternalFileList(newFileList)\n }\n }\n\n const uploadFile = (file: File) => {\n const uploadFile: UploadFile = {\n uid: generateUid(),\n name: file.name,\n status: 'uploading',\n percent: 0,\n originFileObj: file,\n }\n\n const newFileList = [...fileList, uploadFile]\n updateFileList(newFileList)\n onChange?.({ file: uploadFile, fileList: newFileList })\n\n const updateProgress = (percent: number) => {\n const updatedList = newFileList.map((f) =>\n f.uid === uploadFile.uid ? { ...f, percent } : f\n )\n updateFileList(updatedList)\n onChange?.({ file: { ...uploadFile, percent }, fileList: updatedList })\n }\n\n const onSuccess = (response: any) => {\n const successFile = {\n ...uploadFile,\n status: 'done' as const,\n percent: 100,\n response,\n }\n const updatedList = newFileList.map((f) =>\n f.uid === uploadFile.uid ? successFile : f\n )\n updateFileList(updatedList)\n onChange?.({ file: successFile, fileList: updatedList })\n }\n\n const onError = (error: any) => {\n const errorFile = {\n ...uploadFile,\n status: 'error' as const,\n error,\n }\n const updatedList = newFileList.map((f) =>\n f.uid === uploadFile.uid ? errorFile : f\n )\n updateFileList(updatedList)\n onChange?.({ file: errorFile, fileList: updatedList })\n }\n\n if (customRequest) {\n customRequest({\n file,\n onProgress: updateProgress,\n onSuccess,\n onError,\n })\n } else if (action) {\n const formData = new FormData()\n formData.append('file', file)\n\n const xhr = new XMLHttpRequest()\n\n xhr.upload.addEventListener('progress', (e) => {\n if (e.lengthComputable) {\n const percent = Math.round((e.loaded / e.total) * 100)\n updateProgress(percent)\n }\n })\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n onSuccess(xhr.response)\n } else {\n onError(new Error(`Upload failed with status ${xhr.status}`))\n }\n })\n\n xhr.addEventListener('error', () => {\n onError(new Error('Upload failed'))\n })\n\n xhr.open('POST', action)\n xhr.send(formData)\n } else {\n // No upload action, just mark as done\n onSuccess(null)\n }\n }\n\n const handleFiles = async (files: FileList | File[]) => {\n if (disabled) return\n\n const fileArray = Array.from(files)\n\n // Check maxCount\n if (maxCount && fileList.length + fileArray.length > maxCount) {\n console.warn(`Cannot upload more than ${maxCount} files`)\n return\n }\n\n // Check maxSize\n if (maxSize) {\n const oversizedFiles = fileArray.filter((file) => file.size > maxSize)\n if (oversizedFiles.length > 0) {\n console.warn(\n `Files exceed maximum size of ${maxSize} bytes:`,\n oversizedFiles.map((f) => f.name)\n )\n return\n }\n }\n\n // beforeUpload hook\n if (beforeUpload) {\n const results = await Promise.all(\n fileArray.map((file) => beforeUpload(file, fileArray))\n )\n const filteredFiles = fileArray.filter((_, index) => results[index] !== false)\n filteredFiles.forEach(uploadFile)\n } else {\n fileArray.forEach(uploadFile)\n }\n }\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files) {\n handleFiles(e.target.files)\n }\n // Reset input value to allow uploading the same file again\n e.target.value = ''\n }\n\n const handleDragEnter = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n dragCounter.current++\n setIsDragging(true)\n }\n }\n\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n dragCounter.current--\n if (dragCounter.current === 0) {\n setIsDragging(false)\n }\n }\n }\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n }\n\n const handleDrop = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n dragCounter.current = 0\n setIsDragging(false)\n\n if (disabled) return\n\n if (e.dataTransfer.files) {\n handleFiles(e.dataTransfer.files)\n }\n }\n\n const handleRemove = async (file: UploadFile) => {\n if (onRemove) {\n const result = await onRemove(file)\n if (result === false) return\n }\n\n const newFileList = fileList.filter((f) => f.uid !== file.uid)\n updateFileList(newFileList)\n onChange?.({ file, fileList: newFileList })\n }\n\n const renderFileList = () => {\n if (!showUploadList || fileList.length === 0) return null\n\n if (listType === 'picture-card') {\n return (\n <div className=\"flex flex-wrap gap-2 mt-2\">\n {fileList.map((file) => (\n <div\n key={file.uid}\n className=\"relative w-24 h-24 border border-base-content/20 rounded-lg overflow-hidden\"\n >\n {file.status === 'uploading' && (\n <div className=\"absolute inset-0 bg-base-300/80 flex items-center justify-center\">\n <span className={`${dLoading} ${dLoadingSpinner} ${dLoadingSm}`}></span>\n </div>\n )}\n {file.status === 'done' && file.url && (\n <img\n src={file.url}\n alt={file.name}\n className=\"w-full h-full object-cover\"\n />\n )}\n {file.status === 'error' && (\n <div className=\"absolute inset-0 bg-error/10 flex items-center justify-center\">\n <svg\n className=\"w-8 h-8 text-error\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </div>\n )}\n <button\n onClick={() => handleRemove(file)}\n className={`absolute top-1 right-1 ${dBtn} ${dBtnXs} ${dBtnCircle} ${dBtnError}`}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n ))}\n </div>\n )\n }\n\n return (\n <div className=\"mt-2 space-y-2\">\n {fileList.map((file) => (\n <div\n key={file.uid}\n className=\"flex items-center gap-2 p-2 border border-base-content/10 rounded-lg\"\n >\n {listType === 'picture' && file.url && (\n <img\n src={file.url}\n alt={file.name}\n className=\"w-12 h-12 object-cover rounded\"\n />\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"truncate text-sm\">{file.name}</div>\n {file.status === 'uploading' && file.percent !== undefined && (\n <div className=\"w-full bg-base-200 rounded-full h-1.5 mt-1\">\n <div\n className=\"bg-primary h-1.5 rounded-full transition-all\"\n style={{ width: `${file.percent}%` }}\n />\n </div>\n )}\n {file.status === 'error' && (\n <div className=\"text-xs text-error mt-1\">Upload failed</div>\n )}\n </div>\n <button\n onClick={() => handleRemove(file)}\n className={`${dBtn} ${dBtnXs} ${dBtnGhost} ${dBtnCircle}`}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n ))}\n </div>\n )\n }\n\n return (\n <div className={className} data-state={isDragging ? 'dragging' : 'idle'} {...rest}>\n <div\n onDragEnter={handleDragEnter}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={() => !disabled && fileInputRef.current?.click()}\n className={`\n border-2 border-dashed rounded-lg p-4 cursor-pointer transition-colors\n ${isDragging ? 'border-primary bg-primary/5' : 'border-base-content/20'}\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-primary'}\n `}\n >\n {children || (\n <div className=\"flex flex-col items-center gap-2 py-4\">\n <svg\n className=\"w-12 h-12 text-base-content/40\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\"\n />\n </svg>\n <div className=\"text-sm text-center\">\n <span className=\"font-semibold text-primary\">Click to upload</span>\n <span className=\"text-base-content/60\"> or drag and drop</span>\n </div>\n </div>\n )}\n </div>\n\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n disabled={disabled}\n className=\"hidden\"\n />\n\n {renderFileList()}\n </div>\n )\n}\n\nUpload.displayName = 'Upload'\n\nexport default Upload\n"],"names":["dLoading","dLoadingSpinner","dLoadingSm","dBtn","dBtnXs","dBtnGhost","dBtnCircle","dBtnError","Upload","action","accept","multiple","maxCount","maxSize","listType","controlledFileList","defaultFileList","beforeUpload","onChange","onRemove","customRequest","showUploadList","disabled","children","className","rest","internalFileList","setInternalFileList","useState","isDragging","setIsDragging","fileInputRef","useRef","uidCounter","dragCounter","fileList","generateUid","updateFileList","newFileList","uploadFile","file","updateProgress","percent","updatedList","f","onSuccess","response","successFile","onError","error","errorFile","formData","xhr","e","handleFiles","files","fileArray","oversizedFiles","results","_","index","handleChange","handleDragEnter","handleDragLeave","handleDragOver","handleDrop","handleRemove","jsxs","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Upload.js","sources":["../../src/components/Upload.tsx"],"sourcesContent":["import React, { useState, useRef, DragEvent, ChangeEvent, forwardRef } from 'react'\n\n// DaisyUI classes\nconst dLoading = 'loading'\nconst dLoadingSpinner = 'loading-spinner'\nconst dLoadingSm = 'loading-sm'\nconst dBtn = 'btn'\nconst dBtnXs = 'btn-xs'\nconst dBtnGhost = 'btn-ghost'\nconst dBtnCircle = 'btn-circle'\nconst dBtnError = 'btn-error'\n\nexport interface UploadFile {\n uid: string\n name: string\n status: 'uploading' | 'done' | 'error'\n percent?: number\n url?: string\n response?: any\n error?: any\n originFileObj?: File\n}\n\nexport interface UploadProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n action?: string\n accept?: string\n multiple?: boolean\n maxCount?: number\n maxSize?: number // in bytes\n listType?: 'text' | 'picture' | 'picture-card'\n fileList?: UploadFile[]\n defaultFileList?: UploadFile[]\n beforeUpload?: (file: File, fileList: File[]) => boolean | Promise<boolean>\n onChange?: (info: { file: UploadFile; fileList: UploadFile[] }) => void\n onRemove?: (file: UploadFile) => void | boolean | Promise<void | boolean>\n customRequest?: (options: {\n file: File\n onProgress: (percent: number) => void\n onSuccess: (response: any) => void\n onError: (error: any) => void\n }) => void\n showUploadList?: boolean\n disabled?: boolean\n children?: React.ReactNode\n /** Test ID prefix for child elements */\n 'data-testid'?: string\n}\n\nexport const Upload = forwardRef<HTMLDivElement, UploadProps>(function Upload(\n {\n action,\n accept,\n multiple = false,\n maxCount,\n maxSize,\n listType = 'text',\n fileList: controlledFileList,\n defaultFileList = [],\n beforeUpload,\n onChange,\n onRemove,\n customRequest,\n showUploadList = true,\n disabled = false,\n children,\n 'data-testid': testId,\n className = '',\n ...rest\n },\n ref\n) {\n const [internalFileList, setInternalFileList] = useState<UploadFile[]>(defaultFileList)\n\n // Helper for test IDs\n const getTestId = (suffix: string) => (testId ? `${testId}-${suffix}` : undefined)\n const [isDragging, setIsDragging] = useState(false)\n const fileInputRef = useRef<HTMLInputElement>(null)\n const uidCounter = useRef(0)\n const dragCounter = useRef(0)\n\n const fileList = controlledFileList !== undefined ? controlledFileList : internalFileList\n\n const generateUid = () => {\n uidCounter.current += 1\n return `upload-${Date.now()}-${uidCounter.current}`\n }\n\n const updateFileList = (newFileList: UploadFile[]) => {\n if (controlledFileList === undefined) {\n setInternalFileList(newFileList)\n }\n }\n\n const uploadFile = (file: File) => {\n const uploadFile: UploadFile = {\n uid: generateUid(),\n name: file.name,\n status: 'uploading',\n percent: 0,\n originFileObj: file,\n }\n\n const newFileList = [...fileList, uploadFile]\n updateFileList(newFileList)\n onChange?.({ file: uploadFile, fileList: newFileList })\n\n const updateProgress = (percent: number) => {\n const updatedList = newFileList.map((f) =>\n f.uid === uploadFile.uid ? { ...f, percent } : f\n )\n updateFileList(updatedList)\n onChange?.({ file: { ...uploadFile, percent }, fileList: updatedList })\n }\n\n const onSuccess = (response: any) => {\n const successFile = {\n ...uploadFile,\n status: 'done' as const,\n percent: 100,\n response,\n }\n const updatedList = newFileList.map((f) =>\n f.uid === uploadFile.uid ? successFile : f\n )\n updateFileList(updatedList)\n onChange?.({ file: successFile, fileList: updatedList })\n }\n\n const onError = (error: any) => {\n const errorFile = {\n ...uploadFile,\n status: 'error' as const,\n error,\n }\n const updatedList = newFileList.map((f) =>\n f.uid === uploadFile.uid ? errorFile : f\n )\n updateFileList(updatedList)\n onChange?.({ file: errorFile, fileList: updatedList })\n }\n\n if (customRequest) {\n customRequest({\n file,\n onProgress: updateProgress,\n onSuccess,\n onError,\n })\n } else if (action) {\n const formData = new FormData()\n formData.append('file', file)\n\n const xhr = new XMLHttpRequest()\n\n xhr.upload.addEventListener('progress', (e) => {\n if (e.lengthComputable) {\n const percent = Math.round((e.loaded / e.total) * 100)\n updateProgress(percent)\n }\n })\n\n xhr.addEventListener('load', () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n onSuccess(xhr.response)\n } else {\n onError(new Error(`Upload failed with status ${xhr.status}`))\n }\n })\n\n xhr.addEventListener('error', () => {\n onError(new Error('Upload failed'))\n })\n\n xhr.open('POST', action)\n xhr.send(formData)\n } else {\n // No upload action, just mark as done\n onSuccess(null)\n }\n }\n\n const handleFiles = async (files: FileList | File[]) => {\n if (disabled) return\n\n const fileArray = Array.from(files)\n\n // Check maxCount\n if (maxCount && fileList.length + fileArray.length > maxCount) {\n console.warn(`Cannot upload more than ${maxCount} files`)\n return\n }\n\n // Check maxSize\n if (maxSize) {\n const oversizedFiles = fileArray.filter((file) => file.size > maxSize)\n if (oversizedFiles.length > 0) {\n console.warn(\n `Files exceed maximum size of ${maxSize} bytes:`,\n oversizedFiles.map((f) => f.name)\n )\n return\n }\n }\n\n // beforeUpload hook\n if (beforeUpload) {\n const results = await Promise.all(\n fileArray.map((file) => beforeUpload(file, fileArray))\n )\n const filteredFiles = fileArray.filter((_, index) => results[index] !== false)\n filteredFiles.forEach(uploadFile)\n } else {\n fileArray.forEach(uploadFile)\n }\n }\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files) {\n handleFiles(e.target.files)\n }\n // Reset input value to allow uploading the same file again\n e.target.value = ''\n }\n\n const handleDragEnter = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n dragCounter.current++\n setIsDragging(true)\n }\n }\n\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) {\n dragCounter.current--\n if (dragCounter.current === 0) {\n setIsDragging(false)\n }\n }\n }\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n }\n\n const handleDrop = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n dragCounter.current = 0\n setIsDragging(false)\n\n if (disabled) return\n\n if (e.dataTransfer.files) {\n handleFiles(e.dataTransfer.files)\n }\n }\n\n const handleRemove = async (file: UploadFile) => {\n if (onRemove) {\n const result = await onRemove(file)\n if (result === false) return\n }\n\n const newFileList = fileList.filter((f) => f.uid !== file.uid)\n updateFileList(newFileList)\n onChange?.({ file, fileList: newFileList })\n }\n\n const renderFileList = () => {\n if (!showUploadList || fileList.length === 0) return null\n\n if (listType === 'picture-card') {\n return (\n <div className=\"flex flex-wrap gap-2 mt-2\">\n {fileList.map((file) => (\n <div\n key={file.uid}\n className=\"relative w-24 h-24 border border-base-content/20 rounded-lg overflow-hidden\"\n >\n {file.status === 'uploading' && (\n <div className=\"absolute inset-0 bg-base-300/80 flex items-center justify-center\">\n <span className={`${dLoading} ${dLoadingSpinner} ${dLoadingSm}`}></span>\n </div>\n )}\n {file.status === 'done' && file.url && (\n <img\n src={file.url}\n alt={file.name}\n className=\"w-full h-full object-cover\"\n />\n )}\n {file.status === 'error' && (\n <div className=\"absolute inset-0 bg-error/10 flex items-center justify-center\">\n <svg\n className=\"w-8 h-8 text-error\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </div>\n )}\n <button\n onClick={() => handleRemove(file)}\n className={`absolute top-1 right-1 ${dBtn} ${dBtnXs} ${dBtnCircle} ${dBtnError}`}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n ))}\n </div>\n )\n }\n\n return (\n <div className=\"mt-2 space-y-2\">\n {fileList.map((file) => (\n <div\n key={file.uid}\n className=\"flex items-center gap-2 p-2 border border-base-content/10 rounded-lg\"\n >\n {listType === 'picture' && file.url && (\n <img\n src={file.url}\n alt={file.name}\n className=\"w-12 h-12 object-cover rounded\"\n />\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"truncate text-sm\">{file.name}</div>\n {file.status === 'uploading' && file.percent !== undefined && (\n <div className=\"w-full bg-base-200 rounded-full h-1.5 mt-1\">\n <div\n className=\"bg-primary h-1.5 rounded-full transition-all\"\n style={{ width: `${file.percent}%` }}\n />\n </div>\n )}\n {file.status === 'error' && (\n <div className=\"text-xs text-error mt-1\">Upload failed</div>\n )}\n </div>\n <button\n onClick={() => handleRemove(file)}\n className={`${dBtn} ${dBtnXs} ${dBtnGhost} ${dBtnCircle}`}\n type=\"button\"\n >\n ✕\n </button>\n </div>\n ))}\n </div>\n )\n }\n\n return (\n <div ref={ref} className={className} data-state={isDragging ? 'dragging' : 'idle'} data-testid={testId} {...rest}>\n <div\n onDragEnter={handleDragEnter}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={() => !disabled && fileInputRef.current?.click()}\n className={`\n border-2 border-dashed rounded-lg p-4 cursor-pointer transition-colors\n ${isDragging ? 'border-primary bg-primary/5' : 'border-base-content/20'}\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-primary'}\n `}\n data-testid={getTestId('dropzone')}\n >\n {children || (\n <div className=\"flex flex-col items-center gap-2 py-4\">\n <svg\n className=\"w-12 h-12 text-base-content/40\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12\"\n />\n </svg>\n <div className=\"text-sm text-center\">\n <span className=\"font-semibold text-primary\">Click to upload</span>\n <span className=\"text-base-content/60\"> or drag and drop</span>\n </div>\n </div>\n )}\n </div>\n\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n disabled={disabled}\n className=\"hidden\"\n data-testid={getTestId('input')}\n />\n\n {renderFileList()}\n </div>\n )\n})\n\nexport default Upload\n"],"names":["dLoading","dLoadingSpinner","dLoadingSm","dBtn","dBtnXs","dBtnGhost","dBtnCircle","dBtnError","Upload","forwardRef","action","accept","multiple","maxCount","maxSize","listType","controlledFileList","defaultFileList","beforeUpload","onChange","onRemove","customRequest","showUploadList","disabled","children","testId","className","rest","ref","internalFileList","setInternalFileList","useState","getTestId","suffix","isDragging","setIsDragging","fileInputRef","useRef","uidCounter","dragCounter","fileList","generateUid","updateFileList","newFileList","uploadFile","file","updateProgress","percent","updatedList","f","onSuccess","response","successFile","onError","error","errorFile","formData","xhr","e","handleFiles","files","fileArray","oversizedFiles","results","_","index","handleChange","handleDragEnter","handleDragLeave","handleDragOver","handleDrop","handleRemove","renderFileList","jsxs","jsx"],"mappings":"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"}
|
package/dist/hooks/useTheme.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState as i, useEffect as
|
|
1
|
+
import { useState as i, useEffect as m, useMemo as u } from "react";
|
|
2
2
|
import { useHasThemeProvider as d, useThemeContext as l } from "../components/ThemeProvider.js";
|
|
3
3
|
const h = /* @__PURE__ */ new Set([
|
|
4
4
|
"dark",
|
|
@@ -80,14 +80,16 @@ function T() {
|
|
|
80
80
|
isDark: !1,
|
|
81
81
|
colors: a()
|
|
82
82
|
}));
|
|
83
|
-
return
|
|
83
|
+
return m(() => {
|
|
84
84
|
const t = () => {
|
|
85
85
|
const s = b(), f = y();
|
|
86
86
|
let c = !1;
|
|
87
87
|
s ? c = h.has(s) : c = f === "dark", requestAnimationFrame(() => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
requestAnimationFrame(() => {
|
|
89
|
+
e({
|
|
90
|
+
isDark: c,
|
|
91
|
+
colors: a()
|
|
92
|
+
});
|
|
91
93
|
});
|
|
92
94
|
});
|
|
93
95
|
};
|
|
@@ -101,7 +103,7 @@ function T() {
|
|
|
101
103
|
return o.addEventListener("change", t), () => {
|
|
102
104
|
n.disconnect(), o.removeEventListener("change", t);
|
|
103
105
|
};
|
|
104
|
-
}, []),
|
|
106
|
+
}, []), u(() => ({
|
|
105
107
|
theme: void 0,
|
|
106
108
|
resolvedTheme: void 0,
|
|
107
109
|
isDark: r.isDark,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTheme.js","sources":["../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useState, useMemo } from 'react'\nimport { useHasThemeProvider, useThemeContext, type ThemeColors } from '../components/ThemeProvider'\n\nexport type { ThemeColors }\n\n// Common dark themes in DaisyUI\nconst DARK_THEMES = new Set([\n 'dark', 'synthwave', 'halloween', 'forest', 'black', 'luxury', 'dracula',\n 'business', 'night', 'coffee', 'dim', 'sunset'\n])\n\nexport interface UseThemeReturn {\n /** The theme setting (what user selected). Only available with ThemeProvider. */\n theme: string | undefined\n /** The actual applied theme. Only available with ThemeProvider. */\n resolvedTheme: string | undefined\n /** Whether dark mode is active */\n isDark: boolean\n /** Set the theme. Only available with ThemeProvider. */\n setTheme: ((theme: string) => void) | undefined\n /** Computed theme colors as hex values */\n colors: ThemeColors\n /** The system preference. Only available with ThemeProvider. */\n systemTheme: 'light' | 'dark' | undefined\n}\n\n// Convert any CSS color to hex\nfunction colorToHex(color: string): string {\n if (typeof document === 'undefined') return '#000000'\n const canvas = document.createElement('canvas')\n canvas.width = canvas.height = 1\n const ctx = canvas.getContext('2d')\n if (!ctx) return '#000000'\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`\n}\n\nfunction getThemeColors(): ThemeColors {\n if (typeof document === 'undefined') {\n return {\n background: '#ffffff',\n foreground: '#000000',\n primary: '#6366f1',\n primaryContent: '#ffffff',\n secondary: '#f000b8',\n accent: '#37cdbe',\n info: '#3abff8',\n success: '#36d399',\n warning: '#fbbd23',\n error: '#f87272',\n }\n }\n\n const style = getComputedStyle(document.documentElement)\n const getColor = (varName: string, fallback: string): string => {\n const value = style.getPropertyValue(varName).trim()\n return value ? colorToHex(value) : fallback\n }\n\n return {\n background: getColor('--color-base-100', '#ffffff'),\n foreground: getColor('--color-base-content', '#000000'),\n primary: getColor('--color-primary', '#6366f1'),\n primaryContent: getColor('--color-primary-content', '#ffffff'),\n secondary: getColor('--color-secondary', '#f000b8'),\n accent: getColor('--color-accent', '#37cdbe'),\n info: getColor('--color-info', '#3abff8'),\n success: getColor('--color-success', '#36d399'),\n warning: getColor('--color-warning', '#fbbd23'),\n error: getColor('--color-error', '#f87272'),\n }\n}\n\nfunction getSystemTheme(): 'light' | 'dark' {\n if (typeof window === 'undefined') return 'light'\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n}\n\nfunction getCurrentTheme(): string | null {\n if (typeof document === 'undefined') return null\n return document.documentElement.getAttribute('data-theme')\n}\n\n/**\n * Hook to detect current theme and get computed colors.\n *\n * When used within a ThemeProvider, returns full theme control including\n * setTheme, theme selection, and resolved theme.\n *\n * When used standalone (without ThemeProvider), provides read-only access\n * to isDark and colors based on the current data-theme attribute and\n * system preference.\n *\n * @example\n * // With ThemeProvider (full control)\n * const { theme, setTheme, resolvedTheme, isDark, colors } = useTheme()\n * setTheme('dark')\n * setTheme('system')\n *\n * @example\n * // Without ThemeProvider (read-only)\n * const { isDark, colors } = useTheme()\n * // colors.primary, colors.foreground, etc.\n */\nexport function useTheme(): UseThemeReturn {\n const hasProvider = useHasThemeProvider()\n\n // If we have a provider, use its context\n if (hasProvider) {\n // This is safe because hasProvider is stable after initial render\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const context = useThemeContext()\n return {\n theme: context.theme,\n resolvedTheme: context.resolvedTheme,\n isDark: context.isDark,\n setTheme: context.setTheme,\n colors: context.colors,\n systemTheme: context.systemTheme,\n }\n }\n\n // Standalone mode - no provider\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useThemeStandalone()\n}\n\n/**\n * Standalone theme detection (no ThemeProvider)\n */\nfunction useThemeStandalone(): UseThemeReturn {\n const [state, setState] = useState<{ isDark: boolean; colors: ThemeColors }>(() => ({\n isDark: false,\n colors: getThemeColors(),\n }))\n\n useEffect(() => {\n const updateTheme = () => {\n const currentTheme = getCurrentTheme()\n const systemTheme = getSystemTheme()\n\n // Determine if dark based on data-theme or system preference\n let isDark = false\n if (currentTheme) {\n isDark = DARK_THEMES.has(currentTheme)\n } else {\n isDark = systemTheme === 'dark'\n }\n\n //
|
|
1
|
+
{"version":3,"file":"useTheme.js","sources":["../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useState, useMemo } from 'react'\nimport { useHasThemeProvider, useThemeContext, type ThemeColors } from '../components/ThemeProvider'\n\nexport type { ThemeColors }\n\n// Common dark themes in DaisyUI\nconst DARK_THEMES = new Set([\n 'dark', 'synthwave', 'halloween', 'forest', 'black', 'luxury', 'dracula',\n 'business', 'night', 'coffee', 'dim', 'sunset'\n])\n\nexport interface UseThemeReturn {\n /** The theme setting (what user selected). Only available with ThemeProvider. */\n theme: string | undefined\n /** The actual applied theme. Only available with ThemeProvider. */\n resolvedTheme: string | undefined\n /** Whether dark mode is active */\n isDark: boolean\n /** Set the theme. Only available with ThemeProvider. */\n setTheme: ((theme: string) => void) | undefined\n /** Computed theme colors as hex values */\n colors: ThemeColors\n /** The system preference. Only available with ThemeProvider. */\n systemTheme: 'light' | 'dark' | undefined\n}\n\n// Convert any CSS color to hex\nfunction colorToHex(color: string): string {\n if (typeof document === 'undefined') return '#000000'\n const canvas = document.createElement('canvas')\n canvas.width = canvas.height = 1\n const ctx = canvas.getContext('2d')\n if (!ctx) return '#000000'\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data\n return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`\n}\n\nfunction getThemeColors(): ThemeColors {\n if (typeof document === 'undefined') {\n return {\n background: '#ffffff',\n foreground: '#000000',\n primary: '#6366f1',\n primaryContent: '#ffffff',\n secondary: '#f000b8',\n accent: '#37cdbe',\n info: '#3abff8',\n success: '#36d399',\n warning: '#fbbd23',\n error: '#f87272',\n }\n }\n\n const style = getComputedStyle(document.documentElement)\n const getColor = (varName: string, fallback: string): string => {\n const value = style.getPropertyValue(varName).trim()\n return value ? colorToHex(value) : fallback\n }\n\n return {\n background: getColor('--color-base-100', '#ffffff'),\n foreground: getColor('--color-base-content', '#000000'),\n primary: getColor('--color-primary', '#6366f1'),\n primaryContent: getColor('--color-primary-content', '#ffffff'),\n secondary: getColor('--color-secondary', '#f000b8'),\n accent: getColor('--color-accent', '#37cdbe'),\n info: getColor('--color-info', '#3abff8'),\n success: getColor('--color-success', '#36d399'),\n warning: getColor('--color-warning', '#fbbd23'),\n error: getColor('--color-error', '#f87272'),\n }\n}\n\nfunction getSystemTheme(): 'light' | 'dark' {\n if (typeof window === 'undefined') return 'light'\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n}\n\nfunction getCurrentTheme(): string | null {\n if (typeof document === 'undefined') return null\n return document.documentElement.getAttribute('data-theme')\n}\n\n/**\n * Hook to detect current theme and get computed colors.\n *\n * When used within a ThemeProvider, returns full theme control including\n * setTheme, theme selection, and resolved theme.\n *\n * When used standalone (without ThemeProvider), provides read-only access\n * to isDark and colors based on the current data-theme attribute and\n * system preference.\n *\n * @example\n * // With ThemeProvider (full control)\n * const { theme, setTheme, resolvedTheme, isDark, colors } = useTheme()\n * setTheme('dark')\n * setTheme('system')\n *\n * @example\n * // Without ThemeProvider (read-only)\n * const { isDark, colors } = useTheme()\n * // colors.primary, colors.foreground, etc.\n */\nexport function useTheme(): UseThemeReturn {\n const hasProvider = useHasThemeProvider()\n\n // If we have a provider, use its context\n if (hasProvider) {\n // This is safe because hasProvider is stable after initial render\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const context = useThemeContext()\n return {\n theme: context.theme,\n resolvedTheme: context.resolvedTheme,\n isDark: context.isDark,\n setTheme: context.setTheme,\n colors: context.colors,\n systemTheme: context.systemTheme,\n }\n }\n\n // Standalone mode - no provider\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useThemeStandalone()\n}\n\n/**\n * Standalone theme detection (no ThemeProvider)\n */\nfunction useThemeStandalone(): UseThemeReturn {\n const [state, setState] = useState<{ isDark: boolean; colors: ThemeColors }>(() => ({\n isDark: false,\n colors: getThemeColors(),\n }))\n\n useEffect(() => {\n const updateTheme = () => {\n const currentTheme = getCurrentTheme()\n const systemTheme = getSystemTheme()\n\n // Determine if dark based on data-theme or system preference\n let isDark = false\n if (currentTheme) {\n isDark = DARK_THEMES.has(currentTheme)\n } else {\n isDark = systemTheme === 'dark'\n }\n\n // Double RAF ensures CSS has fully recalculated\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setState({\n isDark,\n colors: getThemeColors(),\n })\n })\n })\n }\n\n updateTheme()\n\n // Watch for theme changes via attribute mutation\n const observer = new MutationObserver(updateTheme)\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-theme', 'class']\n })\n\n // Watch for system preference changes\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n mediaQuery.addEventListener('change', updateTheme)\n\n return () => {\n observer.disconnect()\n mediaQuery.removeEventListener('change', updateTheme)\n }\n }, [])\n\n return useMemo(() => ({\n theme: undefined,\n resolvedTheme: undefined,\n isDark: state.isDark,\n setTheme: undefined,\n colors: state.colors,\n systemTheme: undefined,\n }), [state.isDark, state.colors])\n}\n\nexport default useTheme\n"],"names":["DARK_THEMES","colorToHex","color","canvas","ctx","r","g","b","getThemeColors","style","getColor","varName","fallback","value","getSystemTheme","getCurrentTheme","useTheme","useHasThemeProvider","context","useThemeContext","useThemeStandalone","state","setState","useState","useEffect","updateTheme","currentTheme","systemTheme","isDark","observer","mediaQuery","useMemo"],"mappings":"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"}
|