asterui 0.12.47 → 0.12.48
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/Descriptions.d.ts +24 -6
- package/dist/components/Descriptions.js +203 -116
- package/dist/components/Descriptions.js.map +1 -1
- package/dist/components/Notification.js +6 -6
- package/dist/components/Notification.js.map +1 -1
- package/dist/components/QRCode.js +48 -50
- package/dist/components/QRCode.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,30 +2,44 @@ import { default as React } from 'react';
|
|
|
2
2
|
export type DescriptionsSize = 'sm' | 'md' | 'lg';
|
|
3
3
|
export type DescriptionsLayout = 'horizontal' | 'vertical';
|
|
4
4
|
export interface DescriptionsItemProps {
|
|
5
|
+
/** Unique key for the item */
|
|
6
|
+
itemKey?: string;
|
|
5
7
|
/** Label for the item */
|
|
6
8
|
label?: React.ReactNode;
|
|
7
|
-
/** Number of columns to span */
|
|
8
|
-
span?: number;
|
|
9
|
+
/** Number of columns to span, or 'filled' to fill remaining space */
|
|
10
|
+
span?: number | 'filled';
|
|
9
11
|
/** Content of the item */
|
|
10
12
|
children?: React.ReactNode;
|
|
11
13
|
/** Custom label styles */
|
|
12
14
|
labelStyle?: React.CSSProperties;
|
|
13
15
|
/** Custom content styles */
|
|
14
16
|
contentStyle?: React.CSSProperties;
|
|
17
|
+
/** Custom label class */
|
|
18
|
+
labelClassName?: string;
|
|
19
|
+
/** Custom content class */
|
|
20
|
+
contentClassName?: string;
|
|
15
21
|
}
|
|
16
22
|
/** Item configuration for the items prop */
|
|
17
23
|
export interface DescriptionsItemConfig {
|
|
24
|
+
/** Unique key for the item (used for test IDs and React keys) */
|
|
25
|
+
key?: string;
|
|
18
26
|
/** Label for the item */
|
|
19
27
|
label: React.ReactNode;
|
|
20
28
|
/** Content of the item */
|
|
21
29
|
children: React.ReactNode;
|
|
22
|
-
/** Number of columns to span */
|
|
23
|
-
span?: number;
|
|
30
|
+
/** Number of columns to span, or 'filled' to fill remaining space */
|
|
31
|
+
span?: number | 'filled';
|
|
24
32
|
/** Custom label styles */
|
|
25
33
|
labelStyle?: React.CSSProperties;
|
|
26
34
|
/** Custom content styles */
|
|
27
35
|
contentStyle?: React.CSSProperties;
|
|
36
|
+
/** Custom label class */
|
|
37
|
+
labelClassName?: string;
|
|
38
|
+
/** Custom content class */
|
|
39
|
+
contentClassName?: string;
|
|
28
40
|
}
|
|
41
|
+
/** Semantic DOM structure for styles/classNames */
|
|
42
|
+
export type DescriptionsSemanticDOM = 'root' | 'header' | 'title' | 'extra' | 'table' | 'label' | 'content';
|
|
29
43
|
export interface DescriptionsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
30
44
|
/** Title of the descriptions block */
|
|
31
45
|
title?: React.ReactNode;
|
|
@@ -48,10 +62,14 @@ export interface DescriptionsProps extends Omit<React.HTMLAttributes<HTMLDivElem
|
|
|
48
62
|
layout?: DescriptionsLayout;
|
|
49
63
|
/** Show colon after labels */
|
|
50
64
|
colon?: boolean;
|
|
51
|
-
/** Default label styles */
|
|
65
|
+
/** Default label styles (deprecated, use styles.label) */
|
|
52
66
|
labelStyle?: React.CSSProperties;
|
|
53
|
-
/** Default content styles */
|
|
67
|
+
/** Default content styles (deprecated, use styles.content) */
|
|
54
68
|
contentStyle?: React.CSSProperties;
|
|
69
|
+
/** Semantic styles for component parts */
|
|
70
|
+
styles?: Partial<Record<DescriptionsSemanticDOM, React.CSSProperties>>;
|
|
71
|
+
/** Semantic classNames for component parts */
|
|
72
|
+
classNames?: Partial<Record<DescriptionsSemanticDOM, string>>;
|
|
55
73
|
/** Item configurations (alternative to children) */
|
|
56
74
|
items?: DescriptionsItemConfig[];
|
|
57
75
|
/** Children (Descriptions.Item elements) */
|
|
@@ -1,134 +1,221 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import
|
|
3
|
-
function
|
|
1
|
+
import { jsxs as y, jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import g, { forwardRef as q, useId as G, useState as J, useEffect as Q } from "react";
|
|
3
|
+
function T(n) {
|
|
4
4
|
return null;
|
|
5
5
|
}
|
|
6
|
-
const
|
|
6
|
+
const U = {
|
|
7
7
|
sm: "text-sm",
|
|
8
8
|
md: "text-base",
|
|
9
9
|
lg: "text-lg"
|
|
10
|
-
},
|
|
10
|
+
}, S = {
|
|
11
|
+
xs: 0,
|
|
12
|
+
sm: 640,
|
|
13
|
+
md: 768,
|
|
14
|
+
lg: 1024,
|
|
15
|
+
xl: 1280,
|
|
16
|
+
"2xl": 1536
|
|
17
|
+
};
|
|
18
|
+
function X(n) {
|
|
19
|
+
const [h, i] = J(() => typeof n == "number" ? n : n.md ?? n.sm ?? n.xs ?? 3);
|
|
20
|
+
return Q(() => {
|
|
21
|
+
if (typeof n == "number") {
|
|
22
|
+
i(n);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const $ = () => {
|
|
26
|
+
const k = window.innerWidth, u = Object.keys(S).filter((c) => n[c] !== void 0).sort((c, m) => S[m] - S[c]);
|
|
27
|
+
for (const c of u)
|
|
28
|
+
if (k >= S[c]) {
|
|
29
|
+
i(n[c]);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const C = u[u.length - 1];
|
|
33
|
+
i(C ? n[C] : 3);
|
|
34
|
+
};
|
|
35
|
+
return $(), window.addEventListener("resize", $), () => window.removeEventListener("resize", $);
|
|
36
|
+
}, [n]), h;
|
|
37
|
+
}
|
|
38
|
+
const R = q(
|
|
11
39
|
({
|
|
12
|
-
title:
|
|
13
|
-
extra:
|
|
14
|
-
bordered:
|
|
15
|
-
column:
|
|
16
|
-
size:
|
|
17
|
-
layout:
|
|
18
|
-
colon:
|
|
19
|
-
labelStyle:
|
|
20
|
-
contentStyle:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
title: n,
|
|
41
|
+
extra: h,
|
|
42
|
+
bordered: i = !1,
|
|
43
|
+
column: $ = 3,
|
|
44
|
+
size: k = "md",
|
|
45
|
+
layout: u = "horizontal",
|
|
46
|
+
colon: C = !0,
|
|
47
|
+
labelStyle: c,
|
|
48
|
+
contentStyle: m,
|
|
49
|
+
styles: d,
|
|
50
|
+
classNames: b,
|
|
51
|
+
items: x,
|
|
52
|
+
className: z = "",
|
|
53
|
+
style: B,
|
|
24
54
|
children: D,
|
|
25
|
-
"data-testid":
|
|
26
|
-
...
|
|
27
|
-
},
|
|
28
|
-
const w =
|
|
29
|
-
(t) =>
|
|
55
|
+
"data-testid": s = "descriptions",
|
|
56
|
+
...E
|
|
57
|
+
}, M) => {
|
|
58
|
+
const w = G(), f = X($), F = { ...c, ...d?.label }, O = { ...m, ...d?.content }, V = (x || g.Children.toArray(D).filter(
|
|
59
|
+
(t) => g.isValidElement(t)
|
|
30
60
|
).map((t) => ({
|
|
61
|
+
key: t.props.itemKey ?? t.key?.toString().replace(/^\.\$/, ""),
|
|
31
62
|
label: t.props.label,
|
|
32
63
|
children: t.props.children,
|
|
33
64
|
span: t.props.span,
|
|
34
65
|
labelStyle: t.props.labelStyle,
|
|
35
|
-
contentStyle: t.props.contentStyle
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/* @__PURE__ */ a("tr", { children: n.map((e, f) => {
|
|
44
|
-
const h = e.span || 1, p = Math.min(h, r), m = e.labelStyle || x;
|
|
45
|
-
return /* @__PURE__ */ i(
|
|
46
|
-
"th",
|
|
47
|
-
{
|
|
48
|
-
className: `${d ? "border border-base-content/10" : ""} bg-base-200/50 font-semibold text-left px-4 py-2`,
|
|
49
|
-
style: m,
|
|
50
|
-
colSpan: p,
|
|
51
|
-
scope: "col",
|
|
52
|
-
children: [
|
|
53
|
-
e.label,
|
|
54
|
-
g && e.label && ":"
|
|
55
|
-
]
|
|
56
|
-
},
|
|
57
|
-
f
|
|
58
|
-
);
|
|
59
|
-
}) }),
|
|
60
|
-
/* @__PURE__ */ a("tr", { children: n.map((e, f) => {
|
|
61
|
-
const h = e.span || 1, p = Math.min(h, r), m = e.contentStyle || v;
|
|
62
|
-
return /* @__PURE__ */ a(
|
|
63
|
-
"td",
|
|
64
|
-
{
|
|
65
|
-
className: `${d ? "border border-base-content/10" : ""} bg-base-100 px-4 py-2`,
|
|
66
|
-
style: m,
|
|
67
|
-
colSpan: p,
|
|
68
|
-
children: e.children
|
|
69
|
-
},
|
|
70
|
-
f
|
|
71
|
-
);
|
|
72
|
-
}) })
|
|
73
|
-
] }, o));
|
|
74
|
-
}, F = () => {
|
|
66
|
+
contentStyle: t.props.contentStyle,
|
|
67
|
+
labelClassName: t.props.labelClassName,
|
|
68
|
+
contentClassName: t.props.contentClassName
|
|
69
|
+
}))).map((t, a) => ({
|
|
70
|
+
...t,
|
|
71
|
+
_key: t.key ?? `item-${a}`,
|
|
72
|
+
_index: a
|
|
73
|
+
})), v = (() => {
|
|
75
74
|
const t = [];
|
|
76
|
-
let
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
75
|
+
let a = [], e = 0;
|
|
76
|
+
return V.forEach((l) => {
|
|
77
|
+
if (l.span === "filled")
|
|
78
|
+
a.length > 0 ? (a.push({ ...l, span: f - e }), t.push(a), a = [], e = 0) : t.push([{ ...l, span: f }]);
|
|
79
|
+
else {
|
|
80
|
+
const p = l.span ?? 1, o = Math.min(p, f);
|
|
81
|
+
e + o > f ? (t.push(a), a = [l], e = o) : (a.push(l), e += o);
|
|
82
|
+
}
|
|
83
|
+
}), a.length > 0 && t.push(a), t;
|
|
84
|
+
})(), _ = (t) => [
|
|
85
|
+
i ? "border border-base-content/10" : "",
|
|
86
|
+
"bg-base-200/50 font-semibold text-base-content/70 text-left px-4 py-2",
|
|
87
|
+
u === "horizontal" ? "whitespace-nowrap" : "",
|
|
88
|
+
b?.label ?? "",
|
|
89
|
+
t.labelClassName ?? ""
|
|
90
|
+
].filter(Boolean).join(" "), j = (t) => [
|
|
91
|
+
i ? "border border-base-content/10" : "",
|
|
92
|
+
"bg-base-100 text-base-content px-4 py-2",
|
|
93
|
+
b?.content ?? "",
|
|
94
|
+
t.contentClassName ?? ""
|
|
95
|
+
].filter(Boolean).join(" "), N = (t) => ({
|
|
96
|
+
...F,
|
|
97
|
+
...t.labelStyle
|
|
98
|
+
}), L = (t) => ({
|
|
99
|
+
...O,
|
|
100
|
+
...t.contentStyle
|
|
101
|
+
}), A = () => v.map((t, a) => /* @__PURE__ */ y(g.Fragment, { children: [
|
|
102
|
+
/* @__PURE__ */ r("tr", { "data-testid": `${s}-row-${a}-labels`, children: t.map((e) => {
|
|
103
|
+
const l = typeof e.span == "number" ? e.span : 1, p = Math.min(l, f), o = `${w}-${e._key}-label`;
|
|
104
|
+
return /* @__PURE__ */ y(
|
|
105
|
+
"th",
|
|
106
|
+
{
|
|
107
|
+
id: o,
|
|
108
|
+
className: _(e),
|
|
109
|
+
style: N(e),
|
|
110
|
+
colSpan: p,
|
|
111
|
+
scope: "col",
|
|
112
|
+
"data-testid": `${s}-${e._key}-label`,
|
|
113
|
+
children: [
|
|
114
|
+
e.label,
|
|
115
|
+
C && e.label && /* @__PURE__ */ r("span", { "aria-hidden": "true", children: ":" })
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
e._key
|
|
119
|
+
);
|
|
120
|
+
}) }),
|
|
121
|
+
/* @__PURE__ */ r("tr", { "data-testid": `${s}-row-${a}-values`, children: t.map((e) => {
|
|
122
|
+
const l = typeof e.span == "number" ? e.span : 1, p = Math.min(l, f), o = `${w}-${e._key}-label`;
|
|
123
|
+
return /* @__PURE__ */ r(
|
|
124
|
+
"td",
|
|
125
|
+
{
|
|
126
|
+
className: j(e),
|
|
127
|
+
style: L(e),
|
|
128
|
+
colSpan: p,
|
|
129
|
+
"aria-labelledby": o,
|
|
130
|
+
"data-testid": `${s}-${e._key}-content`,
|
|
131
|
+
children: e.children
|
|
132
|
+
},
|
|
133
|
+
e._key
|
|
134
|
+
);
|
|
135
|
+
}) })
|
|
136
|
+
] }, t.map((e) => e._key).join("-"))), H = () => v.map((t, a) => /* @__PURE__ */ r("tr", { "data-testid": `${s}-row-${a}`, children: t.map((e) => {
|
|
137
|
+
const l = typeof e.span == "number" ? e.span : 1, p = Math.min(l, f), o = `${w}-${e._key}-label`;
|
|
138
|
+
return /* @__PURE__ */ y(g.Fragment, { children: [
|
|
139
|
+
/* @__PURE__ */ y(
|
|
140
|
+
"th",
|
|
141
|
+
{
|
|
142
|
+
id: o,
|
|
143
|
+
className: _(e),
|
|
144
|
+
style: N(e),
|
|
145
|
+
scope: "row",
|
|
146
|
+
"data-testid": `${s}-${e._key}-label`,
|
|
147
|
+
children: [
|
|
148
|
+
e.label,
|
|
149
|
+
C && e.label && /* @__PURE__ */ r("span", { "aria-hidden": "true", children: ":" })
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
/* @__PURE__ */ r(
|
|
154
|
+
"td",
|
|
155
|
+
{
|
|
156
|
+
className: j(e),
|
|
157
|
+
style: L(e),
|
|
158
|
+
colSpan: p > 1 ? p * 2 - 1 : 1,
|
|
159
|
+
"aria-labelledby": o,
|
|
160
|
+
"data-testid": `${s}-${e._key}-content`,
|
|
161
|
+
children: e.children
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
] }, e._key);
|
|
165
|
+
}) }, t.map((e) => e._key).join("-"))), K = [
|
|
166
|
+
"w-full",
|
|
167
|
+
i && "border-collapse",
|
|
168
|
+
U[k],
|
|
169
|
+
b?.table ?? "",
|
|
170
|
+
z
|
|
171
|
+
].filter(Boolean).join(" "), W = [b?.root ?? ""].filter(Boolean).join(" ");
|
|
172
|
+
return /* @__PURE__ */ y(
|
|
173
|
+
"div",
|
|
174
|
+
{
|
|
175
|
+
ref: M,
|
|
176
|
+
className: W || void 0,
|
|
177
|
+
style: { ...d?.root, ...B },
|
|
178
|
+
"data-testid": s,
|
|
179
|
+
...E,
|
|
180
|
+
children: [
|
|
181
|
+
(n || h) && /* @__PURE__ */ y(
|
|
182
|
+
"div",
|
|
85
183
|
{
|
|
86
|
-
className:
|
|
87
|
-
style:
|
|
88
|
-
|
|
184
|
+
className: `flex items-center justify-between mb-4 ${b?.header ?? ""}`,
|
|
185
|
+
style: d?.header,
|
|
186
|
+
"data-testid": `${s}-header`,
|
|
89
187
|
children: [
|
|
90
|
-
|
|
91
|
-
|
|
188
|
+
n && /* @__PURE__ */ r(
|
|
189
|
+
"div",
|
|
190
|
+
{
|
|
191
|
+
className: `text-lg font-semibold ${b?.title ?? ""}`,
|
|
192
|
+
style: d?.title,
|
|
193
|
+
"data-testid": `${s}-title`,
|
|
194
|
+
children: n
|
|
195
|
+
}
|
|
196
|
+
),
|
|
197
|
+
h && /* @__PURE__ */ r(
|
|
198
|
+
"div",
|
|
199
|
+
{
|
|
200
|
+
className: b?.extra ?? "",
|
|
201
|
+
style: d?.extra,
|
|
202
|
+
"data-testid": `${s}-extra`,
|
|
203
|
+
children: h
|
|
204
|
+
}
|
|
205
|
+
)
|
|
92
206
|
]
|
|
93
207
|
}
|
|
94
208
|
),
|
|
95
|
-
/* @__PURE__ */
|
|
96
|
-
"td",
|
|
97
|
-
{
|
|
98
|
-
className: `${d ? "border border-base-content/10" : ""} bg-base-100 px-4 py-2`,
|
|
99
|
-
style: A,
|
|
100
|
-
colSpan: p > 1 ? p * 2 - 1 : 1,
|
|
101
|
-
children: e.children
|
|
102
|
-
}
|
|
103
|
-
)
|
|
104
|
-
] }, f);
|
|
105
|
-
}) }, o));
|
|
106
|
-
}, V = [
|
|
107
|
-
"w-full",
|
|
108
|
-
d && "border-collapse",
|
|
109
|
-
O[$],
|
|
110
|
-
M
|
|
111
|
-
].filter(Boolean).join(" ");
|
|
112
|
-
return /* @__PURE__ */ i(
|
|
113
|
-
"div",
|
|
114
|
-
{
|
|
115
|
-
ref: z,
|
|
116
|
-
style: R,
|
|
117
|
-
"data-testid": u,
|
|
118
|
-
...L,
|
|
119
|
-
children: [
|
|
120
|
-
(c || S) && /* @__PURE__ */ i("div", { className: "flex items-center justify-between mb-4", "data-testid": `${u}-header`, children: [
|
|
121
|
-
c && /* @__PURE__ */ a("div", { className: "text-lg font-semibold", children: c }),
|
|
122
|
-
S && /* @__PURE__ */ a("div", { "data-testid": `${u}-extra`, children: S })
|
|
123
|
-
] }),
|
|
124
|
-
/* @__PURE__ */ a(
|
|
209
|
+
/* @__PURE__ */ y(
|
|
125
210
|
"table",
|
|
126
211
|
{
|
|
127
|
-
className:
|
|
128
|
-
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
|
|
212
|
+
className: K,
|
|
213
|
+
style: d?.table,
|
|
214
|
+
"data-testid": `${s}-table`,
|
|
215
|
+
children: [
|
|
216
|
+
n && /* @__PURE__ */ r("caption", { className: "sr-only", children: typeof n == "string" ? n : "Description list" }),
|
|
217
|
+
/* @__PURE__ */ r("tbody", { children: u === "vertical" ? A() : H() })
|
|
218
|
+
]
|
|
132
219
|
}
|
|
133
220
|
)
|
|
134
221
|
]
|
|
@@ -136,12 +223,12 @@ const O = {
|
|
|
136
223
|
);
|
|
137
224
|
}
|
|
138
225
|
);
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
Item:
|
|
226
|
+
R.displayName = "Descriptions";
|
|
227
|
+
const I = Object.assign(R, {
|
|
228
|
+
Item: T
|
|
142
229
|
});
|
|
143
230
|
export {
|
|
144
|
-
|
|
145
|
-
|
|
231
|
+
I as Descriptions,
|
|
232
|
+
I as default
|
|
146
233
|
};
|
|
147
234
|
//# sourceMappingURL=Descriptions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Descriptions.js","sources":["../../src/components/Descriptions.tsx"],"sourcesContent":["import React, { forwardRef } from 'react'\n\nexport type DescriptionsSize = 'sm' | 'md' | 'lg'\nexport type DescriptionsLayout = 'horizontal' | 'vertical'\n\nexport interface DescriptionsItemProps {\n /** Label for the item */\n label?: React.ReactNode\n /** Number of columns to span */\n span?: number\n /** Content of the item */\n children?: React.ReactNode\n /** Custom label styles */\n labelStyle?: React.CSSProperties\n /** Custom content styles */\n contentStyle?: React.CSSProperties\n}\n\n/** Item configuration for the items prop */\nexport interface DescriptionsItemConfig {\n /** Label for the item */\n label: React.ReactNode\n /** Content of the item */\n children: React.ReactNode\n /** Number of columns to span */\n span?: number\n /** Custom label styles */\n labelStyle?: React.CSSProperties\n /** Custom content styles */\n contentStyle?: React.CSSProperties\n}\n\nexport interface DescriptionsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Title of the descriptions block */\n title?: React.ReactNode\n /** Extra content in the top-right corner */\n extra?: React.ReactNode\n /** Show borders around cells */\n bordered?: boolean\n /** Number of columns (or responsive config) */\n column?: number | {\n xs?: number\n sm?: number\n md?: number\n lg?: number\n xl?: number\n '2xl'?: number\n }\n /** Size variant */\n size?: DescriptionsSize\n /** Layout direction */\n layout?: DescriptionsLayout\n /** Show colon after labels */\n colon?: boolean\n /** Default label styles */\n labelStyle?: React.CSSProperties\n /** Default content styles */\n contentStyle?: React.CSSProperties\n /** Item configurations (alternative to children) */\n items?: DescriptionsItemConfig[]\n /** Children (Descriptions.Item elements) */\n children?: React.ReactNode\n /** Test ID for the component */\n 'data-testid'?: string\n}\n\nfunction DescriptionsItem(_props: DescriptionsItemProps) {\n return null\n}\n\nconst sizeClasses: Record<DescriptionsSize, string> = {\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n}\n\nconst DescriptionsRoot = forwardRef<HTMLDivElement, DescriptionsProps>(\n (\n {\n title,\n extra,\n bordered = false,\n column = 3,\n size = 'md',\n layout = 'horizontal',\n colon = true,\n labelStyle,\n contentStyle,\n items: itemsProp,\n className = '',\n style,\n children,\n 'data-testid': testId = 'descriptions',\n ...rest\n },\n ref\n ) => {\n // Convert children to item configs, or use items prop\n const itemConfigs: DescriptionsItemConfig[] = itemsProp\n ? itemsProp\n : React.Children.toArray(children)\n .filter((child): child is React.ReactElement<DescriptionsItemProps> =>\n React.isValidElement(child)\n )\n .map((child) => ({\n label: child.props.label,\n children: child.props.children,\n span: child.props.span,\n labelStyle: child.props.labelStyle,\n contentStyle: child.props.contentStyle,\n }))\n\n const getColumnCount = () => {\n if (typeof column === 'number') {\n return column\n }\n return column.md || column.sm || column.xs || 3\n }\n\n const columnCount = getColumnCount()\n\n const renderVerticalLayout = () => {\n const rows: DescriptionsItemConfig[][] = []\n let currentRow: DescriptionsItemConfig[] = []\n let currentSpan = 0\n\n itemConfigs.forEach((item) => {\n const span = item.span || 1\n const effectiveSpan = Math.min(span, columnCount)\n\n if (currentSpan + effectiveSpan > columnCount) {\n rows.push(currentRow)\n currentRow = [item]\n currentSpan = effectiveSpan\n } else {\n currentRow.push(item)\n currentSpan += effectiveSpan\n }\n })\n\n if (currentRow.length > 0) {\n rows.push(currentRow)\n }\n\n return rows.map((row, rowIndex) => (\n <React.Fragment key={rowIndex}>\n <tr>\n {row.map((item, cellIndex) => {\n const span = item.span || 1\n const effectiveSpan = Math.min(span, columnCount)\n const itemLabelStyle = item.labelStyle || labelStyle\n\n return (\n <th\n key={cellIndex}\n className={`${bordered ? 'border border-base-content/10' : ''} bg-base-200/50 font-semibold text-left px-4 py-2`}\n style={itemLabelStyle}\n colSpan={effectiveSpan}\n scope=\"col\"\n >\n {item.label}\n {colon && item.label && ':'}\n </th>\n )\n })}\n </tr>\n <tr>\n {row.map((item, cellIndex) => {\n const span = item.span || 1\n const effectiveSpan = Math.min(span, columnCount)\n const itemContentStyle = item.contentStyle || contentStyle\n\n return (\n <td\n key={cellIndex}\n className={`${bordered ? 'border border-base-content/10' : ''} bg-base-100 px-4 py-2`}\n style={itemContentStyle}\n colSpan={effectiveSpan}\n >\n {item.children}\n </td>\n )\n })}\n </tr>\n </React.Fragment>\n ))\n }\n\n const renderHorizontalLayout = () => {\n const rows: DescriptionsItemConfig[][] = []\n let currentRow: DescriptionsItemConfig[] = []\n let currentSpan = 0\n\n itemConfigs.forEach((item) => {\n const span = item.span || 1\n const effectiveSpan = Math.min(span, columnCount)\n\n if (currentSpan + effectiveSpan > columnCount) {\n rows.push(currentRow)\n currentRow = [item]\n currentSpan = effectiveSpan\n } else {\n currentRow.push(item)\n currentSpan += effectiveSpan\n }\n })\n\n if (currentRow.length > 0) {\n rows.push(currentRow)\n }\n\n return rows.map((row, rowIndex) => (\n <tr key={rowIndex}>\n {row.map((item, cellIndex) => {\n const span = item.span || 1\n const effectiveSpan = Math.min(span, columnCount)\n const itemLabelStyle = item.labelStyle || labelStyle\n const itemContentStyle = item.contentStyle || contentStyle\n\n return (\n <React.Fragment key={cellIndex}>\n <th\n className={`${bordered ? 'border border-base-content/10' : ''} bg-base-200/50 font-semibold text-left px-4 py-2 whitespace-nowrap`}\n style={itemLabelStyle}\n scope=\"row\"\n >\n {item.label}\n {colon && item.label && ':'}\n </th>\n <td\n className={`${bordered ? 'border border-base-content/10' : ''} bg-base-100 px-4 py-2`}\n style={itemContentStyle}\n colSpan={effectiveSpan > 1 ? effectiveSpan * 2 - 1 : 1}\n >\n {item.children}\n </td>\n </React.Fragment>\n )\n })}\n </tr>\n ))\n }\n\n const containerClasses = [\n 'w-full',\n bordered && 'border-collapse',\n sizeClasses[size],\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <div\n ref={ref}\n style={style}\n data-testid={testId}\n {...rest}\n >\n {(title || extra) && (\n <div className=\"flex items-center justify-between mb-4\" data-testid={`${testId}-header`}>\n {title && (\n <div className=\"text-lg font-semibold\">{title}</div>\n )}\n {extra && (\n <div data-testid={`${testId}-extra`}>{extra}</div>\n )}\n </div>\n )}\n <table\n className={containerClasses}\n role=\"table\"\n aria-label={typeof title === 'string' ? title : undefined}\n data-testid={`${testId}-table`}\n >\n <tbody>\n {layout === 'vertical' ? renderVerticalLayout() : renderHorizontalLayout()}\n </tbody>\n </table>\n </div>\n )\n }\n)\n\nDescriptionsRoot.displayName = 'Descriptions'\n\nexport const Descriptions = Object.assign(DescriptionsRoot, {\n Item: DescriptionsItem,\n})\n\nexport default Descriptions\n"],"names":["DescriptionsItem","_props","sizeClasses","DescriptionsRoot","forwardRef","title","extra","bordered","column","size","layout","colon","labelStyle","contentStyle","itemsProp","className","style","children","testId","rest","ref","itemConfigs","React","child","columnCount","renderVerticalLayout","rows","currentRow","currentSpan","item","span","effectiveSpan","row","rowIndex","jsxs","jsx","cellIndex","itemLabelStyle","itemContentStyle","renderHorizontalLayout","containerClasses","Descriptions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Descriptions.js","sources":["../../src/components/Descriptions.tsx"],"sourcesContent":["import React, { forwardRef, useId, useEffect, useState } from 'react'\n\nexport type DescriptionsSize = 'sm' | 'md' | 'lg'\nexport type DescriptionsLayout = 'horizontal' | 'vertical'\n\nexport interface DescriptionsItemProps {\n /** Unique key for the item */\n itemKey?: string\n /** Label for the item */\n label?: React.ReactNode\n /** Number of columns to span, or 'filled' to fill remaining space */\n span?: number | 'filled'\n /** Content of the item */\n children?: React.ReactNode\n /** Custom label styles */\n labelStyle?: React.CSSProperties\n /** Custom content styles */\n contentStyle?: React.CSSProperties\n /** Custom label class */\n labelClassName?: string\n /** Custom content class */\n contentClassName?: string\n}\n\n/** Item configuration for the items prop */\nexport interface DescriptionsItemConfig {\n /** Unique key for the item (used for test IDs and React keys) */\n key?: string\n /** Label for the item */\n label: React.ReactNode\n /** Content of the item */\n children: React.ReactNode\n /** Number of columns to span, or 'filled' to fill remaining space */\n span?: number | 'filled'\n /** Custom label styles */\n labelStyle?: React.CSSProperties\n /** Custom content styles */\n contentStyle?: React.CSSProperties\n /** Custom label class */\n labelClassName?: string\n /** Custom content class */\n contentClassName?: string\n}\n\n/** Semantic DOM structure for styles/classNames */\nexport type DescriptionsSemanticDOM = 'root' | 'header' | 'title' | 'extra' | 'table' | 'label' | 'content'\n\nexport interface DescriptionsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Title of the descriptions block */\n title?: React.ReactNode\n /** Extra content in the top-right corner */\n extra?: React.ReactNode\n /** Show borders around cells */\n bordered?: boolean\n /** Number of columns (or responsive config) */\n column?: number | {\n xs?: number\n sm?: number\n md?: number\n lg?: number\n xl?: number\n '2xl'?: number\n }\n /** Size variant */\n size?: DescriptionsSize\n /** Layout direction */\n layout?: DescriptionsLayout\n /** Show colon after labels */\n colon?: boolean\n /** Default label styles (deprecated, use styles.label) */\n labelStyle?: React.CSSProperties\n /** Default content styles (deprecated, use styles.content) */\n contentStyle?: React.CSSProperties\n /** Semantic styles for component parts */\n styles?: Partial<Record<DescriptionsSemanticDOM, React.CSSProperties>>\n /** Semantic classNames for component parts */\n classNames?: Partial<Record<DescriptionsSemanticDOM, string>>\n /** Item configurations (alternative to children) */\n items?: DescriptionsItemConfig[]\n /** Children (Descriptions.Item elements) */\n children?: React.ReactNode\n /** Test ID for the component */\n 'data-testid'?: string\n}\n\nfunction DescriptionsItem(_props: DescriptionsItemProps) {\n // This component is used for the compound pattern\n // The parent Descriptions component extracts props from children\n return null\n}\n\nconst sizeClasses: Record<DescriptionsSize, string> = {\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n}\n\n// Breakpoint values in pixels (matches Tailwind defaults)\nconst breakpoints = {\n xs: 0,\n sm: 640,\n md: 768,\n lg: 1024,\n xl: 1280,\n '2xl': 1536,\n}\n\ntype BreakpointKey = keyof typeof breakpoints\n\nfunction useResponsiveColumn(\n column: number | Partial<Record<BreakpointKey, number>>\n): number {\n const [columnCount, setColumnCount] = useState(() => {\n if (typeof column === 'number') return column\n // SSR fallback: use md or first available\n return column.md ?? column.sm ?? column.xs ?? 3\n })\n\n useEffect(() => {\n if (typeof column === 'number') {\n setColumnCount(column)\n return\n }\n\n const updateColumns = () => {\n const width = window.innerWidth\n const sortedBreakpoints = (Object.keys(breakpoints) as BreakpointKey[])\n .filter((key) => column[key] !== undefined)\n .sort((a, b) => breakpoints[b] - breakpoints[a])\n\n for (const bp of sortedBreakpoints) {\n if (width >= breakpoints[bp]) {\n setColumnCount(column[bp]!)\n return\n }\n }\n // Fallback to smallest defined or 3\n const smallest = sortedBreakpoints[sortedBreakpoints.length - 1]\n setColumnCount(smallest ? column[smallest]! : 3)\n }\n\n updateColumns()\n window.addEventListener('resize', updateColumns)\n return () => window.removeEventListener('resize', updateColumns)\n }, [column])\n\n return columnCount\n}\n\n/** Internal item config with resolved key */\ninterface InternalItemConfig extends DescriptionsItemConfig {\n _key: string\n _index: number\n}\n\nconst DescriptionsRoot = forwardRef<HTMLDivElement, DescriptionsProps>(\n (\n {\n title,\n extra,\n bordered = false,\n column = 3,\n size = 'md',\n layout = 'horizontal',\n colon = true,\n labelStyle,\n contentStyle,\n styles,\n classNames,\n items: itemsProp,\n className = '',\n style,\n children,\n 'data-testid': testId = 'descriptions',\n ...rest\n },\n ref\n ) => {\n const baseId = useId()\n const columnCount = useResponsiveColumn(column)\n\n // Merge deprecated props with styles prop\n const mergedLabelStyle = { ...labelStyle, ...styles?.label }\n const mergedContentStyle = { ...contentStyle, ...styles?.content }\n\n // Convert children to item configs, or use items prop\n const itemConfigs: InternalItemConfig[] = (\n itemsProp\n ? itemsProp\n : React.Children.toArray(children)\n .filter((child): child is React.ReactElement<DescriptionsItemProps> =>\n React.isValidElement(child)\n )\n .map((child) => ({\n key: child.props.itemKey ?? child.key?.toString().replace(/^\\.\\$/, ''),\n label: child.props.label,\n children: child.props.children,\n span: child.props.span,\n labelStyle: child.props.labelStyle,\n contentStyle: child.props.contentStyle,\n labelClassName: child.props.labelClassName,\n contentClassName: child.props.contentClassName,\n }))\n ).map((item, index) => ({\n ...item,\n _key: item.key ?? `item-${index}`,\n _index: index,\n }))\n\n // Calculate rows with 'filled' span support\n const calculateRows = (): InternalItemConfig[][] => {\n const rows: InternalItemConfig[][] = []\n let currentRow: InternalItemConfig[] = []\n let currentSpan = 0\n\n itemConfigs.forEach((item) => {\n if (item.span === 'filled') {\n // 'filled' means fill the rest of the row\n if (currentRow.length > 0) {\n currentRow.push({ ...item, span: columnCount - currentSpan })\n rows.push(currentRow)\n currentRow = []\n currentSpan = 0\n } else {\n // First item in row with 'filled' takes whole row\n rows.push([{ ...item, span: columnCount }])\n }\n } else {\n const span = item.span ?? 1\n const effectiveSpan = Math.min(span, columnCount)\n\n if (currentSpan + effectiveSpan > columnCount) {\n rows.push(currentRow)\n currentRow = [item]\n currentSpan = effectiveSpan\n } else {\n currentRow.push(item)\n currentSpan += effectiveSpan\n }\n }\n })\n\n if (currentRow.length > 0) {\n rows.push(currentRow)\n }\n\n return rows\n }\n\n const rows = calculateRows()\n\n const getLabelClasses = (item: InternalItemConfig) => {\n return [\n bordered ? 'border border-base-content/10' : '',\n 'bg-base-200/50 font-semibold text-base-content/70 text-left px-4 py-2',\n layout === 'horizontal' ? 'whitespace-nowrap' : '',\n classNames?.label ?? '',\n item.labelClassName ?? '',\n ].filter(Boolean).join(' ')\n }\n\n const getContentClasses = (item: InternalItemConfig) => {\n return [\n bordered ? 'border border-base-content/10' : '',\n 'bg-base-100 text-base-content px-4 py-2',\n classNames?.content ?? '',\n item.contentClassName ?? '',\n ].filter(Boolean).join(' ')\n }\n\n const getLabelStyle = (item: InternalItemConfig): React.CSSProperties => ({\n ...mergedLabelStyle,\n ...item.labelStyle,\n })\n\n const getContentStyle = (item: InternalItemConfig): React.CSSProperties => ({\n ...mergedContentStyle,\n ...item.contentStyle,\n })\n\n const renderVerticalLayout = () => {\n return rows.map((row, rowIndex) => (\n <React.Fragment key={row.map(r => r._key).join('-')}>\n <tr data-testid={`${testId}-row-${rowIndex}-labels`}>\n {row.map((item) => {\n const span = typeof item.span === 'number' ? item.span : 1\n const effectiveSpan = Math.min(span, columnCount)\n const labelId = `${baseId}-${item._key}-label`\n\n return (\n <th\n key={item._key}\n id={labelId}\n className={getLabelClasses(item)}\n style={getLabelStyle(item)}\n colSpan={effectiveSpan}\n scope=\"col\"\n data-testid={`${testId}-${item._key}-label`}\n >\n {item.label}\n {colon && item.label && <span aria-hidden=\"true\">:</span>}\n </th>\n )\n })}\n </tr>\n <tr data-testid={`${testId}-row-${rowIndex}-values`}>\n {row.map((item) => {\n const span = typeof item.span === 'number' ? item.span : 1\n const effectiveSpan = Math.min(span, columnCount)\n const labelId = `${baseId}-${item._key}-label`\n\n return (\n <td\n key={item._key}\n className={getContentClasses(item)}\n style={getContentStyle(item)}\n colSpan={effectiveSpan}\n aria-labelledby={labelId}\n data-testid={`${testId}-${item._key}-content`}\n >\n {item.children}\n </td>\n )\n })}\n </tr>\n </React.Fragment>\n ))\n }\n\n const renderHorizontalLayout = () => {\n return rows.map((row, rowIndex) => (\n <tr key={row.map(r => r._key).join('-')} data-testid={`${testId}-row-${rowIndex}`}>\n {row.map((item) => {\n const span = typeof item.span === 'number' ? item.span : 1\n const effectiveSpan = Math.min(span, columnCount)\n const labelId = `${baseId}-${item._key}-label`\n\n return (\n <React.Fragment key={item._key}>\n <th\n id={labelId}\n className={getLabelClasses(item)}\n style={getLabelStyle(item)}\n scope=\"row\"\n data-testid={`${testId}-${item._key}-label`}\n >\n {item.label}\n {colon && item.label && <span aria-hidden=\"true\">:</span>}\n </th>\n <td\n className={getContentClasses(item)}\n style={getContentStyle(item)}\n colSpan={effectiveSpan > 1 ? effectiveSpan * 2 - 1 : 1}\n aria-labelledby={labelId}\n data-testid={`${testId}-${item._key}-content`}\n >\n {item.children}\n </td>\n </React.Fragment>\n )\n })}\n </tr>\n ))\n }\n\n const containerClasses = [\n 'w-full',\n bordered && 'border-collapse',\n sizeClasses[size],\n classNames?.table ?? '',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const rootClasses = [classNames?.root ?? ''].filter(Boolean).join(' ')\n\n return (\n <div\n ref={ref}\n className={rootClasses || undefined}\n style={{ ...styles?.root, ...style }}\n data-testid={testId}\n {...rest}\n >\n {(title || extra) && (\n <div\n className={`flex items-center justify-between mb-4 ${classNames?.header ?? ''}`}\n style={styles?.header}\n data-testid={`${testId}-header`}\n >\n {title && (\n <div\n className={`text-lg font-semibold ${classNames?.title ?? ''}`}\n style={styles?.title}\n data-testid={`${testId}-title`}\n >\n {title}\n </div>\n )}\n {extra && (\n <div\n className={classNames?.extra ?? ''}\n style={styles?.extra}\n data-testid={`${testId}-extra`}\n >\n {extra}\n </div>\n )}\n </div>\n )}\n <table\n className={containerClasses}\n style={styles?.table}\n data-testid={`${testId}-table`}\n >\n {title && (\n <caption className=\"sr-only\">\n {typeof title === 'string' ? title : 'Description list'}\n </caption>\n )}\n <tbody>\n {layout === 'vertical' ? renderVerticalLayout() : renderHorizontalLayout()}\n </tbody>\n </table>\n </div>\n )\n }\n)\n\nDescriptionsRoot.displayName = 'Descriptions'\n\nexport const Descriptions = Object.assign(DescriptionsRoot, {\n Item: DescriptionsItem,\n})\n\nexport default Descriptions\n"],"names":["DescriptionsItem","_props","sizeClasses","breakpoints","useResponsiveColumn","column","columnCount","setColumnCount","useState","useEffect","updateColumns","width","sortedBreakpoints","key","a","b","bp","smallest","DescriptionsRoot","forwardRef","title","extra","bordered","size","layout","colon","labelStyle","contentStyle","styles","classNames","itemsProp","className","style","children","testId","rest","ref","baseId","useId","mergedLabelStyle","mergedContentStyle","itemConfigs","React","child","item","index","rows","currentRow","currentSpan","span","effectiveSpan","getLabelClasses","getContentClasses","getLabelStyle","getContentStyle","renderVerticalLayout","row","rowIndex","jsxs","jsx","labelId","r","renderHorizontalLayout","containerClasses","rootClasses","Descriptions"],"mappings":"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"}
|
|
@@ -74,12 +74,12 @@ function v({ manager: t }) {
|
|
|
74
74
|
r[n.placement].push(n);
|
|
75
75
|
});
|
|
76
76
|
const a = {
|
|
77
|
-
topRight: "toast toast-top toast-end",
|
|
78
|
-
topLeft: "toast toast-top toast-start",
|
|
79
|
-
topCenter: "toast toast-top toast-center",
|
|
80
|
-
bottomRight: "toast toast-bottom toast-end",
|
|
81
|
-
bottomLeft: "toast toast-bottom toast-start",
|
|
82
|
-
bottomCenter: "toast toast-bottom toast-center"
|
|
77
|
+
topRight: "toast toast-top toast-end z-[9999]",
|
|
78
|
+
topLeft: "toast toast-top toast-start z-[9999]",
|
|
79
|
+
topCenter: "toast toast-top toast-center z-[9999]",
|
|
80
|
+
bottomRight: "toast toast-bottom toast-end z-[9999]",
|
|
81
|
+
bottomLeft: "toast toast-bottom toast-start z-[9999]",
|
|
82
|
+
bottomCenter: "toast toast-bottom toast-center z-[9999]"
|
|
83
83
|
};
|
|
84
84
|
return /* @__PURE__ */ s(d, { children: Object.entries(r).map(([n, i]) => i.length === 0 ? null : /* @__PURE__ */ s("div", { className: a[n], children: i.map((l) => /* @__PURE__ */ s(
|
|
85
85
|
w,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Notification.js","sources":["../../src/components/Notification.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\nimport ReactDOM from 'react-dom/client'\n\nexport type NotificationType = 'success' | 'info' | 'warning' | 'error'\nexport type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'topCenter' | 'bottomCenter'\nexport type NotificationVariant = 'default' | 'compact'\n\nexport interface NotificationConfig {\n message: React.ReactNode\n description?: React.ReactNode\n type?: NotificationType\n duration?: number // in seconds, 0 = no auto close\n placement?: NotificationPlacement\n variant?: NotificationVariant\n closable?: boolean\n icon?: React.ReactNode\n key?: string\n className?: string\n style?: React.CSSProperties\n 'data-testid'?: string\n onClick?: () => void\n onClose?: () => void\n}\n\ninterface NotificationItem extends NotificationConfig {\n id: string\n createdAt: number\n}\n\ntype Listener = () => void\n\nclass NotificationManager {\n private notifications: NotificationItem[] = []\n private listeners: Listener[] = []\n private container: HTMLDivElement | null = null\n private root: ReactDOM.Root | null = null\n private idCounter = 0\n\n subscribe(listener: Listener) {\n this.listeners.push(listener)\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener)\n }\n }\n\n getNotifications() {\n return this.notifications\n }\n\n private emit() {\n this.listeners.forEach((listener) => listener())\n }\n\n private ensureContainer() {\n if (!this.container) {\n this.container = document.createElement('div')\n document.body.appendChild(this.container)\n this.root = ReactDOM.createRoot(this.container)\n this.root.render(<NotificationContainer manager={this} />)\n }\n }\n\n open(config: NotificationConfig) {\n this.ensureContainer()\n\n const id = config.key ?? `notification-${++this.idCounter}`\n const isCompact = config.variant === 'compact'\n const notificationItem: NotificationItem = {\n ...config,\n id,\n createdAt: Date.now(),\n duration: config.duration ?? (isCompact ? 3 : 4.5),\n placement: config.placement ?? (isCompact ? 'topCenter' : 'topRight'),\n variant: config.variant ?? 'default',\n closable: config.closable ?? !isCompact,\n type: config.type ?? 'info',\n }\n\n // If key exists, update the existing notification\n const existingIndex = this.notifications.findIndex((n) => n.id === id)\n if (existingIndex !== -1) {\n this.notifications[existingIndex] = notificationItem\n } else {\n this.notifications.push(notificationItem)\n }\n this.emit()\n\n // Auto-dismiss\n if (notificationItem.duration && notificationItem.duration > 0) {\n setTimeout(() => {\n this.close(id)\n }, notificationItem.duration * 1000)\n }\n\n return id\n }\n\n close(id: string) {\n const notification = this.notifications.find((n) => n.id === id)\n this.notifications = this.notifications.filter((n) => n.id !== id)\n this.emit()\n\n if (notification?.onClose) {\n notification.onClose()\n }\n }\n\n success(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'success' })\n }\n\n error(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'error' })\n }\n\n info(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'info' })\n }\n\n warning(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'warning' })\n }\n\n destroy() {\n this.notifications = []\n this.emit()\n }\n}\n\ninterface NotificationContainerProps {\n manager: NotificationManager\n}\n\nfunction NotificationContainer({ manager }: NotificationContainerProps) {\n const [, forceUpdate] = useState({})\n\n useEffect(() => {\n const unsubscribe = manager.subscribe(() => {\n forceUpdate({})\n })\n return unsubscribe\n }, [manager])\n\n const notifications = manager.getNotifications()\n\n // Group by placement\n const grouped: Record<NotificationPlacement, NotificationItem[]> = {\n topLeft: [],\n topRight: [],\n topCenter: [],\n bottomLeft: [],\n bottomRight: [],\n bottomCenter: [],\n }\n\n notifications.forEach((notification) => {\n grouped[notification.placement!].push(notification)\n })\n\n const placementClasses: Record<NotificationPlacement, string> = {\n topRight: 'toast toast-top toast-end',\n topLeft: 'toast toast-top toast-start',\n topCenter: 'toast toast-top toast-center',\n bottomRight: 'toast toast-bottom toast-end',\n bottomLeft: 'toast toast-bottom toast-start',\n bottomCenter: 'toast toast-bottom toast-center',\n }\n\n return (\n <>\n {Object.entries(grouped).map(([placement, items]) => {\n if (items.length === 0) return null\n\n return (\n <div key={placement} className={placementClasses[placement as NotificationPlacement]}>\n {items.map((notification) => (\n <NotificationItem\n key={notification.id}\n notification={notification}\n onClose={() => manager.close(notification.id)}\n />\n ))}\n </div>\n )\n })}\n </>\n )\n}\n\ninterface NotificationItemProps {\n notification: NotificationItem\n onClose: () => void\n}\n\nfunction NotificationItem({ notification, onClose }: NotificationItemProps) {\n const isCompact = notification.variant === 'compact'\n\n const alertTypeClasses: Record<NotificationType, string> = {\n success: 'alert-success',\n error: 'alert-error',\n info: 'alert-info',\n warning: 'alert-warning',\n }\n\n const typeIcons: Record<NotificationType, React.ReactNode> = {\n success: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clipRule=\"evenodd\" /></svg>,\n error: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clipRule=\"evenodd\" /></svg>,\n info: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clipRule=\"evenodd\" /></svg>,\n warning: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clipRule=\"evenodd\" /></svg>,\n }\n\n const handleClick = () => {\n if (notification.onClick) {\n notification.onClick()\n }\n }\n\n const icon = notification.icon ?? typeIcons[notification.type!]\n\n if (isCompact) {\n return (\n <div\n className={`alert ${alertTypeClasses[notification.type!]} shadow-md py-2 px-4 cursor-pointer${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n >\n <div className=\"flex items-center gap-2\">\n {icon}\n <span>{notification.message}</span>\n </div>\n </div>\n )\n }\n\n return (\n <div\n className={`alert ${alertTypeClasses[notification.type!]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n >\n <div className={notification.closable ? 'pr-8' : ''}>\n {notification.message && <div className=\"font-bold\">{notification.message}</div>}\n {notification.description && <div className=\"text-sm\">{notification.description}</div>}\n </div>\n {notification.closable && (\n <button\n className=\"btn btn-xs btn-ghost btn-circle absolute top-2 right-2\"\n onClick={(e) => {\n e.stopPropagation()\n onClose()\n }}\n >\n ✕\n </button>\n )}\n </div>\n )\n}\n\nexport const notification = new NotificationManager()\n"],"names":["NotificationManager","listener","l","ReactDOM","jsx","NotificationContainer","config","id","isCompact","notificationItem","existingIndex","n","notification","manager","forceUpdate","useState","useEffect","notifications","grouped","placementClasses","Fragment","placement","items","NotificationItem","onClose","alertTypeClasses","typeIcons","handleClick","icon","jsxs","e"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Notification.js","sources":["../../src/components/Notification.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\nimport ReactDOM from 'react-dom/client'\n\nexport type NotificationType = 'success' | 'info' | 'warning' | 'error'\nexport type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'topCenter' | 'bottomCenter'\nexport type NotificationVariant = 'default' | 'compact'\n\nexport interface NotificationConfig {\n message: React.ReactNode\n description?: React.ReactNode\n type?: NotificationType\n duration?: number // in seconds, 0 = no auto close\n placement?: NotificationPlacement\n variant?: NotificationVariant\n closable?: boolean\n icon?: React.ReactNode\n key?: string\n className?: string\n style?: React.CSSProperties\n 'data-testid'?: string\n onClick?: () => void\n onClose?: () => void\n}\n\ninterface NotificationItem extends NotificationConfig {\n id: string\n createdAt: number\n}\n\ntype Listener = () => void\n\nclass NotificationManager {\n private notifications: NotificationItem[] = []\n private listeners: Listener[] = []\n private container: HTMLDivElement | null = null\n private root: ReactDOM.Root | null = null\n private idCounter = 0\n\n subscribe(listener: Listener) {\n this.listeners.push(listener)\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener)\n }\n }\n\n getNotifications() {\n return this.notifications\n }\n\n private emit() {\n this.listeners.forEach((listener) => listener())\n }\n\n private ensureContainer() {\n if (!this.container) {\n this.container = document.createElement('div')\n document.body.appendChild(this.container)\n this.root = ReactDOM.createRoot(this.container)\n this.root.render(<NotificationContainer manager={this} />)\n }\n }\n\n open(config: NotificationConfig) {\n this.ensureContainer()\n\n const id = config.key ?? `notification-${++this.idCounter}`\n const isCompact = config.variant === 'compact'\n const notificationItem: NotificationItem = {\n ...config,\n id,\n createdAt: Date.now(),\n duration: config.duration ?? (isCompact ? 3 : 4.5),\n placement: config.placement ?? (isCompact ? 'topCenter' : 'topRight'),\n variant: config.variant ?? 'default',\n closable: config.closable ?? !isCompact,\n type: config.type ?? 'info',\n }\n\n // If key exists, update the existing notification\n const existingIndex = this.notifications.findIndex((n) => n.id === id)\n if (existingIndex !== -1) {\n this.notifications[existingIndex] = notificationItem\n } else {\n this.notifications.push(notificationItem)\n }\n this.emit()\n\n // Auto-dismiss\n if (notificationItem.duration && notificationItem.duration > 0) {\n setTimeout(() => {\n this.close(id)\n }, notificationItem.duration * 1000)\n }\n\n return id\n }\n\n close(id: string) {\n const notification = this.notifications.find((n) => n.id === id)\n this.notifications = this.notifications.filter((n) => n.id !== id)\n this.emit()\n\n if (notification?.onClose) {\n notification.onClose()\n }\n }\n\n success(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'success' })\n }\n\n error(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'error' })\n }\n\n info(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'info' })\n }\n\n warning(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'warning' })\n }\n\n destroy() {\n this.notifications = []\n this.emit()\n }\n}\n\ninterface NotificationContainerProps {\n manager: NotificationManager\n}\n\nfunction NotificationContainer({ manager }: NotificationContainerProps) {\n const [, forceUpdate] = useState({})\n\n useEffect(() => {\n const unsubscribe = manager.subscribe(() => {\n forceUpdate({})\n })\n return unsubscribe\n }, [manager])\n\n const notifications = manager.getNotifications()\n\n // Group by placement\n const grouped: Record<NotificationPlacement, NotificationItem[]> = {\n topLeft: [],\n topRight: [],\n topCenter: [],\n bottomLeft: [],\n bottomRight: [],\n bottomCenter: [],\n }\n\n notifications.forEach((notification) => {\n grouped[notification.placement!].push(notification)\n })\n\n const placementClasses: Record<NotificationPlacement, string> = {\n topRight: 'toast toast-top toast-end z-[9999]',\n topLeft: 'toast toast-top toast-start z-[9999]',\n topCenter: 'toast toast-top toast-center z-[9999]',\n bottomRight: 'toast toast-bottom toast-end z-[9999]',\n bottomLeft: 'toast toast-bottom toast-start z-[9999]',\n bottomCenter: 'toast toast-bottom toast-center z-[9999]',\n }\n\n return (\n <>\n {Object.entries(grouped).map(([placement, items]) => {\n if (items.length === 0) return null\n\n return (\n <div key={placement} className={placementClasses[placement as NotificationPlacement]}>\n {items.map((notification) => (\n <NotificationItem\n key={notification.id}\n notification={notification}\n onClose={() => manager.close(notification.id)}\n />\n ))}\n </div>\n )\n })}\n </>\n )\n}\n\ninterface NotificationItemProps {\n notification: NotificationItem\n onClose: () => void\n}\n\nfunction NotificationItem({ notification, onClose }: NotificationItemProps) {\n const isCompact = notification.variant === 'compact'\n\n const alertTypeClasses: Record<NotificationType, string> = {\n success: 'alert-success',\n error: 'alert-error',\n info: 'alert-info',\n warning: 'alert-warning',\n }\n\n const typeIcons: Record<NotificationType, React.ReactNode> = {\n success: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clipRule=\"evenodd\" /></svg>,\n error: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clipRule=\"evenodd\" /></svg>,\n info: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clipRule=\"evenodd\" /></svg>,\n warning: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clipRule=\"evenodd\" /></svg>,\n }\n\n const handleClick = () => {\n if (notification.onClick) {\n notification.onClick()\n }\n }\n\n const icon = notification.icon ?? typeIcons[notification.type!]\n\n if (isCompact) {\n return (\n <div\n className={`alert ${alertTypeClasses[notification.type!]} shadow-md py-2 px-4 cursor-pointer${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n >\n <div className=\"flex items-center gap-2\">\n {icon}\n <span>{notification.message}</span>\n </div>\n </div>\n )\n }\n\n return (\n <div\n className={`alert ${alertTypeClasses[notification.type!]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n >\n <div className={notification.closable ? 'pr-8' : ''}>\n {notification.message && <div className=\"font-bold\">{notification.message}</div>}\n {notification.description && <div className=\"text-sm\">{notification.description}</div>}\n </div>\n {notification.closable && (\n <button\n className=\"btn btn-xs btn-ghost btn-circle absolute top-2 right-2\"\n onClick={(e) => {\n e.stopPropagation()\n onClose()\n }}\n >\n ✕\n </button>\n )}\n </div>\n )\n}\n\nexport const notification = new NotificationManager()\n"],"names":["NotificationManager","listener","l","ReactDOM","jsx","NotificationContainer","config","id","isCompact","notificationItem","existingIndex","n","notification","manager","forceUpdate","useState","useEffect","notifications","grouped","placementClasses","Fragment","placement","items","NotificationItem","onClose","alertTypeClasses","typeIcons","handleClick","icon","jsxs","e"],"mappings":"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"}
|
|
@@ -1,62 +1,60 @@
|
|
|
1
|
-
import { jsx as e, jsxs as
|
|
2
|
-
import { useRef as
|
|
3
|
-
import
|
|
4
|
-
const
|
|
5
|
-
value:
|
|
1
|
+
import { jsx as e, jsxs as b } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as R, useEffect as C } from "react";
|
|
3
|
+
import w from "qrcode";
|
|
4
|
+
const Q = ({
|
|
5
|
+
value: o,
|
|
6
6
|
size: a = 160,
|
|
7
7
|
errorLevel: v = "M",
|
|
8
|
-
icon:
|
|
8
|
+
icon: m,
|
|
9
9
|
iconSize: t = 40,
|
|
10
|
-
type:
|
|
11
|
-
color:
|
|
12
|
-
bgColor:
|
|
13
|
-
bordered:
|
|
14
|
-
status:
|
|
15
|
-
onRefresh:
|
|
16
|
-
className:
|
|
17
|
-
...
|
|
10
|
+
type: f = "canvas",
|
|
11
|
+
color: g = "#000000",
|
|
12
|
+
bgColor: h = "#FFFFFF",
|
|
13
|
+
bordered: n = !0,
|
|
14
|
+
status: s = "active",
|
|
15
|
+
onRefresh: x,
|
|
16
|
+
className: y = "",
|
|
17
|
+
...l
|
|
18
18
|
}) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}, [n]), R(() => {
|
|
23
|
-
if (n !== "active" || !m) return;
|
|
19
|
+
const c = R(null);
|
|
20
|
+
C(() => {
|
|
21
|
+
if (s !== "active" || !o || f !== "canvas") return;
|
|
24
22
|
(async () => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
if (c.current)
|
|
24
|
+
try {
|
|
25
|
+
if (await w.toCanvas(c.current, o, {
|
|
26
|
+
width: a,
|
|
27
|
+
margin: 1,
|
|
28
|
+
color: {
|
|
29
|
+
dark: g,
|
|
30
|
+
light: h
|
|
31
|
+
},
|
|
32
|
+
errorCorrectionLevel: v
|
|
33
|
+
}), m && c.current) {
|
|
34
|
+
const i = c.current.getContext("2d");
|
|
35
|
+
if (i) {
|
|
36
|
+
const d = new Image();
|
|
37
|
+
d.crossOrigin = "anonymous", d.onload = () => {
|
|
38
|
+
const u = (a - t) / 2, N = (a - t) / 2;
|
|
39
|
+
i.fillStyle = h, i.fillRect(u - 4, N - 4, t + 8, t + 8), i.drawImage(d, u, N, t, t);
|
|
40
|
+
}, d.src = m;
|
|
41
|
+
}
|
|
42
42
|
}
|
|
43
|
+
} catch (p) {
|
|
44
|
+
console.error("QR Code generation error:", p);
|
|
43
45
|
}
|
|
44
|
-
i(!1);
|
|
45
|
-
} catch (N) {
|
|
46
|
-
console.error("QR Code generation error:", N), i(!1);
|
|
47
|
-
}
|
|
48
46
|
})();
|
|
49
|
-
}, [
|
|
47
|
+
}, [o, a, v, m, t, f, g, h, s]);
|
|
50
48
|
const r = [
|
|
51
49
|
"inline-flex items-center justify-center",
|
|
52
|
-
|
|
50
|
+
n && "border border-base-content/20 p-3",
|
|
53
51
|
"bg-base-100",
|
|
54
|
-
|
|
52
|
+
y
|
|
55
53
|
].filter(Boolean).join(" ");
|
|
56
|
-
return
|
|
54
|
+
return s === "loading" ? /* @__PURE__ */ e("div", { className: r, style: { width: a + (n ? 24 : 0), height: a + (n ? 24 : 0) }, "data-state": "loading", ...l, children: /* @__PURE__ */ b("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
57
55
|
/* @__PURE__ */ e("span", { className: "loading loading-spinner loading-lg" }),
|
|
58
56
|
/* @__PURE__ */ e("span", { className: "text-sm text-base-content/70", children: "Loading..." })
|
|
59
|
-
] }) }) :
|
|
57
|
+
] }) }) : s === "expired" ? /* @__PURE__ */ e("div", { className: r, style: { width: a + (n ? 24 : 0), height: a + (n ? 24 : 0) }, "data-state": "expired", ...l, children: /* @__PURE__ */ b("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
60
58
|
/* @__PURE__ */ e("svg", { className: "w-12 h-12 text-base-content/30", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ e(
|
|
61
59
|
"path",
|
|
62
60
|
{
|
|
@@ -66,12 +64,12 @@ const k = ({
|
|
|
66
64
|
}
|
|
67
65
|
) }),
|
|
68
66
|
/* @__PURE__ */ e("span", { className: "text-sm text-base-content/70", children: "QR Code Expired" }),
|
|
69
|
-
|
|
70
|
-
] }) }) :
|
|
67
|
+
x && /* @__PURE__ */ e("button", { className: "btn btn-sm btn-primary", onClick: x, children: "Refresh" })
|
|
68
|
+
] }) }) : f === "canvas" ? /* @__PURE__ */ e("div", { className: "inline-block", "data-state": "active", ...l, children: /* @__PURE__ */ e("div", { className: r, children: /* @__PURE__ */ e("canvas", { ref: c, style: { display: "block" } }) }) }) : /* @__PURE__ */ e("div", { className: "inline-block", "data-state": "active", ...l, children: /* @__PURE__ */ e("div", { className: r, children: /* @__PURE__ */ e("div", { style: { width: a, height: a }, className: "bg-base-content/5", children: /* @__PURE__ */ e("span", { className: "text-xs text-base-content/50", children: "SVG mode placeholder" }) }) }) });
|
|
71
69
|
};
|
|
72
|
-
|
|
70
|
+
Q.displayName = "QRCode";
|
|
73
71
|
export {
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
Q as QRCode,
|
|
73
|
+
Q as default
|
|
76
74
|
};
|
|
77
75
|
//# sourceMappingURL=QRCode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QRCode.js","sources":["../../src/components/QRCode.tsx"],"sourcesContent":["import React, { useEffect, useRef
|
|
1
|
+
{"version":3,"file":"QRCode.js","sources":["../../src/components/QRCode.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react'\nimport QRCodeLib from 'qrcode'\n\nexport type QRCodeErrorLevel = 'L' | 'M' | 'Q' | 'H'\nexport type QRCodeType = 'canvas' | 'svg'\nexport type QRCodeStatus = 'active' | 'loading' | 'expired'\n\nexport interface QRCodeProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'> {\n value: string\n size?: number\n errorLevel?: QRCodeErrorLevel\n icon?: string\n iconSize?: number\n type?: QRCodeType\n color?: string\n bgColor?: string\n bordered?: boolean\n status?: QRCodeStatus\n onRefresh?: () => void\n}\n\nexport const QRCode: React.FC<QRCodeProps> = ({\n value,\n size = 160,\n errorLevel = 'M',\n icon,\n iconSize = 40,\n type = 'canvas',\n color = '#000000',\n bgColor = '#FFFFFF',\n bordered = true,\n status = 'active',\n onRefresh,\n className = '',\n ...rest\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n\n useEffect(() => {\n if (status !== 'active' || !value || type !== 'canvas') return\n\n const generateQRCode = async () => {\n if (!canvasRef.current) return\n\n try {\n await QRCodeLib.toCanvas(canvasRef.current, value, {\n width: size,\n margin: 1,\n color: {\n dark: color,\n light: bgColor,\n },\n errorCorrectionLevel: errorLevel,\n })\n\n if (icon && canvasRef.current) {\n const canvas = canvasRef.current\n const ctx = canvas.getContext('2d')\n if (ctx) {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n img.onload = () => {\n const iconX = (size - iconSize) / 2\n const iconY = (size - iconSize) / 2\n ctx.fillStyle = bgColor\n ctx.fillRect(iconX - 4, iconY - 4, iconSize + 8, iconSize + 8)\n ctx.drawImage(img, iconX, iconY, iconSize, iconSize)\n }\n img.src = icon\n }\n }\n } catch (error) {\n console.error('QR Code generation error:', error)\n }\n }\n\n generateQRCode()\n }, [value, size, errorLevel, icon, iconSize, type, color, bgColor, status])\n\n // Download functionality can be implemented by consumers\n // by accessing the canvas ref and converting to data URL\n\n const containerClasses = [\n 'inline-flex items-center justify-center',\n bordered && 'border border-base-content/20 p-3',\n 'bg-base-100',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n if (status === 'loading') {\n return (\n <div className={containerClasses} style={{ width: size + (bordered ? 24 : 0), height: size + (bordered ? 24 : 0) }} data-state=\"loading\" {...rest}>\n <div className=\"flex flex-col items-center justify-center gap-2\">\n <span className=\"loading loading-spinner loading-lg\"></span>\n <span className=\"text-sm text-base-content/70\">Loading...</span>\n </div>\n </div>\n )\n }\n\n if (status === 'expired') {\n return (\n <div className={containerClasses} style={{ width: size + (bordered ? 24 : 0), height: size + (bordered ? 24 : 0) }} data-state=\"expired\" {...rest}>\n <div className=\"flex flex-col items-center justify-center gap-2\">\n <svg className=\"w-12 h-12 text-base-content/30\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n <path\n fillRule=\"evenodd\"\n d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n <span className=\"text-sm text-base-content/70\">QR Code Expired</span>\n {onRefresh && (\n <button className=\"btn btn-sm btn-primary\" onClick={onRefresh}>\n Refresh\n </button>\n )}\n </div>\n </div>\n )\n }\n\n if (type === 'canvas') {\n return (\n <div className=\"inline-block\" data-state=\"active\" {...rest}>\n <div className={containerClasses}>\n <canvas ref={canvasRef} style={{ display: 'block' }} />\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"inline-block\" data-state=\"active\" {...rest}>\n <div className={containerClasses}>\n <div style={{ width: size, height: size }} className=\"bg-base-content/5\">\n <span className=\"text-xs text-base-content/50\">SVG mode placeholder</span>\n </div>\n </div>\n </div>\n )\n}\n\nQRCode.displayName = 'QRCode'\n\nexport default QRCode\n"],"names":["QRCode","value","size","errorLevel","icon","iconSize","type","color","bgColor","bordered","status","onRefresh","className","rest","canvasRef","useRef","useEffect","QRCodeLib","ctx","img","iconX","iconY","error","containerClasses","jsx","jsxs"],"mappings":"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"}
|