asterui 0.12.32 → 0.12.35
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/README.md +89 -47
- package/dist/components/Drawer.d.ts +34 -4
- package/dist/components/Drawer.js +240 -169
- package/dist/components/Drawer.js.map +1 -1
- package/dist/components/Layout.d.ts +40 -32
- package/dist/components/Layout.js +178 -130
- package/dist/components/Layout.js.map +1 -1
- package/dist/components/QRCode.js +55 -44
- package/dist/components/QRCode.js.map +1 -1
- package/dist/components/ResponsiveDrawer.d.ts +34 -0
- package/dist/components/ResponsiveDrawer.js +75 -0
- package/dist/components/ResponsiveDrawer.js.map +1 -0
- package/dist/components/Space.js +5 -5
- package/dist/components/Space.js.map +1 -1
- package/dist/index.d.ts +4 -6
- package/dist/index.js +127 -129
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/PageLayout.d.ts +0 -9
- package/dist/components/PageLayout.js +0 -35
- package/dist/components/PageLayout.js.map +0 -1
- package/dist/components/SidebarDrawer.d.ts +0 -21
- package/dist/components/SidebarDrawer.js +0 -44
- package/dist/components/SidebarDrawer.js.map +0 -1
|
@@ -1,140 +1,188 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import
|
|
3
|
-
const
|
|
4
|
-
function
|
|
5
|
-
return
|
|
1
|
+
import { jsx as a, jsxs as Q } from "react/jsx-runtime";
|
|
2
|
+
import N, { forwardRef as y, useContext as Z, createContext as _, useState as S, useEffect as q, useCallback as G } from "react";
|
|
3
|
+
const B = _(null);
|
|
4
|
+
function I() {
|
|
5
|
+
return Z(B);
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
7
|
+
const v = y(
|
|
8
|
+
({ children: s, hasSider: o, className: n = "", "data-testid": e, ...l }, r) => {
|
|
9
|
+
const d = N.Children.toArray(s), f = d.some(
|
|
10
|
+
(t) => N.isValidElement(t) && t.type.displayName === "LayoutSider"
|
|
11
|
+
), c = o ?? f, p = [
|
|
12
|
+
"flex",
|
|
13
|
+
"min-h-0",
|
|
14
|
+
c ? "flex-row" : "flex-col",
|
|
15
|
+
n
|
|
16
|
+
].filter(Boolean).join(" "), b = c ? d.map((t) => {
|
|
17
|
+
if (N.isValidElement(t) && (t.type === v || t.type.displayName === "LayoutRoot") && t.type.displayName !== "LayoutSider") {
|
|
18
|
+
const g = t.props.className || "";
|
|
19
|
+
if (!g.includes("flex-1"))
|
|
20
|
+
return N.cloneElement(t, {
|
|
21
|
+
className: `flex-1 ${g}`.trim()
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
}) : s;
|
|
26
|
+
return /* @__PURE__ */ a("div", { ref: r, className: p, "data-testid": e, ...l, children: b });
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
v.displayName = "LayoutRoot";
|
|
30
|
+
const E = y(
|
|
31
|
+
({ children: s, className: o = "", "data-testid": n, ...e }, l) => {
|
|
32
|
+
const r = [
|
|
33
|
+
"flex",
|
|
34
|
+
"items-center",
|
|
35
|
+
"px-6",
|
|
36
|
+
"h-16",
|
|
37
|
+
"bg-base-300",
|
|
38
|
+
"flex-shrink-0",
|
|
39
|
+
o
|
|
40
|
+
].filter(Boolean).join(" ");
|
|
41
|
+
return /* @__PURE__ */ a("header", { ref: l, className: r, "data-testid": n, ...e, children: s });
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
E.displayName = "LayoutHeader";
|
|
45
|
+
const R = y(
|
|
46
|
+
({ children: s, className: o = "", "data-testid": n, ...e }, l) => {
|
|
47
|
+
const r = [
|
|
48
|
+
"px-6",
|
|
49
|
+
"py-4",
|
|
50
|
+
"text-center",
|
|
51
|
+
"bg-base-300",
|
|
52
|
+
"flex-shrink-0",
|
|
53
|
+
o
|
|
54
|
+
].filter(Boolean).join(" ");
|
|
55
|
+
return /* @__PURE__ */ a("footer", { ref: l, className: r, "data-testid": n, ...e, children: s });
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
R.displayName = "LayoutFooter";
|
|
59
|
+
const $ = y(
|
|
60
|
+
({ children: s, className: o = "", "data-testid": n, ...e }, l) => {
|
|
61
|
+
const r = ["flex-1", "min-h-0", "overflow-auto", o].filter(Boolean).join(" ");
|
|
62
|
+
return /* @__PURE__ */ a("main", { ref: l, className: r, "data-testid": n, ...e, children: s });
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
$.displayName = "LayoutContent";
|
|
66
|
+
const J = {
|
|
56
67
|
sm: "(max-width: 639px)",
|
|
57
68
|
md: "(max-width: 767px)",
|
|
58
69
|
lg: "(max-width: 1023px)",
|
|
59
70
|
xl: "(max-width: 1279px)",
|
|
60
71
|
"2xl": "(max-width: 1535px)"
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
"
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
72
|
+
}, A = y(
|
|
73
|
+
({
|
|
74
|
+
children: s,
|
|
75
|
+
width: o = 200,
|
|
76
|
+
collapsedWidth: n = 80,
|
|
77
|
+
collapsed: e,
|
|
78
|
+
defaultCollapsed: l = !1,
|
|
79
|
+
collapsible: r = !1,
|
|
80
|
+
onCollapse: d,
|
|
81
|
+
trigger: f,
|
|
82
|
+
breakpoint: c,
|
|
83
|
+
onBreakpoint: p,
|
|
84
|
+
reverseArrow: b = !1,
|
|
85
|
+
theme: t = "dark",
|
|
86
|
+
zeroWidthTriggerStyle: g,
|
|
87
|
+
className: M = "",
|
|
88
|
+
style: T,
|
|
89
|
+
"data-testid": x,
|
|
90
|
+
...W
|
|
91
|
+
}, z) => {
|
|
92
|
+
const [F, L] = S(l), [w, H] = S(!1), i = e ?? F;
|
|
93
|
+
q(() => {
|
|
94
|
+
if (!c) return;
|
|
95
|
+
const m = window.matchMedia(J[c]), C = (K) => {
|
|
96
|
+
const h = K.matches;
|
|
97
|
+
H(h), p?.(h), e === void 0 && L(h), h !== w && d?.(h, "responsive");
|
|
98
|
+
};
|
|
99
|
+
return C(m), m.addEventListener("change", C), () => m.removeEventListener("change", C);
|
|
100
|
+
}, [c, p, e, d, w]);
|
|
101
|
+
const k = G(() => {
|
|
102
|
+
const m = !i;
|
|
103
|
+
e === void 0 && L(m), d?.(m, "clickTrigger");
|
|
104
|
+
}, [i, e, d]), u = i ? n : o, j = u === 0 || u === "0" || u === "0px", P = [
|
|
105
|
+
"flex",
|
|
106
|
+
"flex-col",
|
|
107
|
+
{
|
|
108
|
+
light: "bg-base-100",
|
|
109
|
+
dark: "bg-base-200"
|
|
110
|
+
}[t],
|
|
111
|
+
"flex-shrink-0",
|
|
112
|
+
"transition-all",
|
|
113
|
+
"duration-200",
|
|
114
|
+
"relative",
|
|
115
|
+
M
|
|
116
|
+
].filter(Boolean).join(" "), O = () => b ? i ? "" : "rotate-180" : i ? "rotate-180" : "", V = r && f !== null && /* @__PURE__ */ a(
|
|
117
|
+
"button",
|
|
118
|
+
{
|
|
119
|
+
onClick: k,
|
|
120
|
+
className: "flex items-center justify-center h-10 w-full bg-base-300 hover:bg-base-content/10 transition-colors",
|
|
121
|
+
"aria-label": i ? "Expand sidebar" : "Collapse sidebar",
|
|
122
|
+
"data-testid": x ? `${x}-trigger` : void 0,
|
|
123
|
+
children: /* @__PURE__ */ a(
|
|
124
|
+
"svg",
|
|
125
|
+
{
|
|
126
|
+
className: `w-4 h-4 transition-transform ${O()}`,
|
|
127
|
+
fill: "none",
|
|
128
|
+
viewBox: "0 0 24 24",
|
|
129
|
+
stroke: "currentColor",
|
|
130
|
+
children: /* @__PURE__ */ a("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" })
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
), D = r && j && i && /* @__PURE__ */ a(
|
|
135
|
+
"button",
|
|
136
|
+
{
|
|
137
|
+
onClick: k,
|
|
138
|
+
className: "absolute top-1/2 -translate-y-1/2 right-0 translate-x-full w-6 h-12 flex items-center justify-center bg-base-300 hover:bg-base-content/10 transition-colors rounded-r z-10",
|
|
139
|
+
"aria-label": "Expand sidebar",
|
|
140
|
+
style: g,
|
|
141
|
+
"data-testid": x ? `${x}-zero-trigger` : void 0,
|
|
142
|
+
children: /* @__PURE__ */ a(
|
|
143
|
+
"svg",
|
|
144
|
+
{
|
|
145
|
+
className: `w-3 h-3 ${b ? "rotate-180" : ""}`,
|
|
146
|
+
fill: "none",
|
|
147
|
+
viewBox: "0 0 24 24",
|
|
148
|
+
stroke: "currentColor",
|
|
149
|
+
children: /* @__PURE__ */ a("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
return /* @__PURE__ */ a(B.Provider, { value: { collapsed: i, collapsedWidth: n, width: o }, children: /* @__PURE__ */ Q(
|
|
155
|
+
"aside",
|
|
156
|
+
{
|
|
157
|
+
ref: z,
|
|
158
|
+
className: P,
|
|
159
|
+
style: {
|
|
160
|
+
width: typeof u == "number" ? `${u}px` : u,
|
|
161
|
+
...T
|
|
162
|
+
},
|
|
163
|
+
"data-collapsed": i,
|
|
164
|
+
"data-theme": t,
|
|
165
|
+
"data-testid": x,
|
|
166
|
+
"aria-expanded": !i,
|
|
167
|
+
...W,
|
|
168
|
+
children: [
|
|
169
|
+
/* @__PURE__ */ a("div", { className: "flex-1 overflow-auto", children: s }),
|
|
170
|
+
!j && f !== null && (f ?? V),
|
|
171
|
+
D
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
) });
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
A.displayName = "LayoutSider";
|
|
178
|
+
const ee = Object.assign(v, {
|
|
179
|
+
Header: E,
|
|
180
|
+
Footer: R,
|
|
181
|
+
Content: $,
|
|
182
|
+
Sider: A
|
|
135
183
|
});
|
|
136
184
|
export {
|
|
137
|
-
|
|
138
|
-
|
|
185
|
+
ee as Layout,
|
|
186
|
+
I as useSiderContext
|
|
139
187
|
};
|
|
140
188
|
//# sourceMappingURL=Layout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layout.js","sources":["../../src/components/Layout.tsx"],"sourcesContent":["import React, { createContext, useContext, useState, useCallback, useEffect } from 'react'\n\nexport interface LayoutProps {\n children: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\nexport interface LayoutHeaderProps {\n children: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\nexport interface LayoutFooterProps {\n children: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\nexport interface LayoutContentProps {\n children: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\nexport interface LayoutSiderProps {\n children: React.ReactNode\n width?: number | string\n collapsedWidth?: number | string\n collapsed?: boolean\n defaultCollapsed?: boolean\n collapsible?: boolean\n onCollapse?: (collapsed: boolean) => void\n trigger?: React.ReactNode | null\n breakpoint?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n onBreakpoint?: (broken: boolean) => void\n className?: string\n style?: React.CSSProperties\n}\n\ninterface SiderContextValue {\n collapsed: boolean\n collapsedWidth: number | string\n width: number | string\n}\n\nconst SiderContext = createContext<SiderContextValue | null>(null)\n\nexport function useSiderContext() {\n return useContext(SiderContext)\n}\n\nfunction LayoutRoot({ children, className = '', style }: LayoutProps) {\n // Check if any child is a Sider to determine flex direction\n const childArray = React.Children.toArray(children)\n const hasSider = childArray.some(\n (child) => React.isValidElement(child) && (child.type as any).displayName === 'LayoutSider'\n )\n\n const layoutClasses = [\n 'flex',\n 'min-h-0',\n hasSider ? 'flex-row' : 'flex-col',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n // If we have a Sider, auto-add flex-1 to non-Sider Layout children\n const processedChildren = hasSider\n ? childArray.map((child) => {\n if (\n React.isValidElement(child) &&\n (child.type === LayoutRoot || (child.type as any).displayName === 'LayoutRoot') &&\n (child.type as any).displayName !== 'LayoutSider'\n ) {\n // Clone the Layout child and add flex-1 if not already present\n const existingClassName = (child.props as any).className || ''\n if (!existingClassName.includes('flex-1')) {\n return React.cloneElement(child as React.ReactElement<any>, {\n className: `flex-1 ${existingClassName}`.trim(),\n })\n }\n }\n return child\n })\n : children\n\n return (\n <div className={layoutClasses} style={style}>\n {processedChildren}\n </div>\n )\n}\n\nLayoutRoot.displayName = 'LayoutRoot'\n\nfunction LayoutHeader({ children, className = '', style }: LayoutHeaderProps) {\n const headerClasses = [\n 'flex',\n 'items-center',\n 'px-6',\n 'h-16',\n 'bg-base-300',\n 'flex-shrink-0',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <header className={headerClasses} style={style}>\n {children}\n </header>\n )\n}\n\nfunction LayoutFooter({ children, className = '', style }: LayoutFooterProps) {\n const footerClasses = [\n 'px-6',\n 'py-4',\n 'text-center',\n 'bg-base-300',\n 'flex-shrink-0',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <footer className={footerClasses} style={style}>\n {children}\n </footer>\n )\n}\n\nfunction LayoutContent({ children, className = '', style }: LayoutContentProps) {\n // flex-1 by default so Content fills available space\n const contentClasses = ['flex-1', 'min-h-0', 'overflow-auto', className].filter(Boolean).join(' ')\n\n return (\n <main className={contentClasses} style={style}>\n {children}\n </main>\n )\n}\n\nconst BREAKPOINT_MAP: Record<string, string> = {\n sm: '(max-width: 639px)',\n md: '(max-width: 767px)',\n lg: '(max-width: 1023px)',\n xl: '(max-width: 1279px)',\n '2xl': '(max-width: 1535px)',\n}\n\nfunction LayoutSider({\n children,\n width = 200,\n collapsedWidth = 80,\n collapsed: controlledCollapsed,\n defaultCollapsed = false,\n collapsible = false,\n onCollapse,\n trigger,\n breakpoint,\n onBreakpoint,\n className = '',\n style,\n}: LayoutSiderProps) {\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed)\n const [broken, setBroken] = useState(false)\n\n const collapsed = controlledCollapsed ?? internalCollapsed\n\n // Handle responsive breakpoint\n useEffect(() => {\n if (!breakpoint) return\n\n const mediaQuery = window.matchMedia(BREAKPOINT_MAP[breakpoint])\n\n const handleChange = (e: MediaQueryListEvent | MediaQueryList) => {\n const isBroken = e.matches\n setBroken(isBroken)\n onBreakpoint?.(isBroken)\n\n // Auto-collapse when breakpoint is crossed\n if (controlledCollapsed === undefined) {\n setInternalCollapsed(isBroken)\n }\n if (isBroken !== broken) {\n onCollapse?.(isBroken)\n }\n }\n\n // Check initial state\n handleChange(mediaQuery)\n\n // Listen for changes\n mediaQuery.addEventListener('change', handleChange)\n return () => mediaQuery.removeEventListener('change', handleChange)\n }, [breakpoint, onBreakpoint, controlledCollapsed, onCollapse, broken])\n\n const handleCollapse = useCallback(() => {\n const newCollapsed = !collapsed\n if (controlledCollapsed === undefined) {\n setInternalCollapsed(newCollapsed)\n }\n onCollapse?.(newCollapsed)\n }, [collapsed, controlledCollapsed, onCollapse])\n\n const currentWidth = collapsed ? collapsedWidth : width\n\n const siderClasses = [\n 'flex',\n 'flex-col',\n 'bg-base-200',\n 'flex-shrink-0',\n 'transition-all',\n 'duration-200',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const defaultTrigger = collapsible && trigger !== null && (\n <button\n onClick={handleCollapse}\n className=\"flex items-center justify-center h-10 w-full bg-base-300 hover:bg-base-content/10 transition-colors\"\n aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n >\n <svg\n className={`w-4 h-4 transition-transform ${collapsed ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n )\n\n return (\n <SiderContext.Provider value={{ collapsed, collapsedWidth, width }}>\n <aside\n className={siderClasses}\n style={{\n width: typeof currentWidth === 'number' ? `${currentWidth}px` : currentWidth,\n ...style,\n }}\n >\n <div className=\"flex-1 overflow-auto\">{children}</div>\n {trigger !== null && (trigger ?? defaultTrigger)}\n </aside>\n </SiderContext.Provider>\n )\n}\n\nLayoutSider.displayName = 'LayoutSider'\n\nexport const Layout = Object.assign(LayoutRoot, {\n Header: LayoutHeader,\n Footer: LayoutFooter,\n Content: LayoutContent,\n Sider: LayoutSider,\n})\n"],"names":["SiderContext","createContext","useSiderContext","useContext","LayoutRoot","children","className","style","childArray","React","hasSider","child","layoutClasses","processedChildren","existingClassName","jsx","LayoutHeader","headerClasses","LayoutFooter","footerClasses","LayoutContent","contentClasses","BREAKPOINT_MAP","LayoutSider","width","collapsedWidth","controlledCollapsed","defaultCollapsed","collapsible","onCollapse","trigger","breakpoint","onBreakpoint","internalCollapsed","setInternalCollapsed","useState","broken","setBroken","collapsed","useEffect","mediaQuery","handleChange","e","isBroken","handleCollapse","useCallback","newCollapsed","currentWidth","siderClasses","defaultTrigger","jsxs","Layout"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Layout.js","sources":["../../src/components/Layout.tsx"],"sourcesContent":["import React, { createContext, useContext, useState, useCallback, useEffect, forwardRef } from 'react'\n\nexport type SiderTheme = 'light' | 'dark'\nexport type SiderCollapsedType = 'clickTrigger' | 'responsive'\n\nexport interface LayoutProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n /** Whether contains Sider (auto-detected if not specified) */\n hasSider?: boolean\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nexport interface LayoutHeaderProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nexport interface LayoutFooterProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nexport interface LayoutContentProps extends React.HTMLAttributes<HTMLElement> {\n children: React.ReactNode\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nexport interface LayoutSiderProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onSelect'> {\n children: React.ReactNode\n /** Width of the sider */\n width?: number | string\n /** Width when collapsed */\n collapsedWidth?: number | string\n /** Controlled collapsed state */\n collapsed?: boolean\n /** Initial collapsed state (uncontrolled) */\n defaultCollapsed?: boolean\n /** Whether can be collapsed */\n collapsible?: boolean\n /** Callback when collapse state changes */\n onCollapse?: (collapsed: boolean, type: SiderCollapsedType) => void\n /** Custom trigger element (null to hide) */\n trigger?: React.ReactNode | null\n /** Responsive breakpoint for auto-collapse */\n breakpoint?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'\n /** Callback when breakpoint is crossed */\n onBreakpoint?: (broken: boolean) => void\n /** Reverse direction of arrow (for right-side sider) */\n reverseArrow?: boolean\n /** Color theme of the sider */\n theme?: SiderTheme\n /** Style for zero-width trigger */\n zeroWidthTriggerStyle?: React.CSSProperties\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\ninterface SiderContextValue {\n collapsed: boolean\n collapsedWidth: number | string\n width: number | string\n}\n\nconst SiderContext = createContext<SiderContextValue | null>(null)\n\nexport function useSiderContext() {\n return useContext(SiderContext)\n}\n\nconst LayoutRoot = forwardRef<HTMLDivElement, LayoutProps>(\n ({ children, hasSider: hasSiderProp, className = '', 'data-testid': testId, ...rest }, ref) => {\n // Check if any child is a Sider to determine flex direction\n const childArray = React.Children.toArray(children)\n const hasSiderDetected = childArray.some(\n (child) => React.isValidElement(child) && (child.type as any).displayName === 'LayoutSider'\n )\n const hasSider = hasSiderProp ?? hasSiderDetected\n\n const layoutClasses = [\n 'flex',\n 'min-h-0',\n hasSider ? 'flex-row' : 'flex-col',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n // If we have a Sider, auto-add flex-1 to non-Sider Layout children\n const processedChildren = hasSider\n ? childArray.map((child) => {\n if (\n React.isValidElement(child) &&\n (child.type === LayoutRoot || (child.type as any).displayName === 'LayoutRoot') &&\n (child.type as any).displayName !== 'LayoutSider'\n ) {\n // Clone the Layout child and add flex-1 if not already present\n const existingClassName = (child.props as any).className || ''\n if (!existingClassName.includes('flex-1')) {\n return React.cloneElement(child as React.ReactElement<any>, {\n className: `flex-1 ${existingClassName}`.trim(),\n })\n }\n }\n return child\n })\n : children\n\n return (\n <div ref={ref} className={layoutClasses} data-testid={testId} {...rest}>\n {processedChildren}\n </div>\n )\n }\n)\n\nLayoutRoot.displayName = 'LayoutRoot'\n\nconst LayoutHeader = forwardRef<HTMLElement, LayoutHeaderProps>(\n ({ children, className = '', 'data-testid': testId, ...rest }, ref) => {\n const headerClasses = [\n 'flex',\n 'items-center',\n 'px-6',\n 'h-16',\n 'bg-base-300',\n 'flex-shrink-0',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <header ref={ref} className={headerClasses} data-testid={testId} {...rest}>\n {children}\n </header>\n )\n }\n)\n\nLayoutHeader.displayName = 'LayoutHeader'\n\nconst LayoutFooter = forwardRef<HTMLElement, LayoutFooterProps>(\n ({ children, className = '', 'data-testid': testId, ...rest }, ref) => {\n const footerClasses = [\n 'px-6',\n 'py-4',\n 'text-center',\n 'bg-base-300',\n 'flex-shrink-0',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <footer ref={ref} className={footerClasses} data-testid={testId} {...rest}>\n {children}\n </footer>\n )\n }\n)\n\nLayoutFooter.displayName = 'LayoutFooter'\n\nconst LayoutContent = forwardRef<HTMLElement, LayoutContentProps>(\n ({ children, className = '', 'data-testid': testId, ...rest }, ref) => {\n // flex-1 by default so Content fills available space\n const contentClasses = ['flex-1', 'min-h-0', 'overflow-auto', className].filter(Boolean).join(' ')\n\n return (\n <main ref={ref} className={contentClasses} data-testid={testId} {...rest}>\n {children}\n </main>\n )\n }\n)\n\nLayoutContent.displayName = 'LayoutContent'\n\nconst BREAKPOINT_MAP: Record<string, string> = {\n sm: '(max-width: 639px)',\n md: '(max-width: 767px)',\n lg: '(max-width: 1023px)',\n xl: '(max-width: 1279px)',\n '2xl': '(max-width: 1535px)',\n}\n\nconst LayoutSider = forwardRef<HTMLElement, LayoutSiderProps>(\n (\n {\n children,\n width = 200,\n collapsedWidth = 80,\n collapsed: controlledCollapsed,\n defaultCollapsed = false,\n collapsible = false,\n onCollapse,\n trigger,\n breakpoint,\n onBreakpoint,\n reverseArrow = false,\n theme = 'dark',\n zeroWidthTriggerStyle,\n className = '',\n style,\n 'data-testid': testId,\n ...rest\n },\n ref\n ) => {\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed)\n const [broken, setBroken] = useState(false)\n\n const collapsed = controlledCollapsed ?? internalCollapsed\n\n // Handle responsive breakpoint\n useEffect(() => {\n if (!breakpoint) return\n\n const mediaQuery = window.matchMedia(BREAKPOINT_MAP[breakpoint])\n\n const handleChange = (e: MediaQueryListEvent | MediaQueryList) => {\n const isBroken = e.matches\n setBroken(isBroken)\n onBreakpoint?.(isBroken)\n\n // Auto-collapse when breakpoint is crossed\n if (controlledCollapsed === undefined) {\n setInternalCollapsed(isBroken)\n }\n if (isBroken !== broken) {\n onCollapse?.(isBroken, 'responsive')\n }\n }\n\n // Check initial state\n handleChange(mediaQuery)\n\n // Listen for changes\n mediaQuery.addEventListener('change', handleChange)\n return () => mediaQuery.removeEventListener('change', handleChange)\n }, [breakpoint, onBreakpoint, controlledCollapsed, onCollapse, broken])\n\n const handleCollapse = useCallback(() => {\n const newCollapsed = !collapsed\n if (controlledCollapsed === undefined) {\n setInternalCollapsed(newCollapsed)\n }\n onCollapse?.(newCollapsed, 'clickTrigger')\n }, [collapsed, controlledCollapsed, onCollapse])\n\n const currentWidth = collapsed ? collapsedWidth : width\n const isZeroWidth = currentWidth === 0 || currentWidth === '0' || currentWidth === '0px'\n\n const themeClasses: Record<SiderTheme, string> = {\n light: 'bg-base-100',\n dark: 'bg-base-200',\n }\n\n const siderClasses = [\n 'flex',\n 'flex-col',\n themeClasses[theme],\n 'flex-shrink-0',\n 'transition-all',\n 'duration-200',\n 'relative',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n // Determine arrow rotation based on collapsed state and reverseArrow prop\n const getArrowRotation = () => {\n if (reverseArrow) {\n return collapsed ? '' : 'rotate-180'\n }\n return collapsed ? 'rotate-180' : ''\n }\n\n const defaultTrigger = collapsible && trigger !== null && (\n <button\n onClick={handleCollapse}\n className=\"flex items-center justify-center h-10 w-full bg-base-300 hover:bg-base-content/10 transition-colors\"\n aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n data-testid={testId ? `${testId}-trigger` : undefined}\n >\n <svg\n className={`w-4 h-4 transition-transform ${getArrowRotation()}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n )\n\n // Zero-width trigger (floating button when sider is collapsed to 0)\n const zeroWidthTrigger = collapsible && isZeroWidth && collapsed && (\n <button\n onClick={handleCollapse}\n className=\"absolute top-1/2 -translate-y-1/2 right-0 translate-x-full w-6 h-12 flex items-center justify-center bg-base-300 hover:bg-base-content/10 transition-colors rounded-r z-10\"\n aria-label=\"Expand sidebar\"\n style={zeroWidthTriggerStyle}\n data-testid={testId ? `${testId}-zero-trigger` : undefined}\n >\n <svg\n className={`w-3 h-3 ${reverseArrow ? 'rotate-180' : ''}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n )\n\n return (\n <SiderContext.Provider value={{ collapsed, collapsedWidth, width }}>\n <aside\n ref={ref}\n className={siderClasses}\n style={{\n width: typeof currentWidth === 'number' ? `${currentWidth}px` : currentWidth,\n ...style,\n }}\n data-collapsed={collapsed}\n data-theme={theme}\n data-testid={testId}\n aria-expanded={!collapsed}\n {...rest}\n >\n <div className=\"flex-1 overflow-auto\">{children}</div>\n {!isZeroWidth && trigger !== null && (trigger ?? defaultTrigger)}\n {zeroWidthTrigger}\n </aside>\n </SiderContext.Provider>\n )\n }\n)\n\nLayoutSider.displayName = 'LayoutSider'\n\nexport const Layout = Object.assign(LayoutRoot, {\n Header: LayoutHeader,\n Footer: LayoutFooter,\n Content: LayoutContent,\n Sider: LayoutSider,\n})\n"],"names":["SiderContext","createContext","useSiderContext","useContext","LayoutRoot","forwardRef","children","hasSiderProp","className","testId","rest","ref","childArray","React","hasSiderDetected","child","hasSider","layoutClasses","processedChildren","existingClassName","jsx","LayoutHeader","headerClasses","LayoutFooter","footerClasses","LayoutContent","contentClasses","BREAKPOINT_MAP","LayoutSider","width","collapsedWidth","controlledCollapsed","defaultCollapsed","collapsible","onCollapse","trigger","breakpoint","onBreakpoint","reverseArrow","theme","zeroWidthTriggerStyle","style","internalCollapsed","setInternalCollapsed","useState","broken","setBroken","collapsed","useEffect","mediaQuery","handleChange","e","isBroken","handleCollapse","useCallback","newCollapsed","currentWidth","isZeroWidth","siderClasses","getArrowRotation","defaultTrigger","zeroWidthTrigger","jsxs","Layout"],"mappings":"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"}
|
|
@@ -1,62 +1,73 @@
|
|
|
1
|
-
import { jsx as e, jsxs as
|
|
2
|
-
import { useRef as Q, useState as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
size: a = 160,
|
|
1
|
+
import { jsx as e, jsxs as p } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as Q, useState as w, useEffect as C } from "react";
|
|
3
|
+
const F = ({
|
|
4
|
+
value: h,
|
|
5
|
+
size: t = 160,
|
|
7
6
|
errorLevel: v = "M",
|
|
8
7
|
icon: f,
|
|
9
|
-
iconSize:
|
|
10
|
-
type:
|
|
11
|
-
color:
|
|
12
|
-
bgColor:
|
|
13
|
-
bordered:
|
|
14
|
-
status:
|
|
15
|
-
onRefresh:
|
|
16
|
-
className:
|
|
8
|
+
iconSize: a = 40,
|
|
9
|
+
type: g = "canvas",
|
|
10
|
+
color: u = "#000000",
|
|
11
|
+
bgColor: x = "#FFFFFF",
|
|
12
|
+
bordered: n = !0,
|
|
13
|
+
status: s = "active",
|
|
14
|
+
onRefresh: N,
|
|
15
|
+
className: R = "",
|
|
17
16
|
...c
|
|
18
17
|
}) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}, [
|
|
23
|
-
if (
|
|
18
|
+
const r = Q(null), [k, l] = w(s === "loading"), [j, L] = w(!1);
|
|
19
|
+
C(() => {
|
|
20
|
+
l(s === "loading");
|
|
21
|
+
}, [s]), C(() => {
|
|
22
|
+
if (s !== "active" || !h) return;
|
|
24
23
|
(async () => {
|
|
25
24
|
try {
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
l(!0);
|
|
26
|
+
let o;
|
|
27
|
+
try {
|
|
28
|
+
o = await import("qrcode");
|
|
29
|
+
} catch {
|
|
30
|
+
L(!0), l(!1);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (g === "canvas" && r.current && (await o.toCanvas(r.current, h, {
|
|
34
|
+
width: t,
|
|
28
35
|
margin: 1,
|
|
29
36
|
color: {
|
|
30
|
-
dark:
|
|
31
|
-
light:
|
|
37
|
+
dark: u,
|
|
38
|
+
light: x
|
|
32
39
|
},
|
|
33
40
|
errorCorrectionLevel: v
|
|
34
41
|
}), f)) {
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
+
const d = r.current.getContext("2d");
|
|
43
|
+
if (d) {
|
|
44
|
+
const m = new Image();
|
|
45
|
+
m.crossOrigin = "anonymous", m.onload = () => {
|
|
46
|
+
const y = (t - a) / 2, b = (t - a) / 2;
|
|
47
|
+
d.fillStyle = x, d.fillRect(y - 4, b - 4, a + 8, a + 8), d.drawImage(m, y, b, a, a);
|
|
48
|
+
}, m.src = f;
|
|
42
49
|
}
|
|
43
50
|
}
|
|
44
|
-
|
|
45
|
-
} catch (
|
|
46
|
-
console.error("QR Code generation error:",
|
|
51
|
+
l(!1);
|
|
52
|
+
} catch (o) {
|
|
53
|
+
console.error("QR Code generation error:", o), l(!1);
|
|
47
54
|
}
|
|
48
55
|
})();
|
|
49
|
-
}, [
|
|
50
|
-
const
|
|
56
|
+
}, [h, t, v, f, a, g, u, x, s]);
|
|
57
|
+
const i = [
|
|
51
58
|
"inline-flex items-center justify-center",
|
|
52
|
-
|
|
59
|
+
n && "border border-base-content/20 p-3",
|
|
53
60
|
"bg-base-100",
|
|
54
|
-
|
|
61
|
+
R
|
|
55
62
|
].filter(Boolean).join(" ");
|
|
56
|
-
return
|
|
63
|
+
return j ? /* @__PURE__ */ e("div", { className: i, style: { width: t + (n ? 24 : 0), height: t + (n ? 24 : 0) }, "data-state": "error", ...c, children: /* @__PURE__ */ p("div", { className: "flex flex-col items-center justify-center gap-2 p-4 text-center", children: [
|
|
64
|
+
/* @__PURE__ */ e("svg", { className: "w-8 h-8 text-warning", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ e("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
|
|
65
|
+
/* @__PURE__ */ e("span", { className: "text-sm text-base-content/70", children: "Missing dependency" }),
|
|
66
|
+
/* @__PURE__ */ e("code", { className: "text-xs bg-base-200 px-2 py-1 rounded", children: "npm install qrcode" })
|
|
67
|
+
] }) }) : s === "loading" || k ? /* @__PURE__ */ e("div", { className: i, style: { width: t + (n ? 24 : 0), height: t + (n ? 24 : 0) }, "data-state": "loading", ...c, children: /* @__PURE__ */ p("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
57
68
|
/* @__PURE__ */ e("span", { className: "loading loading-spinner loading-lg" }),
|
|
58
69
|
/* @__PURE__ */ e("span", { className: "text-sm text-base-content/70", children: "Loading..." })
|
|
59
|
-
] }) }) :
|
|
70
|
+
] }) }) : s === "expired" ? /* @__PURE__ */ e("div", { className: i, style: { width: t + (n ? 24 : 0), height: t + (n ? 24 : 0) }, "data-state": "expired", ...c, children: /* @__PURE__ */ p("div", { className: "flex flex-col items-center justify-center gap-2", children: [
|
|
60
71
|
/* @__PURE__ */ e("svg", { className: "w-12 h-12 text-base-content/30", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ e(
|
|
61
72
|
"path",
|
|
62
73
|
{
|
|
@@ -66,12 +77,12 @@ const k = ({
|
|
|
66
77
|
}
|
|
67
78
|
) }),
|
|
68
79
|
/* @__PURE__ */ e("span", { className: "text-sm text-base-content/70", children: "QR Code Expired" }),
|
|
69
|
-
|
|
70
|
-
] }) }) :
|
|
80
|
+
N && /* @__PURE__ */ e("button", { className: "btn btn-sm btn-primary", onClick: N, children: "Refresh" })
|
|
81
|
+
] }) }) : g === "canvas" ? /* @__PURE__ */ e("div", { className: "inline-block", "data-state": "active", ...c, children: /* @__PURE__ */ e("div", { className: i, children: /* @__PURE__ */ e("canvas", { ref: r, style: { display: "block" } }) }) }) : /* @__PURE__ */ e("div", { className: "inline-block", "data-state": "active", ...c, children: /* @__PURE__ */ e("div", { className: i, children: /* @__PURE__ */ e("div", { style: { width: t, height: t }, className: "bg-base-content/5", children: /* @__PURE__ */ e("span", { className: "text-xs text-base-content/50", children: "SVG mode placeholder" }) }) }) });
|
|
71
82
|
};
|
|
72
|
-
|
|
83
|
+
F.displayName = "QRCode";
|
|
73
84
|
export {
|
|
74
|
-
|
|
75
|
-
|
|
85
|
+
F as QRCode,
|
|
86
|
+
F as default
|
|
76
87
|
};
|
|
77
88
|
//# sourceMappingURL=QRCode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QRCode.js","sources":["../../src/components/QRCode.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\
|
|
1
|
+
{"version":3,"file":"QRCode.js","sources":["../../src/components/QRCode.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\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 const [loading, setLoading] = useState(status === 'loading')\n const [missingDep, setMissingDep] = useState(false)\n\n useEffect(() => {\n setLoading(status === 'loading')\n }, [status])\n\n useEffect(() => {\n if (status !== 'active' || !value) return\n\n const generateQRCode = async () => {\n try {\n setLoading(true)\n\n // Dynamic import to gracefully handle missing dependency\n let QRCodeLib\n try {\n QRCodeLib = await import('qrcode')\n } catch {\n setMissingDep(true)\n setLoading(false)\n return\n }\n\n if (type === 'canvas' && canvasRef.current) {\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) {\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 }\n\n setLoading(false)\n } catch (error) {\n console.error('QR Code generation error:', error)\n setLoading(false)\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 (missingDep) {\n return (\n <div className={containerClasses} style={{ width: size + (bordered ? 24 : 0), height: size + (bordered ? 24 : 0) }} data-state=\"error\" {...rest}>\n <div className=\"flex flex-col items-center justify-center gap-2 p-4 text-center\">\n <svg className=\"w-8 h-8 text-warning\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\" />\n </svg>\n <span className=\"text-sm text-base-content/70\">Missing dependency</span>\n <code className=\"text-xs bg-base-200 px-2 py-1 rounded\">npm install qrcode</code>\n </div>\n </div>\n )\n }\n\n if (status === 'loading' || 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","loading","setLoading","useState","missingDep","setMissingDep","useEffect","QRCodeLib","ctx","img","iconX","iconY","error","containerClasses","jsx","jsxs"],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type ResponsiveDrawerBreakpoint = 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
3
|
+
export interface ResponsiveDrawerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
|
+
/** Main content area */
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
/** Sidebar content */
|
|
7
|
+
sidebar: React.ReactNode;
|
|
8
|
+
/** Controlled open state */
|
|
9
|
+
open?: boolean;
|
|
10
|
+
/** Callback when open state changes */
|
|
11
|
+
onOpenChange?: (open: boolean) => void;
|
|
12
|
+
/** Position sidebar on the right side */
|
|
13
|
+
end?: boolean;
|
|
14
|
+
/** Width of the sidebar */
|
|
15
|
+
width?: number | string;
|
|
16
|
+
/** Breakpoint at which sidebar becomes always visible (e.g., 'lg' for lg:drawer-open) */
|
|
17
|
+
responsive?: ResponsiveDrawerBreakpoint;
|
|
18
|
+
/** Additional classes for sidebar container */
|
|
19
|
+
sidebarClassName?: string;
|
|
20
|
+
/** Additional classes for content area */
|
|
21
|
+
contentClassName?: string;
|
|
22
|
+
/** Additional classes for the overlay */
|
|
23
|
+
overlayClassName?: string;
|
|
24
|
+
/** Unique ID for the drawer (auto-generated if not provided) */
|
|
25
|
+
id?: string;
|
|
26
|
+
/** Test ID for testing */
|
|
27
|
+
'data-testid'?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* ResponsiveDrawer - A responsive sidebar layout using DaisyUI's drawer.
|
|
31
|
+
* Use for navigation sidebars that toggle on mobile but can be always visible on larger screens.
|
|
32
|
+
* For overlay panel drawers (forms, details), use the Drawer component instead.
|
|
33
|
+
*/
|
|
34
|
+
export declare const ResponsiveDrawer: React.ForwardRefExoticComponent<ResponsiveDrawerProps & React.RefAttributes<HTMLDivElement>>;
|