@marcoschwartz/lite-ui 0.24.3 → 0.24.5
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/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +879 -832
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +666 -620
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -69,6 +69,7 @@ __export(index_exports, {
|
|
|
69
69
|
ChevronUpIcon: () => ChevronUpIcon,
|
|
70
70
|
CloseIcon: () => CloseIcon,
|
|
71
71
|
CloudIcon: () => CloudIcon,
|
|
72
|
+
Code: () => Code,
|
|
72
73
|
CodeIcon: () => CodeIcon,
|
|
73
74
|
CopyIcon: () => CopyIcon,
|
|
74
75
|
DatabaseIcon: () => DatabaseIcon,
|
|
@@ -1443,7 +1444,7 @@ var AppShell = ({
|
|
|
1443
1444
|
)
|
|
1444
1445
|
] })
|
|
1445
1446
|
] }),
|
|
1446
|
-
header && !headerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("header", { className: `${needsMobileHeader ? desktopShowClass : ""} sticky top-0 z-20 ${heightClasses[headerHeight]} ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""} px-4 items-center shrink-0`, children: header.content }),
|
|
1447
|
+
header && !headerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("header", { className: `${needsMobileHeader ? desktopShowClass : "flex"} sticky top-0 z-20 ${heightClasses[headerHeight]} ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""} px-4 items-center shrink-0`, children: header.content }),
|
|
1447
1448
|
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: `flex-1 overflow-y-auto ${paddingClasses[padding]}`, children }),
|
|
1448
1449
|
footer && !footerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("footer", { className: `${heightClasses[footerHeight]} ${getVariantClasses(footerVariant, footerWithBorder)} ${footerWithBorder ? "border-t" : ""} px-4 flex items-center shrink-0`, children: footer.content })
|
|
1449
1450
|
] }),
|
|
@@ -1503,7 +1504,7 @@ var AppShell = ({
|
|
|
1503
1504
|
)
|
|
1504
1505
|
] })
|
|
1505
1506
|
] }),
|
|
1506
|
-
header && !headerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("header", { className: `${needsMobileHeader ? desktopShowClass : ""} sticky top-0 z-20 ${heightClasses[headerHeight]} ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""} px-4 items-center`, children: [
|
|
1507
|
+
header && !headerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("header", { className: `${needsMobileHeader ? desktopShowClass : "flex"} sticky top-0 z-20 ${heightClasses[headerHeight]} ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""} px-4 items-center`, children: [
|
|
1507
1508
|
(logo || title) && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "mr-4 shrink-0", children: logo || /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
|
|
1508
1509
|
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex-1", children: header.content })
|
|
1509
1510
|
] }),
|
|
@@ -1980,8 +1981,53 @@ var Card = ({
|
|
|
1980
1981
|
);
|
|
1981
1982
|
};
|
|
1982
1983
|
|
|
1983
|
-
// src/components/
|
|
1984
|
+
// src/components/Code.tsx
|
|
1985
|
+
var import_react10 = __toESM(require("react"));
|
|
1984
1986
|
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
1987
|
+
var colorClasses = {
|
|
1988
|
+
default: "bg-[hsl(var(--muted))] text-[hsl(var(--foreground))]",
|
|
1989
|
+
primary: "bg-[hsl(var(--primary))]/10 text-[hsl(var(--primary))]",
|
|
1990
|
+
success: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
|
|
1991
|
+
warning: "bg-amber-500/10 text-amber-600 dark:text-amber-400",
|
|
1992
|
+
error: "bg-red-500/10 text-red-600 dark:text-red-400"
|
|
1993
|
+
};
|
|
1994
|
+
var Code = ({
|
|
1995
|
+
children,
|
|
1996
|
+
block = false,
|
|
1997
|
+
color = "default",
|
|
1998
|
+
className = "",
|
|
1999
|
+
copyable = false
|
|
2000
|
+
}) => {
|
|
2001
|
+
const [copied, setCopied] = import_react10.default.useState(false);
|
|
2002
|
+
const handleCopy = async () => {
|
|
2003
|
+
const text = typeof children === "string" ? children : "";
|
|
2004
|
+
if (text) {
|
|
2005
|
+
await navigator.clipboard.writeText(text);
|
|
2006
|
+
setCopied(true);
|
|
2007
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
2010
|
+
const baseClasses = `font-mono text-sm ${colorClasses[color]}`;
|
|
2011
|
+
if (block) {
|
|
2012
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: `relative group ${className}`, children: [
|
|
2013
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("pre", { className: `${baseClasses} p-4 rounded-lg overflow-x-auto`, children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("code", { children }) }),
|
|
2014
|
+
copyable && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
2015
|
+
"button",
|
|
2016
|
+
{
|
|
2017
|
+
onClick: handleCopy,
|
|
2018
|
+
className: "absolute top-2 right-2 p-1.5 rounded-md bg-[hsl(var(--background))]/80 hover:bg-[hsl(var(--accent))] opacity-0 group-hover:opacity-100 transition-opacity text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]",
|
|
2019
|
+
"aria-label": "Copy code",
|
|
2020
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
2021
|
+
}
|
|
2022
|
+
)
|
|
2023
|
+
] });
|
|
2024
|
+
}
|
|
2025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("code", { className: `${baseClasses} px-1.5 py-0.5 rounded ${className}`, children });
|
|
2026
|
+
};
|
|
2027
|
+
Code.displayName = "Code";
|
|
2028
|
+
|
|
2029
|
+
// src/components/Alert.tsx
|
|
2030
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
1985
2031
|
var variantStyles = {
|
|
1986
2032
|
info: "bg-[hsl(var(--info))]/10 border-[hsl(var(--info))]/20 text-[hsl(var(--info))]",
|
|
1987
2033
|
success: "bg-[hsl(var(--success))]/10 border-[hsl(var(--success))]/20 text-[hsl(var(--success))]",
|
|
@@ -2003,38 +2049,38 @@ var Alert = ({
|
|
|
2003
2049
|
}) => {
|
|
2004
2050
|
const variantClass = variantStyles[variant];
|
|
2005
2051
|
const iconClass = iconStyles[variant];
|
|
2006
|
-
return /* @__PURE__ */ (0,
|
|
2007
|
-
/* @__PURE__ */ (0,
|
|
2008
|
-
variant === "info" && /* @__PURE__ */ (0,
|
|
2009
|
-
variant === "success" && /* @__PURE__ */ (0,
|
|
2010
|
-
variant === "warning" && /* @__PURE__ */ (0,
|
|
2011
|
-
variant === "error" && /* @__PURE__ */ (0,
|
|
2052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: `rounded-[--radius] border p-4 ${variantClass} ${className}`, role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
2053
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: `flex-shrink-0 ${iconClass}`, children: [
|
|
2054
|
+
variant === "info" && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("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" }) }),
|
|
2055
|
+
variant === "success" && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("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" }) }),
|
|
2056
|
+
variant === "warning" && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("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" }) }),
|
|
2057
|
+
variant === "error" && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("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" }) })
|
|
2012
2058
|
] }),
|
|
2013
|
-
/* @__PURE__ */ (0,
|
|
2014
|
-
title && /* @__PURE__ */ (0,
|
|
2015
|
-
/* @__PURE__ */ (0,
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "flex-1", children: [
|
|
2060
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("h3", { className: "font-semibold mb-1", children: title }),
|
|
2061
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "text-sm", children })
|
|
2016
2062
|
] }),
|
|
2017
|
-
onClose && /* @__PURE__ */ (0,
|
|
2063
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
2018
2064
|
"button",
|
|
2019
2065
|
{
|
|
2020
2066
|
onClick: onClose,
|
|
2021
2067
|
className: `flex-shrink-0 ${iconClass} hover:opacity-70 transition-opacity`,
|
|
2022
2068
|
"aria-label": "Close alert",
|
|
2023
|
-
children: /* @__PURE__ */ (0,
|
|
2069
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
2024
2070
|
}
|
|
2025
2071
|
)
|
|
2026
2072
|
] }) });
|
|
2027
2073
|
};
|
|
2028
2074
|
|
|
2029
2075
|
// src/components/Checkbox.tsx
|
|
2030
|
-
var
|
|
2031
|
-
var
|
|
2032
|
-
var Checkbox = (0,
|
|
2076
|
+
var import_react11 = require("react");
|
|
2077
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
2078
|
+
var Checkbox = (0, import_react11.forwardRef)(
|
|
2033
2079
|
({ label, error, className = "", disabled, checked, ...props }, ref) => {
|
|
2034
|
-
return /* @__PURE__ */ (0,
|
|
2035
|
-
/* @__PURE__ */ (0,
|
|
2036
|
-
/* @__PURE__ */ (0,
|
|
2037
|
-
/* @__PURE__ */ (0,
|
|
2080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className, children: [
|
|
2081
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer group", children: [
|
|
2082
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "relative inline-flex items-center", children: [
|
|
2083
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
2038
2084
|
"input",
|
|
2039
2085
|
{
|
|
2040
2086
|
ref,
|
|
@@ -2045,19 +2091,19 @@ var Checkbox = (0, import_react10.forwardRef)(
|
|
|
2045
2091
|
...props
|
|
2046
2092
|
}
|
|
2047
2093
|
),
|
|
2048
|
-
/* @__PURE__ */ (0,
|
|
2094
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: `w-4 h-4 border-2 rounded-sm transition-all duration-200 flex items-center justify-center
|
|
2049
2095
|
${error ? "border-[hsl(var(--destructive))]" : "border-[hsl(var(--input))]"}
|
|
2050
2096
|
${disabled ? "opacity-50 cursor-not-allowed bg-[hsl(var(--muted))]" : "peer-hover:border-[hsl(var(--ring))]"}
|
|
2051
2097
|
peer-checked:bg-[hsl(var(--primary))] peer-checked:border-[hsl(var(--primary))]
|
|
2052
2098
|
peer-focus:ring-1 peer-focus:ring-[hsl(var(--ring))]/50
|
|
2053
|
-
`, children: /* @__PURE__ */ (0,
|
|
2099
|
+
`, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
2054
2100
|
"svg",
|
|
2055
2101
|
{
|
|
2056
2102
|
className: `w-3 h-3 text-white transition-opacity duration-200 ${checked ? "opacity-100" : "opacity-0"}`,
|
|
2057
2103
|
viewBox: "0 0 12 12",
|
|
2058
2104
|
fill: "none",
|
|
2059
2105
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2060
|
-
children: /* @__PURE__ */ (0,
|
|
2106
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
2061
2107
|
"path",
|
|
2062
2108
|
{
|
|
2063
2109
|
d: "M10 3L4.5 8.5L2 6",
|
|
@@ -2070,18 +2116,18 @@ var Checkbox = (0, import_react10.forwardRef)(
|
|
|
2070
2116
|
}
|
|
2071
2117
|
) })
|
|
2072
2118
|
] }),
|
|
2073
|
-
label && /* @__PURE__ */ (0,
|
|
2119
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: `text-sm text-[hsl(var(--foreground))] ${disabled ? "opacity-50 cursor-not-allowed" : ""}`, children: label })
|
|
2074
2120
|
] }),
|
|
2075
|
-
error && /* @__PURE__ */ (0,
|
|
2121
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "mt-1 text-sm text-[hsl(var(--destructive))]", children: error })
|
|
2076
2122
|
] });
|
|
2077
2123
|
}
|
|
2078
2124
|
);
|
|
2079
2125
|
Checkbox.displayName = "Checkbox";
|
|
2080
2126
|
|
|
2081
2127
|
// src/components/Toggle.tsx
|
|
2082
|
-
var
|
|
2083
|
-
var
|
|
2084
|
-
var Toggle = (0,
|
|
2128
|
+
var import_react12 = require("react");
|
|
2129
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
2130
|
+
var Toggle = (0, import_react12.forwardRef)(
|
|
2085
2131
|
({ label, size = "md", className = "", disabled, checked, onChange, ...props }, ref) => {
|
|
2086
2132
|
const handleChange = (e) => {
|
|
2087
2133
|
onChange?.(e.target.checked);
|
|
@@ -2101,9 +2147,9 @@ var Toggle = (0, import_react11.forwardRef)(
|
|
|
2101
2147
|
}
|
|
2102
2148
|
};
|
|
2103
2149
|
const currentSize = toggleClasses[size];
|
|
2104
|
-
return /* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("label", { className: `inline-flex items-center gap-3 cursor-pointer ${disabled ? "opacity-50 cursor-not-allowed" : ""} ${className}`, children: [
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "relative", children: [
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
2107
2153
|
"input",
|
|
2108
2154
|
{
|
|
2109
2155
|
ref,
|
|
@@ -2115,27 +2161,27 @@ var Toggle = (0, import_react11.forwardRef)(
|
|
|
2115
2161
|
...props
|
|
2116
2162
|
}
|
|
2117
2163
|
),
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
2119
2165
|
"div",
|
|
2120
2166
|
{
|
|
2121
2167
|
className: `${currentSize.switch} bg-[hsl(var(--input))] peer-focus:ring-1 peer-focus:ring-[hsl(var(--ring))]/50 rounded-full peer peer-checked:bg-[hsl(var(--primary))] transition-colors`
|
|
2122
2168
|
}
|
|
2123
2169
|
),
|
|
2124
|
-
/* @__PURE__ */ (0,
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
2125
2171
|
"div",
|
|
2126
2172
|
{
|
|
2127
2173
|
className: `${currentSize.thumb} bg-white rounded-full shadow-md absolute top-0.5 left-0.5 transition-transform`
|
|
2128
2174
|
}
|
|
2129
2175
|
)
|
|
2130
2176
|
] }),
|
|
2131
|
-
label && /* @__PURE__ */ (0,
|
|
2177
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "text-sm font-medium text-[hsl(var(--foreground))]", children: label })
|
|
2132
2178
|
] });
|
|
2133
2179
|
}
|
|
2134
2180
|
);
|
|
2135
2181
|
Toggle.displayName = "Toggle";
|
|
2136
2182
|
|
|
2137
2183
|
// src/components/Badge.tsx
|
|
2138
|
-
var
|
|
2184
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
2139
2185
|
var variantStyles2 = {
|
|
2140
2186
|
default: "bg-[hsl(var(--secondary))] text-[hsl(var(--secondary-foreground))]",
|
|
2141
2187
|
primary: "bg-[hsl(var(--primary))]/10 text-[hsl(var(--primary))]",
|
|
@@ -2157,18 +2203,18 @@ var Badge = ({
|
|
|
2157
2203
|
}) => {
|
|
2158
2204
|
const variantClass = variantStyles2[variant];
|
|
2159
2205
|
const sizeClass = sizeStyles[size];
|
|
2160
|
-
return /* @__PURE__ */ (0,
|
|
2206
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { className: `inline-flex items-center font-medium rounded-full ${variantClass} ${sizeClass} ${className}`, children });
|
|
2161
2207
|
};
|
|
2162
2208
|
|
|
2163
2209
|
// src/components/Spinner.tsx
|
|
2164
|
-
var
|
|
2210
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
2165
2211
|
var sizeClasses6 = {
|
|
2166
2212
|
sm: "w-4 h-4 border-2",
|
|
2167
2213
|
md: "w-8 h-8 border-2",
|
|
2168
2214
|
lg: "w-12 h-12 border-3",
|
|
2169
2215
|
xl: "w-16 h-16 border-4"
|
|
2170
2216
|
};
|
|
2171
|
-
var
|
|
2217
|
+
var colorClasses2 = {
|
|
2172
2218
|
primary: "border-[hsl(var(--primary))] border-t-transparent",
|
|
2173
2219
|
secondary: "border-[hsl(var(--muted-foreground))] border-t-transparent",
|
|
2174
2220
|
white: "border-white border-t-transparent"
|
|
@@ -2179,35 +2225,35 @@ var Spinner = ({
|
|
|
2179
2225
|
className = ""
|
|
2180
2226
|
}) => {
|
|
2181
2227
|
const sizeClass = sizeClasses6[size];
|
|
2182
|
-
const colorClass =
|
|
2183
|
-
return /* @__PURE__ */ (0,
|
|
2228
|
+
const colorClass = colorClasses2[color];
|
|
2229
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
2184
2230
|
"div",
|
|
2185
2231
|
{
|
|
2186
2232
|
className: `inline-block rounded-full animate-spin ${sizeClass} ${colorClass} ${className}`,
|
|
2187
2233
|
role: "status",
|
|
2188
2234
|
"aria-label": "Loading",
|
|
2189
|
-
children: /* @__PURE__ */ (0,
|
|
2235
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "sr-only", children: "Loading..." })
|
|
2190
2236
|
}
|
|
2191
2237
|
);
|
|
2192
2238
|
};
|
|
2193
2239
|
|
|
2194
2240
|
// src/components/Tabs.tsx
|
|
2195
|
-
var
|
|
2196
|
-
var
|
|
2241
|
+
var import_react13 = require("react");
|
|
2242
|
+
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
2197
2243
|
var Tabs = ({
|
|
2198
2244
|
tabs,
|
|
2199
2245
|
defaultIndex = 0,
|
|
2200
2246
|
onChange,
|
|
2201
2247
|
className = ""
|
|
2202
2248
|
}) => {
|
|
2203
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
2249
|
+
const [activeIndex, setActiveIndex] = (0, import_react13.useState)(defaultIndex);
|
|
2204
2250
|
const handleTabClick = (index) => {
|
|
2205
2251
|
if (tabs[index].disabled) return;
|
|
2206
2252
|
setActiveIndex(index);
|
|
2207
2253
|
onChange?.(index);
|
|
2208
2254
|
};
|
|
2209
|
-
return /* @__PURE__ */ (0,
|
|
2210
|
-
/* @__PURE__ */ (0,
|
|
2255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className, children: [
|
|
2256
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { className: "border-b border-[hsl(var(--border))] px-4", children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("nav", { className: "flex gap-4 -mb-px", "aria-label": "Tabs", children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2211
2257
|
"button",
|
|
2212
2258
|
{
|
|
2213
2259
|
onClick: () => handleTabClick(index),
|
|
@@ -2218,12 +2264,12 @@ var Tabs = ({
|
|
|
2218
2264
|
},
|
|
2219
2265
|
index
|
|
2220
2266
|
)) }) }),
|
|
2221
|
-
/* @__PURE__ */ (0,
|
|
2267
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { children: tabs[activeIndex]?.content })
|
|
2222
2268
|
] });
|
|
2223
2269
|
};
|
|
2224
2270
|
|
|
2225
2271
|
// src/components/Table.tsx
|
|
2226
|
-
var
|
|
2272
|
+
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
2227
2273
|
function Table({
|
|
2228
2274
|
columns,
|
|
2229
2275
|
data,
|
|
@@ -2233,12 +2279,12 @@ function Table({
|
|
|
2233
2279
|
className = "",
|
|
2234
2280
|
responsive = true
|
|
2235
2281
|
}) {
|
|
2236
|
-
return /* @__PURE__ */ (0,
|
|
2237
|
-
/* @__PURE__ */ (0,
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2239
|
-
/* @__PURE__ */ (0,
|
|
2282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className, children: [
|
|
2283
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: `${responsive ? "hidden md:block" : ""} overflow-x-auto`, children: [
|
|
2284
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("table", { className: "w-full text-left", children: [
|
|
2285
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("thead", { className: "bg-[hsl(var(--muted))] border-b border-[hsl(var(--border))]", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("tr", { children: columns.map((column, colIndex) => {
|
|
2240
2286
|
const isLast = colIndex === columns.length - 1;
|
|
2241
|
-
return /* @__PURE__ */ (0,
|
|
2287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2242
2288
|
"th",
|
|
2243
2289
|
{
|
|
2244
2290
|
className: isLast ? "px-6 py-3 text-xs font-medium text-[hsl(var(--muted-foreground))] uppercase tracking-wider relative" : "px-6 py-3 text-xs font-medium text-[hsl(var(--muted-foreground))] uppercase tracking-wider",
|
|
@@ -2248,18 +2294,18 @@ function Table({
|
|
|
2248
2294
|
column.key
|
|
2249
2295
|
);
|
|
2250
2296
|
}) }) }),
|
|
2251
|
-
/* @__PURE__ */ (0,
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("tbody", { className: "bg-[hsl(var(--card))] divide-y divide-[hsl(var(--border))]", children: data.map((row, rowIndex) => {
|
|
2252
2298
|
const rowClasses = [
|
|
2253
2299
|
striped && rowIndex % 2 === 1 ? "bg-[hsl(var(--muted))]/50" : "",
|
|
2254
2300
|
hoverable ? "hover:bg-[hsl(var(--muted))] transition-colors" : ""
|
|
2255
2301
|
].filter(Boolean).join(" ");
|
|
2256
|
-
return /* @__PURE__ */ (0,
|
|
2302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2257
2303
|
"tr",
|
|
2258
2304
|
{
|
|
2259
2305
|
className: rowClasses,
|
|
2260
2306
|
children: columns.map((column, colIndex) => {
|
|
2261
2307
|
const isLast = colIndex === columns.length - 1;
|
|
2262
|
-
return /* @__PURE__ */ (0,
|
|
2308
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2263
2309
|
"td",
|
|
2264
2310
|
{
|
|
2265
2311
|
className: isLast ? "px-6 py-4 text-sm text-[hsl(var(--foreground))] overflow-visible" : "px-6 py-4 text-sm text-[hsl(var(--foreground))]",
|
|
@@ -2273,9 +2319,9 @@ function Table({
|
|
|
2273
2319
|
);
|
|
2274
2320
|
}) })
|
|
2275
2321
|
] }),
|
|
2276
|
-
data.length === 0 && /* @__PURE__ */ (0,
|
|
2322
|
+
data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "text-center py-8 text-[hsl(var(--muted-foreground))]", children: "No data available" })
|
|
2277
2323
|
] }),
|
|
2278
|
-
responsive && /* @__PURE__ */ (0,
|
|
2324
|
+
responsive && /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "md:hidden space-y-3", children: [
|
|
2279
2325
|
data.map((row, rowIndex) => {
|
|
2280
2326
|
const cardClasses = [
|
|
2281
2327
|
"bg-[hsl(var(--card))] border border-[hsl(var(--border))] rounded-[--radius] p-4 shadow-sm",
|
|
@@ -2283,17 +2329,17 @@ function Table({
|
|
|
2283
2329
|
"relative isolate"
|
|
2284
2330
|
// Ensure cards are isolated layers
|
|
2285
2331
|
].filter(Boolean).join(" ");
|
|
2286
|
-
return /* @__PURE__ */ (0,
|
|
2332
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2287
2333
|
"div",
|
|
2288
2334
|
{
|
|
2289
2335
|
className: cardClasses,
|
|
2290
|
-
children: columns.map((column) => /* @__PURE__ */ (0,
|
|
2336
|
+
children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
|
|
2291
2337
|
"div",
|
|
2292
2338
|
{
|
|
2293
2339
|
className: "flex justify-between items-start py-2 border-b border-[hsl(var(--border))]/50 last:border-b-0",
|
|
2294
2340
|
children: [
|
|
2295
|
-
/* @__PURE__ */ (0,
|
|
2296
|
-
/* @__PURE__ */ (0,
|
|
2341
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))] uppercase tracking-wider flex-shrink-0 mr-4", children: column.title }),
|
|
2342
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "text-sm text-[hsl(var(--foreground))] text-right", children: column.render ? column.render(row[column.key], row, rowIndex) : row[column.key] })
|
|
2297
2343
|
]
|
|
2298
2344
|
},
|
|
2299
2345
|
column.key
|
|
@@ -2302,13 +2348,13 @@ function Table({
|
|
|
2302
2348
|
row[keyField] || rowIndex
|
|
2303
2349
|
);
|
|
2304
2350
|
}),
|
|
2305
|
-
data.length === 0 && /* @__PURE__ */ (0,
|
|
2351
|
+
data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "text-center py-8 text-[hsl(var(--muted-foreground))]", children: "No data available" })
|
|
2306
2352
|
] })
|
|
2307
2353
|
] });
|
|
2308
2354
|
}
|
|
2309
2355
|
|
|
2310
2356
|
// src/components/Pagination.tsx
|
|
2311
|
-
var
|
|
2357
|
+
var import_jsx_runtime92 = require("react/jsx-runtime");
|
|
2312
2358
|
var Pagination = ({
|
|
2313
2359
|
currentPage,
|
|
2314
2360
|
totalPages,
|
|
@@ -2348,8 +2394,8 @@ var Pagination = ({
|
|
|
2348
2394
|
return range(1, totalPages);
|
|
2349
2395
|
};
|
|
2350
2396
|
const pages = paginationRange();
|
|
2351
|
-
return /* @__PURE__ */ (0,
|
|
2352
|
-
/* @__PURE__ */ (0,
|
|
2397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("nav", { className: `flex items-center gap-1 ${className}`, "aria-label": "Pagination", children: [
|
|
2398
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
2353
2399
|
"button",
|
|
2354
2400
|
{
|
|
2355
2401
|
onClick: () => onPageChange(currentPage - 1),
|
|
@@ -2361,7 +2407,7 @@ var Pagination = ({
|
|
|
2361
2407
|
),
|
|
2362
2408
|
pages.map((page, index) => {
|
|
2363
2409
|
if (page === "...") {
|
|
2364
|
-
return /* @__PURE__ */ (0,
|
|
2410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
2365
2411
|
"span",
|
|
2366
2412
|
{
|
|
2367
2413
|
className: "px-3 py-2 text-[hsl(var(--muted-foreground))]",
|
|
@@ -2370,7 +2416,7 @@ var Pagination = ({
|
|
|
2370
2416
|
`dots-${index}`
|
|
2371
2417
|
);
|
|
2372
2418
|
}
|
|
2373
|
-
return /* @__PURE__ */ (0,
|
|
2419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
2374
2420
|
"button",
|
|
2375
2421
|
{
|
|
2376
2422
|
onClick: () => onPageChange(page),
|
|
@@ -2382,7 +2428,7 @@ var Pagination = ({
|
|
|
2382
2428
|
page
|
|
2383
2429
|
);
|
|
2384
2430
|
}),
|
|
2385
|
-
/* @__PURE__ */ (0,
|
|
2431
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
2386
2432
|
"button",
|
|
2387
2433
|
{
|
|
2388
2434
|
onClick: () => onPageChange(currentPage + 1),
|
|
@@ -2396,9 +2442,9 @@ var Pagination = ({
|
|
|
2396
2442
|
};
|
|
2397
2443
|
|
|
2398
2444
|
// src/components/DatePicker.tsx
|
|
2399
|
-
var
|
|
2445
|
+
var import_react14 = require("react");
|
|
2400
2446
|
var import_react_dom2 = require("react-dom");
|
|
2401
|
-
var
|
|
2447
|
+
var import_jsx_runtime93 = require("react/jsx-runtime");
|
|
2402
2448
|
var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2403
2449
|
var MONTHS = [
|
|
2404
2450
|
"January",
|
|
@@ -2426,16 +2472,16 @@ var DatePicker = ({
|
|
|
2426
2472
|
className = "",
|
|
2427
2473
|
placeholder = "Select date..."
|
|
2428
2474
|
}) => {
|
|
2429
|
-
const [isOpen, setIsOpen] = (0,
|
|
2430
|
-
const [viewDate, setViewDate] = (0,
|
|
2431
|
-
const [mounted, setMounted] = (0,
|
|
2432
|
-
const [calendarPosition, setCalendarPosition] = (0,
|
|
2433
|
-
const inputRef = (0,
|
|
2434
|
-
const calendarRef = (0,
|
|
2435
|
-
(0,
|
|
2475
|
+
const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
|
|
2476
|
+
const [viewDate, setViewDate] = (0, import_react14.useState)(value || /* @__PURE__ */ new Date());
|
|
2477
|
+
const [mounted, setMounted] = (0, import_react14.useState)(false);
|
|
2478
|
+
const [calendarPosition, setCalendarPosition] = (0, import_react14.useState)(null);
|
|
2479
|
+
const inputRef = (0, import_react14.useRef)(null);
|
|
2480
|
+
const calendarRef = (0, import_react14.useRef)(null);
|
|
2481
|
+
(0, import_react14.useEffect)(() => {
|
|
2436
2482
|
setMounted(true);
|
|
2437
2483
|
}, []);
|
|
2438
|
-
(0,
|
|
2484
|
+
(0, import_react14.useEffect)(() => {
|
|
2439
2485
|
const handleClickOutside = (event) => {
|
|
2440
2486
|
if (calendarRef.current && !calendarRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
2441
2487
|
setIsOpen(false);
|
|
@@ -2446,7 +2492,7 @@ var DatePicker = ({
|
|
|
2446
2492
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2447
2493
|
}
|
|
2448
2494
|
}, [isOpen]);
|
|
2449
|
-
(0,
|
|
2495
|
+
(0, import_react14.useEffect)(() => {
|
|
2450
2496
|
if (isOpen && inputRef.current) {
|
|
2451
2497
|
const rect = inputRef.current.getBoundingClientRect();
|
|
2452
2498
|
setCalendarPosition({
|
|
@@ -2518,7 +2564,7 @@ var DatePicker = ({
|
|
|
2518
2564
|
const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-base transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))] cursor-pointer";
|
|
2519
2565
|
const errorStyles = error ? "border-[hsl(var(--destructive))] focus:ring-[hsl(var(--destructive))]/50" : "";
|
|
2520
2566
|
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-[hsl(var(--muted))]" : "";
|
|
2521
|
-
const calendar = isOpen && mounted && calendarPosition ? /* @__PURE__ */ (0,
|
|
2567
|
+
const calendar = isOpen && mounted && calendarPosition ? /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
|
|
2522
2568
|
"div",
|
|
2523
2569
|
{
|
|
2524
2570
|
ref: calendarRef,
|
|
@@ -2529,23 +2575,23 @@ var DatePicker = ({
|
|
|
2529
2575
|
minWidth: "320px"
|
|
2530
2576
|
},
|
|
2531
2577
|
children: [
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2533
|
-
/* @__PURE__ */ (0,
|
|
2578
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2579
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
2534
2580
|
"button",
|
|
2535
2581
|
{
|
|
2536
2582
|
onClick: handlePrevMonth,
|
|
2537
2583
|
className: "p-2 hover:bg-[hsl(var(--accent))] rounded-md transition-colors",
|
|
2538
2584
|
"aria-label": "Previous month",
|
|
2539
|
-
children: /* @__PURE__ */ (0,
|
|
2585
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
2540
2586
|
}
|
|
2541
2587
|
),
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2543
|
-
/* @__PURE__ */ (0,
|
|
2588
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2589
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("h2", { className: "text-base font-semibold text-[hsl(var(--foreground))]", children: [
|
|
2544
2590
|
MONTHS[month],
|
|
2545
2591
|
" ",
|
|
2546
2592
|
year
|
|
2547
2593
|
] }),
|
|
2548
|
-
/* @__PURE__ */ (0,
|
|
2594
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
2549
2595
|
"button",
|
|
2550
2596
|
{
|
|
2551
2597
|
onClick: handleToday,
|
|
@@ -2554,23 +2600,23 @@ var DatePicker = ({
|
|
|
2554
2600
|
}
|
|
2555
2601
|
)
|
|
2556
2602
|
] }),
|
|
2557
|
-
/* @__PURE__ */ (0,
|
|
2603
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
2558
2604
|
"button",
|
|
2559
2605
|
{
|
|
2560
2606
|
onClick: handleNextMonth,
|
|
2561
2607
|
className: "p-2 hover:bg-[hsl(var(--accent))] rounded-md transition-colors",
|
|
2562
2608
|
"aria-label": "Next month",
|
|
2563
|
-
children: /* @__PURE__ */ (0,
|
|
2609
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
2564
2610
|
}
|
|
2565
2611
|
)
|
|
2566
2612
|
] }),
|
|
2567
|
-
/* @__PURE__ */ (0,
|
|
2568
|
-
/* @__PURE__ */ (0,
|
|
2613
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "text-center text-xs font-semibold text-[hsl(var(--muted-foreground))] py-1", children: day }, day)) }),
|
|
2614
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
2569
2615
|
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2570
2616
|
const isTodayDay = isToday(date);
|
|
2571
2617
|
const isSelectedDay = isSelected(date);
|
|
2572
2618
|
const isDisabledDay = isDisabled(date);
|
|
2573
|
-
return /* @__PURE__ */ (0,
|
|
2619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
2574
2620
|
"button",
|
|
2575
2621
|
{
|
|
2576
2622
|
onClick: () => handleDateClick(date),
|
|
@@ -2591,38 +2637,38 @@ var DatePicker = ({
|
|
|
2591
2637
|
]
|
|
2592
2638
|
}
|
|
2593
2639
|
) : null;
|
|
2594
|
-
return /* @__PURE__ */ (0,
|
|
2595
|
-
label && /* @__PURE__ */ (0,
|
|
2596
|
-
/* @__PURE__ */ (0,
|
|
2640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className, children: [
|
|
2641
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("label", { className: "block text-sm font-medium text-[hsl(var(--foreground))] mb-1.5", children: label }),
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
|
|
2597
2643
|
"div",
|
|
2598
2644
|
{
|
|
2599
2645
|
ref: inputRef,
|
|
2600
2646
|
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
2601
2647
|
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
2602
2648
|
children: [
|
|
2603
|
-
/* @__PURE__ */ (0,
|
|
2604
|
-
/* @__PURE__ */ (0,
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { className: !value ? "text-[hsl(var(--muted-foreground))]" : "", children: value ? formatDate2(value) : placeholder }),
|
|
2650
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
2605
2651
|
]
|
|
2606
2652
|
}
|
|
2607
2653
|
),
|
|
2608
|
-
error && /* @__PURE__ */ (0,
|
|
2609
|
-
helperText && !error && /* @__PURE__ */ (0,
|
|
2654
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--destructive))]", children: error }),
|
|
2655
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--muted-foreground))]", children: helperText }),
|
|
2610
2656
|
mounted && (0, import_react_dom2.createPortal)(calendar, document.body)
|
|
2611
2657
|
] });
|
|
2612
2658
|
};
|
|
2613
2659
|
DatePicker.displayName = "DatePicker";
|
|
2614
2660
|
|
|
2615
2661
|
// src/components/TimePicker.tsx
|
|
2616
|
-
var
|
|
2617
|
-
var
|
|
2618
|
-
var TimePicker = (0,
|
|
2662
|
+
var import_react15 = require("react");
|
|
2663
|
+
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
2664
|
+
var TimePicker = (0, import_react15.forwardRef)(
|
|
2619
2665
|
({ label, error, helperText, className = "", disabled, ...props }, ref) => {
|
|
2620
2666
|
const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-base transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))]";
|
|
2621
2667
|
const errorStyles = error ? "border-[hsl(var(--destructive))] focus:ring-[hsl(var(--destructive))]/50" : "";
|
|
2622
2668
|
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-[hsl(var(--muted))]" : "";
|
|
2623
|
-
return /* @__PURE__ */ (0,
|
|
2624
|
-
label && /* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className, children: [
|
|
2670
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("label", { className: "block text-sm font-medium text-[hsl(var(--foreground))] mb-1.5", children: label }),
|
|
2671
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
2626
2672
|
"input",
|
|
2627
2673
|
{
|
|
2628
2674
|
ref,
|
|
@@ -2632,17 +2678,17 @@ var TimePicker = (0, import_react14.forwardRef)(
|
|
|
2632
2678
|
...props
|
|
2633
2679
|
}
|
|
2634
2680
|
),
|
|
2635
|
-
error && /* @__PURE__ */ (0,
|
|
2636
|
-
helperText && !error && /* @__PURE__ */ (0,
|
|
2681
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--destructive))]", children: error }),
|
|
2682
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--muted-foreground))]", children: helperText })
|
|
2637
2683
|
] });
|
|
2638
2684
|
}
|
|
2639
2685
|
);
|
|
2640
2686
|
TimePicker.displayName = "TimePicker";
|
|
2641
2687
|
|
|
2642
2688
|
// src/components/DateTimePicker.tsx
|
|
2643
|
-
var
|
|
2689
|
+
var import_react16 = require("react");
|
|
2644
2690
|
var import_react_dom3 = require("react-dom");
|
|
2645
|
-
var
|
|
2691
|
+
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
2646
2692
|
var DAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2647
2693
|
var MONTHS2 = [
|
|
2648
2694
|
"January",
|
|
@@ -2671,19 +2717,19 @@ var DateTimePicker = ({
|
|
|
2671
2717
|
className = "",
|
|
2672
2718
|
placeholder = "Select date and time..."
|
|
2673
2719
|
}) => {
|
|
2674
|
-
const [isOpen, setIsOpen] = (0,
|
|
2675
|
-
const [viewDate, setViewDate] = (0,
|
|
2676
|
-
const [selectedTime, setSelectedTime] = (0,
|
|
2720
|
+
const [isOpen, setIsOpen] = (0, import_react16.useState)(false);
|
|
2721
|
+
const [viewDate, setViewDate] = (0, import_react16.useState)(value || /* @__PURE__ */ new Date());
|
|
2722
|
+
const [selectedTime, setSelectedTime] = (0, import_react16.useState)(
|
|
2677
2723
|
value ? { hours: value.getHours(), minutes: value.getMinutes() } : { hours: 12, minutes: 0 }
|
|
2678
2724
|
);
|
|
2679
|
-
const [mounted, setMounted] = (0,
|
|
2680
|
-
const [pickerPosition, setPickerPosition] = (0,
|
|
2681
|
-
const inputRef = (0,
|
|
2682
|
-
const pickerRef = (0,
|
|
2683
|
-
(0,
|
|
2725
|
+
const [mounted, setMounted] = (0, import_react16.useState)(false);
|
|
2726
|
+
const [pickerPosition, setPickerPosition] = (0, import_react16.useState)(null);
|
|
2727
|
+
const inputRef = (0, import_react16.useRef)(null);
|
|
2728
|
+
const pickerRef = (0, import_react16.useRef)(null);
|
|
2729
|
+
(0, import_react16.useEffect)(() => {
|
|
2684
2730
|
setMounted(true);
|
|
2685
2731
|
}, []);
|
|
2686
|
-
(0,
|
|
2732
|
+
(0, import_react16.useEffect)(() => {
|
|
2687
2733
|
const handleClickOutside = (event) => {
|
|
2688
2734
|
if (pickerRef.current && !pickerRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
2689
2735
|
setIsOpen(false);
|
|
@@ -2694,7 +2740,7 @@ var DateTimePicker = ({
|
|
|
2694
2740
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2695
2741
|
}
|
|
2696
2742
|
}, [isOpen]);
|
|
2697
|
-
(0,
|
|
2743
|
+
(0, import_react16.useEffect)(() => {
|
|
2698
2744
|
if (isOpen && inputRef.current) {
|
|
2699
2745
|
const rect = inputRef.current.getBoundingClientRect();
|
|
2700
2746
|
setPickerPosition({
|
|
@@ -2800,7 +2846,7 @@ var DateTimePicker = ({
|
|
|
2800
2846
|
const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-base transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))] cursor-pointer";
|
|
2801
2847
|
const errorStyles = error ? "border-[hsl(var(--destructive))] focus:ring-[hsl(var(--destructive))]/50" : "";
|
|
2802
2848
|
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-[hsl(var(--muted))]" : "";
|
|
2803
|
-
const picker = isOpen && mounted && pickerPosition ? /* @__PURE__ */ (0,
|
|
2849
|
+
const picker = isOpen && mounted && pickerPosition ? /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
2804
2850
|
"div",
|
|
2805
2851
|
{
|
|
2806
2852
|
ref: pickerRef,
|
|
@@ -2811,23 +2857,23 @@ var DateTimePicker = ({
|
|
|
2811
2857
|
minWidth: "360px"
|
|
2812
2858
|
},
|
|
2813
2859
|
children: [
|
|
2814
|
-
/* @__PURE__ */ (0,
|
|
2815
|
-
/* @__PURE__ */ (0,
|
|
2860
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2861
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2816
2862
|
"button",
|
|
2817
2863
|
{
|
|
2818
2864
|
onClick: handlePrevMonth,
|
|
2819
2865
|
className: "p-2 hover:bg-[hsl(var(--accent))] rounded-md transition-colors",
|
|
2820
2866
|
"aria-label": "Previous month",
|
|
2821
|
-
children: /* @__PURE__ */ (0,
|
|
2867
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
2822
2868
|
}
|
|
2823
2869
|
),
|
|
2824
|
-
/* @__PURE__ */ (0,
|
|
2825
|
-
/* @__PURE__ */ (0,
|
|
2870
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2871
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("h2", { className: "text-base font-semibold text-[hsl(var(--foreground))]", children: [
|
|
2826
2872
|
MONTHS2[month],
|
|
2827
2873
|
" ",
|
|
2828
2874
|
year
|
|
2829
2875
|
] }),
|
|
2830
|
-
/* @__PURE__ */ (0,
|
|
2876
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2831
2877
|
"button",
|
|
2832
2878
|
{
|
|
2833
2879
|
onClick: handleToday,
|
|
@@ -2836,23 +2882,23 @@ var DateTimePicker = ({
|
|
|
2836
2882
|
}
|
|
2837
2883
|
)
|
|
2838
2884
|
] }),
|
|
2839
|
-
/* @__PURE__ */ (0,
|
|
2885
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2840
2886
|
"button",
|
|
2841
2887
|
{
|
|
2842
2888
|
onClick: handleNextMonth,
|
|
2843
2889
|
className: "p-2 hover:bg-[hsl(var(--accent))] rounded-md transition-colors",
|
|
2844
2890
|
"aria-label": "Next month",
|
|
2845
|
-
children: /* @__PURE__ */ (0,
|
|
2891
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
2846
2892
|
}
|
|
2847
2893
|
)
|
|
2848
2894
|
] }),
|
|
2849
|
-
/* @__PURE__ */ (0,
|
|
2850
|
-
/* @__PURE__ */ (0,
|
|
2895
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS2.map((day) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "text-center text-xs font-semibold text-[hsl(var(--muted-foreground))] py-1", children: day }, day)) }),
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-4", children: calendarDays.map((date, index) => {
|
|
2851
2897
|
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2852
2898
|
const isTodayDay = isToday(date);
|
|
2853
2899
|
const isSelectedDay = isSelected(date);
|
|
2854
2900
|
const isDisabledDay = isDisabled(date);
|
|
2855
|
-
return /* @__PURE__ */ (0,
|
|
2901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2856
2902
|
"button",
|
|
2857
2903
|
{
|
|
2858
2904
|
onClick: () => handleDateClick(date),
|
|
@@ -2870,21 +2916,21 @@ var DateTimePicker = ({
|
|
|
2870
2916
|
index
|
|
2871
2917
|
);
|
|
2872
2918
|
}) }),
|
|
2873
|
-
/* @__PURE__ */ (0,
|
|
2874
|
-
/* @__PURE__ */ (0,
|
|
2875
|
-
/* @__PURE__ */ (0,
|
|
2876
|
-
/* @__PURE__ */ (0,
|
|
2877
|
-
/* @__PURE__ */ (0,
|
|
2878
|
-
/* @__PURE__ */ (0,
|
|
2919
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "border-t border-[hsl(var(--border))] pt-4", children: [
|
|
2920
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex items-center justify-center gap-4 mb-4", children: [
|
|
2921
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2922
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("label", { className: "text-xs font-semibold text-[hsl(var(--muted-foreground))] mb-2", children: "Hour" }),
|
|
2923
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2879
2925
|
"button",
|
|
2880
2926
|
{
|
|
2881
2927
|
type: "button",
|
|
2882
2928
|
onClick: () => handleTimeChange((selectedTime.hours + 1) % 24, selectedTime.minutes),
|
|
2883
2929
|
className: "p-1 hover:bg-[hsl(var(--accent))] rounded transition-colors",
|
|
2884
|
-
children: /* @__PURE__ */ (0,
|
|
2930
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("svg", { className: "w-4 h-4 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2885
2931
|
}
|
|
2886
2932
|
),
|
|
2887
|
-
/* @__PURE__ */ (0,
|
|
2933
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2888
2934
|
"input",
|
|
2889
2935
|
{
|
|
2890
2936
|
type: "number",
|
|
@@ -2900,31 +2946,31 @@ var DateTimePicker = ({
|
|
|
2900
2946
|
className: "w-16 px-2 py-2 text-center border border-[hsl(var(--input))] rounded-md bg-transparent text-[hsl(var(--foreground))] focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 text-lg font-semibold [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
|
2901
2947
|
}
|
|
2902
2948
|
),
|
|
2903
|
-
/* @__PURE__ */ (0,
|
|
2949
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2904
2950
|
"button",
|
|
2905
2951
|
{
|
|
2906
2952
|
type: "button",
|
|
2907
2953
|
onClick: () => handleTimeChange((selectedTime.hours - 1 + 24) % 24, selectedTime.minutes),
|
|
2908
2954
|
className: "p-1 hover:bg-[hsl(var(--accent))] rounded transition-colors",
|
|
2909
|
-
children: /* @__PURE__ */ (0,
|
|
2955
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("svg", { className: "w-4 h-4 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2910
2956
|
}
|
|
2911
2957
|
)
|
|
2912
2958
|
] })
|
|
2913
2959
|
] }),
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
2915
|
-
/* @__PURE__ */ (0,
|
|
2916
|
-
/* @__PURE__ */ (0,
|
|
2917
|
-
/* @__PURE__ */ (0,
|
|
2918
|
-
/* @__PURE__ */ (0,
|
|
2960
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "text-2xl font-bold text-[hsl(var(--muted-foreground))] mt-8", children: ":" }),
|
|
2961
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2962
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("label", { className: "text-xs font-semibold text-[hsl(var(--muted-foreground))] mb-2", children: "Minute" }),
|
|
2963
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2964
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2919
2965
|
"button",
|
|
2920
2966
|
{
|
|
2921
2967
|
type: "button",
|
|
2922
2968
|
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes + 1) % 60),
|
|
2923
2969
|
className: "p-1 hover:bg-[hsl(var(--accent))] rounded transition-colors",
|
|
2924
|
-
children: /* @__PURE__ */ (0,
|
|
2970
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("svg", { className: "w-4 h-4 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2925
2971
|
}
|
|
2926
2972
|
),
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
2973
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2928
2974
|
"input",
|
|
2929
2975
|
{
|
|
2930
2976
|
type: "number",
|
|
@@ -2940,20 +2986,20 @@ var DateTimePicker = ({
|
|
|
2940
2986
|
className: "w-16 px-2 py-2 text-center border border-[hsl(var(--input))] rounded-md bg-transparent text-[hsl(var(--foreground))] focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 text-lg font-semibold [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
|
2941
2987
|
}
|
|
2942
2988
|
),
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
2989
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2944
2990
|
"button",
|
|
2945
2991
|
{
|
|
2946
2992
|
type: "button",
|
|
2947
2993
|
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes - 1 + 60) % 60),
|
|
2948
2994
|
className: "p-1 hover:bg-[hsl(var(--accent))] rounded transition-colors",
|
|
2949
|
-
children: /* @__PURE__ */ (0,
|
|
2995
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("svg", { className: "w-4 h-4 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2950
2996
|
}
|
|
2951
2997
|
)
|
|
2952
2998
|
] })
|
|
2953
2999
|
] })
|
|
2954
3000
|
] }),
|
|
2955
|
-
/* @__PURE__ */ (0,
|
|
2956
|
-
/* @__PURE__ */ (0,
|
|
3001
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "text-center text-sm text-[hsl(var(--muted-foreground))] mb-4", children: formatTime(selectedTime.hours, selectedTime.minutes) }),
|
|
3002
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
2957
3003
|
"button",
|
|
2958
3004
|
{
|
|
2959
3005
|
onClick: handleDone,
|
|
@@ -2965,30 +3011,30 @@ var DateTimePicker = ({
|
|
|
2965
3011
|
]
|
|
2966
3012
|
}
|
|
2967
3013
|
) : null;
|
|
2968
|
-
return /* @__PURE__ */ (0,
|
|
2969
|
-
label && /* @__PURE__ */ (0,
|
|
2970
|
-
/* @__PURE__ */ (0,
|
|
3014
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className, children: [
|
|
3015
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("label", { className: "block text-sm font-medium text-[hsl(var(--foreground))] mb-1.5", children: label }),
|
|
3016
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
2971
3017
|
"div",
|
|
2972
3018
|
{
|
|
2973
3019
|
ref: inputRef,
|
|
2974
3020
|
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
2975
3021
|
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
2976
3022
|
children: [
|
|
2977
|
-
/* @__PURE__ */ (0,
|
|
2978
|
-
/* @__PURE__ */ (0,
|
|
3023
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: !value ? "text-[hsl(var(--muted-foreground))]" : "", children: value ? formatDateTime(value) : placeholder }),
|
|
3024
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
2979
3025
|
]
|
|
2980
3026
|
}
|
|
2981
3027
|
),
|
|
2982
|
-
error && /* @__PURE__ */ (0,
|
|
2983
|
-
helperText && !error && /* @__PURE__ */ (0,
|
|
3028
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--destructive))]", children: error }),
|
|
3029
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--muted-foreground))]", children: helperText }),
|
|
2984
3030
|
mounted && (0, import_react_dom3.createPortal)(picker, document.body)
|
|
2985
3031
|
] });
|
|
2986
3032
|
};
|
|
2987
3033
|
DateTimePicker.displayName = "DateTimePicker";
|
|
2988
3034
|
|
|
2989
3035
|
// src/components/Calendar.tsx
|
|
2990
|
-
var
|
|
2991
|
-
var
|
|
3036
|
+
var import_react17 = require("react");
|
|
3037
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
2992
3038
|
var DAYS3 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2993
3039
|
var MONTHS3 = [
|
|
2994
3040
|
"January",
|
|
@@ -3011,8 +3057,8 @@ var Calendar = ({
|
|
|
3011
3057
|
maxDate,
|
|
3012
3058
|
className = ""
|
|
3013
3059
|
}) => {
|
|
3014
|
-
const [currentDate, setCurrentDate] = (0,
|
|
3015
|
-
const [viewDate, setViewDate] = (0,
|
|
3060
|
+
const [currentDate, setCurrentDate] = (0, import_react17.useState)(value || /* @__PURE__ */ new Date());
|
|
3061
|
+
const [viewDate, setViewDate] = (0, import_react17.useState)(value || /* @__PURE__ */ new Date());
|
|
3016
3062
|
const year = viewDate.getFullYear();
|
|
3017
3063
|
const month = viewDate.getMonth();
|
|
3018
3064
|
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
@@ -3063,24 +3109,24 @@ var Calendar = ({
|
|
|
3063
3109
|
setCurrentDate(today);
|
|
3064
3110
|
onChange?.(today);
|
|
3065
3111
|
};
|
|
3066
|
-
return /* @__PURE__ */ (0,
|
|
3067
|
-
/* @__PURE__ */ (0,
|
|
3068
|
-
/* @__PURE__ */ (0,
|
|
3112
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: `bg-[hsl(var(--card))] rounded-md border border-[hsl(var(--border))] p-4 ${className}`, children: [
|
|
3113
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
3114
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
3069
3115
|
"button",
|
|
3070
3116
|
{
|
|
3071
3117
|
onClick: handlePrevMonth,
|
|
3072
3118
|
className: "p-2 hover:bg-[hsl(var(--accent))] rounded-md transition-colors",
|
|
3073
3119
|
"aria-label": "Previous month",
|
|
3074
|
-
children: /* @__PURE__ */ (0,
|
|
3120
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
3075
3121
|
}
|
|
3076
3122
|
),
|
|
3077
|
-
/* @__PURE__ */ (0,
|
|
3078
|
-
/* @__PURE__ */ (0,
|
|
3123
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3124
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("h2", { className: "text-lg font-semibold text-[hsl(var(--foreground))]", children: [
|
|
3079
3125
|
MONTHS3[month],
|
|
3080
3126
|
" ",
|
|
3081
3127
|
year
|
|
3082
3128
|
] }),
|
|
3083
|
-
/* @__PURE__ */ (0,
|
|
3129
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
3084
3130
|
"button",
|
|
3085
3131
|
{
|
|
3086
3132
|
onClick: handleToday,
|
|
@@ -3089,17 +3135,17 @@ var Calendar = ({
|
|
|
3089
3135
|
}
|
|
3090
3136
|
)
|
|
3091
3137
|
] }),
|
|
3092
|
-
/* @__PURE__ */ (0,
|
|
3138
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
3093
3139
|
"button",
|
|
3094
3140
|
{
|
|
3095
3141
|
onClick: handleNextMonth,
|
|
3096
3142
|
className: "p-2 hover:bg-[hsl(var(--accent))] rounded-md transition-colors",
|
|
3097
3143
|
"aria-label": "Next month",
|
|
3098
|
-
children: /* @__PURE__ */ (0,
|
|
3144
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("svg", { className: "w-5 h-5 text-[hsl(var(--muted-foreground))]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
3099
3145
|
}
|
|
3100
3146
|
)
|
|
3101
3147
|
] }),
|
|
3102
|
-
/* @__PURE__ */ (0,
|
|
3148
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS3.map((day) => /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
3103
3149
|
"div",
|
|
3104
3150
|
{
|
|
3105
3151
|
className: "text-center text-xs font-semibold text-[hsl(var(--muted-foreground))] py-2",
|
|
@@ -3107,13 +3153,13 @@ var Calendar = ({
|
|
|
3107
3153
|
},
|
|
3108
3154
|
day
|
|
3109
3155
|
)) }),
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3111
|
-
if (!date) return /* @__PURE__ */ (0,
|
|
3156
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
3157
|
+
if (!date) return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("div", {}, index);
|
|
3112
3158
|
const isCurrentMonthDay = isCurrentMonth(date);
|
|
3113
3159
|
const isTodayDay = isToday(date);
|
|
3114
3160
|
const isSelectedDay = isSelected(date);
|
|
3115
3161
|
const isDisabledDay = isDisabled(date);
|
|
3116
|
-
return /* @__PURE__ */ (0,
|
|
3162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
3117
3163
|
"button",
|
|
3118
3164
|
{
|
|
3119
3165
|
onClick: () => handleDateClick(date),
|
|
@@ -3135,8 +3181,8 @@ var Calendar = ({
|
|
|
3135
3181
|
};
|
|
3136
3182
|
|
|
3137
3183
|
// src/components/Radio.tsx
|
|
3138
|
-
var
|
|
3139
|
-
var
|
|
3184
|
+
var import_react18 = __toESM(require("react"));
|
|
3185
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
3140
3186
|
var Radio = ({
|
|
3141
3187
|
name,
|
|
3142
3188
|
options,
|
|
@@ -3147,7 +3193,7 @@ var Radio = ({
|
|
|
3147
3193
|
orientation = "vertical",
|
|
3148
3194
|
className = ""
|
|
3149
3195
|
}) => {
|
|
3150
|
-
const [internalValue, setInternalValue] =
|
|
3196
|
+
const [internalValue, setInternalValue] = import_react18.default.useState(defaultValue || "");
|
|
3151
3197
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
3152
3198
|
const handleChange = (optionValue) => {
|
|
3153
3199
|
if (disabled) return;
|
|
@@ -3155,18 +3201,18 @@ var Radio = ({
|
|
|
3155
3201
|
onChange?.(optionValue);
|
|
3156
3202
|
};
|
|
3157
3203
|
const containerClass = orientation === "horizontal" ? "flex flex-wrap gap-4" : "flex flex-col gap-2";
|
|
3158
|
-
return /* @__PURE__ */ (0,
|
|
3204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: `${containerClass} ${className}`, role: "radiogroup", children: options.map((option) => {
|
|
3159
3205
|
const isDisabled = disabled || option.disabled;
|
|
3160
3206
|
const isChecked = value === option.value;
|
|
3161
3207
|
const id = `${name}-${option.value}`;
|
|
3162
|
-
return /* @__PURE__ */ (0,
|
|
3208
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(
|
|
3163
3209
|
"label",
|
|
3164
3210
|
{
|
|
3165
3211
|
htmlFor: id,
|
|
3166
3212
|
className: `flex items-center gap-2 cursor-pointer group ${isDisabled ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
3167
3213
|
children: [
|
|
3168
|
-
/* @__PURE__ */ (0,
|
|
3169
|
-
/* @__PURE__ */ (0,
|
|
3214
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "relative inline-flex items-center", children: [
|
|
3215
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3170
3216
|
"input",
|
|
3171
3217
|
{
|
|
3172
3218
|
type: "radio",
|
|
@@ -3179,14 +3225,14 @@ var Radio = ({
|
|
|
3179
3225
|
className: "sr-only peer"
|
|
3180
3226
|
}
|
|
3181
3227
|
),
|
|
3182
|
-
/* @__PURE__ */ (0,
|
|
3228
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: `w-4 h-4 rounded-full border-2 transition-all duration-200 flex items-center justify-center
|
|
3183
3229
|
border-[hsl(var(--input))]
|
|
3184
3230
|
${isDisabled ? "bg-[hsl(var(--muted))]" : "peer-hover:border-[hsl(var(--ring))]"}
|
|
3185
3231
|
${isChecked ? "border-[hsl(var(--primary))] bg-[hsl(var(--background))]" : ""}
|
|
3186
3232
|
peer-focus:ring-1 peer-focus:ring-[hsl(var(--ring))]/50
|
|
3187
|
-
`, children: /* @__PURE__ */ (0,
|
|
3233
|
+
`, children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: `w-2 h-2 rounded-full bg-[hsl(var(--primary))] transition-all duration-200 ${isChecked ? "scale-100" : "scale-0"}` }) })
|
|
3188
3234
|
] }),
|
|
3189
|
-
/* @__PURE__ */ (0,
|
|
3235
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: `text-sm font-medium text-[hsl(var(--foreground))] ${!isDisabled && "group-hover:text-[hsl(var(--foreground))]"}`, children: option.label })
|
|
3190
3236
|
]
|
|
3191
3237
|
},
|
|
3192
3238
|
option.value
|
|
@@ -3195,7 +3241,7 @@ var Radio = ({
|
|
|
3195
3241
|
};
|
|
3196
3242
|
|
|
3197
3243
|
// src/components/ProgressBar.tsx
|
|
3198
|
-
var
|
|
3244
|
+
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
3199
3245
|
var ProgressBar = ({
|
|
3200
3246
|
value,
|
|
3201
3247
|
max = 100,
|
|
@@ -3217,15 +3263,15 @@ var ProgressBar = ({
|
|
|
3217
3263
|
warning: "bg-[hsl(var(--warning))]",
|
|
3218
3264
|
danger: "bg-[hsl(var(--destructive))]"
|
|
3219
3265
|
};
|
|
3220
|
-
return /* @__PURE__ */ (0,
|
|
3221
|
-
(showLabel || label) && /* @__PURE__ */ (0,
|
|
3222
|
-
label && /* @__PURE__ */ (0,
|
|
3223
|
-
showLabel && /* @__PURE__ */ (0,
|
|
3266
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3267
|
+
(showLabel || label) && /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "flex justify-between items-center mb-1", children: [
|
|
3268
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "text-sm font-medium text-[hsl(var(--foreground))]", children: label }),
|
|
3269
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("span", { className: "text-sm font-medium text-[hsl(var(--muted-foreground))]", children: [
|
|
3224
3270
|
Math.round(percentage),
|
|
3225
3271
|
"%"
|
|
3226
3272
|
] })
|
|
3227
3273
|
] }),
|
|
3228
|
-
/* @__PURE__ */ (0,
|
|
3274
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
3229
3275
|
"div",
|
|
3230
3276
|
{
|
|
3231
3277
|
className: `w-full bg-[hsl(var(--muted))] rounded-full overflow-hidden ${sizeClasses7[size]}`,
|
|
@@ -3233,7 +3279,7 @@ var ProgressBar = ({
|
|
|
3233
3279
|
"aria-valuenow": value,
|
|
3234
3280
|
"aria-valuemin": 0,
|
|
3235
3281
|
"aria-valuemax": max,
|
|
3236
|
-
children: /* @__PURE__ */ (0,
|
|
3282
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
3237
3283
|
"div",
|
|
3238
3284
|
{
|
|
3239
3285
|
className: `${sizeClasses7[size]} ${variantClasses[variant]} rounded-full transition-all duration-300 ease-out`,
|
|
@@ -3246,8 +3292,8 @@ var ProgressBar = ({
|
|
|
3246
3292
|
};
|
|
3247
3293
|
|
|
3248
3294
|
// src/components/Slider.tsx
|
|
3249
|
-
var
|
|
3250
|
-
var
|
|
3295
|
+
var import_react19 = __toESM(require("react"));
|
|
3296
|
+
var import_jsx_runtime99 = require("react/jsx-runtime");
|
|
3251
3297
|
var Slider = ({
|
|
3252
3298
|
value: controlledValue,
|
|
3253
3299
|
defaultValue = 50,
|
|
@@ -3264,10 +3310,10 @@ var Slider = ({
|
|
|
3264
3310
|
defaultRangeValue = [25, 75],
|
|
3265
3311
|
onRangeChange
|
|
3266
3312
|
}) => {
|
|
3267
|
-
const [internalValue, setInternalValue] =
|
|
3268
|
-
const [internalRangeValue, setInternalRangeValue] =
|
|
3269
|
-
const trackRef = (0,
|
|
3270
|
-
const [isDragging, setIsDragging] =
|
|
3313
|
+
const [internalValue, setInternalValue] = import_react19.default.useState(defaultValue);
|
|
3314
|
+
const [internalRangeValue, setInternalRangeValue] = import_react19.default.useState(defaultRangeValue);
|
|
3315
|
+
const trackRef = (0, import_react19.useRef)(null);
|
|
3316
|
+
const [isDragging, setIsDragging] = import_react19.default.useState(null);
|
|
3271
3317
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
3272
3318
|
const rangeValue = controlledRangeValue !== void 0 ? controlledRangeValue : internalRangeValue;
|
|
3273
3319
|
const handleChange = (e) => {
|
|
@@ -3315,7 +3361,7 @@ var Slider = ({
|
|
|
3315
3361
|
const handleRangeEnd = () => {
|
|
3316
3362
|
setIsDragging(null);
|
|
3317
3363
|
};
|
|
3318
|
-
|
|
3364
|
+
import_react19.default.useEffect(() => {
|
|
3319
3365
|
if (isDragging) {
|
|
3320
3366
|
document.addEventListener("mousemove", handleRangeMouseMove);
|
|
3321
3367
|
document.addEventListener("mouseup", handleRangeEnd);
|
|
@@ -3333,18 +3379,18 @@ var Slider = ({
|
|
|
3333
3379
|
const minPercentage = (rangeValue[0] - min) / (max - min) * 100;
|
|
3334
3380
|
const maxPercentage = (rangeValue[1] - min) / (max - min) * 100;
|
|
3335
3381
|
if (range) {
|
|
3336
|
-
return /* @__PURE__ */ (0,
|
|
3337
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
3338
|
-
label && /* @__PURE__ */ (0,
|
|
3339
|
-
showValue && /* @__PURE__ */ (0,
|
|
3382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3383
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [
|
|
3384
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("label", { className: "text-sm font-medium text-[hsl(var(--foreground))]", children: label }),
|
|
3385
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("span", { className: "text-sm font-medium text-[hsl(var(--muted-foreground))]", children: [
|
|
3340
3386
|
rangeValue[0],
|
|
3341
3387
|
" - ",
|
|
3342
3388
|
rangeValue[1]
|
|
3343
3389
|
] })
|
|
3344
3390
|
] }),
|
|
3345
|
-
/* @__PURE__ */ (0,
|
|
3346
|
-
/* @__PURE__ */ (0,
|
|
3347
|
-
/* @__PURE__ */ (0,
|
|
3391
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "relative h-10 flex items-center", ref: trackRef, children: [
|
|
3392
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "absolute w-full h-2 bg-[hsl(var(--muted))] rounded-full" }),
|
|
3393
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3348
3394
|
"div",
|
|
3349
3395
|
{
|
|
3350
3396
|
className: "absolute h-2 bg-[hsl(var(--primary))] rounded-full pointer-events-none",
|
|
@@ -3354,7 +3400,7 @@ var Slider = ({
|
|
|
3354
3400
|
}
|
|
3355
3401
|
}
|
|
3356
3402
|
),
|
|
3357
|
-
/* @__PURE__ */ (0,
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3358
3404
|
"div",
|
|
3359
3405
|
{
|
|
3360
3406
|
className: `absolute w-4 h-4 -ml-2 rounded-full bg-[hsl(var(--background))] border-2 border-[hsl(var(--primary))] shadow-md cursor-pointer z-10
|
|
@@ -3371,7 +3417,7 @@ var Slider = ({
|
|
|
3371
3417
|
tabIndex: disabled ? -1 : 0
|
|
3372
3418
|
}
|
|
3373
3419
|
),
|
|
3374
|
-
/* @__PURE__ */ (0,
|
|
3420
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3375
3421
|
"div",
|
|
3376
3422
|
{
|
|
3377
3423
|
className: `absolute w-4 h-4 -ml-2 rounded-full bg-[hsl(var(--background))] border-2 border-[hsl(var(--primary))] shadow-md cursor-pointer z-10
|
|
@@ -3391,21 +3437,21 @@ var Slider = ({
|
|
|
3391
3437
|
] })
|
|
3392
3438
|
] });
|
|
3393
3439
|
}
|
|
3394
|
-
return /* @__PURE__ */ (0,
|
|
3395
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
3396
|
-
label && /* @__PURE__ */ (0,
|
|
3397
|
-
showValue && /* @__PURE__ */ (0,
|
|
3440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3441
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [
|
|
3442
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("label", { className: "text-sm font-medium text-[hsl(var(--foreground))]", children: label }),
|
|
3443
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "text-sm font-medium text-[hsl(var(--muted-foreground))]", children: value })
|
|
3398
3444
|
] }),
|
|
3399
|
-
/* @__PURE__ */ (0,
|
|
3400
|
-
/* @__PURE__ */ (0,
|
|
3401
|
-
/* @__PURE__ */ (0,
|
|
3445
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "relative h-10 flex items-center", children: [
|
|
3446
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "absolute w-full h-2 bg-[hsl(var(--muted))] rounded-full" }),
|
|
3447
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3402
3448
|
"div",
|
|
3403
3449
|
{
|
|
3404
3450
|
className: "absolute h-2 bg-[hsl(var(--primary))] rounded-full pointer-events-none",
|
|
3405
3451
|
style: { width: `${percentage}%` }
|
|
3406
3452
|
}
|
|
3407
3453
|
),
|
|
3408
|
-
/* @__PURE__ */ (0,
|
|
3454
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3409
3455
|
"div",
|
|
3410
3456
|
{
|
|
3411
3457
|
className: `absolute w-4 h-4 -ml-2 rounded-full bg-[hsl(var(--background))] border-2 border-[hsl(var(--primary))] shadow-md pointer-events-none z-10
|
|
@@ -3414,7 +3460,7 @@ var Slider = ({
|
|
|
3414
3460
|
style: { left: `${percentage}%` }
|
|
3415
3461
|
}
|
|
3416
3462
|
),
|
|
3417
|
-
/* @__PURE__ */ (0,
|
|
3463
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3418
3464
|
"input",
|
|
3419
3465
|
{
|
|
3420
3466
|
type: "range",
|
|
@@ -3436,8 +3482,8 @@ var Slider = ({
|
|
|
3436
3482
|
};
|
|
3437
3483
|
|
|
3438
3484
|
// src/components/Avatar.tsx
|
|
3439
|
-
var
|
|
3440
|
-
var
|
|
3485
|
+
var import_react20 = __toESM(require("react"));
|
|
3486
|
+
var import_jsx_runtime100 = require("react/jsx-runtime");
|
|
3441
3487
|
var Avatar = ({
|
|
3442
3488
|
src,
|
|
3443
3489
|
alt,
|
|
@@ -3447,7 +3493,7 @@ var Avatar = ({
|
|
|
3447
3493
|
className = "",
|
|
3448
3494
|
fallbackColor = "bg-[hsl(var(--primary))]"
|
|
3449
3495
|
}) => {
|
|
3450
|
-
const [imageError, setImageError] =
|
|
3496
|
+
const [imageError, setImageError] = import_react20.default.useState(false);
|
|
3451
3497
|
const sizeClasses7 = {
|
|
3452
3498
|
xs: "w-6 h-6 text-xs",
|
|
3453
3499
|
sm: "w-8 h-8 text-sm",
|
|
@@ -3465,11 +3511,11 @@ var Avatar = ({
|
|
|
3465
3511
|
};
|
|
3466
3512
|
const showImage = src && !imageError;
|
|
3467
3513
|
const showInitials = !showImage && name;
|
|
3468
|
-
return /* @__PURE__ */ (0,
|
|
3514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
|
|
3469
3515
|
"div",
|
|
3470
3516
|
{
|
|
3471
3517
|
className: `${sizeClasses7[size]} ${shapeClass} flex items-center justify-center overflow-hidden ${showImage ? "bg-[hsl(var(--muted))]" : `${fallbackColor} text-white`} ${className}`,
|
|
3472
|
-
children: showImage ? /* @__PURE__ */ (0,
|
|
3518
|
+
children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
|
|
3473
3519
|
"img",
|
|
3474
3520
|
{
|
|
3475
3521
|
src,
|
|
@@ -3477,13 +3523,13 @@ var Avatar = ({
|
|
|
3477
3523
|
className: "w-full h-full object-cover",
|
|
3478
3524
|
onError: () => setImageError(true)
|
|
3479
3525
|
}
|
|
3480
|
-
) : showInitials ? /* @__PURE__ */ (0,
|
|
3526
|
+
) : showInitials ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "font-semibold select-none", children: getInitials(name) }) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
|
|
3481
3527
|
"svg",
|
|
3482
3528
|
{
|
|
3483
3529
|
className: "w-full h-full text-[hsl(var(--muted-foreground))]",
|
|
3484
3530
|
fill: "currentColor",
|
|
3485
3531
|
viewBox: "0 0 24 24",
|
|
3486
|
-
children: /* @__PURE__ */ (0,
|
|
3532
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("path", { d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" })
|
|
3487
3533
|
}
|
|
3488
3534
|
)
|
|
3489
3535
|
}
|
|
@@ -3491,7 +3537,7 @@ var Avatar = ({
|
|
|
3491
3537
|
};
|
|
3492
3538
|
|
|
3493
3539
|
// src/components/Textarea.tsx
|
|
3494
|
-
var
|
|
3540
|
+
var import_jsx_runtime101 = require("react/jsx-runtime");
|
|
3495
3541
|
var Textarea = ({
|
|
3496
3542
|
label,
|
|
3497
3543
|
error,
|
|
@@ -3518,9 +3564,9 @@ var Textarea = ({
|
|
|
3518
3564
|
bg-transparent text-[hsl(var(--foreground))]
|
|
3519
3565
|
placeholder:text-[hsl(var(--muted-foreground))]
|
|
3520
3566
|
disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-[hsl(var(--muted))]`;
|
|
3521
|
-
return /* @__PURE__ */ (0,
|
|
3522
|
-
label && /* @__PURE__ */ (0,
|
|
3523
|
-
/* @__PURE__ */ (0,
|
|
3567
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3568
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("label", { className: "block text-sm font-medium text-[hsl(var(--foreground))] mb-1.5", children: label }),
|
|
3569
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
3524
3570
|
"textarea",
|
|
3525
3571
|
{
|
|
3526
3572
|
className: `${baseClasses} ${sizeClasses7[size]} ${resizeClasses[resize]}`,
|
|
@@ -3528,14 +3574,14 @@ var Textarea = ({
|
|
|
3528
3574
|
...props
|
|
3529
3575
|
}
|
|
3530
3576
|
),
|
|
3531
|
-
error && /* @__PURE__ */ (0,
|
|
3532
|
-
helperText && !error && /* @__PURE__ */ (0,
|
|
3577
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--destructive))]", children: error }),
|
|
3578
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "mt-1.5 text-sm text-[hsl(var(--muted-foreground))]", children: helperText })
|
|
3533
3579
|
] });
|
|
3534
3580
|
};
|
|
3535
3581
|
|
|
3536
3582
|
// src/components/RichTextEditor.tsx
|
|
3537
|
-
var
|
|
3538
|
-
var
|
|
3583
|
+
var import_react21 = require("react");
|
|
3584
|
+
var import_jsx_runtime102 = require("react/jsx-runtime");
|
|
3539
3585
|
var RichTextEditor = ({
|
|
3540
3586
|
value = "",
|
|
3541
3587
|
onChange,
|
|
@@ -3549,16 +3595,16 @@ var RichTextEditor = ({
|
|
|
3549
3595
|
helperText
|
|
3550
3596
|
}) => {
|
|
3551
3597
|
const { themeName } = useTheme();
|
|
3552
|
-
const editorRef = (0,
|
|
3553
|
-
const [isFocused, setIsFocused] = (0,
|
|
3554
|
-
const [activeFormats, setActiveFormats] = (0,
|
|
3555
|
-
const [showLinkModal, setShowLinkModal] = (0,
|
|
3556
|
-
const [linkUrl, setLinkUrl] = (0,
|
|
3557
|
-
const [showImageModal, setShowImageModal] = (0,
|
|
3558
|
-
const [imageUrl, setImageUrl] = (0,
|
|
3559
|
-
const [imageAlt, setImageAlt] = (0,
|
|
3560
|
-
const savedSelection = (0,
|
|
3561
|
-
(0,
|
|
3598
|
+
const editorRef = (0, import_react21.useRef)(null);
|
|
3599
|
+
const [isFocused, setIsFocused] = (0, import_react21.useState)(false);
|
|
3600
|
+
const [activeFormats, setActiveFormats] = (0, import_react21.useState)(/* @__PURE__ */ new Set());
|
|
3601
|
+
const [showLinkModal, setShowLinkModal] = (0, import_react21.useState)(false);
|
|
3602
|
+
const [linkUrl, setLinkUrl] = (0, import_react21.useState)("");
|
|
3603
|
+
const [showImageModal, setShowImageModal] = (0, import_react21.useState)(false);
|
|
3604
|
+
const [imageUrl, setImageUrl] = (0, import_react21.useState)("");
|
|
3605
|
+
const [imageAlt, setImageAlt] = (0, import_react21.useState)("");
|
|
3606
|
+
const savedSelection = (0, import_react21.useRef)(null);
|
|
3607
|
+
(0, import_react21.useLayoutEffect)(() => {
|
|
3562
3608
|
const styleId = "rich-text-editor-styles";
|
|
3563
3609
|
if (!document.getElementById(styleId)) {
|
|
3564
3610
|
const style = document.createElement("style");
|
|
@@ -3620,9 +3666,9 @@ var RichTextEditor = ({
|
|
|
3620
3666
|
document.head.appendChild(style);
|
|
3621
3667
|
}
|
|
3622
3668
|
}, []);
|
|
3623
|
-
const isInitialRender = (0,
|
|
3624
|
-
const isInternalUpdate = (0,
|
|
3625
|
-
(0,
|
|
3669
|
+
const isInitialRender = (0, import_react21.useRef)(true);
|
|
3670
|
+
const isInternalUpdate = (0, import_react21.useRef)(false);
|
|
3671
|
+
(0, import_react21.useEffect)(() => {
|
|
3626
3672
|
if (isInitialRender.current && editorRef.current) {
|
|
3627
3673
|
editorRef.current.innerHTML = value;
|
|
3628
3674
|
isInitialRender.current = false;
|
|
@@ -3633,7 +3679,7 @@ var RichTextEditor = ({
|
|
|
3633
3679
|
}
|
|
3634
3680
|
}
|
|
3635
3681
|
}, []);
|
|
3636
|
-
(0,
|
|
3682
|
+
(0, import_react21.useEffect)(() => {
|
|
3637
3683
|
if (!isInitialRender.current && !isInternalUpdate.current && editorRef.current) {
|
|
3638
3684
|
const currentHtml = editorRef.current.innerHTML;
|
|
3639
3685
|
if (currentHtml !== value) {
|
|
@@ -3676,7 +3722,7 @@ var RichTextEditor = ({
|
|
|
3676
3722
|
}
|
|
3677
3723
|
isInternalUpdate.current = false;
|
|
3678
3724
|
}, [value]);
|
|
3679
|
-
const updateActiveFormats = (0,
|
|
3725
|
+
const updateActiveFormats = (0, import_react21.useCallback)(() => {
|
|
3680
3726
|
const formats = /* @__PURE__ */ new Set();
|
|
3681
3727
|
if (document.queryCommandState("bold")) formats.add("bold");
|
|
3682
3728
|
if (document.queryCommandState("italic")) formats.add("italic");
|
|
@@ -3693,14 +3739,14 @@ var RichTextEditor = ({
|
|
|
3693
3739
|
}
|
|
3694
3740
|
setActiveFormats(formats);
|
|
3695
3741
|
}, []);
|
|
3696
|
-
const handleInput = (0,
|
|
3742
|
+
const handleInput = (0, import_react21.useCallback)(() => {
|
|
3697
3743
|
if (editorRef.current && onChange) {
|
|
3698
3744
|
isInternalUpdate.current = true;
|
|
3699
3745
|
onChange(editorRef.current.innerHTML);
|
|
3700
3746
|
}
|
|
3701
3747
|
updateActiveFormats();
|
|
3702
3748
|
}, [onChange, updateActiveFormats]);
|
|
3703
|
-
const handleFocus = (0,
|
|
3749
|
+
const handleFocus = (0, import_react21.useCallback)(() => {
|
|
3704
3750
|
setIsFocused(true);
|
|
3705
3751
|
if (editorRef.current && (!editorRef.current.innerHTML || editorRef.current.innerHTML === "")) {
|
|
3706
3752
|
editorRef.current.innerHTML = "<p><br></p>";
|
|
@@ -3714,28 +3760,28 @@ var RichTextEditor = ({
|
|
|
3714
3760
|
}
|
|
3715
3761
|
}
|
|
3716
3762
|
}, []);
|
|
3717
|
-
const handleFormat = (0,
|
|
3763
|
+
const handleFormat = (0, import_react21.useCallback)((command) => {
|
|
3718
3764
|
if (disabled) return;
|
|
3719
3765
|
document.execCommand(command, false);
|
|
3720
3766
|
editorRef.current?.focus();
|
|
3721
3767
|
updateActiveFormats();
|
|
3722
3768
|
handleInput();
|
|
3723
3769
|
}, [disabled, updateActiveFormats, handleInput]);
|
|
3724
|
-
const handleList = (0,
|
|
3770
|
+
const handleList = (0, import_react21.useCallback)((command) => {
|
|
3725
3771
|
if (disabled) return;
|
|
3726
3772
|
document.execCommand(command, false);
|
|
3727
3773
|
editorRef.current?.focus();
|
|
3728
3774
|
updateActiveFormats();
|
|
3729
3775
|
handleInput();
|
|
3730
3776
|
}, [disabled, updateActiveFormats, handleInput]);
|
|
3731
|
-
const handleHeading = (0,
|
|
3777
|
+
const handleHeading = (0, import_react21.useCallback)((level) => {
|
|
3732
3778
|
if (disabled) return;
|
|
3733
3779
|
document.execCommand("formatBlock", false, level);
|
|
3734
3780
|
editorRef.current?.focus();
|
|
3735
3781
|
updateActiveFormats();
|
|
3736
3782
|
handleInput();
|
|
3737
3783
|
}, [disabled, updateActiveFormats, handleInput]);
|
|
3738
|
-
const handleLink = (0,
|
|
3784
|
+
const handleLink = (0, import_react21.useCallback)(() => {
|
|
3739
3785
|
if (disabled) return;
|
|
3740
3786
|
const selection = window.getSelection();
|
|
3741
3787
|
if (selection && selection.rangeCount > 0) {
|
|
@@ -3743,7 +3789,7 @@ var RichTextEditor = ({
|
|
|
3743
3789
|
}
|
|
3744
3790
|
setShowLinkModal(true);
|
|
3745
3791
|
}, [disabled]);
|
|
3746
|
-
const insertLink = (0,
|
|
3792
|
+
const insertLink = (0, import_react21.useCallback)(() => {
|
|
3747
3793
|
if (!linkUrl || !editorRef.current) return;
|
|
3748
3794
|
const selection = window.getSelection();
|
|
3749
3795
|
if (savedSelection.current && selection) {
|
|
@@ -3761,7 +3807,7 @@ var RichTextEditor = ({
|
|
|
3761
3807
|
editorRef.current?.focus();
|
|
3762
3808
|
handleInput();
|
|
3763
3809
|
}, [linkUrl, handleInput]);
|
|
3764
|
-
const handleCode = (0,
|
|
3810
|
+
const handleCode = (0, import_react21.useCallback)(() => {
|
|
3765
3811
|
if (disabled) return;
|
|
3766
3812
|
const selection = window.getSelection();
|
|
3767
3813
|
if (selection && selection.rangeCount > 0) {
|
|
@@ -3777,7 +3823,7 @@ var RichTextEditor = ({
|
|
|
3777
3823
|
}
|
|
3778
3824
|
editorRef.current?.focus();
|
|
3779
3825
|
}, [disabled, handleInput]);
|
|
3780
|
-
const handleImage = (0,
|
|
3826
|
+
const handleImage = (0, import_react21.useCallback)(() => {
|
|
3781
3827
|
if (disabled) return;
|
|
3782
3828
|
const selection = window.getSelection();
|
|
3783
3829
|
if (selection && selection.rangeCount > 0) {
|
|
@@ -3785,7 +3831,7 @@ var RichTextEditor = ({
|
|
|
3785
3831
|
}
|
|
3786
3832
|
setShowImageModal(true);
|
|
3787
3833
|
}, [disabled]);
|
|
3788
|
-
const insertImage = (0,
|
|
3834
|
+
const insertImage = (0, import_react21.useCallback)(() => {
|
|
3789
3835
|
if (!imageUrl || !editorRef.current) return;
|
|
3790
3836
|
editorRef.current.focus();
|
|
3791
3837
|
const img = document.createElement("img");
|
|
@@ -3865,11 +3911,11 @@ var RichTextEditor = ({
|
|
|
3865
3911
|
const editorBaseClass = themeName === "minimalistic" ? "bg-transparent border-2 border-white text-white placeholder:text-[hsl(var(--muted-foreground))]" : "bg-[hsl(var(--card))] border border-[hsl(var(--input))] text-[hsl(var(--foreground))]";
|
|
3866
3912
|
const focusClass = isFocused && !disabled ? themeName === "minimalistic" ? "border-white" : "border-[hsl(var(--primary))] ring-1 ring-[hsl(var(--ring))]/50" : "";
|
|
3867
3913
|
const errorClass = error ? "border-red-500 dark:border-red-400" : "";
|
|
3868
|
-
return /* @__PURE__ */ (0,
|
|
3869
|
-
label && /* @__PURE__ */ (0,
|
|
3870
|
-
/* @__PURE__ */ (0,
|
|
3871
|
-
/* @__PURE__ */ (0,
|
|
3872
|
-
/* @__PURE__ */ (0,
|
|
3914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3915
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("label", { className: "block text-sm font-medium text-[hsl(var(--foreground))] mb-2", children: label }),
|
|
3916
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: `rounded-t-lg border-b ${editorBaseClass} p-2 flex flex-wrap gap-1`, children: [
|
|
3917
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex gap-1", children: [
|
|
3918
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3873
3919
|
"button",
|
|
3874
3920
|
{
|
|
3875
3921
|
type: "button",
|
|
@@ -3877,10 +3923,10 @@ var RichTextEditor = ({
|
|
|
3877
3923
|
className: getButtonClass(activeFormats.has("bold")),
|
|
3878
3924
|
disabled,
|
|
3879
3925
|
title: "Bold (Ctrl+B)",
|
|
3880
|
-
children: /* @__PURE__ */ (0,
|
|
3926
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { d: "M12.78 4c1.09 0 2.04.38 2.84 1.14.8.76 1.2 1.74 1.2 2.94 0 .9-.25 1.68-.76 2.36-.51.68-1.2 1.14-2.04 1.38v.08c1.06.22 1.89.7 2.48 1.44.59.74.88 1.64.88 2.7 0 1.34-.47 2.43-1.41 3.27C14.96 19.77 13.74 20 12.24 20H4V4h8.78zm-.66 7.14c.62 0 1.12-.18 1.5-.54.38-.36.57-.84.57-1.44 0-.6-.19-1.08-.57-1.44-.38-.36-.88-.54-1.5-.54H7.5v3.96h4.62zm.24 6.86c.68 0 1.24-.19 1.68-.57.44-.38.66-.9.66-1.56 0-.66-.22-1.18-.66-1.56-.44-.38-1-.57-1.68-.57H7.5v4.26h4.86z" }) })
|
|
3881
3927
|
}
|
|
3882
3928
|
),
|
|
3883
|
-
/* @__PURE__ */ (0,
|
|
3929
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3884
3930
|
"button",
|
|
3885
3931
|
{
|
|
3886
3932
|
type: "button",
|
|
@@ -3888,10 +3934,10 @@ var RichTextEditor = ({
|
|
|
3888
3934
|
className: getButtonClass(activeFormats.has("italic")),
|
|
3889
3935
|
disabled,
|
|
3890
3936
|
title: "Italic (Ctrl+I)",
|
|
3891
|
-
children: /* @__PURE__ */ (0,
|
|
3937
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { d: "M11.59 4H16v2h-1.71l-3.58 8H13v2H8v-2h1.71l3.58-8H11.59V4z" }) })
|
|
3892
3938
|
}
|
|
3893
3939
|
),
|
|
3894
|
-
/* @__PURE__ */ (0,
|
|
3940
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3895
3941
|
"button",
|
|
3896
3942
|
{
|
|
3897
3943
|
type: "button",
|
|
@@ -3899,10 +3945,10 @@ var RichTextEditor = ({
|
|
|
3899
3945
|
className: getButtonClass(activeFormats.has("underline")),
|
|
3900
3946
|
disabled,
|
|
3901
3947
|
title: "Underline (Ctrl+U)",
|
|
3902
|
-
children: /* @__PURE__ */ (0,
|
|
3948
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { d: "M10 16c-2.21 0-4-1.79-4-4V4h2v8c0 1.1.9 2 2 2s2-.9 2-2V4h2v8c0 2.21-1.79 4-4 4zM4 18h12v2H4v-2z" }) })
|
|
3903
3949
|
}
|
|
3904
3950
|
),
|
|
3905
|
-
/* @__PURE__ */ (0,
|
|
3951
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3906
3952
|
"button",
|
|
3907
3953
|
{
|
|
3908
3954
|
type: "button",
|
|
@@ -3910,13 +3956,13 @@ var RichTextEditor = ({
|
|
|
3910
3956
|
className: getButtonClass(activeFormats.has("strikeThrough")),
|
|
3911
3957
|
disabled,
|
|
3912
3958
|
title: "Strikethrough",
|
|
3913
|
-
children: /* @__PURE__ */ (0,
|
|
3959
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { d: "M10 4c-2 0-3.5.5-4.5 1.5S4 7.5 4 9h2c0-.7.2-1.2.6-1.6.4-.4 1-.6 1.9-.6.8 0 1.4.2 1.8.5.4.3.7.8.7 1.4 0 .5-.2.9-.5 1.2-.3.3-.9.6-1.8.9l-.7.2c-1.2.3-2.1.7-2.7 1.2C4.2 12.7 4 13.5 4 14.5c0 1.1.4 2 1.1 2.6.7.6 1.7.9 3 .9 2.1 0 3.6-.5 4.6-1.5.9-1 1.3-2.3 1.3-3.8h-2c0 .9-.2 1.6-.7 2.1-.5.5-1.2.7-2.2.7-.8 0-1.4-.2-1.8-.5-.4-.3-.6-.8-.6-1.4 0-.5.2-.9.5-1.2.3-.3.9-.6 1.8-.9l.7-.2c1.2-.3 2.1-.7 2.7-1.2.6-.5.9-1.3.9-2.3 0-1.2-.4-2.1-1.2-2.8-.8-.7-1.9-1-3.3-1zM2 10h16v1H2v-1z" }) })
|
|
3914
3960
|
}
|
|
3915
3961
|
)
|
|
3916
3962
|
] }),
|
|
3917
|
-
/* @__PURE__ */ (0,
|
|
3918
|
-
/* @__PURE__ */ (0,
|
|
3919
|
-
/* @__PURE__ */ (0,
|
|
3963
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "w-px bg-[hsl(var(--border))] mx-1" }),
|
|
3964
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex gap-1", children: [
|
|
3965
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3920
3966
|
"button",
|
|
3921
3967
|
{
|
|
3922
3968
|
type: "button",
|
|
@@ -3924,10 +3970,10 @@ var RichTextEditor = ({
|
|
|
3924
3970
|
className: getButtonClass(activeFormats.has("h1")),
|
|
3925
3971
|
disabled,
|
|
3926
3972
|
title: "Heading 1",
|
|
3927
|
-
children: /* @__PURE__ */ (0,
|
|
3973
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("text", { x: "2", y: "16", fontSize: "14", fontWeight: "bold", children: "H1" }) })
|
|
3928
3974
|
}
|
|
3929
3975
|
),
|
|
3930
|
-
/* @__PURE__ */ (0,
|
|
3976
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3931
3977
|
"button",
|
|
3932
3978
|
{
|
|
3933
3979
|
type: "button",
|
|
@@ -3935,10 +3981,10 @@ var RichTextEditor = ({
|
|
|
3935
3981
|
className: getButtonClass(activeFormats.has("h2")),
|
|
3936
3982
|
disabled,
|
|
3937
3983
|
title: "Heading 2",
|
|
3938
|
-
children: /* @__PURE__ */ (0,
|
|
3984
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("text", { x: "2", y: "16", fontSize: "14", fontWeight: "bold", children: "H2" }) })
|
|
3939
3985
|
}
|
|
3940
3986
|
),
|
|
3941
|
-
/* @__PURE__ */ (0,
|
|
3987
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3942
3988
|
"button",
|
|
3943
3989
|
{
|
|
3944
3990
|
type: "button",
|
|
@@ -3946,13 +3992,13 @@ var RichTextEditor = ({
|
|
|
3946
3992
|
className: getButtonClass(activeFormats.has("h3")),
|
|
3947
3993
|
disabled,
|
|
3948
3994
|
title: "Heading 3",
|
|
3949
|
-
children: /* @__PURE__ */ (0,
|
|
3995
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("text", { x: "2", y: "16", fontSize: "14", fontWeight: "bold", children: "H3" }) })
|
|
3950
3996
|
}
|
|
3951
3997
|
)
|
|
3952
3998
|
] }),
|
|
3953
|
-
/* @__PURE__ */ (0,
|
|
3954
|
-
/* @__PURE__ */ (0,
|
|
3955
|
-
/* @__PURE__ */ (0,
|
|
3999
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "w-px bg-[hsl(var(--border))] mx-1" }),
|
|
4000
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex gap-1", children: [
|
|
4001
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3956
4002
|
"button",
|
|
3957
4003
|
{
|
|
3958
4004
|
type: "button",
|
|
@@ -3960,10 +4006,10 @@ var RichTextEditor = ({
|
|
|
3960
4006
|
className: getButtonClass(activeFormats.has("ul")),
|
|
3961
4007
|
disabled,
|
|
3962
4008
|
title: "Bullet List",
|
|
3963
|
-
children: /* @__PURE__ */ (0,
|
|
4009
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { d: "M4 4h2v2H4V4zm4 0h8v2H8V4zM4 8h2v2H4V8zm4 0h8v2H8V8zm-4 4h2v2H4v-2zm4 0h8v2H8v-2zm-4 4h2v2H4v-2zm4 0h8v2H8v-2z" }) })
|
|
3964
4010
|
}
|
|
3965
4011
|
),
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
4012
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3967
4013
|
"button",
|
|
3968
4014
|
{
|
|
3969
4015
|
type: "button",
|
|
@@ -3971,13 +4017,13 @@ var RichTextEditor = ({
|
|
|
3971
4017
|
className: getButtonClass(activeFormats.has("ol")),
|
|
3972
4018
|
disabled,
|
|
3973
4019
|
title: "Numbered List",
|
|
3974
|
-
children: /* @__PURE__ */ (0,
|
|
4020
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { d: "M4 4h1v3H4V4zm0 4h1v1H3V8h2v1H4zm1 2H3v1h2v1H3v1h2v-3zM8 4h8v2H8V4zm0 4h8v2H8V8zm0 4h8v2H8v-2zm0 4h8v2H8v-2z" }) })
|
|
3975
4021
|
}
|
|
3976
4022
|
)
|
|
3977
4023
|
] }),
|
|
3978
|
-
/* @__PURE__ */ (0,
|
|
3979
|
-
/* @__PURE__ */ (0,
|
|
3980
|
-
/* @__PURE__ */ (0,
|
|
4024
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "w-px bg-[hsl(var(--border))] mx-1" }),
|
|
4025
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex gap-1", children: [
|
|
4026
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3981
4027
|
"button",
|
|
3982
4028
|
{
|
|
3983
4029
|
type: "button",
|
|
@@ -3985,10 +4031,10 @@ var RichTextEditor = ({
|
|
|
3985
4031
|
className: getButtonClass(false),
|
|
3986
4032
|
disabled,
|
|
3987
4033
|
title: "Insert Link",
|
|
3988
|
-
children: /* @__PURE__ */ (0,
|
|
4034
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" }) })
|
|
3989
4035
|
}
|
|
3990
4036
|
),
|
|
3991
|
-
/* @__PURE__ */ (0,
|
|
4037
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
3992
4038
|
"button",
|
|
3993
4039
|
{
|
|
3994
4040
|
type: "button",
|
|
@@ -3996,10 +4042,10 @@ var RichTextEditor = ({
|
|
|
3996
4042
|
className: getButtonClass(false),
|
|
3997
4043
|
disabled,
|
|
3998
4044
|
title: "Insert Image/Video",
|
|
3999
|
-
children: /* @__PURE__ */ (0,
|
|
4045
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
4000
4046
|
}
|
|
4001
4047
|
),
|
|
4002
|
-
/* @__PURE__ */ (0,
|
|
4048
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4003
4049
|
"button",
|
|
4004
4050
|
{
|
|
4005
4051
|
type: "button",
|
|
@@ -4007,12 +4053,12 @@ var RichTextEditor = ({
|
|
|
4007
4053
|
className: getButtonClass(false),
|
|
4008
4054
|
disabled,
|
|
4009
4055
|
title: "Code",
|
|
4010
|
-
children: /* @__PURE__ */ (0,
|
|
4056
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" }) })
|
|
4011
4057
|
}
|
|
4012
4058
|
)
|
|
4013
4059
|
] })
|
|
4014
4060
|
] }),
|
|
4015
|
-
/* @__PURE__ */ (0,
|
|
4061
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4016
4062
|
"div",
|
|
4017
4063
|
{
|
|
4018
4064
|
ref: editorRef,
|
|
@@ -4036,9 +4082,9 @@ var RichTextEditor = ({
|
|
|
4036
4082
|
suppressContentEditableWarning: true
|
|
4037
4083
|
}
|
|
4038
4084
|
),
|
|
4039
|
-
error && /* @__PURE__ */ (0,
|
|
4040
|
-
helperText && !error && /* @__PURE__ */ (0,
|
|
4041
|
-
/* @__PURE__ */ (0,
|
|
4085
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
4086
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("p", { className: "mt-1 text-sm text-[hsl(var(--muted-foreground))]", children: helperText }),
|
|
4087
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4042
4088
|
Modal,
|
|
4043
4089
|
{
|
|
4044
4090
|
isOpen: showLinkModal,
|
|
@@ -4048,8 +4094,8 @@ var RichTextEditor = ({
|
|
|
4048
4094
|
},
|
|
4049
4095
|
title: "Insert Link",
|
|
4050
4096
|
size: "sm",
|
|
4051
|
-
children: /* @__PURE__ */ (0,
|
|
4052
|
-
/* @__PURE__ */ (0,
|
|
4097
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "space-y-4", children: [
|
|
4098
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4053
4099
|
TextInput,
|
|
4054
4100
|
{
|
|
4055
4101
|
label: "URL",
|
|
@@ -4065,8 +4111,8 @@ var RichTextEditor = ({
|
|
|
4065
4111
|
}
|
|
4066
4112
|
}
|
|
4067
4113
|
),
|
|
4068
|
-
/* @__PURE__ */ (0,
|
|
4069
|
-
/* @__PURE__ */ (0,
|
|
4114
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex gap-2 justify-end", children: [
|
|
4115
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4070
4116
|
Button,
|
|
4071
4117
|
{
|
|
4072
4118
|
variant: "secondary",
|
|
@@ -4077,7 +4123,7 @@ var RichTextEditor = ({
|
|
|
4077
4123
|
children: "Cancel"
|
|
4078
4124
|
}
|
|
4079
4125
|
),
|
|
4080
|
-
/* @__PURE__ */ (0,
|
|
4126
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4081
4127
|
Button,
|
|
4082
4128
|
{
|
|
4083
4129
|
variant: "primary",
|
|
@@ -4090,7 +4136,7 @@ var RichTextEditor = ({
|
|
|
4090
4136
|
] })
|
|
4091
4137
|
}
|
|
4092
4138
|
),
|
|
4093
|
-
/* @__PURE__ */ (0,
|
|
4139
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4094
4140
|
Modal,
|
|
4095
4141
|
{
|
|
4096
4142
|
isOpen: showImageModal,
|
|
@@ -4101,8 +4147,8 @@ var RichTextEditor = ({
|
|
|
4101
4147
|
},
|
|
4102
4148
|
title: "Insert Image",
|
|
4103
4149
|
size: "sm",
|
|
4104
|
-
children: /* @__PURE__ */ (0,
|
|
4105
|
-
/* @__PURE__ */ (0,
|
|
4150
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "space-y-4", children: [
|
|
4151
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4106
4152
|
TextInput,
|
|
4107
4153
|
{
|
|
4108
4154
|
label: "Image URL",
|
|
@@ -4118,7 +4164,7 @@ var RichTextEditor = ({
|
|
|
4118
4164
|
}
|
|
4119
4165
|
}
|
|
4120
4166
|
),
|
|
4121
|
-
/* @__PURE__ */ (0,
|
|
4167
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4122
4168
|
TextInput,
|
|
4123
4169
|
{
|
|
4124
4170
|
label: "Alt Text (optional)",
|
|
@@ -4127,8 +4173,8 @@ var RichTextEditor = ({
|
|
|
4127
4173
|
placeholder: "Describe the image"
|
|
4128
4174
|
}
|
|
4129
4175
|
),
|
|
4130
|
-
/* @__PURE__ */ (0,
|
|
4131
|
-
/* @__PURE__ */ (0,
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex gap-2 justify-end", children: [
|
|
4177
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4132
4178
|
Button,
|
|
4133
4179
|
{
|
|
4134
4180
|
variant: "secondary",
|
|
@@ -4140,7 +4186,7 @@ var RichTextEditor = ({
|
|
|
4140
4186
|
children: "Cancel"
|
|
4141
4187
|
}
|
|
4142
4188
|
),
|
|
4143
|
-
/* @__PURE__ */ (0,
|
|
4189
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4144
4190
|
Button,
|
|
4145
4191
|
{
|
|
4146
4192
|
variant: "primary",
|
|
@@ -4157,19 +4203,19 @@ var RichTextEditor = ({
|
|
|
4157
4203
|
};
|
|
4158
4204
|
|
|
4159
4205
|
// src/components/Toast.tsx
|
|
4160
|
-
var
|
|
4161
|
-
var
|
|
4162
|
-
var ToastContext = (0,
|
|
4206
|
+
var import_react22 = require("react");
|
|
4207
|
+
var import_jsx_runtime103 = require("react/jsx-runtime");
|
|
4208
|
+
var ToastContext = (0, import_react22.createContext)(void 0);
|
|
4163
4209
|
var useToast = () => {
|
|
4164
|
-
const context = (0,
|
|
4210
|
+
const context = (0, import_react22.useContext)(ToastContext);
|
|
4165
4211
|
if (!context) {
|
|
4166
4212
|
throw new Error("useToast must be used within a ToastProvider");
|
|
4167
4213
|
}
|
|
4168
4214
|
return context;
|
|
4169
4215
|
};
|
|
4170
4216
|
var ToastProvider = ({ children, position = "top-right" }) => {
|
|
4171
|
-
const [toasts, setToasts] = (0,
|
|
4172
|
-
const addToast = (0,
|
|
4217
|
+
const [toasts, setToasts] = (0, import_react22.useState)([]);
|
|
4218
|
+
const addToast = (0, import_react22.useCallback)((toast2) => {
|
|
4173
4219
|
const id = Math.random().toString(36).substring(7);
|
|
4174
4220
|
const newToast = { ...toast2, id };
|
|
4175
4221
|
setToasts((prev) => [...prev, newToast]);
|
|
@@ -4178,7 +4224,7 @@ var ToastProvider = ({ children, position = "top-right" }) => {
|
|
|
4178
4224
|
removeToast(id);
|
|
4179
4225
|
}, duration);
|
|
4180
4226
|
}, []);
|
|
4181
|
-
const removeToast = (0,
|
|
4227
|
+
const removeToast = (0, import_react22.useCallback)((id) => {
|
|
4182
4228
|
setToasts((prev) => prev.filter((toast2) => toast2.id !== id));
|
|
4183
4229
|
}, []);
|
|
4184
4230
|
const positionClasses2 = {
|
|
@@ -4189,9 +4235,9 @@ var ToastProvider = ({ children, position = "top-right" }) => {
|
|
|
4189
4235
|
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
4190
4236
|
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
4191
4237
|
};
|
|
4192
|
-
return /* @__PURE__ */ (0,
|
|
4238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)(ToastContext.Provider, { value: { toasts, addToast, removeToast }, children: [
|
|
4193
4239
|
children,
|
|
4194
|
-
/* @__PURE__ */ (0,
|
|
4240
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)("div", { className: `fixed ${positionClasses2[position]} z-50 flex flex-col gap-2 max-w-md`, children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(ToastItem, { toast: toast2, onClose: () => removeToast(toast2.id) }, toast2.id)) })
|
|
4195
4241
|
] });
|
|
4196
4242
|
};
|
|
4197
4243
|
var ToastItem = ({ toast: toast2, onClose }) => {
|
|
@@ -4202,27 +4248,27 @@ var ToastItem = ({ toast: toast2, onClose }) => {
|
|
|
4202
4248
|
info: "bg-[hsl(var(--info))]/10 border-[hsl(var(--info))] text-[hsl(var(--info))]"
|
|
4203
4249
|
};
|
|
4204
4250
|
const typeIcons = {
|
|
4205
|
-
success: /* @__PURE__ */ (0,
|
|
4206
|
-
error: /* @__PURE__ */ (0,
|
|
4207
|
-
warning: /* @__PURE__ */ (0,
|
|
4208
|
-
info: /* @__PURE__ */ (0,
|
|
4251
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(CheckIcon, { size: "sm", className: "text-[hsl(var(--success))]" }),
|
|
4252
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(CloseIcon, { size: "sm", className: "text-[hsl(var(--destructive))]" }),
|
|
4253
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("svg", { className: "w-4 h-4 text-[hsl(var(--warning))]", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("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" }) }),
|
|
4254
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("svg", { className: "w-4 h-4 text-[hsl(var(--info))]", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("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" }) })
|
|
4209
4255
|
};
|
|
4210
4256
|
const type = toast2.type || "info";
|
|
4211
|
-
return /* @__PURE__ */ (0,
|
|
4257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)(
|
|
4212
4258
|
"div",
|
|
4213
4259
|
{
|
|
4214
4260
|
className: `flex items-start gap-3 p-4 rounded-md border-l-4 shadow-lg bg-[hsl(var(--card))] ${typeStyles[type]} animate-slide-in`,
|
|
4215
4261
|
role: "alert",
|
|
4216
4262
|
children: [
|
|
4217
|
-
/* @__PURE__ */ (0,
|
|
4218
|
-
/* @__PURE__ */ (0,
|
|
4219
|
-
/* @__PURE__ */ (0,
|
|
4263
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)("div", { className: "flex-shrink-0 mt-0.5", children: typeIcons[type] }),
|
|
4264
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)("p", { className: "flex-1 text-sm font-medium text-[hsl(var(--foreground))]", children: toast2.message }),
|
|
4265
|
+
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(
|
|
4220
4266
|
"button",
|
|
4221
4267
|
{
|
|
4222
4268
|
onClick: onClose,
|
|
4223
4269
|
className: "flex-shrink-0 text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] transition-colors",
|
|
4224
4270
|
"aria-label": "Close",
|
|
4225
|
-
children: /* @__PURE__ */ (0,
|
|
4271
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)(CloseIcon, { size: "sm" })
|
|
4226
4272
|
}
|
|
4227
4273
|
)
|
|
4228
4274
|
]
|
|
@@ -4253,8 +4299,8 @@ var toast = {
|
|
|
4253
4299
|
};
|
|
4254
4300
|
|
|
4255
4301
|
// src/components/Stepper.tsx
|
|
4256
|
-
var
|
|
4257
|
-
var
|
|
4302
|
+
var import_react23 = __toESM(require("react"));
|
|
4303
|
+
var import_jsx_runtime104 = require("react/jsx-runtime");
|
|
4258
4304
|
var Stepper = ({
|
|
4259
4305
|
steps,
|
|
4260
4306
|
currentStep,
|
|
@@ -4274,8 +4320,8 @@ var Stepper = ({
|
|
|
4274
4320
|
return { mobile: mobileVisible, desktop: desktopVisible };
|
|
4275
4321
|
};
|
|
4276
4322
|
const shouldShowCounter = isHorizontal && steps.length > 3;
|
|
4277
|
-
return /* @__PURE__ */ (0,
|
|
4278
|
-
shouldShowCounter && /* @__PURE__ */ (0,
|
|
4323
|
+
return /* @__PURE__ */ (0, import_jsx_runtime104.jsxs)("div", { className: `${isHorizontal ? "flex items-start w-full" : "flex flex-col"} ${className}`, children: [
|
|
4324
|
+
shouldShowCounter && /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("div", { className: "md:hidden flex items-center mr-4 flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime104.jsxs)("span", { className: "text-sm font-medium text-[hsl(var(--muted-foreground))]", children: [
|
|
4279
4325
|
currentStep,
|
|
4280
4326
|
"/",
|
|
4281
4327
|
steps.length
|
|
@@ -4288,19 +4334,19 @@ var Stepper = ({
|
|
|
4288
4334
|
const visibility = getStepVisibility(index);
|
|
4289
4335
|
const visibleMobileSteps = steps.filter((_, i) => getStepVisibility(i).mobile);
|
|
4290
4336
|
const isLastVisibleMobile = index === steps.map((_, i) => i).filter((i) => getStepVisibility(i).mobile).slice(-1)[0];
|
|
4291
|
-
return /* @__PURE__ */ (0,
|
|
4292
|
-
/* @__PURE__ */ (0,
|
|
4337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime104.jsxs)(import_react23.default.Fragment, { children: [
|
|
4338
|
+
/* @__PURE__ */ (0, import_jsx_runtime104.jsxs)("div", { className: `
|
|
4293
4339
|
flex ${isHorizontal ? "flex-col items-center flex-shrink-0" : "flex-row items-start"}
|
|
4294
4340
|
${isHorizontal ? "" : isLast ? "" : "mb-6"}
|
|
4295
4341
|
${!visibility.mobile ? "hidden md:flex" : ""}
|
|
4296
4342
|
${!visibility.desktop && visibility.mobile ? "md:hidden" : ""}
|
|
4297
4343
|
`, children: [
|
|
4298
|
-
/* @__PURE__ */ (0,
|
|
4299
|
-
/* @__PURE__ */ (0,
|
|
4344
|
+
/* @__PURE__ */ (0, import_jsx_runtime104.jsxs)("div", { className: `flex ${isHorizontal ? "flex-col items-center" : "flex-col items-center flex-shrink-0"}`, children: [
|
|
4345
|
+
/* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
4300
4346
|
"div",
|
|
4301
4347
|
{
|
|
4302
4348
|
className: `flex items-center justify-center w-10 h-10 rounded-full border-2 transition-all ${isCompleted ? "bg-[hsl(var(--primary))] border-[hsl(var(--primary))]" : isActive ? "border-[hsl(var(--primary))] bg-[hsl(var(--background))]" : "border-[hsl(var(--border))] bg-[hsl(var(--background))]"}`,
|
|
4303
|
-
children: isCompleted ? /* @__PURE__ */ (0,
|
|
4349
|
+
children: isCompleted ? /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(CheckIcon, { size: "sm", className: "text-[hsl(var(--primary-foreground))]" }) : /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
4304
4350
|
"span",
|
|
4305
4351
|
{
|
|
4306
4352
|
className: `text-sm font-semibold ${isActive ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))]"}`,
|
|
@@ -4309,29 +4355,29 @@ var Stepper = ({
|
|
|
4309
4355
|
)
|
|
4310
4356
|
}
|
|
4311
4357
|
),
|
|
4312
|
-
!isLast && !isHorizontal && /* @__PURE__ */ (0,
|
|
4358
|
+
!isLast && !isHorizontal && /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
4313
4359
|
"div",
|
|
4314
4360
|
{
|
|
4315
4361
|
className: `w-0.5 flex-1 min-h-[24px] ${isCompleted ? "bg-[hsl(var(--primary))]" : "bg-[hsl(var(--border))]"}`
|
|
4316
4362
|
}
|
|
4317
4363
|
)
|
|
4318
4364
|
] }),
|
|
4319
|
-
/* @__PURE__ */ (0,
|
|
4320
|
-
/* @__PURE__ */ (0,
|
|
4365
|
+
/* @__PURE__ */ (0, import_jsx_runtime104.jsxs)("div", { className: `${isHorizontal ? "mt-3 text-center" : "ml-4 flex-1 min-h-[40px] flex flex-col justify-center"}`, children: [
|
|
4366
|
+
/* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
4321
4367
|
"p",
|
|
4322
4368
|
{
|
|
4323
4369
|
className: `text-sm font-medium whitespace-nowrap ${isActive || isCompleted ? "text-[hsl(var(--foreground))]" : "text-[hsl(var(--muted-foreground))]"}`,
|
|
4324
4370
|
children: step.label
|
|
4325
4371
|
}
|
|
4326
4372
|
),
|
|
4327
|
-
step.description && /* @__PURE__ */ (0,
|
|
4373
|
+
step.description && /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("p", { className: "text-xs text-[hsl(var(--muted-foreground))] mt-1 whitespace-nowrap", children: step.description })
|
|
4328
4374
|
] })
|
|
4329
4375
|
] }),
|
|
4330
|
-
!isLast && isHorizontal && /* @__PURE__ */ (0,
|
|
4376
|
+
!isLast && isHorizontal && /* @__PURE__ */ (0, import_jsx_runtime104.jsx)("div", { className: `
|
|
4331
4377
|
flex items-start pt-5 mx-4 min-w-[80px] max-w-[200px] flex-1
|
|
4332
4378
|
${!visibility.mobile || isLastVisibleMobile ? "hidden md:flex" : ""}
|
|
4333
4379
|
${!visibility.desktop && visibility.mobile ? "md:hidden" : ""}
|
|
4334
|
-
`, children: /* @__PURE__ */ (0,
|
|
4380
|
+
`, children: /* @__PURE__ */ (0, import_jsx_runtime104.jsx)(
|
|
4335
4381
|
"div",
|
|
4336
4382
|
{
|
|
4337
4383
|
className: `h-0.5 w-full ${isCompleted ? "bg-[hsl(var(--primary))]" : "bg-[hsl(var(--border))]"}`
|
|
@@ -4343,7 +4389,7 @@ var Stepper = ({
|
|
|
4343
4389
|
};
|
|
4344
4390
|
|
|
4345
4391
|
// src/components/Divider.tsx
|
|
4346
|
-
var
|
|
4392
|
+
var import_jsx_runtime105 = require("react/jsx-runtime");
|
|
4347
4393
|
var Divider = ({
|
|
4348
4394
|
orientation = "horizontal",
|
|
4349
4395
|
variant = "solid",
|
|
@@ -4362,14 +4408,14 @@ var Divider = ({
|
|
|
4362
4408
|
center: "justify-center",
|
|
4363
4409
|
right: "justify-end"
|
|
4364
4410
|
};
|
|
4365
|
-
return /* @__PURE__ */ (0,
|
|
4366
|
-
labelPosition !== "left" && /* @__PURE__ */ (0,
|
|
4367
|
-
/* @__PURE__ */ (0,
|
|
4368
|
-
labelPosition !== "right" && /* @__PURE__ */ (0,
|
|
4411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)("div", { className: `flex items-center ${alignmentClasses[labelPosition]} ${className}`, role: "separator", children: [
|
|
4412
|
+
labelPosition !== "left" && /* @__PURE__ */ (0, import_jsx_runtime105.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-[hsl(var(--input))]` }),
|
|
4413
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)("span", { className: "px-4 text-sm text-[hsl(var(--muted-foreground))]", children: label }),
|
|
4414
|
+
labelPosition !== "right" && /* @__PURE__ */ (0, import_jsx_runtime105.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-[hsl(var(--input))]` })
|
|
4369
4415
|
] });
|
|
4370
4416
|
}
|
|
4371
4417
|
if (orientation === "vertical") {
|
|
4372
|
-
return /* @__PURE__ */ (0,
|
|
4418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
4373
4419
|
"div",
|
|
4374
4420
|
{
|
|
4375
4421
|
className: `inline-block h-full border-l ${variantClasses[variant]} border-[hsl(var(--input))] ${className}`,
|
|
@@ -4378,7 +4424,7 @@ var Divider = ({
|
|
|
4378
4424
|
}
|
|
4379
4425
|
);
|
|
4380
4426
|
}
|
|
4381
|
-
return /* @__PURE__ */ (0,
|
|
4427
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
4382
4428
|
"hr",
|
|
4383
4429
|
{
|
|
4384
4430
|
className: `border-t ${variantClasses[variant]} border-[hsl(var(--input))] ${className}`,
|
|
@@ -4388,8 +4434,8 @@ var Divider = ({
|
|
|
4388
4434
|
};
|
|
4389
4435
|
|
|
4390
4436
|
// src/components/FileUpload.tsx
|
|
4391
|
-
var
|
|
4392
|
-
var
|
|
4437
|
+
var import_react24 = require("react");
|
|
4438
|
+
var import_jsx_runtime106 = require("react/jsx-runtime");
|
|
4393
4439
|
var FileUpload = ({
|
|
4394
4440
|
accept,
|
|
4395
4441
|
multiple = false,
|
|
@@ -4402,9 +4448,9 @@ var FileUpload = ({
|
|
|
4402
4448
|
label,
|
|
4403
4449
|
helperText
|
|
4404
4450
|
}) => {
|
|
4405
|
-
const [files, setFiles] = (0,
|
|
4406
|
-
const [isDragging, setIsDragging] = (0,
|
|
4407
|
-
const fileInputRef = (0,
|
|
4451
|
+
const [files, setFiles] = (0, import_react24.useState)([]);
|
|
4452
|
+
const [isDragging, setIsDragging] = (0, import_react24.useState)(false);
|
|
4453
|
+
const fileInputRef = (0, import_react24.useRef)(null);
|
|
4408
4454
|
const formatFileSize = (bytes) => {
|
|
4409
4455
|
if (bytes === 0) return "0 Bytes";
|
|
4410
4456
|
const k = 1024;
|
|
@@ -4462,9 +4508,9 @@ var FileUpload = ({
|
|
|
4462
4508
|
setFiles(newFiles);
|
|
4463
4509
|
onChange?.(newFiles);
|
|
4464
4510
|
};
|
|
4465
|
-
return /* @__PURE__ */ (0,
|
|
4466
|
-
label && /* @__PURE__ */ (0,
|
|
4467
|
-
/* @__PURE__ */ (0,
|
|
4511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
4512
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("label", { className: "block text-sm font-medium text-[hsl(var(--foreground))] mb-2", children: label }),
|
|
4513
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
|
|
4468
4514
|
"div",
|
|
4469
4515
|
{
|
|
4470
4516
|
onDrop: handleDrop,
|
|
@@ -4473,7 +4519,7 @@ var FileUpload = ({
|
|
|
4473
4519
|
onClick: handleClick,
|
|
4474
4520
|
className: `relative border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-all ${isDragging ? "border-[hsl(var(--primary))] bg-[hsl(var(--primary))]/10" : "border-[hsl(var(--input))] hover:border-[hsl(var(--muted-foreground))]"} ${disabled ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
4475
4521
|
children: [
|
|
4476
|
-
/* @__PURE__ */ (0,
|
|
4522
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
4477
4523
|
"input",
|
|
4478
4524
|
{
|
|
4479
4525
|
ref: fileInputRef,
|
|
@@ -4485,14 +4531,14 @@ var FileUpload = ({
|
|
|
4485
4531
|
className: "hidden"
|
|
4486
4532
|
}
|
|
4487
4533
|
),
|
|
4488
|
-
/* @__PURE__ */ (0,
|
|
4489
|
-
/* @__PURE__ */ (0,
|
|
4490
|
-
/* @__PURE__ */ (0,
|
|
4491
|
-
/* @__PURE__ */ (0,
|
|
4492
|
-
/* @__PURE__ */ (0,
|
|
4534
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex flex-col items-center gap-2", children: [
|
|
4535
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "w-12 h-12 rounded-full bg-[hsl(var(--muted))] flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(UploadIcon, { size: "lg", className: "text-[hsl(var(--muted-foreground))]" }) }),
|
|
4536
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { children: [
|
|
4537
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("p", { className: "text-sm font-medium text-[hsl(var(--foreground))]", children: [
|
|
4538
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: "text-[hsl(var(--primary))]", children: "Click to upload" }),
|
|
4493
4539
|
" or drag and drop"
|
|
4494
4540
|
] }),
|
|
4495
|
-
/* @__PURE__ */ (0,
|
|
4541
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("p", { className: "text-xs text-[hsl(var(--muted-foreground))] mt-1", children: [
|
|
4496
4542
|
accept ? `Accepted: ${accept}` : "Any file type",
|
|
4497
4543
|
maxSize && ` \u2022 Max size: ${formatFileSize(maxSize)}`
|
|
4498
4544
|
] })
|
|
@@ -4501,17 +4547,17 @@ var FileUpload = ({
|
|
|
4501
4547
|
]
|
|
4502
4548
|
}
|
|
4503
4549
|
),
|
|
4504
|
-
helperText && /* @__PURE__ */ (0,
|
|
4505
|
-
files.length > 0 && /* @__PURE__ */ (0,
|
|
4550
|
+
helperText && /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("p", { className: "mt-2 text-sm text-[hsl(var(--muted-foreground))]", children: helperText }),
|
|
4551
|
+
files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "mt-4 space-y-2", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
|
|
4506
4552
|
"div",
|
|
4507
4553
|
{
|
|
4508
4554
|
className: "flex items-center justify-between p-3 bg-[hsl(var(--muted))] rounded-lg border border-[hsl(var(--border))]",
|
|
4509
4555
|
children: [
|
|
4510
|
-
/* @__PURE__ */ (0,
|
|
4511
|
-
/* @__PURE__ */ (0,
|
|
4512
|
-
/* @__PURE__ */ (0,
|
|
4556
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
4557
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("p", { className: "text-sm font-medium text-[hsl(var(--foreground))] truncate", children: file.name }),
|
|
4558
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("p", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: formatFileSize(file.size) })
|
|
4513
4559
|
] }),
|
|
4514
|
-
/* @__PURE__ */ (0,
|
|
4560
|
+
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
4515
4561
|
"button",
|
|
4516
4562
|
{
|
|
4517
4563
|
onClick: (e) => {
|
|
@@ -4520,7 +4566,7 @@ var FileUpload = ({
|
|
|
4520
4566
|
},
|
|
4521
4567
|
className: "ml-4 text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--destructive))] transition-colors",
|
|
4522
4568
|
"aria-label": "Remove file",
|
|
4523
|
-
children: /* @__PURE__ */ (0,
|
|
4569
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(CloseIcon, { size: "sm" })
|
|
4524
4570
|
}
|
|
4525
4571
|
)
|
|
4526
4572
|
]
|
|
@@ -4531,8 +4577,8 @@ var FileUpload = ({
|
|
|
4531
4577
|
};
|
|
4532
4578
|
|
|
4533
4579
|
// src/components/AudioPlayer.tsx
|
|
4534
|
-
var
|
|
4535
|
-
var
|
|
4580
|
+
var import_react25 = require("react");
|
|
4581
|
+
var import_jsx_runtime107 = require("react/jsx-runtime");
|
|
4536
4582
|
var AudioPlayer = ({
|
|
4537
4583
|
src,
|
|
4538
4584
|
title,
|
|
@@ -4555,18 +4601,18 @@ var AudioPlayer = ({
|
|
|
4555
4601
|
showChapters = true,
|
|
4556
4602
|
onChapterChange
|
|
4557
4603
|
}) => {
|
|
4558
|
-
const audioRef = (0,
|
|
4559
|
-
const [isPlaying, setIsPlaying] = (0,
|
|
4560
|
-
const [currentTime, setCurrentTime] = (0,
|
|
4561
|
-
const [duration, setDuration] = (0,
|
|
4562
|
-
const [volume, setVolume] = (0,
|
|
4563
|
-
const [isMuted, setIsMuted] = (0,
|
|
4564
|
-
const [isLoading, setIsLoading] = (0,
|
|
4565
|
-
const [currentChapter, setCurrentChapter] = (0,
|
|
4566
|
-
const [showChapterList, setShowChapterList] = (0,
|
|
4567
|
-
const [hoveredChapter, setHoveredChapter] = (0,
|
|
4568
|
-
const [hoverPosition, setHoverPosition] = (0,
|
|
4569
|
-
(0,
|
|
4604
|
+
const audioRef = (0, import_react25.useRef)(null);
|
|
4605
|
+
const [isPlaying, setIsPlaying] = (0, import_react25.useState)(false);
|
|
4606
|
+
const [currentTime, setCurrentTime] = (0, import_react25.useState)(0);
|
|
4607
|
+
const [duration, setDuration] = (0, import_react25.useState)(0);
|
|
4608
|
+
const [volume, setVolume] = (0, import_react25.useState)(1);
|
|
4609
|
+
const [isMuted, setIsMuted] = (0, import_react25.useState)(false);
|
|
4610
|
+
const [isLoading, setIsLoading] = (0, import_react25.useState)(true);
|
|
4611
|
+
const [currentChapter, setCurrentChapter] = (0, import_react25.useState)(null);
|
|
4612
|
+
const [showChapterList, setShowChapterList] = (0, import_react25.useState)(false);
|
|
4613
|
+
const [hoveredChapter, setHoveredChapter] = (0, import_react25.useState)(null);
|
|
4614
|
+
const [hoverPosition, setHoverPosition] = (0, import_react25.useState)({ x: 0, y: 0 });
|
|
4615
|
+
(0, import_react25.useEffect)(() => {
|
|
4570
4616
|
const audio = audioRef.current;
|
|
4571
4617
|
if (!audio) return;
|
|
4572
4618
|
const handleLoadedMetadata = () => {
|
|
@@ -4630,7 +4676,7 @@ var AudioPlayer = ({
|
|
|
4630
4676
|
audio.removeEventListener("error", handleError);
|
|
4631
4677
|
};
|
|
4632
4678
|
}, [onPlay, onPause, onEnded, onTimeUpdate]);
|
|
4633
|
-
(0,
|
|
4679
|
+
(0, import_react25.useEffect)(() => {
|
|
4634
4680
|
const audio = audioRef.current;
|
|
4635
4681
|
if (!audio) return;
|
|
4636
4682
|
audio.load();
|
|
@@ -4717,9 +4763,9 @@ var AudioPlayer = ({
|
|
|
4717
4763
|
};
|
|
4718
4764
|
const progress = duration > 0 ? currentTime / duration * 100 : 0;
|
|
4719
4765
|
if (variant === "mini") {
|
|
4720
|
-
return /* @__PURE__ */ (0,
|
|
4721
|
-
/* @__PURE__ */ (0,
|
|
4722
|
-
/* @__PURE__ */ (0,
|
|
4766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: `flex items-center gap-2 p-2 bg-[hsl(var(--card))] rounded-lg border border-[hsl(var(--border))] ${className}`, children: [
|
|
4767
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("audio", { ref: audioRef, src, preload, loop, autoPlay }),
|
|
4768
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4723
4769
|
Button,
|
|
4724
4770
|
{
|
|
4725
4771
|
iconOnly: true,
|
|
@@ -4728,16 +4774,16 @@ var AudioPlayer = ({
|
|
|
4728
4774
|
onClick: togglePlayPause,
|
|
4729
4775
|
disabled: isLoading,
|
|
4730
4776
|
"aria-label": isPlaying ? "Pause" : "Play",
|
|
4731
|
-
children: isPlaying ? /* @__PURE__ */ (0,
|
|
4777
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(PauseIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(PlayIcon, { size: "sm" })
|
|
4732
4778
|
}
|
|
4733
4779
|
),
|
|
4734
|
-
title && /* @__PURE__ */ (0,
|
|
4780
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-sm font-medium text-[hsl(var(--foreground))] truncate", children: title })
|
|
4735
4781
|
] });
|
|
4736
4782
|
}
|
|
4737
4783
|
if (variant === "compact") {
|
|
4738
|
-
return /* @__PURE__ */ (0,
|
|
4739
|
-
/* @__PURE__ */ (0,
|
|
4740
|
-
/* @__PURE__ */ (0,
|
|
4784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: `flex items-center gap-3 p-3 bg-[hsl(var(--card))] rounded-lg border border-[hsl(var(--border))] shadow-sm ${className}`, children: [
|
|
4785
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("audio", { ref: audioRef, src, preload, loop, autoPlay }),
|
|
4786
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4741
4787
|
Button,
|
|
4742
4788
|
{
|
|
4743
4789
|
iconOnly: true,
|
|
@@ -4746,17 +4792,17 @@ var AudioPlayer = ({
|
|
|
4746
4792
|
onClick: togglePlayPause,
|
|
4747
4793
|
disabled: isLoading,
|
|
4748
4794
|
"aria-label": isPlaying ? "Pause" : "Play",
|
|
4749
|
-
children: isPlaying ? /* @__PURE__ */ (0,
|
|
4795
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(PauseIcon, { size: "md" }) : /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(PlayIcon, { size: "md" })
|
|
4750
4796
|
}
|
|
4751
4797
|
),
|
|
4752
|
-
/* @__PURE__ */ (0,
|
|
4753
|
-
title && /* @__PURE__ */ (0,
|
|
4754
|
-
artist && /* @__PURE__ */ (0,
|
|
4798
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
4799
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "text-sm font-medium text-[hsl(var(--foreground))] truncate", children: title }),
|
|
4800
|
+
artist && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "text-xs text-[hsl(var(--muted-foreground))] truncate", children: artist })
|
|
4755
4801
|
] }),
|
|
4756
|
-
/* @__PURE__ */ (0,
|
|
4757
|
-
/* @__PURE__ */ (0,
|
|
4758
|
-
/* @__PURE__ */ (0,
|
|
4759
|
-
/* @__PURE__ */ (0,
|
|
4802
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [
|
|
4803
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-xs text-[hsl(var(--muted-foreground))] tabular-nums", children: formatTime(currentTime) }),
|
|
4804
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "relative flex-1 h-1.5 bg-[hsl(var(--muted))] rounded-full overflow-visible", children: [
|
|
4805
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4760
4806
|
"div",
|
|
4761
4807
|
{
|
|
4762
4808
|
className: "absolute h-full bg-[hsl(var(--primary))] rounded-full transition-all",
|
|
@@ -4765,7 +4811,7 @@ var AudioPlayer = ({
|
|
|
4765
4811
|
),
|
|
4766
4812
|
showChapters && chapters.length > 0 && chapters.map((chapter, index) => {
|
|
4767
4813
|
const markerPosition = duration > 0 ? chapter.startTime / duration * 100 : 0;
|
|
4768
|
-
return /* @__PURE__ */ (0,
|
|
4814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4769
4815
|
"div",
|
|
4770
4816
|
{
|
|
4771
4817
|
className: "absolute top-0 bottom-0 w-1 -ml-0.5 bg-[hsl(var(--background))] opacity-70 hover:opacity-100 hover:w-1.5 hover:-ml-0.5 cursor-pointer z-10 transition-all",
|
|
@@ -4781,7 +4827,7 @@ var AudioPlayer = ({
|
|
|
4781
4827
|
index
|
|
4782
4828
|
);
|
|
4783
4829
|
}),
|
|
4784
|
-
/* @__PURE__ */ (0,
|
|
4830
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4785
4831
|
"input",
|
|
4786
4832
|
{
|
|
4787
4833
|
type: "range",
|
|
@@ -4795,23 +4841,23 @@ var AudioPlayer = ({
|
|
|
4795
4841
|
}
|
|
4796
4842
|
)
|
|
4797
4843
|
] }),
|
|
4798
|
-
/* @__PURE__ */ (0,
|
|
4799
|
-
currentChapter && showChapters && /* @__PURE__ */ (0,
|
|
4844
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-xs text-[hsl(var(--muted-foreground))] tabular-nums", children: formatTime(duration) }),
|
|
4845
|
+
currentChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("span", { className: "text-xs text-[hsl(var(--primary))] font-medium truncate max-w-[120px]", children: [
|
|
4800
4846
|
"\u2022 ",
|
|
4801
4847
|
currentChapter.title
|
|
4802
4848
|
] })
|
|
4803
4849
|
] }),
|
|
4804
|
-
/* @__PURE__ */ (0,
|
|
4805
|
-
/* @__PURE__ */ (0,
|
|
4850
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4851
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4806
4852
|
"button",
|
|
4807
4853
|
{
|
|
4808
4854
|
onClick: toggleMute,
|
|
4809
4855
|
className: "text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))]",
|
|
4810
4856
|
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
4811
|
-
children: isMuted ? /* @__PURE__ */ (0,
|
|
4857
|
+
children: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(VolumeOffIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(VolumeUpIcon, { size: "sm" })
|
|
4812
4858
|
}
|
|
4813
4859
|
),
|
|
4814
|
-
/* @__PURE__ */ (0,
|
|
4860
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4815
4861
|
"input",
|
|
4816
4862
|
{
|
|
4817
4863
|
type: "range",
|
|
@@ -4825,24 +4871,24 @@ var AudioPlayer = ({
|
|
|
4825
4871
|
}
|
|
4826
4872
|
)
|
|
4827
4873
|
] }),
|
|
4828
|
-
hoveredChapter && showChapters && /* @__PURE__ */ (0,
|
|
4874
|
+
hoveredChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(
|
|
4829
4875
|
"div",
|
|
4830
4876
|
{
|
|
4831
4877
|
className: "fixed z-50 px-3 py-2 bg-[hsl(var(--popover))] text-white text-xs font-medium rounded shadow-lg pointer-events-none transform -translate-x-1/2 -translate-y-full",
|
|
4832
4878
|
style: { left: hoverPosition.x, top: hoverPosition.y - 8 },
|
|
4833
4879
|
children: [
|
|
4834
|
-
/* @__PURE__ */ (0,
|
|
4835
|
-
/* @__PURE__ */ (0,
|
|
4836
|
-
/* @__PURE__ */ (0,
|
|
4880
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "whitespace-nowrap", children: hoveredChapter.title }),
|
|
4881
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "text-[hsl(var(--muted-foreground))] text-[10px] mt-0.5", children: formatTime(hoveredChapter.startTime) }),
|
|
4882
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "absolute left-1/2 -bottom-1 w-2 h-2 bg-[hsl(var(--popover))] transform -translate-x-1/2 rotate-45" })
|
|
4837
4883
|
]
|
|
4838
4884
|
}
|
|
4839
4885
|
)
|
|
4840
4886
|
] });
|
|
4841
4887
|
}
|
|
4842
|
-
return /* @__PURE__ */ (0,
|
|
4843
|
-
/* @__PURE__ */ (0,
|
|
4844
|
-
/* @__PURE__ */ (0,
|
|
4845
|
-
coverArt && /* @__PURE__ */ (0,
|
|
4888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: `bg-[hsl(var(--card))] rounded-lg border border-[hsl(var(--border))] shadow-md overflow-hidden ${className}`, children: [
|
|
4889
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("audio", { ref: audioRef, src, preload, loop, autoPlay }),
|
|
4890
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center gap-4 p-4 border-b border-[hsl(var(--border))]", children: [
|
|
4891
|
+
coverArt && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "w-16 h-16 flex-shrink-0 rounded-md overflow-hidden bg-[hsl(var(--muted))]", children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4846
4892
|
"img",
|
|
4847
4893
|
{
|
|
4848
4894
|
src: coverArt,
|
|
@@ -4850,15 +4896,15 @@ var AudioPlayer = ({
|
|
|
4850
4896
|
className: "w-full h-full object-cover"
|
|
4851
4897
|
}
|
|
4852
4898
|
) }),
|
|
4853
|
-
/* @__PURE__ */ (0,
|
|
4854
|
-
title && /* @__PURE__ */ (0,
|
|
4855
|
-
artist && /* @__PURE__ */ (0,
|
|
4856
|
-
album && /* @__PURE__ */ (0,
|
|
4899
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
4900
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("h3", { className: "text-base font-semibold text-[hsl(var(--foreground))] truncate", children: title }),
|
|
4901
|
+
artist && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("p", { className: "text-sm text-[hsl(var(--muted-foreground))] truncate", children: artist }),
|
|
4902
|
+
album && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("p", { className: "text-xs text-[hsl(var(--muted-foreground))] truncate", children: album })
|
|
4857
4903
|
] })
|
|
4858
4904
|
] }),
|
|
4859
|
-
/* @__PURE__ */ (0,
|
|
4860
|
-
/* @__PURE__ */ (0,
|
|
4861
|
-
/* @__PURE__ */ (0,
|
|
4905
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "px-4 pt-4", children: [
|
|
4906
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "relative h-2 bg-[hsl(var(--muted))] rounded-full overflow-visible", children: [
|
|
4907
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4862
4908
|
"div",
|
|
4863
4909
|
{
|
|
4864
4910
|
className: "absolute h-full bg-[hsl(var(--primary))] rounded-full transition-all",
|
|
@@ -4867,7 +4913,7 @@ var AudioPlayer = ({
|
|
|
4867
4913
|
),
|
|
4868
4914
|
showChapters && chapters.length > 0 && chapters.map((chapter, index) => {
|
|
4869
4915
|
const markerPosition = duration > 0 ? chapter.startTime / duration * 100 : 0;
|
|
4870
|
-
return /* @__PURE__ */ (0,
|
|
4916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4871
4917
|
"div",
|
|
4872
4918
|
{
|
|
4873
4919
|
className: "absolute top-0 bottom-0 w-1 -ml-0.5 bg-[hsl(var(--background))] opacity-70 hover:opacity-100 hover:w-1.5 hover:-ml-0.5 cursor-pointer z-10 transition-all",
|
|
@@ -4883,19 +4929,19 @@ var AudioPlayer = ({
|
|
|
4883
4929
|
index
|
|
4884
4930
|
);
|
|
4885
4931
|
}),
|
|
4886
|
-
hoveredChapter && showChapters && /* @__PURE__ */ (0,
|
|
4932
|
+
hoveredChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(
|
|
4887
4933
|
"div",
|
|
4888
4934
|
{
|
|
4889
4935
|
className: "fixed z-50 px-3 py-2 bg-[hsl(var(--popover))] text-white text-xs font-medium rounded shadow-lg pointer-events-none transform -translate-x-1/2 -translate-y-full",
|
|
4890
4936
|
style: { left: hoverPosition.x, top: hoverPosition.y - 8 },
|
|
4891
4937
|
children: [
|
|
4892
|
-
/* @__PURE__ */ (0,
|
|
4893
|
-
/* @__PURE__ */ (0,
|
|
4894
|
-
/* @__PURE__ */ (0,
|
|
4938
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "whitespace-nowrap", children: hoveredChapter.title }),
|
|
4939
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "text-[hsl(var(--muted-foreground))] text-[10px] mt-0.5", children: formatTime(hoveredChapter.startTime) }),
|
|
4940
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "absolute left-1/2 -bottom-1 w-2 h-2 bg-[hsl(var(--popover))] transform -translate-x-1/2 rotate-45" })
|
|
4895
4941
|
]
|
|
4896
4942
|
}
|
|
4897
4943
|
),
|
|
4898
|
-
/* @__PURE__ */ (0,
|
|
4944
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4899
4945
|
"input",
|
|
4900
4946
|
{
|
|
4901
4947
|
type: "range",
|
|
@@ -4909,24 +4955,24 @@ var AudioPlayer = ({
|
|
|
4909
4955
|
}
|
|
4910
4956
|
)
|
|
4911
4957
|
] }),
|
|
4912
|
-
/* @__PURE__ */ (0,
|
|
4913
|
-
/* @__PURE__ */ (0,
|
|
4914
|
-
currentChapter && showChapters && /* @__PURE__ */ (0,
|
|
4915
|
-
/* @__PURE__ */ (0,
|
|
4958
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex justify-between items-center mt-1 text-xs text-[hsl(var(--muted-foreground))] tabular-nums", children: [
|
|
4959
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { children: formatTime(currentTime) }),
|
|
4960
|
+
currentChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-[hsl(var(--primary))] font-medium truncate max-w-[200px]", children: currentChapter.title }),
|
|
4961
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { children: formatTime(duration) })
|
|
4916
4962
|
] })
|
|
4917
4963
|
] }),
|
|
4918
|
-
/* @__PURE__ */ (0,
|
|
4919
|
-
/* @__PURE__ */ (0,
|
|
4920
|
-
/* @__PURE__ */ (0,
|
|
4964
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center justify-between px-4 py-4", children: [
|
|
4965
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [
|
|
4966
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4921
4967
|
"button",
|
|
4922
4968
|
{
|
|
4923
4969
|
onClick: toggleMute,
|
|
4924
4970
|
className: "text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] transition-colors",
|
|
4925
4971
|
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
4926
|
-
children: isMuted ? /* @__PURE__ */ (0,
|
|
4972
|
+
children: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(VolumeOffIcon, { size: "md" }) : /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(VolumeUpIcon, { size: "md" })
|
|
4927
4973
|
}
|
|
4928
4974
|
),
|
|
4929
|
-
/* @__PURE__ */ (0,
|
|
4975
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4930
4976
|
"input",
|
|
4931
4977
|
{
|
|
4932
4978
|
type: "range",
|
|
@@ -4940,8 +4986,8 @@ var AudioPlayer = ({
|
|
|
4940
4986
|
}
|
|
4941
4987
|
)
|
|
4942
4988
|
] }),
|
|
4943
|
-
/* @__PURE__ */ (0,
|
|
4944
|
-
showSkipButtons && /* @__PURE__ */ (0,
|
|
4989
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4990
|
+
showSkipButtons && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4945
4991
|
Button,
|
|
4946
4992
|
{
|
|
4947
4993
|
iconOnly: true,
|
|
@@ -4950,10 +4996,10 @@ var AudioPlayer = ({
|
|
|
4950
4996
|
onClick: handleSkipBack,
|
|
4951
4997
|
disabled: isLoading,
|
|
4952
4998
|
"aria-label": "Skip back 10 seconds",
|
|
4953
|
-
children: /* @__PURE__ */ (0,
|
|
4999
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(SkipBackIcon, { size: "md" })
|
|
4954
5000
|
}
|
|
4955
5001
|
),
|
|
4956
|
-
/* @__PURE__ */ (0,
|
|
5002
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4957
5003
|
Button,
|
|
4958
5004
|
{
|
|
4959
5005
|
iconOnly: true,
|
|
@@ -4962,10 +5008,10 @@ var AudioPlayer = ({
|
|
|
4962
5008
|
onClick: togglePlayPause,
|
|
4963
5009
|
disabled: isLoading,
|
|
4964
5010
|
"aria-label": isPlaying ? "Pause" : "Play",
|
|
4965
|
-
children: isPlaying ? /* @__PURE__ */ (0,
|
|
5011
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(PauseIcon, { size: "lg" }) : /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(PlayIcon, { size: "lg" })
|
|
4966
5012
|
}
|
|
4967
5013
|
),
|
|
4968
|
-
showSkipButtons && /* @__PURE__ */ (0,
|
|
5014
|
+
showSkipButtons && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4969
5015
|
Button,
|
|
4970
5016
|
{
|
|
4971
5017
|
iconOnly: true,
|
|
@@ -4974,11 +5020,11 @@ var AudioPlayer = ({
|
|
|
4974
5020
|
onClick: handleSkipForward,
|
|
4975
5021
|
disabled: isLoading,
|
|
4976
5022
|
"aria-label": "Skip forward 10 seconds",
|
|
4977
|
-
children: /* @__PURE__ */ (0,
|
|
5023
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(SkipForwardIcon, { size: "md" })
|
|
4978
5024
|
}
|
|
4979
5025
|
)
|
|
4980
5026
|
] }),
|
|
4981
|
-
/* @__PURE__ */ (0,
|
|
5027
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "flex-1 flex justify-end", children: showChapters && chapters.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(
|
|
4982
5028
|
"button",
|
|
4983
5029
|
{
|
|
4984
5030
|
onClick: () => setShowChapterList(!showChapterList),
|
|
@@ -4992,16 +5038,16 @@ var AudioPlayer = ({
|
|
|
4992
5038
|
}
|
|
4993
5039
|
) })
|
|
4994
5040
|
] }),
|
|
4995
|
-
showChapters && showChapterList && chapters.length > 0 && /* @__PURE__ */ (0,
|
|
5041
|
+
showChapters && showChapterList && chapters.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "border-t border-[hsl(var(--border))] bg-[hsl(var(--muted))]/50 max-h-48 overflow-y-auto", children: chapters.map((chapter, index) => {
|
|
4996
5042
|
const isCurrentChapter = currentChapter?.startTime === chapter.startTime;
|
|
4997
|
-
return /* @__PURE__ */ (0,
|
|
5043
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
4998
5044
|
"button",
|
|
4999
5045
|
{
|
|
5000
5046
|
onClick: () => jumpToChapter(chapter),
|
|
5001
5047
|
className: `w-full text-left px-4 py-2 hover:bg-[hsl(var(--accent))] transition-colors ${isCurrentChapter ? "bg-[hsl(var(--primary))]/10 border-l-2 border-[hsl(var(--primary))]" : ""}`,
|
|
5002
|
-
children: /* @__PURE__ */ (0,
|
|
5003
|
-
/* @__PURE__ */ (0,
|
|
5004
|
-
/* @__PURE__ */ (0,
|
|
5048
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
5049
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: `text-sm font-medium ${isCurrentChapter ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--foreground))]"}`, children: chapter.title }),
|
|
5050
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-xs text-[hsl(var(--muted-foreground))] tabular-nums", children: formatTime(chapter.startTime) })
|
|
5005
5051
|
] })
|
|
5006
5052
|
},
|
|
5007
5053
|
index
|
|
@@ -5011,8 +5057,8 @@ var AudioPlayer = ({
|
|
|
5011
5057
|
};
|
|
5012
5058
|
|
|
5013
5059
|
// src/components/VideoPlayer.tsx
|
|
5014
|
-
var
|
|
5015
|
-
var
|
|
5060
|
+
var import_react26 = require("react");
|
|
5061
|
+
var import_jsx_runtime108 = require("react/jsx-runtime");
|
|
5016
5062
|
var VideoPlayer = ({
|
|
5017
5063
|
src,
|
|
5018
5064
|
poster,
|
|
@@ -5036,21 +5082,21 @@ var VideoPlayer = ({
|
|
|
5036
5082
|
showChapters = true,
|
|
5037
5083
|
onChapterChange
|
|
5038
5084
|
}) => {
|
|
5039
|
-
const videoRef = (0,
|
|
5040
|
-
const containerRef = (0,
|
|
5041
|
-
const [isPlaying, setIsPlaying] = (0,
|
|
5042
|
-
const [currentTime, setCurrentTime] = (0,
|
|
5043
|
-
const [duration, setDuration] = (0,
|
|
5044
|
-
const [volume, setVolume] = (0,
|
|
5045
|
-
const [isMuted, setIsMuted] = (0,
|
|
5046
|
-
const [isLoading, setIsLoading] = (0,
|
|
5047
|
-
const [isFullscreen, setIsFullscreen] = (0,
|
|
5048
|
-
const [showControlsOverlay, setShowControlsOverlay] = (0,
|
|
5049
|
-
const hideControlsTimeout = (0,
|
|
5050
|
-
const [currentChapter, setCurrentChapter] = (0,
|
|
5051
|
-
const [hoveredChapter, setHoveredChapter] = (0,
|
|
5052
|
-
const [hoverPosition, setHoverPosition] = (0,
|
|
5053
|
-
(0,
|
|
5085
|
+
const videoRef = (0, import_react26.useRef)(null);
|
|
5086
|
+
const containerRef = (0, import_react26.useRef)(null);
|
|
5087
|
+
const [isPlaying, setIsPlaying] = (0, import_react26.useState)(false);
|
|
5088
|
+
const [currentTime, setCurrentTime] = (0, import_react26.useState)(0);
|
|
5089
|
+
const [duration, setDuration] = (0, import_react26.useState)(0);
|
|
5090
|
+
const [volume, setVolume] = (0, import_react26.useState)(muted ? 0 : 1);
|
|
5091
|
+
const [isMuted, setIsMuted] = (0, import_react26.useState)(muted);
|
|
5092
|
+
const [isLoading, setIsLoading] = (0, import_react26.useState)(true);
|
|
5093
|
+
const [isFullscreen, setIsFullscreen] = (0, import_react26.useState)(false);
|
|
5094
|
+
const [showControlsOverlay, setShowControlsOverlay] = (0, import_react26.useState)(true);
|
|
5095
|
+
const hideControlsTimeout = (0, import_react26.useRef)(null);
|
|
5096
|
+
const [currentChapter, setCurrentChapter] = (0, import_react26.useState)(null);
|
|
5097
|
+
const [hoveredChapter, setHoveredChapter] = (0, import_react26.useState)(null);
|
|
5098
|
+
const [hoverPosition, setHoverPosition] = (0, import_react26.useState)({ x: 0, y: 0 });
|
|
5099
|
+
(0, import_react26.useEffect)(() => {
|
|
5054
5100
|
const video = videoRef.current;
|
|
5055
5101
|
if (!video) return;
|
|
5056
5102
|
const handleLoadedMetadata = () => {
|
|
@@ -5119,12 +5165,12 @@ var VideoPlayer = ({
|
|
|
5119
5165
|
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
5120
5166
|
};
|
|
5121
5167
|
}, [onPlay, onPause, onEnded, onTimeUpdate]);
|
|
5122
|
-
(0,
|
|
5168
|
+
(0, import_react26.useEffect)(() => {
|
|
5123
5169
|
const video = videoRef.current;
|
|
5124
5170
|
if (!video) return;
|
|
5125
5171
|
video.load();
|
|
5126
5172
|
}, [src]);
|
|
5127
|
-
(0,
|
|
5173
|
+
(0, import_react26.useEffect)(() => {
|
|
5128
5174
|
if (!isFullscreen || !isPlaying) return;
|
|
5129
5175
|
const resetTimeout = () => {
|
|
5130
5176
|
if (hideControlsTimeout.current) {
|
|
@@ -5239,7 +5285,7 @@ var VideoPlayer = ({
|
|
|
5239
5285
|
}
|
|
5240
5286
|
};
|
|
5241
5287
|
if (variant === "compact") {
|
|
5242
|
-
return /* @__PURE__ */ (0,
|
|
5288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5243
5289
|
"div",
|
|
5244
5290
|
{
|
|
5245
5291
|
ref: containerRef,
|
|
@@ -5247,7 +5293,7 @@ var VideoPlayer = ({
|
|
|
5247
5293
|
style: { width, height },
|
|
5248
5294
|
onMouseMove: handleMouseMove,
|
|
5249
5295
|
children: [
|
|
5250
|
-
/* @__PURE__ */ (0,
|
|
5296
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5251
5297
|
"video",
|
|
5252
5298
|
{
|
|
5253
5299
|
ref: videoRef,
|
|
@@ -5261,8 +5307,8 @@ var VideoPlayer = ({
|
|
|
5261
5307
|
onClick: togglePlayPause
|
|
5262
5308
|
}
|
|
5263
5309
|
),
|
|
5264
|
-
showControls && /* @__PURE__ */ (0,
|
|
5265
|
-
/* @__PURE__ */ (0,
|
|
5310
|
+
showControls && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: `absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent transition-opacity ${showControlsOverlay || !isPlaying ? "opacity-100" : "opacity-0"}`, children: [
|
|
5311
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5266
5312
|
Button,
|
|
5267
5313
|
{
|
|
5268
5314
|
iconOnly: true,
|
|
@@ -5272,12 +5318,12 @@ var VideoPlayer = ({
|
|
|
5272
5318
|
disabled: isLoading,
|
|
5273
5319
|
className: "!w-16 !h-16 !rounded-full bg-white/20 hover:bg-white/30 backdrop-blur-sm",
|
|
5274
5320
|
"aria-label": isPlaying ? "Pause" : "Play",
|
|
5275
|
-
children: isPlaying ? /* @__PURE__ */ (0,
|
|
5321
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(PauseIcon, { size: "xl" }) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(PlayIcon, { size: "xl" })
|
|
5276
5322
|
}
|
|
5277
5323
|
) }),
|
|
5278
|
-
/* @__PURE__ */ (0,
|
|
5279
|
-
/* @__PURE__ */ (0,
|
|
5280
|
-
/* @__PURE__ */ (0,
|
|
5324
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "absolute bottom-0 left-0 right-0 p-3 space-y-2", children: [
|
|
5325
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "relative h-1 bg-white/30 rounded-full overflow-visible", children: [
|
|
5326
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5281
5327
|
"div",
|
|
5282
5328
|
{
|
|
5283
5329
|
className: "absolute h-full bg-[hsl(var(--primary))] rounded-full transition-all",
|
|
@@ -5286,7 +5332,7 @@ var VideoPlayer = ({
|
|
|
5286
5332
|
),
|
|
5287
5333
|
showChapters && chapters.length > 0 && chapters.map((chapter, index) => {
|
|
5288
5334
|
const markerPosition = duration > 0 ? chapter.startTime / duration * 100 : 0;
|
|
5289
|
-
return /* @__PURE__ */ (0,
|
|
5335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5290
5336
|
"div",
|
|
5291
5337
|
{
|
|
5292
5338
|
className: "absolute top-0 bottom-0 w-1 -ml-0.5 bg-white opacity-70 hover:opacity-100 hover:w-1.5 hover:-ml-0.5 cursor-pointer z-10 transition-all",
|
|
@@ -5302,7 +5348,7 @@ var VideoPlayer = ({
|
|
|
5302
5348
|
index
|
|
5303
5349
|
);
|
|
5304
5350
|
}),
|
|
5305
|
-
/* @__PURE__ */ (0,
|
|
5351
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5306
5352
|
"input",
|
|
5307
5353
|
{
|
|
5308
5354
|
type: "range",
|
|
@@ -5316,50 +5362,50 @@ var VideoPlayer = ({
|
|
|
5316
5362
|
}
|
|
5317
5363
|
)
|
|
5318
5364
|
] }),
|
|
5319
|
-
/* @__PURE__ */ (0,
|
|
5320
|
-
/* @__PURE__ */ (0,
|
|
5321
|
-
/* @__PURE__ */ (0,
|
|
5365
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
5366
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5367
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("span", { className: "text-xs text-white tabular-nums", children: [
|
|
5322
5368
|
formatTime(currentTime),
|
|
5323
5369
|
" / ",
|
|
5324
5370
|
formatTime(duration)
|
|
5325
5371
|
] }),
|
|
5326
|
-
currentChapter && showChapters && /* @__PURE__ */ (0,
|
|
5372
|
+
currentChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("span", { className: "text-xs text-white/90 font-medium truncate max-w-[150px]", children: [
|
|
5327
5373
|
"\u2022 ",
|
|
5328
5374
|
currentChapter.title
|
|
5329
5375
|
] })
|
|
5330
5376
|
] }),
|
|
5331
|
-
/* @__PURE__ */ (0,
|
|
5332
|
-
/* @__PURE__ */ (0,
|
|
5377
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5378
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5333
5379
|
"button",
|
|
5334
5380
|
{
|
|
5335
5381
|
onClick: toggleMute,
|
|
5336
5382
|
className: "text-white hover:text-[hsl(var(--foreground))] transition-colors",
|
|
5337
5383
|
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
5338
|
-
children: isMuted ? /* @__PURE__ */ (0,
|
|
5384
|
+
children: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(VolumeOffIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(VolumeUpIcon, { size: "sm" })
|
|
5339
5385
|
}
|
|
5340
5386
|
),
|
|
5341
|
-
/* @__PURE__ */ (0,
|
|
5387
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5342
5388
|
"button",
|
|
5343
5389
|
{
|
|
5344
5390
|
onClick: toggleFullscreen,
|
|
5345
5391
|
className: "text-white hover:text-[hsl(var(--foreground))] transition-colors",
|
|
5346
5392
|
"aria-label": isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
|
|
5347
|
-
children: isFullscreen ? /* @__PURE__ */ (0,
|
|
5393
|
+
children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(FullscreenExitIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(FullscreenIcon, { size: "sm" })
|
|
5348
5394
|
}
|
|
5349
5395
|
)
|
|
5350
5396
|
] })
|
|
5351
5397
|
] })
|
|
5352
5398
|
] })
|
|
5353
5399
|
] }),
|
|
5354
|
-
hoveredChapter && showChapters && /* @__PURE__ */ (0,
|
|
5400
|
+
hoveredChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5355
5401
|
"div",
|
|
5356
5402
|
{
|
|
5357
5403
|
className: "fixed z-50 px-3 py-2 bg-[hsl(var(--popover))] text-white text-xs font-medium rounded shadow-lg pointer-events-none transform -translate-x-1/2 -translate-y-full",
|
|
5358
5404
|
style: { left: hoverPosition.x, top: hoverPosition.y - 8 },
|
|
5359
5405
|
children: [
|
|
5360
|
-
/* @__PURE__ */ (0,
|
|
5361
|
-
/* @__PURE__ */ (0,
|
|
5362
|
-
/* @__PURE__ */ (0,
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "whitespace-nowrap", children: hoveredChapter.title }),
|
|
5407
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "text-[hsl(var(--muted-foreground))] text-[10px] mt-0.5", children: formatTime(hoveredChapter.startTime) }),
|
|
5408
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "absolute left-1/2 -bottom-1 w-2 h-2 bg-[hsl(var(--popover))] transform -translate-x-1/2 rotate-45" })
|
|
5363
5409
|
]
|
|
5364
5410
|
}
|
|
5365
5411
|
)
|
|
@@ -5367,9 +5413,9 @@ var VideoPlayer = ({
|
|
|
5367
5413
|
}
|
|
5368
5414
|
);
|
|
5369
5415
|
}
|
|
5370
|
-
return /* @__PURE__ */ (0,
|
|
5371
|
-
title && /* @__PURE__ */ (0,
|
|
5372
|
-
/* @__PURE__ */ (0,
|
|
5416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: `bg-[hsl(var(--card))] rounded-lg border border-[hsl(var(--border))] shadow-md overflow-hidden ${className}`, children: [
|
|
5417
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "px-4 py-3 border-b border-[hsl(var(--border))]", children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("h3", { className: "text-base font-semibold text-[hsl(var(--foreground))] truncate", children: title }) }),
|
|
5418
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5373
5419
|
"div",
|
|
5374
5420
|
{
|
|
5375
5421
|
ref: containerRef,
|
|
@@ -5377,7 +5423,7 @@ var VideoPlayer = ({
|
|
|
5377
5423
|
style: { width, height },
|
|
5378
5424
|
onMouseMove: handleMouseMove,
|
|
5379
5425
|
children: [
|
|
5380
|
-
/* @__PURE__ */ (0,
|
|
5426
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5381
5427
|
"video",
|
|
5382
5428
|
{
|
|
5383
5429
|
ref: videoRef,
|
|
@@ -5392,8 +5438,8 @@ var VideoPlayer = ({
|
|
|
5392
5438
|
onClick: togglePlayPause
|
|
5393
5439
|
}
|
|
5394
5440
|
),
|
|
5395
|
-
showControls && !controls && /* @__PURE__ */ (0,
|
|
5396
|
-
/* @__PURE__ */ (0,
|
|
5441
|
+
showControls && !controls && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: `absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent transition-opacity ${showControlsOverlay || !isPlaying ? "opacity-100" : "opacity-0"}`, children: [
|
|
5442
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5397
5443
|
Button,
|
|
5398
5444
|
{
|
|
5399
5445
|
iconOnly: true,
|
|
@@ -5403,12 +5449,12 @@ var VideoPlayer = ({
|
|
|
5403
5449
|
disabled: isLoading,
|
|
5404
5450
|
className: "!w-20 !h-20 !rounded-full bg-white/20 hover:bg-white/30 backdrop-blur-sm",
|
|
5405
5451
|
"aria-label": isPlaying ? "Pause" : "Play",
|
|
5406
|
-
children: isPlaying ? /* @__PURE__ */ (0,
|
|
5452
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(PauseIcon, { size: "xl" }) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(PlayIcon, { size: "xl" })
|
|
5407
5453
|
}
|
|
5408
5454
|
) }),
|
|
5409
|
-
/* @__PURE__ */ (0,
|
|
5410
|
-
/* @__PURE__ */ (0,
|
|
5411
|
-
/* @__PURE__ */ (0,
|
|
5455
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "absolute bottom-0 left-0 right-0 p-4 space-y-3", children: [
|
|
5456
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "relative h-1.5 bg-white/30 rounded-full overflow-visible", children: [
|
|
5457
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5412
5458
|
"div",
|
|
5413
5459
|
{
|
|
5414
5460
|
className: "absolute h-full bg-[hsl(var(--primary))] rounded-full transition-all",
|
|
@@ -5417,7 +5463,7 @@ var VideoPlayer = ({
|
|
|
5417
5463
|
),
|
|
5418
5464
|
showChapters && chapters.length > 0 && chapters.map((chapter, index) => {
|
|
5419
5465
|
const markerPosition = duration > 0 ? chapter.startTime / duration * 100 : 0;
|
|
5420
|
-
return /* @__PURE__ */ (0,
|
|
5466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5421
5467
|
"div",
|
|
5422
5468
|
{
|
|
5423
5469
|
className: "absolute top-0 bottom-0 w-1 -ml-0.5 bg-white opacity-70 hover:opacity-100 hover:w-1.5 hover:-ml-0.5 cursor-pointer z-10 transition-all",
|
|
@@ -5433,7 +5479,7 @@ var VideoPlayer = ({
|
|
|
5433
5479
|
index
|
|
5434
5480
|
);
|
|
5435
5481
|
}),
|
|
5436
|
-
/* @__PURE__ */ (0,
|
|
5482
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5437
5483
|
"input",
|
|
5438
5484
|
{
|
|
5439
5485
|
type: "range",
|
|
@@ -5447,9 +5493,9 @@ var VideoPlayer = ({
|
|
|
5447
5493
|
}
|
|
5448
5494
|
)
|
|
5449
5495
|
] }),
|
|
5450
|
-
/* @__PURE__ */ (0,
|
|
5451
|
-
/* @__PURE__ */ (0,
|
|
5452
|
-
/* @__PURE__ */ (0,
|
|
5496
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
|
|
5497
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5498
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5453
5499
|
Button,
|
|
5454
5500
|
{
|
|
5455
5501
|
iconOnly: true,
|
|
@@ -5459,33 +5505,33 @@ var VideoPlayer = ({
|
|
|
5459
5505
|
disabled: isLoading,
|
|
5460
5506
|
className: "bg-white/20 hover:bg-white/30 backdrop-blur-sm border-white/30",
|
|
5461
5507
|
"aria-label": isPlaying ? "Pause" : "Play",
|
|
5462
|
-
children: isPlaying ? /* @__PURE__ */ (0,
|
|
5508
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(PauseIcon, { size: "md" }) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(PlayIcon, { size: "md" })
|
|
5463
5509
|
}
|
|
5464
5510
|
),
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5466
|
-
/* @__PURE__ */ (0,
|
|
5511
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5512
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("span", { className: "text-sm text-white tabular-nums", children: [
|
|
5467
5513
|
formatTime(currentTime),
|
|
5468
5514
|
" / ",
|
|
5469
5515
|
formatTime(duration)
|
|
5470
5516
|
] }),
|
|
5471
|
-
currentChapter && showChapters && /* @__PURE__ */ (0,
|
|
5517
|
+
currentChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("span", { className: "text-sm text-white/90 font-medium truncate max-w-[200px]", children: [
|
|
5472
5518
|
"\u2022 ",
|
|
5473
5519
|
currentChapter.title
|
|
5474
5520
|
] })
|
|
5475
5521
|
] })
|
|
5476
5522
|
] }),
|
|
5477
|
-
/* @__PURE__ */ (0,
|
|
5478
|
-
/* @__PURE__ */ (0,
|
|
5479
|
-
/* @__PURE__ */ (0,
|
|
5523
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5524
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5525
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5480
5526
|
"button",
|
|
5481
5527
|
{
|
|
5482
5528
|
onClick: toggleMute,
|
|
5483
5529
|
className: "text-white hover:text-[hsl(var(--foreground))] transition-colors",
|
|
5484
5530
|
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
5485
|
-
children: isMuted ? /* @__PURE__ */ (0,
|
|
5531
|
+
children: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(VolumeOffIcon, { size: "md" }) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(VolumeUpIcon, { size: "md" })
|
|
5486
5532
|
}
|
|
5487
5533
|
),
|
|
5488
|
-
/* @__PURE__ */ (0,
|
|
5534
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5489
5535
|
"input",
|
|
5490
5536
|
{
|
|
5491
5537
|
type: "range",
|
|
@@ -5499,28 +5545,28 @@ var VideoPlayer = ({
|
|
|
5499
5545
|
}
|
|
5500
5546
|
)
|
|
5501
5547
|
] }),
|
|
5502
|
-
/* @__PURE__ */ (0,
|
|
5548
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
5503
5549
|
"button",
|
|
5504
5550
|
{
|
|
5505
5551
|
onClick: toggleFullscreen,
|
|
5506
5552
|
className: "text-white hover:text-[hsl(var(--foreground))] transition-colors",
|
|
5507
5553
|
"aria-label": isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
|
|
5508
|
-
children: isFullscreen ? /* @__PURE__ */ (0,
|
|
5554
|
+
children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(FullscreenExitIcon, { size: "md" }) : /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(FullscreenIcon, { size: "md" })
|
|
5509
5555
|
}
|
|
5510
5556
|
)
|
|
5511
5557
|
] })
|
|
5512
5558
|
] })
|
|
5513
5559
|
] })
|
|
5514
5560
|
] }),
|
|
5515
|
-
hoveredChapter && showChapters && /* @__PURE__ */ (0,
|
|
5561
|
+
hoveredChapter && showChapters && /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)(
|
|
5516
5562
|
"div",
|
|
5517
5563
|
{
|
|
5518
5564
|
className: "fixed z-50 px-3 py-2 bg-[hsl(var(--popover))] text-white text-xs font-medium rounded shadow-lg pointer-events-none transform -translate-x-1/2 -translate-y-full",
|
|
5519
5565
|
style: { left: hoverPosition.x, top: hoverPosition.y - 8 },
|
|
5520
5566
|
children: [
|
|
5521
|
-
/* @__PURE__ */ (0,
|
|
5522
|
-
/* @__PURE__ */ (0,
|
|
5523
|
-
/* @__PURE__ */ (0,
|
|
5567
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "whitespace-nowrap", children: hoveredChapter.title }),
|
|
5568
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "text-[hsl(var(--muted-foreground))] text-[10px] mt-0.5", children: formatTime(hoveredChapter.startTime) }),
|
|
5569
|
+
/* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "absolute left-1/2 -bottom-1 w-2 h-2 bg-[hsl(var(--popover))] transform -translate-x-1/2 rotate-45" })
|
|
5524
5570
|
]
|
|
5525
5571
|
}
|
|
5526
5572
|
)
|
|
@@ -5531,7 +5577,7 @@ var VideoPlayer = ({
|
|
|
5531
5577
|
};
|
|
5532
5578
|
|
|
5533
5579
|
// src/charts/LineChart.tsx
|
|
5534
|
-
var
|
|
5580
|
+
var import_react29 = __toESM(require("react"));
|
|
5535
5581
|
|
|
5536
5582
|
// src/charts/constants.ts
|
|
5537
5583
|
var CHART_DEFAULTS = {
|
|
@@ -5847,8 +5893,8 @@ function createTickFormatter(domain) {
|
|
|
5847
5893
|
}
|
|
5848
5894
|
|
|
5849
5895
|
// src/charts/components/ChartTooltip.tsx
|
|
5850
|
-
var
|
|
5851
|
-
var
|
|
5896
|
+
var import_react27 = __toESM(require("react"));
|
|
5897
|
+
var import_jsx_runtime109 = require("react/jsx-runtime");
|
|
5852
5898
|
var DefaultTooltipContent = ({
|
|
5853
5899
|
active,
|
|
5854
5900
|
label,
|
|
@@ -5860,22 +5906,22 @@ var DefaultTooltipContent = ({
|
|
|
5860
5906
|
return null;
|
|
5861
5907
|
}
|
|
5862
5908
|
const formattedLabel = labelFormatter ? labelFormatter(label ?? "") : String(label ?? "");
|
|
5863
|
-
return /* @__PURE__ */ (0,
|
|
5864
|
-
formattedLabel && /* @__PURE__ */ (0,
|
|
5865
|
-
/* @__PURE__ */ (0,
|
|
5909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "bg-[hsl(var(--popover))] text-white rounded-lg shadow-xl border border-[hsl(var(--border))] overflow-hidden min-w-[120px]", children: [
|
|
5910
|
+
formattedLabel && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "px-3 py-2 bg-[hsl(var(--popover))] border-b border-[hsl(var(--border))]", children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("span", { className: "text-sm font-medium text-[hsl(var(--muted-foreground))]", children: formattedLabel }) }),
|
|
5911
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "px-3 py-2 space-y-1", children: payload.map((item, index) => {
|
|
5866
5912
|
const formattedValue = formatter ? formatter(item.value, item.name, item) : String(item.value);
|
|
5867
|
-
return /* @__PURE__ */ (0,
|
|
5868
|
-
/* @__PURE__ */ (0,
|
|
5869
|
-
item.color && /* @__PURE__ */ (0,
|
|
5913
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex items-center justify-between gap-4", children: [
|
|
5914
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5915
|
+
item.color && /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
5870
5916
|
"span",
|
|
5871
5917
|
{
|
|
5872
5918
|
className: "w-2.5 h-2.5 rounded-full flex-shrink-0",
|
|
5873
5919
|
style: { backgroundColor: item.color }
|
|
5874
5920
|
}
|
|
5875
5921
|
),
|
|
5876
|
-
/* @__PURE__ */ (0,
|
|
5922
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: item.name })
|
|
5877
5923
|
] }),
|
|
5878
|
-
/* @__PURE__ */ (0,
|
|
5924
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("span", { className: "text-sm font-semibold text-white", children: formattedValue })
|
|
5879
5925
|
] }, `${item.name}-${index}`);
|
|
5880
5926
|
}) })
|
|
5881
5927
|
] });
|
|
@@ -5894,10 +5940,10 @@ var ChartTooltip = ({
|
|
|
5894
5940
|
containerBounds,
|
|
5895
5941
|
animationDuration = 150
|
|
5896
5942
|
}) => {
|
|
5897
|
-
const tooltipRef = (0,
|
|
5898
|
-
const [position, setPosition] = (0,
|
|
5899
|
-
const [isVisible, setIsVisible] = (0,
|
|
5900
|
-
(0,
|
|
5943
|
+
const tooltipRef = (0, import_react27.useRef)(null);
|
|
5944
|
+
const [position, setPosition] = (0, import_react27.useState)({ x: 0, y: 0 });
|
|
5945
|
+
const [isVisible, setIsVisible] = (0, import_react27.useState)(false);
|
|
5946
|
+
(0, import_react27.useEffect)(() => {
|
|
5901
5947
|
if (!active || !tooltipRef.current) {
|
|
5902
5948
|
setIsVisible(false);
|
|
5903
5949
|
return;
|
|
@@ -5926,19 +5972,19 @@ var ChartTooltip = ({
|
|
|
5926
5972
|
if (!active) {
|
|
5927
5973
|
return null;
|
|
5928
5974
|
}
|
|
5929
|
-
const tooltipContent = content ?
|
|
5975
|
+
const tooltipContent = content ? import_react27.default.isValidElement(content) ? import_react27.default.cloneElement(content, {
|
|
5930
5976
|
active,
|
|
5931
5977
|
label,
|
|
5932
5978
|
payload,
|
|
5933
5979
|
formatter,
|
|
5934
5980
|
labelFormatter
|
|
5935
|
-
}) :
|
|
5981
|
+
}) : import_react27.default.createElement(content, {
|
|
5936
5982
|
active,
|
|
5937
5983
|
label,
|
|
5938
5984
|
payload,
|
|
5939
5985
|
formatter,
|
|
5940
5986
|
labelFormatter
|
|
5941
|
-
}) : /* @__PURE__ */ (0,
|
|
5987
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
5942
5988
|
DefaultTooltipContent,
|
|
5943
5989
|
{
|
|
5944
5990
|
active,
|
|
@@ -5948,7 +5994,7 @@ var ChartTooltip = ({
|
|
|
5948
5994
|
labelFormatter
|
|
5949
5995
|
}
|
|
5950
5996
|
);
|
|
5951
|
-
return /* @__PURE__ */ (0,
|
|
5997
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
5952
5998
|
"div",
|
|
5953
5999
|
{
|
|
5954
6000
|
ref: tooltipRef,
|
|
@@ -5965,26 +6011,26 @@ var ChartTooltip = ({
|
|
|
5965
6011
|
);
|
|
5966
6012
|
};
|
|
5967
6013
|
function useTooltip() {
|
|
5968
|
-
const [tooltipData, setTooltipData] = (0,
|
|
6014
|
+
const [tooltipData, setTooltipData] = (0, import_react27.useState)({
|
|
5969
6015
|
active: false,
|
|
5970
6016
|
x: 0,
|
|
5971
6017
|
y: 0,
|
|
5972
6018
|
label: void 0,
|
|
5973
6019
|
payload: void 0
|
|
5974
6020
|
});
|
|
5975
|
-
const showTooltip =
|
|
6021
|
+
const showTooltip = import_react27.default.useCallback((data) => {
|
|
5976
6022
|
setTooltipData({
|
|
5977
6023
|
active: true,
|
|
5978
6024
|
...data
|
|
5979
6025
|
});
|
|
5980
6026
|
}, []);
|
|
5981
|
-
const hideTooltip =
|
|
6027
|
+
const hideTooltip = import_react27.default.useCallback(() => {
|
|
5982
6028
|
setTooltipData((prev) => ({
|
|
5983
6029
|
...prev,
|
|
5984
6030
|
active: false
|
|
5985
6031
|
}));
|
|
5986
6032
|
}, []);
|
|
5987
|
-
const updatePosition =
|
|
6033
|
+
const updatePosition = import_react27.default.useCallback((x, y) => {
|
|
5988
6034
|
setTooltipData((prev) => ({
|
|
5989
6035
|
...prev,
|
|
5990
6036
|
x,
|
|
@@ -6000,7 +6046,7 @@ function useTooltip() {
|
|
|
6000
6046
|
}
|
|
6001
6047
|
|
|
6002
6048
|
// src/charts/components/Legend.tsx
|
|
6003
|
-
var
|
|
6049
|
+
var import_jsx_runtime110 = require("react/jsx-runtime");
|
|
6004
6050
|
var Legend = ({
|
|
6005
6051
|
items = [],
|
|
6006
6052
|
layout = "horizontal",
|
|
@@ -6024,7 +6070,7 @@ var Legend = ({
|
|
|
6024
6070
|
const style = { backgroundColor: item.color };
|
|
6025
6071
|
switch (item.type) {
|
|
6026
6072
|
case "line":
|
|
6027
|
-
return /* @__PURE__ */ (0,
|
|
6073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6028
6074
|
"div",
|
|
6029
6075
|
{
|
|
6030
6076
|
className: "flex-shrink-0",
|
|
@@ -6036,7 +6082,7 @@ var Legend = ({
|
|
|
6036
6082
|
}
|
|
6037
6083
|
);
|
|
6038
6084
|
case "circle":
|
|
6039
|
-
return /* @__PURE__ */ (0,
|
|
6085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6040
6086
|
"div",
|
|
6041
6087
|
{
|
|
6042
6088
|
className: "rounded-full flex-shrink-0",
|
|
@@ -6050,7 +6096,7 @@ var Legend = ({
|
|
|
6050
6096
|
case "rect":
|
|
6051
6097
|
case "square":
|
|
6052
6098
|
default:
|
|
6053
|
-
return /* @__PURE__ */ (0,
|
|
6099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6054
6100
|
"div",
|
|
6055
6101
|
{
|
|
6056
6102
|
className: "rounded-sm flex-shrink-0",
|
|
@@ -6063,12 +6109,12 @@ var Legend = ({
|
|
|
6063
6109
|
);
|
|
6064
6110
|
}
|
|
6065
6111
|
};
|
|
6066
|
-
return /* @__PURE__ */ (0,
|
|
6112
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
6067
6113
|
"div",
|
|
6068
6114
|
{
|
|
6069
6115
|
className: `flex gap-4 px-4 py-2 ${layoutClass} ${alignClass} ${className}`,
|
|
6070
6116
|
style: wrapperStyle,
|
|
6071
|
-
children: items.map((item, index) => /* @__PURE__ */ (0,
|
|
6117
|
+
children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
|
|
6072
6118
|
"button",
|
|
6073
6119
|
{
|
|
6074
6120
|
type: "button",
|
|
@@ -6082,7 +6128,7 @@ var Legend = ({
|
|
|
6082
6128
|
onMouseLeave,
|
|
6083
6129
|
children: [
|
|
6084
6130
|
renderIcon(item),
|
|
6085
|
-
/* @__PURE__ */ (0,
|
|
6131
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)("span", { className: "text-[hsl(var(--foreground))]", children: formatter ? formatter(item.name, item, index) : item.name })
|
|
6086
6132
|
]
|
|
6087
6133
|
},
|
|
6088
6134
|
`${item.name}-${index}`
|
|
@@ -6092,7 +6138,7 @@ var Legend = ({
|
|
|
6092
6138
|
};
|
|
6093
6139
|
|
|
6094
6140
|
// src/charts/components/ReferenceLine.tsx
|
|
6095
|
-
var
|
|
6141
|
+
var import_jsx_runtime111 = require("react/jsx-runtime");
|
|
6096
6142
|
var ReferenceLine = ({
|
|
6097
6143
|
x,
|
|
6098
6144
|
y,
|
|
@@ -6204,8 +6250,8 @@ var ReferenceLine = ({
|
|
|
6204
6250
|
} else {
|
|
6205
6251
|
return null;
|
|
6206
6252
|
}
|
|
6207
|
-
return /* @__PURE__ */ (0,
|
|
6208
|
-
/* @__PURE__ */ (0,
|
|
6253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("g", { className: `reference-line ${className}`, children: [
|
|
6254
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6209
6255
|
"line",
|
|
6210
6256
|
{
|
|
6211
6257
|
x1,
|
|
@@ -6217,7 +6263,7 @@ var ReferenceLine = ({
|
|
|
6217
6263
|
strokeDasharray
|
|
6218
6264
|
}
|
|
6219
6265
|
),
|
|
6220
|
-
label && (typeof label === "string" ? /* @__PURE__ */ (0,
|
|
6266
|
+
label && (typeof label === "string" ? /* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6221
6267
|
"text",
|
|
6222
6268
|
{
|
|
6223
6269
|
x: labelX,
|
|
@@ -6229,7 +6275,7 @@ var ReferenceLine = ({
|
|
|
6229
6275
|
className: "fill-[hsl(var(--muted-foreground))]",
|
|
6230
6276
|
children: label
|
|
6231
6277
|
}
|
|
6232
|
-
) : /* @__PURE__ */ (0,
|
|
6278
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
6233
6279
|
"foreignObject",
|
|
6234
6280
|
{
|
|
6235
6281
|
x: labelX - 50,
|
|
@@ -6243,7 +6289,7 @@ var ReferenceLine = ({
|
|
|
6243
6289
|
};
|
|
6244
6290
|
|
|
6245
6291
|
// src/charts/components/ReferenceArea.tsx
|
|
6246
|
-
var
|
|
6292
|
+
var import_jsx_runtime112 = require("react/jsx-runtime");
|
|
6247
6293
|
var ReferenceArea = ({
|
|
6248
6294
|
x1,
|
|
6249
6295
|
x2,
|
|
@@ -6351,8 +6397,8 @@ var ReferenceArea = ({
|
|
|
6351
6397
|
labelX = rectX + rectWidth / 2;
|
|
6352
6398
|
labelY = rectY + rectHeight / 2;
|
|
6353
6399
|
}
|
|
6354
|
-
return /* @__PURE__ */ (0,
|
|
6355
|
-
/* @__PURE__ */ (0,
|
|
6400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime112.jsxs)("g", { className: `reference-area ${className}`, children: [
|
|
6401
|
+
/* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
6356
6402
|
"rect",
|
|
6357
6403
|
{
|
|
6358
6404
|
x: rectX,
|
|
@@ -6365,7 +6411,7 @@ var ReferenceArea = ({
|
|
|
6365
6411
|
strokeWidth
|
|
6366
6412
|
}
|
|
6367
6413
|
),
|
|
6368
|
-
label && (typeof label === "string" ? /* @__PURE__ */ (0,
|
|
6414
|
+
label && (typeof label === "string" ? /* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
6369
6415
|
"text",
|
|
6370
6416
|
{
|
|
6371
6417
|
x: labelX,
|
|
@@ -6377,7 +6423,7 @@ var ReferenceArea = ({
|
|
|
6377
6423
|
className: "fill-[hsl(var(--muted-foreground))]",
|
|
6378
6424
|
children: label
|
|
6379
6425
|
}
|
|
6380
|
-
) : /* @__PURE__ */ (0,
|
|
6426
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
6381
6427
|
"foreignObject",
|
|
6382
6428
|
{
|
|
6383
6429
|
x: labelX - 50,
|
|
@@ -6391,8 +6437,8 @@ var ReferenceArea = ({
|
|
|
6391
6437
|
};
|
|
6392
6438
|
|
|
6393
6439
|
// src/charts/components/CartesianGrid.tsx
|
|
6394
|
-
var
|
|
6395
|
-
var
|
|
6440
|
+
var import_react28 = require("react");
|
|
6441
|
+
var import_jsx_runtime113 = require("react/jsx-runtime");
|
|
6396
6442
|
var CartesianGrid = ({
|
|
6397
6443
|
horizontal = true,
|
|
6398
6444
|
vertical = true,
|
|
@@ -6409,18 +6455,18 @@ var CartesianGrid = ({
|
|
|
6409
6455
|
return null;
|
|
6410
6456
|
}
|
|
6411
6457
|
const { width, height } = _chartDimensions;
|
|
6412
|
-
const hPoints = (0,
|
|
6458
|
+
const hPoints = (0, import_react28.useMemo)(() => {
|
|
6413
6459
|
if (horizontalPoints) return horizontalPoints;
|
|
6414
6460
|
const count = 5;
|
|
6415
6461
|
return Array.from({ length: count + 1 }, (_, i) => height / count * i);
|
|
6416
6462
|
}, [horizontalPoints, height]);
|
|
6417
|
-
const vPoints = (0,
|
|
6463
|
+
const vPoints = (0, import_react28.useMemo)(() => {
|
|
6418
6464
|
if (verticalPoints) return verticalPoints;
|
|
6419
6465
|
const count = 6;
|
|
6420
6466
|
return Array.from({ length: count + 1 }, (_, i) => width / count * i);
|
|
6421
6467
|
}, [verticalPoints, width]);
|
|
6422
|
-
return /* @__PURE__ */ (0,
|
|
6423
|
-
horizontal && hPoints.map((y, i) => /* @__PURE__ */ (0,
|
|
6468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime113.jsxs)("g", { className: `cartesian-grid ${className}`, children: [
|
|
6469
|
+
horizontal && hPoints.map((y, i) => /* @__PURE__ */ (0, import_jsx_runtime113.jsx)(
|
|
6424
6470
|
"line",
|
|
6425
6471
|
{
|
|
6426
6472
|
x1: 0,
|
|
@@ -6435,7 +6481,7 @@ var CartesianGrid = ({
|
|
|
6435
6481
|
},
|
|
6436
6482
|
`h-${i}`
|
|
6437
6483
|
)),
|
|
6438
|
-
vertical && vPoints.map((x, i) => /* @__PURE__ */ (0,
|
|
6484
|
+
vertical && vPoints.map((x, i) => /* @__PURE__ */ (0, import_jsx_runtime113.jsx)(
|
|
6439
6485
|
"line",
|
|
6440
6486
|
{
|
|
6441
6487
|
x1: x,
|
|
@@ -6454,7 +6500,7 @@ var CartesianGrid = ({
|
|
|
6454
6500
|
};
|
|
6455
6501
|
|
|
6456
6502
|
// src/charts/LineChart.tsx
|
|
6457
|
-
var
|
|
6503
|
+
var import_jsx_runtime114 = require("react/jsx-runtime");
|
|
6458
6504
|
var LineChart = ({
|
|
6459
6505
|
data,
|
|
6460
6506
|
width: providedWidth,
|
|
@@ -6486,14 +6532,14 @@ var LineChart = ({
|
|
|
6486
6532
|
colors = CHART_DEFAULTS.colors,
|
|
6487
6533
|
ariaLabel
|
|
6488
6534
|
}) => {
|
|
6489
|
-
const containerRef = (0,
|
|
6490
|
-
const svgRef = (0,
|
|
6491
|
-
const [hoveredPoint, setHoveredPoint] = (0,
|
|
6492
|
-
const [crosshairX, setCrosshairX] = (0,
|
|
6535
|
+
const containerRef = (0, import_react29.useRef)(null);
|
|
6536
|
+
const svgRef = (0, import_react29.useRef)(null);
|
|
6537
|
+
const [hoveredPoint, setHoveredPoint] = (0, import_react29.useState)(null);
|
|
6538
|
+
const [crosshairX, setCrosshairX] = (0, import_react29.useState)(null);
|
|
6493
6539
|
const { tooltipData, showTooltip: showTooltipFn, hideTooltip } = useTooltip();
|
|
6494
6540
|
const width = providedWidth || 800;
|
|
6495
6541
|
const height = providedHeight || 400;
|
|
6496
|
-
const padding = (0,
|
|
6542
|
+
const padding = (0, import_react29.useMemo)(() => ({
|
|
6497
6543
|
top: customPadding?.top ?? CHART_DEFAULTS.padding.top,
|
|
6498
6544
|
right: customPadding?.right ?? (showValueLabels ? 80 : CHART_DEFAULTS.padding.right),
|
|
6499
6545
|
bottom: customPadding?.bottom ?? (showXAxis ? 60 : CHART_DEFAULTS.padding.bottom),
|
|
@@ -6501,17 +6547,17 @@ var LineChart = ({
|
|
|
6501
6547
|
}), [customPadding, showXAxis, showYAxis, showValueLabels]);
|
|
6502
6548
|
const chartWidth = width - padding.left - padding.right;
|
|
6503
6549
|
const chartHeight = height - padding.top - padding.bottom;
|
|
6504
|
-
const allPoints = (0,
|
|
6550
|
+
const allPoints = (0, import_react29.useMemo)(
|
|
6505
6551
|
() => data.flatMap((series) => series.data),
|
|
6506
6552
|
[data]
|
|
6507
6553
|
);
|
|
6508
|
-
const xValueType = (0,
|
|
6554
|
+
const xValueType = (0, import_react29.useMemo)(() => {
|
|
6509
6555
|
const firstX = data[0]?.data[0]?.x;
|
|
6510
6556
|
if (firstX instanceof Date) return "date";
|
|
6511
6557
|
if (typeof firstX === "number") return "number";
|
|
6512
6558
|
return "string";
|
|
6513
6559
|
}, [data]);
|
|
6514
|
-
const xDomainCalc = (0,
|
|
6560
|
+
const xDomainCalc = (0, import_react29.useMemo)(() => {
|
|
6515
6561
|
if (xValueType === "date") {
|
|
6516
6562
|
const dates = allPoints.map((p) => p.x.getTime());
|
|
6517
6563
|
return [Math.min(...dates), Math.max(...dates)];
|
|
@@ -6523,12 +6569,12 @@ var LineChart = ({
|
|
|
6523
6569
|
const maxLen = Math.max(...data.map((s) => s.data.length));
|
|
6524
6570
|
return [0, maxLen - 1];
|
|
6525
6571
|
}, [allPoints, xValueType, data]);
|
|
6526
|
-
const yDomainCalc = (0,
|
|
6572
|
+
const yDomainCalc = (0, import_react29.useMemo)(() => {
|
|
6527
6573
|
if (yDomain) return yDomain;
|
|
6528
6574
|
const yValues = allPoints.map((p) => p.y);
|
|
6529
6575
|
return calculateDomain(yValues, { includeZero: true, padding: 0.1 });
|
|
6530
6576
|
}, [allPoints, yDomain]);
|
|
6531
|
-
const xScale = (0,
|
|
6577
|
+
const xScale = (0, import_react29.useMemo)(() => {
|
|
6532
6578
|
if (xValueType === "date") {
|
|
6533
6579
|
return (value) => {
|
|
6534
6580
|
const time = value instanceof Date ? value.getTime() : Number(value);
|
|
@@ -6551,18 +6597,18 @@ var LineChart = ({
|
|
|
6551
6597
|
return index / maxLen * chartWidth;
|
|
6552
6598
|
};
|
|
6553
6599
|
}, [xValueType, xDomainCalc, chartWidth, data]);
|
|
6554
|
-
const yScale = (0,
|
|
6600
|
+
const yScale = (0, import_react29.useMemo)(
|
|
6555
6601
|
() => scaleLinear({
|
|
6556
6602
|
domain: yDomainCalc,
|
|
6557
6603
|
range: [chartHeight, 0]
|
|
6558
6604
|
}),
|
|
6559
6605
|
[yDomainCalc, chartHeight]
|
|
6560
6606
|
);
|
|
6561
|
-
const yTicks = (0,
|
|
6607
|
+
const yTicks = (0, import_react29.useMemo)(
|
|
6562
6608
|
() => getTicks(yDomainCalc, yAxisTickCount),
|
|
6563
6609
|
[yDomainCalc, yAxisTickCount]
|
|
6564
6610
|
);
|
|
6565
|
-
const xTicks = (0,
|
|
6611
|
+
const xTicks = (0, import_react29.useMemo)(() => {
|
|
6566
6612
|
if (xValueType === "string") {
|
|
6567
6613
|
return data[0]?.data.map((p, i) => ({ value: p.x, index: i })) || [];
|
|
6568
6614
|
}
|
|
@@ -6570,7 +6616,7 @@ var LineChart = ({
|
|
|
6570
6616
|
const ticks = getTicks(xDomainCalc, tickCount);
|
|
6571
6617
|
return ticks.map((t) => ({ value: t, index: 0 }));
|
|
6572
6618
|
}, [xValueType, xDomainCalc, data]);
|
|
6573
|
-
const xFormatter = (0,
|
|
6619
|
+
const xFormatter = (0, import_react29.useCallback)((value) => {
|
|
6574
6620
|
if (formatXValue) return formatXValue(value);
|
|
6575
6621
|
if (value instanceof Date) {
|
|
6576
6622
|
const range = xDomainCalc[1] - xDomainCalc[0];
|
|
@@ -6578,11 +6624,11 @@ var LineChart = ({
|
|
|
6578
6624
|
}
|
|
6579
6625
|
return String(value);
|
|
6580
6626
|
}, [formatXValue, xDomainCalc]);
|
|
6581
|
-
const yFormatter = (0,
|
|
6627
|
+
const yFormatter = (0, import_react29.useMemo)(() => {
|
|
6582
6628
|
if (formatYValue) return formatYValue;
|
|
6583
6629
|
return createTickFormatter(yDomainCalc);
|
|
6584
6630
|
}, [formatYValue, yDomainCalc]);
|
|
6585
|
-
const seriesPaths = (0,
|
|
6631
|
+
const seriesPaths = (0, import_react29.useMemo)(() => {
|
|
6586
6632
|
return data.map((series) => {
|
|
6587
6633
|
const points = series.data.map((point, i) => ({
|
|
6588
6634
|
x: xScale(point.x, i),
|
|
@@ -6607,7 +6653,7 @@ var LineChart = ({
|
|
|
6607
6653
|
return { points, path };
|
|
6608
6654
|
});
|
|
6609
6655
|
}, [data, xScale, yScale]);
|
|
6610
|
-
const handlePointEnter = (0,
|
|
6656
|
+
const handlePointEnter = (0, import_react29.useCallback)((e, seriesIndex, pointIndex) => {
|
|
6611
6657
|
const series = data[seriesIndex];
|
|
6612
6658
|
const point = series.data[pointIndex];
|
|
6613
6659
|
const scaledPoint = seriesPaths[seriesIndex].points[pointIndex];
|
|
@@ -6634,17 +6680,17 @@ var LineChart = ({
|
|
|
6634
6680
|
}
|
|
6635
6681
|
onPointHover?.(point, seriesIndex, pointIndex);
|
|
6636
6682
|
}, [data, seriesPaths, showCrosshair, showTooltip, colors, xFormatter, showTooltipFn, onPointHover]);
|
|
6637
|
-
const handlePointLeave = (0,
|
|
6683
|
+
const handlePointLeave = (0, import_react29.useCallback)(() => {
|
|
6638
6684
|
setHoveredPoint(null);
|
|
6639
6685
|
setCrosshairX(null);
|
|
6640
6686
|
hideTooltip();
|
|
6641
6687
|
onPointHover?.(null, -1, -1);
|
|
6642
6688
|
}, [hideTooltip, onPointHover]);
|
|
6643
|
-
const handlePointClick = (0,
|
|
6689
|
+
const handlePointClick = (0, import_react29.useCallback)((seriesIndex, pointIndex) => {
|
|
6644
6690
|
const point = data[seriesIndex].data[pointIndex];
|
|
6645
6691
|
onPointClick?.(point, seriesIndex, pointIndex);
|
|
6646
6692
|
}, [data, onPointClick]);
|
|
6647
|
-
const legendItems = (0,
|
|
6693
|
+
const legendItems = (0, import_react29.useMemo)(
|
|
6648
6694
|
() => data.map((series, i) => ({
|
|
6649
6695
|
name: series.name,
|
|
6650
6696
|
color: series.color || colors[i % colors.length],
|
|
@@ -6652,7 +6698,7 @@ var LineChart = ({
|
|
|
6652
6698
|
})),
|
|
6653
6699
|
[data, colors]
|
|
6654
6700
|
);
|
|
6655
|
-
const referenceElements = (0,
|
|
6701
|
+
const referenceElements = (0, import_react29.useMemo)(() => {
|
|
6656
6702
|
if (!children) return null;
|
|
6657
6703
|
const chartDimensions = {
|
|
6658
6704
|
width: chartWidth,
|
|
@@ -6669,10 +6715,10 @@ var LineChart = ({
|
|
|
6669
6715
|
},
|
|
6670
6716
|
yScale
|
|
6671
6717
|
};
|
|
6672
|
-
return
|
|
6673
|
-
if (!
|
|
6718
|
+
return import_react29.default.Children.map(children, (child) => {
|
|
6719
|
+
if (!import_react29.default.isValidElement(child)) return child;
|
|
6674
6720
|
if (child.type === ReferenceLine || child.type === ReferenceArea || child.type === CartesianGrid) {
|
|
6675
|
-
return
|
|
6721
|
+
return import_react29.default.cloneElement(child, {
|
|
6676
6722
|
_chartDimensions: chartDimensions,
|
|
6677
6723
|
_scales: scales
|
|
6678
6724
|
});
|
|
@@ -6680,19 +6726,19 @@ var LineChart = ({
|
|
|
6680
6726
|
return child;
|
|
6681
6727
|
});
|
|
6682
6728
|
}, [children, chartWidth, chartHeight, padding, xScale, yScale, xValueType, data]);
|
|
6683
|
-
const accessibleDescription = (0,
|
|
6729
|
+
const accessibleDescription = (0, import_react29.useMemo)(() => {
|
|
6684
6730
|
if (ariaLabel) return ariaLabel;
|
|
6685
6731
|
const seriesNames = data.map((s) => s.name).join(", ");
|
|
6686
6732
|
return `Line chart with ${data.length} series: ${seriesNames}`;
|
|
6687
6733
|
}, [data, ariaLabel]);
|
|
6688
|
-
return /* @__PURE__ */ (0,
|
|
6734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime114.jsxs)(
|
|
6689
6735
|
"div",
|
|
6690
6736
|
{
|
|
6691
6737
|
ref: containerRef,
|
|
6692
6738
|
className: `relative ${className}`,
|
|
6693
6739
|
style: { width, height: "auto" },
|
|
6694
6740
|
children: [
|
|
6695
|
-
/* @__PURE__ */ (0,
|
|
6741
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsxs)(
|
|
6696
6742
|
"svg",
|
|
6697
6743
|
{
|
|
6698
6744
|
ref: svgRef,
|
|
@@ -6703,14 +6749,14 @@ var LineChart = ({
|
|
|
6703
6749
|
"aria-label": accessibleDescription,
|
|
6704
6750
|
className: "bg-[hsl(var(--card))]",
|
|
6705
6751
|
children: [
|
|
6706
|
-
/* @__PURE__ */ (0,
|
|
6752
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)("defs", { children: animate && data.map((series, i) => /* @__PURE__ */ (0, import_jsx_runtime114.jsx)("style", { children: `
|
|
6707
6753
|
@keyframes drawLine${i} {
|
|
6708
6754
|
from { stroke-dashoffset: 2000; }
|
|
6709
6755
|
to { stroke-dashoffset: 0; }
|
|
6710
6756
|
}
|
|
6711
6757
|
` }, `anim-${i}`)) }),
|
|
6712
|
-
/* @__PURE__ */ (0,
|
|
6713
|
-
showGrid && /* @__PURE__ */ (0,
|
|
6758
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
6759
|
+
showGrid && /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6714
6760
|
CartesianGrid,
|
|
6715
6761
|
{
|
|
6716
6762
|
_chartDimensions: { width: chartWidth, height: chartHeight },
|
|
@@ -6718,7 +6764,7 @@ var LineChart = ({
|
|
|
6718
6764
|
}
|
|
6719
6765
|
),
|
|
6720
6766
|
referenceElements,
|
|
6721
|
-
showCrosshair && crosshairX !== null && /* @__PURE__ */ (0,
|
|
6767
|
+
showCrosshair && crosshairX !== null && /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6722
6768
|
"line",
|
|
6723
6769
|
{
|
|
6724
6770
|
x1: crosshairX,
|
|
@@ -6736,7 +6782,7 @@ var LineChart = ({
|
|
|
6736
6782
|
const { path } = seriesPaths[seriesIndex];
|
|
6737
6783
|
const color = series.color || colors[seriesIndex % colors.length];
|
|
6738
6784
|
const strokeWidth = series.strokeWidth || CHART_DEFAULTS.line.strokeWidth;
|
|
6739
|
-
return /* @__PURE__ */ (0,
|
|
6785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6740
6786
|
"path",
|
|
6741
6787
|
{
|
|
6742
6788
|
d: path,
|
|
@@ -6760,7 +6806,7 @@ var LineChart = ({
|
|
|
6760
6806
|
if (!showSeriesDots) return null;
|
|
6761
6807
|
return points.map((point, pointIndex) => {
|
|
6762
6808
|
const isHovered = hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex;
|
|
6763
|
-
return /* @__PURE__ */ (0,
|
|
6809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6764
6810
|
"circle",
|
|
6765
6811
|
{
|
|
6766
6812
|
cx: point.x,
|
|
@@ -6788,8 +6834,8 @@ var LineChart = ({
|
|
|
6788
6834
|
const lastScaled = points[points.length - 1];
|
|
6789
6835
|
const color = series.color || colors[seriesIndex % colors.length];
|
|
6790
6836
|
if (!lastPoint || !lastScaled) return null;
|
|
6791
|
-
return /* @__PURE__ */ (0,
|
|
6792
|
-
/* @__PURE__ */ (0,
|
|
6837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime114.jsxs)("g", { children: [
|
|
6838
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6793
6839
|
"circle",
|
|
6794
6840
|
{
|
|
6795
6841
|
cx: chartWidth + 12,
|
|
@@ -6798,7 +6844,7 @@ var LineChart = ({
|
|
|
6798
6844
|
fill: color
|
|
6799
6845
|
}
|
|
6800
6846
|
),
|
|
6801
|
-
/* @__PURE__ */ (0,
|
|
6847
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6802
6848
|
"text",
|
|
6803
6849
|
{
|
|
6804
6850
|
x: chartWidth + 22,
|
|
@@ -6812,8 +6858,8 @@ var LineChart = ({
|
|
|
6812
6858
|
)
|
|
6813
6859
|
] }, `label-${seriesIndex}`);
|
|
6814
6860
|
}),
|
|
6815
|
-
showXAxis && /* @__PURE__ */ (0,
|
|
6816
|
-
/* @__PURE__ */ (0,
|
|
6861
|
+
showXAxis && /* @__PURE__ */ (0, import_jsx_runtime114.jsxs)("g", { transform: `translate(0, ${chartHeight})`, children: [
|
|
6862
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6817
6863
|
"line",
|
|
6818
6864
|
{
|
|
6819
6865
|
x1: 0,
|
|
@@ -6826,9 +6872,9 @@ var LineChart = ({
|
|
|
6826
6872
|
),
|
|
6827
6873
|
xTicks.map((tick, i) => {
|
|
6828
6874
|
const x = xValueType === "string" ? xScale(tick.value, tick.index) : xScale(xValueType === "date" ? new Date(tick.value) : tick.value, 0);
|
|
6829
|
-
return /* @__PURE__ */ (0,
|
|
6830
|
-
/* @__PURE__ */ (0,
|
|
6831
|
-
/* @__PURE__ */ (0,
|
|
6875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime114.jsxs)("g", { transform: `translate(${x}, 0)`, children: [
|
|
6876
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)("line", { y2: 6, className: "stroke-[hsl(var(--border))]" }),
|
|
6877
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6832
6878
|
"text",
|
|
6833
6879
|
{
|
|
6834
6880
|
y: 20,
|
|
@@ -6840,7 +6886,7 @@ var LineChart = ({
|
|
|
6840
6886
|
)
|
|
6841
6887
|
] }, `x-tick-${i}`);
|
|
6842
6888
|
}),
|
|
6843
|
-
xAxisLabel && /* @__PURE__ */ (0,
|
|
6889
|
+
xAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6844
6890
|
"text",
|
|
6845
6891
|
{
|
|
6846
6892
|
x: chartWidth / 2,
|
|
@@ -6853,8 +6899,8 @@ var LineChart = ({
|
|
|
6853
6899
|
}
|
|
6854
6900
|
)
|
|
6855
6901
|
] }),
|
|
6856
|
-
showYAxis && /* @__PURE__ */ (0,
|
|
6857
|
-
/* @__PURE__ */ (0,
|
|
6902
|
+
showYAxis && /* @__PURE__ */ (0, import_jsx_runtime114.jsxs)("g", { children: [
|
|
6903
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6858
6904
|
"line",
|
|
6859
6905
|
{
|
|
6860
6906
|
x1: 0,
|
|
@@ -6865,9 +6911,9 @@ var LineChart = ({
|
|
|
6865
6911
|
strokeWidth: 1
|
|
6866
6912
|
}
|
|
6867
6913
|
),
|
|
6868
|
-
yTicks.map((tick, i) => /* @__PURE__ */ (0,
|
|
6869
|
-
/* @__PURE__ */ (0,
|
|
6870
|
-
/* @__PURE__ */ (0,
|
|
6914
|
+
yTicks.map((tick, i) => /* @__PURE__ */ (0, import_jsx_runtime114.jsxs)("g", { transform: `translate(0, ${yScale(tick)})`, children: [
|
|
6915
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)("line", { x2: -6, className: "stroke-[hsl(var(--border))]" }),
|
|
6916
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6871
6917
|
"text",
|
|
6872
6918
|
{
|
|
6873
6919
|
x: -12,
|
|
@@ -6879,7 +6925,7 @@ var LineChart = ({
|
|
|
6879
6925
|
}
|
|
6880
6926
|
)
|
|
6881
6927
|
] }, `y-tick-${i}`)),
|
|
6882
|
-
yAxisLabel && /* @__PURE__ */ (0,
|
|
6928
|
+
yAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6883
6929
|
"text",
|
|
6884
6930
|
{
|
|
6885
6931
|
x: -chartHeight / 2,
|
|
@@ -6894,7 +6940,7 @@ var LineChart = ({
|
|
|
6894
6940
|
)
|
|
6895
6941
|
] })
|
|
6896
6942
|
] }),
|
|
6897
|
-
/* @__PURE__ */ (0,
|
|
6943
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsx)("style", { children: `
|
|
6898
6944
|
@keyframes fadeIn {
|
|
6899
6945
|
from { opacity: 0; }
|
|
6900
6946
|
to { opacity: 1; }
|
|
@@ -6903,7 +6949,7 @@ var LineChart = ({
|
|
|
6903
6949
|
]
|
|
6904
6950
|
}
|
|
6905
6951
|
),
|
|
6906
|
-
showLegend && /* @__PURE__ */ (0,
|
|
6952
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6907
6953
|
Legend,
|
|
6908
6954
|
{
|
|
6909
6955
|
items: legendItems,
|
|
@@ -6911,7 +6957,7 @@ var LineChart = ({
|
|
|
6911
6957
|
align: "center"
|
|
6912
6958
|
}
|
|
6913
6959
|
),
|
|
6914
|
-
showTooltip && /* @__PURE__ */ (0,
|
|
6960
|
+
showTooltip && /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
6915
6961
|
ChartTooltip,
|
|
6916
6962
|
{
|
|
6917
6963
|
...tooltipData,
|
|
@@ -6927,8 +6973,8 @@ var LineChart = ({
|
|
|
6927
6973
|
};
|
|
6928
6974
|
|
|
6929
6975
|
// src/charts/BarChart.tsx
|
|
6930
|
-
var
|
|
6931
|
-
var
|
|
6976
|
+
var import_react30 = __toESM(require("react"));
|
|
6977
|
+
var import_jsx_runtime115 = require("react/jsx-runtime");
|
|
6932
6978
|
var BarChart = ({
|
|
6933
6979
|
data,
|
|
6934
6980
|
width: providedWidth,
|
|
@@ -6960,12 +7006,12 @@ var BarChart = ({
|
|
|
6960
7006
|
colors = CHART_DEFAULTS.colors,
|
|
6961
7007
|
ariaLabel
|
|
6962
7008
|
}) => {
|
|
6963
|
-
const containerRef = (0,
|
|
6964
|
-
const [hoveredBar, setHoveredBar] = (0,
|
|
7009
|
+
const containerRef = (0, import_react30.useRef)(null);
|
|
7010
|
+
const [hoveredBar, setHoveredBar] = (0, import_react30.useState)(null);
|
|
6965
7011
|
const { tooltipData, showTooltip: showTooltipFn, hideTooltip } = useTooltip();
|
|
6966
7012
|
const width = providedWidth || 800;
|
|
6967
7013
|
const height = providedHeight || 400;
|
|
6968
|
-
const padding = (0,
|
|
7014
|
+
const padding = (0, import_react30.useMemo)(() => ({
|
|
6969
7015
|
top: customPadding?.top ?? CHART_DEFAULTS.padding.top,
|
|
6970
7016
|
right: customPadding?.right ?? CHART_DEFAULTS.padding.right,
|
|
6971
7017
|
bottom: customPadding?.bottom ?? (showXAxis ? 70 : CHART_DEFAULTS.padding.bottom),
|
|
@@ -6973,11 +7019,11 @@ var BarChart = ({
|
|
|
6973
7019
|
}), [customPadding, showXAxis, showYAxis]);
|
|
6974
7020
|
const chartWidth = width - padding.left - padding.right;
|
|
6975
7021
|
const chartHeight = height - padding.top - padding.bottom;
|
|
6976
|
-
const categories = (0,
|
|
7022
|
+
const categories = (0, import_react30.useMemo)(() => {
|
|
6977
7023
|
const cats = data[0]?.data.map((d) => String(d.x)) || [];
|
|
6978
7024
|
return [...new Set(cats)];
|
|
6979
7025
|
}, [data]);
|
|
6980
|
-
const yDomainCalc = (0,
|
|
7026
|
+
const yDomainCalc = (0, import_react30.useMemo)(() => {
|
|
6981
7027
|
if (yDomain) return yDomain;
|
|
6982
7028
|
if (stacked) {
|
|
6983
7029
|
const maxStacked = categories.map((_, catIndex) => {
|
|
@@ -6990,7 +7036,7 @@ var BarChart = ({
|
|
|
6990
7036
|
const allY = data.flatMap((s) => s.data.map((d) => d.y));
|
|
6991
7037
|
return calculateDomain(allY, { includeZero: true, padding: 0.1 });
|
|
6992
7038
|
}, [data, categories, stacked, yDomain]);
|
|
6993
|
-
const xBandScale = (0,
|
|
7039
|
+
const xBandScale = (0, import_react30.useMemo)(
|
|
6994
7040
|
() => scaleBand({
|
|
6995
7041
|
domain: categories,
|
|
6996
7042
|
range: horizontal ? [chartHeight, 0] : [0, chartWidth],
|
|
@@ -6998,25 +7044,25 @@ var BarChart = ({
|
|
|
6998
7044
|
}),
|
|
6999
7045
|
[categories, chartWidth, chartHeight, horizontal, barCategoryGap]
|
|
7000
7046
|
);
|
|
7001
|
-
const yScale = (0,
|
|
7047
|
+
const yScale = (0, import_react30.useMemo)(
|
|
7002
7048
|
() => scaleLinear({
|
|
7003
7049
|
domain: yDomainCalc,
|
|
7004
7050
|
range: horizontal ? [0, chartWidth] : [chartHeight, 0]
|
|
7005
7051
|
}),
|
|
7006
7052
|
[yDomainCalc, chartWidth, chartHeight, horizontal]
|
|
7007
7053
|
);
|
|
7008
|
-
const yTicks = (0,
|
|
7054
|
+
const yTicks = (0, import_react30.useMemo)(
|
|
7009
7055
|
() => getTicks(yDomainCalc, yAxisTickCount),
|
|
7010
7056
|
[yDomainCalc, yAxisTickCount]
|
|
7011
7057
|
);
|
|
7012
|
-
const yFormatter = (0,
|
|
7058
|
+
const yFormatter = (0, import_react30.useMemo)(() => {
|
|
7013
7059
|
if (formatYValue) return formatYValue;
|
|
7014
7060
|
return createTickFormatter(yDomainCalc);
|
|
7015
7061
|
}, [formatYValue, yDomainCalc]);
|
|
7016
7062
|
const numSeries = data.length;
|
|
7017
7063
|
const bandwidth = xBandScale.bandwidth();
|
|
7018
7064
|
const barWidth = stacked ? bandwidth : (bandwidth - bandwidth * barGap * (numSeries - 1)) / numSeries;
|
|
7019
|
-
const handleBarEnter = (0,
|
|
7065
|
+
const handleBarEnter = (0, import_react30.useCallback)((e, seriesIndex, barIndex) => {
|
|
7020
7066
|
const series = data[seriesIndex];
|
|
7021
7067
|
const point = series.data[barIndex];
|
|
7022
7068
|
setHoveredBar({ seriesIndex, barIndex });
|
|
@@ -7039,16 +7085,16 @@ var BarChart = ({
|
|
|
7039
7085
|
}
|
|
7040
7086
|
onBarHover?.(point, seriesIndex, barIndex);
|
|
7041
7087
|
}, [data, showTooltip, colors, showTooltipFn, onBarHover]);
|
|
7042
|
-
const handleBarLeave = (0,
|
|
7088
|
+
const handleBarLeave = (0, import_react30.useCallback)(() => {
|
|
7043
7089
|
setHoveredBar(null);
|
|
7044
7090
|
hideTooltip();
|
|
7045
7091
|
onBarHover?.(null, -1, -1);
|
|
7046
7092
|
}, [hideTooltip, onBarHover]);
|
|
7047
|
-
const handleBarClick = (0,
|
|
7093
|
+
const handleBarClick = (0, import_react30.useCallback)((seriesIndex, barIndex) => {
|
|
7048
7094
|
const point = data[seriesIndex].data[barIndex];
|
|
7049
7095
|
onBarClick?.(point, seriesIndex, barIndex);
|
|
7050
7096
|
}, [data, onBarClick]);
|
|
7051
|
-
const legendItems = (0,
|
|
7097
|
+
const legendItems = (0, import_react30.useMemo)(
|
|
7052
7098
|
() => data.map((series, i) => ({
|
|
7053
7099
|
name: series.name,
|
|
7054
7100
|
color: series.color || colors[i % colors.length],
|
|
@@ -7056,7 +7102,7 @@ var BarChart = ({
|
|
|
7056
7102
|
})),
|
|
7057
7103
|
[data, colors]
|
|
7058
7104
|
);
|
|
7059
|
-
const bars = (0,
|
|
7105
|
+
const bars = (0, import_react30.useMemo)(() => {
|
|
7060
7106
|
const result = [];
|
|
7061
7107
|
const cumulativeValues = {};
|
|
7062
7108
|
data.forEach((series, seriesIndex) => {
|
|
@@ -7096,7 +7142,7 @@ var BarChart = ({
|
|
|
7096
7142
|
}
|
|
7097
7143
|
const isHovered = hoveredBar?.seriesIndex === seriesIndex && hoveredBar?.barIndex === barIndex;
|
|
7098
7144
|
result.push(
|
|
7099
|
-
/* @__PURE__ */ (0,
|
|
7145
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7100
7146
|
"rect",
|
|
7101
7147
|
{
|
|
7102
7148
|
x: barX,
|
|
@@ -7124,7 +7170,7 @@ var BarChart = ({
|
|
|
7124
7170
|
const labelX = horizontal ? barX + barW + 8 : barX + barW / 2;
|
|
7125
7171
|
const labelY = horizontal ? barY + barH / 2 : barY - 8;
|
|
7126
7172
|
result.push(
|
|
7127
|
-
/* @__PURE__ */ (0,
|
|
7173
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7128
7174
|
"text",
|
|
7129
7175
|
{
|
|
7130
7176
|
x: labelX,
|
|
@@ -7168,17 +7214,17 @@ var BarChart = ({
|
|
|
7168
7214
|
handleBarLeave,
|
|
7169
7215
|
handleBarClick
|
|
7170
7216
|
]);
|
|
7171
|
-
const referenceElements = (0,
|
|
7217
|
+
const referenceElements = (0, import_react30.useMemo)(() => {
|
|
7172
7218
|
if (!children) return null;
|
|
7173
7219
|
const chartDimensions = { width: chartWidth, height: chartHeight, padding };
|
|
7174
7220
|
const scales = {
|
|
7175
7221
|
xScale: (value) => xBandScale.scale(String(value)) + bandwidth / 2,
|
|
7176
7222
|
yScale
|
|
7177
7223
|
};
|
|
7178
|
-
return
|
|
7179
|
-
if (!
|
|
7224
|
+
return import_react30.default.Children.map(children, (child) => {
|
|
7225
|
+
if (!import_react30.default.isValidElement(child)) return child;
|
|
7180
7226
|
if (child.type === ReferenceLine || child.type === ReferenceArea || child.type === CartesianGrid) {
|
|
7181
|
-
return
|
|
7227
|
+
return import_react30.default.cloneElement(child, {
|
|
7182
7228
|
_chartDimensions: chartDimensions,
|
|
7183
7229
|
_scales: scales
|
|
7184
7230
|
});
|
|
@@ -7186,19 +7232,19 @@ var BarChart = ({
|
|
|
7186
7232
|
return child;
|
|
7187
7233
|
});
|
|
7188
7234
|
}, [children, chartWidth, chartHeight, padding, xBandScale, bandwidth, yScale]);
|
|
7189
|
-
const accessibleDescription = (0,
|
|
7235
|
+
const accessibleDescription = (0, import_react30.useMemo)(() => {
|
|
7190
7236
|
if (ariaLabel) return ariaLabel;
|
|
7191
7237
|
const seriesNames = data.map((s) => s.name).join(", ");
|
|
7192
7238
|
return `Bar chart with ${data.length} series: ${seriesNames}`;
|
|
7193
7239
|
}, [data, ariaLabel]);
|
|
7194
|
-
return /* @__PURE__ */ (0,
|
|
7240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)(
|
|
7195
7241
|
"div",
|
|
7196
7242
|
{
|
|
7197
7243
|
ref: containerRef,
|
|
7198
7244
|
className: `relative ${className}`,
|
|
7199
7245
|
style: { width, height: "auto" },
|
|
7200
7246
|
children: [
|
|
7201
|
-
/* @__PURE__ */ (0,
|
|
7247
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsxs)(
|
|
7202
7248
|
"svg",
|
|
7203
7249
|
{
|
|
7204
7250
|
width,
|
|
@@ -7208,7 +7254,7 @@ var BarChart = ({
|
|
|
7208
7254
|
"aria-label": accessibleDescription,
|
|
7209
7255
|
className: "bg-[hsl(var(--card))]",
|
|
7210
7256
|
children: [
|
|
7211
|
-
/* @__PURE__ */ (0,
|
|
7257
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("style", { children: `
|
|
7212
7258
|
@keyframes growY {
|
|
7213
7259
|
from { transform: scaleY(0); }
|
|
7214
7260
|
to { transform: scaleY(1); }
|
|
@@ -7222,8 +7268,8 @@ var BarChart = ({
|
|
|
7222
7268
|
to { opacity: 1; }
|
|
7223
7269
|
}
|
|
7224
7270
|
` }) }),
|
|
7225
|
-
/* @__PURE__ */ (0,
|
|
7226
|
-
showGrid && /* @__PURE__ */ (0,
|
|
7271
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
7272
|
+
showGrid && /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7227
7273
|
CartesianGrid,
|
|
7228
7274
|
{
|
|
7229
7275
|
_chartDimensions: { width: chartWidth, height: chartHeight },
|
|
@@ -7235,8 +7281,8 @@ var BarChart = ({
|
|
|
7235
7281
|
),
|
|
7236
7282
|
referenceElements,
|
|
7237
7283
|
bars,
|
|
7238
|
-
showXAxis && /* @__PURE__ */ (0,
|
|
7239
|
-
/* @__PURE__ */ (0,
|
|
7284
|
+
showXAxis && /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("g", { transform: `translate(0, ${chartHeight})`, children: [
|
|
7285
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7240
7286
|
"line",
|
|
7241
7287
|
{
|
|
7242
7288
|
x1: 0,
|
|
@@ -7248,9 +7294,9 @@ var BarChart = ({
|
|
|
7248
7294
|
),
|
|
7249
7295
|
categories.map((cat, i) => {
|
|
7250
7296
|
const x = xBandScale.scale(cat) + bandwidth / 2;
|
|
7251
|
-
return /* @__PURE__ */ (0,
|
|
7252
|
-
/* @__PURE__ */ (0,
|
|
7253
|
-
/* @__PURE__ */ (0,
|
|
7297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("g", { transform: `translate(${x}, 0)`, children: [
|
|
7298
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)("line", { y2: 6, className: "stroke-[hsl(var(--border))]" }),
|
|
7299
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7254
7300
|
"text",
|
|
7255
7301
|
{
|
|
7256
7302
|
y: 20,
|
|
@@ -7262,7 +7308,7 @@ var BarChart = ({
|
|
|
7262
7308
|
)
|
|
7263
7309
|
] }, `x-tick-${i}`);
|
|
7264
7310
|
}),
|
|
7265
|
-
xAxisLabel && /* @__PURE__ */ (0,
|
|
7311
|
+
xAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7266
7312
|
"text",
|
|
7267
7313
|
{
|
|
7268
7314
|
x: chartWidth / 2,
|
|
@@ -7275,8 +7321,8 @@ var BarChart = ({
|
|
|
7275
7321
|
}
|
|
7276
7322
|
)
|
|
7277
7323
|
] }),
|
|
7278
|
-
showYAxis && /* @__PURE__ */ (0,
|
|
7279
|
-
/* @__PURE__ */ (0,
|
|
7324
|
+
showYAxis && /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("g", { children: [
|
|
7325
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7280
7326
|
"line",
|
|
7281
7327
|
{
|
|
7282
7328
|
x1: 0,
|
|
@@ -7286,9 +7332,9 @@ var BarChart = ({
|
|
|
7286
7332
|
className: "stroke-[hsl(var(--border))]"
|
|
7287
7333
|
}
|
|
7288
7334
|
),
|
|
7289
|
-
yTicks.map((tick, i) => /* @__PURE__ */ (0,
|
|
7290
|
-
/* @__PURE__ */ (0,
|
|
7291
|
-
/* @__PURE__ */ (0,
|
|
7335
|
+
yTicks.map((tick, i) => /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("g", { transform: `translate(0, ${yScale(tick)})`, children: [
|
|
7336
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)("line", { x2: -6, className: "stroke-[hsl(var(--border))]" }),
|
|
7337
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7292
7338
|
"text",
|
|
7293
7339
|
{
|
|
7294
7340
|
x: -12,
|
|
@@ -7300,7 +7346,7 @@ var BarChart = ({
|
|
|
7300
7346
|
}
|
|
7301
7347
|
)
|
|
7302
7348
|
] }, `y-tick-${i}`)),
|
|
7303
|
-
yAxisLabel && /* @__PURE__ */ (0,
|
|
7349
|
+
yAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7304
7350
|
"text",
|
|
7305
7351
|
{
|
|
7306
7352
|
x: -chartHeight / 2,
|
|
@@ -7318,8 +7364,8 @@ var BarChart = ({
|
|
|
7318
7364
|
]
|
|
7319
7365
|
}
|
|
7320
7366
|
),
|
|
7321
|
-
showLegend && /* @__PURE__ */ (0,
|
|
7322
|
-
showTooltip && /* @__PURE__ */ (0,
|
|
7367
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(Legend, { items: legendItems, layout: "horizontal", align: "center" }),
|
|
7368
|
+
showTooltip && /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
7323
7369
|
ChartTooltip,
|
|
7324
7370
|
{
|
|
7325
7371
|
...tooltipData,
|
|
@@ -7333,8 +7379,8 @@ var BarChart = ({
|
|
|
7333
7379
|
};
|
|
7334
7380
|
|
|
7335
7381
|
// src/charts/AreaChart.tsx
|
|
7336
|
-
var
|
|
7337
|
-
var
|
|
7382
|
+
var import_react31 = __toESM(require("react"));
|
|
7383
|
+
var import_jsx_runtime116 = require("react/jsx-runtime");
|
|
7338
7384
|
var AreaChart = ({
|
|
7339
7385
|
data,
|
|
7340
7386
|
width: providedWidth,
|
|
@@ -7365,12 +7411,12 @@ var AreaChart = ({
|
|
|
7365
7411
|
colors = CHART_DEFAULTS.colors,
|
|
7366
7412
|
ariaLabel
|
|
7367
7413
|
}) => {
|
|
7368
|
-
const containerRef = (0,
|
|
7369
|
-
const [hoveredPoint, setHoveredPoint] = (0,
|
|
7414
|
+
const containerRef = (0, import_react31.useRef)(null);
|
|
7415
|
+
const [hoveredPoint, setHoveredPoint] = (0, import_react31.useState)(null);
|
|
7370
7416
|
const { tooltipData, showTooltip: showTooltipFn, hideTooltip } = useTooltip();
|
|
7371
7417
|
const width = providedWidth || 800;
|
|
7372
7418
|
const height = providedHeight || 400;
|
|
7373
|
-
const padding = (0,
|
|
7419
|
+
const padding = (0, import_react31.useMemo)(() => ({
|
|
7374
7420
|
top: customPadding?.top ?? CHART_DEFAULTS.padding.top,
|
|
7375
7421
|
right: customPadding?.right ?? CHART_DEFAULTS.padding.right,
|
|
7376
7422
|
bottom: customPadding?.bottom ?? (showXAxis ? 60 : CHART_DEFAULTS.padding.bottom),
|
|
@@ -7378,17 +7424,17 @@ var AreaChart = ({
|
|
|
7378
7424
|
}), [customPadding, showXAxis, showYAxis]);
|
|
7379
7425
|
const chartWidth = width - padding.left - padding.right;
|
|
7380
7426
|
const chartHeight = height - padding.top - padding.bottom;
|
|
7381
|
-
const allPoints = (0,
|
|
7427
|
+
const allPoints = (0, import_react31.useMemo)(
|
|
7382
7428
|
() => data.flatMap((series) => series.data),
|
|
7383
7429
|
[data]
|
|
7384
7430
|
);
|
|
7385
|
-
const xValueType = (0,
|
|
7431
|
+
const xValueType = (0, import_react31.useMemo)(() => {
|
|
7386
7432
|
const firstX = data[0]?.data[0]?.x;
|
|
7387
7433
|
if (firstX instanceof Date) return "date";
|
|
7388
7434
|
if (typeof firstX === "number") return "number";
|
|
7389
7435
|
return "string";
|
|
7390
7436
|
}, [data]);
|
|
7391
|
-
const xDomainCalc = (0,
|
|
7437
|
+
const xDomainCalc = (0, import_react31.useMemo)(() => {
|
|
7392
7438
|
if (xValueType === "date") {
|
|
7393
7439
|
const dates = allPoints.map((p) => p.x.getTime());
|
|
7394
7440
|
return [Math.min(...dates), Math.max(...dates)];
|
|
@@ -7400,7 +7446,7 @@ var AreaChart = ({
|
|
|
7400
7446
|
const maxLen = Math.max(...data.map((s) => s.data.length));
|
|
7401
7447
|
return [0, maxLen - 1];
|
|
7402
7448
|
}, [allPoints, xValueType, data]);
|
|
7403
|
-
const yDomainCalc = (0,
|
|
7449
|
+
const yDomainCalc = (0, import_react31.useMemo)(() => {
|
|
7404
7450
|
if (yDomain) return yDomain;
|
|
7405
7451
|
if (stacked) {
|
|
7406
7452
|
const maxPoints = Math.max(...data.map((s) => s.data.length));
|
|
@@ -7412,7 +7458,7 @@ var AreaChart = ({
|
|
|
7412
7458
|
const yValues = allPoints.map((p) => p.y);
|
|
7413
7459
|
return calculateDomain(yValues, { includeZero: true, padding: 0.1 });
|
|
7414
7460
|
}, [allPoints, stacked, data, yDomain]);
|
|
7415
|
-
const xScale = (0,
|
|
7461
|
+
const xScale = (0, import_react31.useMemo)(() => {
|
|
7416
7462
|
if (xValueType === "date") {
|
|
7417
7463
|
return (value) => {
|
|
7418
7464
|
const time = value instanceof Date ? value.getTime() : Number(value);
|
|
@@ -7435,18 +7481,18 @@ var AreaChart = ({
|
|
|
7435
7481
|
return index / maxLen * chartWidth;
|
|
7436
7482
|
};
|
|
7437
7483
|
}, [xValueType, xDomainCalc, chartWidth, data]);
|
|
7438
|
-
const yScale = (0,
|
|
7484
|
+
const yScale = (0, import_react31.useMemo)(
|
|
7439
7485
|
() => scaleLinear({
|
|
7440
7486
|
domain: yDomainCalc,
|
|
7441
7487
|
range: [chartHeight, 0]
|
|
7442
7488
|
}),
|
|
7443
7489
|
[yDomainCalc, chartHeight]
|
|
7444
7490
|
);
|
|
7445
|
-
const yTicks = (0,
|
|
7491
|
+
const yTicks = (0, import_react31.useMemo)(
|
|
7446
7492
|
() => getTicks(yDomainCalc, yAxisTickCount),
|
|
7447
7493
|
[yDomainCalc, yAxisTickCount]
|
|
7448
7494
|
);
|
|
7449
|
-
const xTicks = (0,
|
|
7495
|
+
const xTicks = (0, import_react31.useMemo)(() => {
|
|
7450
7496
|
if (xValueType === "string") {
|
|
7451
7497
|
return data[0]?.data.map((p, i) => ({ value: p.x, index: i })) || [];
|
|
7452
7498
|
}
|
|
@@ -7454,7 +7500,7 @@ var AreaChart = ({
|
|
|
7454
7500
|
const ticks = getTicks(xDomainCalc, tickCount);
|
|
7455
7501
|
return ticks.map((t) => ({ value: t, index: 0 }));
|
|
7456
7502
|
}, [xValueType, xDomainCalc, data]);
|
|
7457
|
-
const xFormatter = (0,
|
|
7503
|
+
const xFormatter = (0, import_react31.useCallback)((value) => {
|
|
7458
7504
|
if (formatXValue) return formatXValue(value);
|
|
7459
7505
|
if (value instanceof Date) {
|
|
7460
7506
|
const range = xDomainCalc[1] - xDomainCalc[0];
|
|
@@ -7462,11 +7508,11 @@ var AreaChart = ({
|
|
|
7462
7508
|
}
|
|
7463
7509
|
return String(value);
|
|
7464
7510
|
}, [formatXValue, xDomainCalc]);
|
|
7465
|
-
const yFormatter = (0,
|
|
7511
|
+
const yFormatter = (0, import_react31.useMemo)(() => {
|
|
7466
7512
|
if (formatYValue) return formatYValue;
|
|
7467
7513
|
return createTickFormatter(yDomainCalc);
|
|
7468
7514
|
}, [formatYValue, yDomainCalc]);
|
|
7469
|
-
const areaPaths = (0,
|
|
7515
|
+
const areaPaths = (0, import_react31.useMemo)(() => {
|
|
7470
7516
|
const paths = [];
|
|
7471
7517
|
const cumulativeY = Array(data[0]?.data.length || 0).fill(0);
|
|
7472
7518
|
data.forEach((series) => {
|
|
@@ -7500,7 +7546,7 @@ var AreaChart = ({
|
|
|
7500
7546
|
});
|
|
7501
7547
|
return paths;
|
|
7502
7548
|
}, [data, xScale, yScale, stacked, curved]);
|
|
7503
|
-
const handlePointEnter = (0,
|
|
7549
|
+
const handlePointEnter = (0, import_react31.useCallback)((e, seriesIndex, pointIndex) => {
|
|
7504
7550
|
const series = data[seriesIndex];
|
|
7505
7551
|
const point = series.data[pointIndex];
|
|
7506
7552
|
setHoveredPoint({ seriesIndex, pointIndex });
|
|
@@ -7523,16 +7569,16 @@ var AreaChart = ({
|
|
|
7523
7569
|
}
|
|
7524
7570
|
onPointHover?.(point, seriesIndex, pointIndex);
|
|
7525
7571
|
}, [data, showTooltip, colors, xFormatter, showTooltipFn, onPointHover]);
|
|
7526
|
-
const handlePointLeave = (0,
|
|
7572
|
+
const handlePointLeave = (0, import_react31.useCallback)(() => {
|
|
7527
7573
|
setHoveredPoint(null);
|
|
7528
7574
|
hideTooltip();
|
|
7529
7575
|
onPointHover?.(null, -1, -1);
|
|
7530
7576
|
}, [hideTooltip, onPointHover]);
|
|
7531
|
-
const handlePointClick = (0,
|
|
7577
|
+
const handlePointClick = (0, import_react31.useCallback)((seriesIndex, pointIndex) => {
|
|
7532
7578
|
const point = data[seriesIndex].data[pointIndex];
|
|
7533
7579
|
onPointClick?.(point, seriesIndex, pointIndex);
|
|
7534
7580
|
}, [data, onPointClick]);
|
|
7535
|
-
const legendItems = (0,
|
|
7581
|
+
const legendItems = (0, import_react31.useMemo)(
|
|
7536
7582
|
() => data.map((series, i) => ({
|
|
7537
7583
|
name: series.name,
|
|
7538
7584
|
color: series.color || colors[i % colors.length],
|
|
@@ -7540,7 +7586,7 @@ var AreaChart = ({
|
|
|
7540
7586
|
})),
|
|
7541
7587
|
[data, colors]
|
|
7542
7588
|
);
|
|
7543
|
-
const referenceElements = (0,
|
|
7589
|
+
const referenceElements = (0, import_react31.useMemo)(() => {
|
|
7544
7590
|
if (!children) return null;
|
|
7545
7591
|
const chartDimensions = { width: chartWidth, height: chartHeight, padding };
|
|
7546
7592
|
const scales = {
|
|
@@ -7553,10 +7599,10 @@ var AreaChart = ({
|
|
|
7553
7599
|
},
|
|
7554
7600
|
yScale
|
|
7555
7601
|
};
|
|
7556
|
-
return
|
|
7557
|
-
if (!
|
|
7602
|
+
return import_react31.default.Children.map(children, (child) => {
|
|
7603
|
+
if (!import_react31.default.isValidElement(child)) return child;
|
|
7558
7604
|
if (child.type === ReferenceLine || child.type === ReferenceArea || child.type === CartesianGrid) {
|
|
7559
|
-
return
|
|
7605
|
+
return import_react31.default.cloneElement(child, {
|
|
7560
7606
|
_chartDimensions: chartDimensions,
|
|
7561
7607
|
_scales: scales
|
|
7562
7608
|
});
|
|
@@ -7564,19 +7610,19 @@ var AreaChart = ({
|
|
|
7564
7610
|
return child;
|
|
7565
7611
|
});
|
|
7566
7612
|
}, [children, chartWidth, chartHeight, padding, xScale, yScale, xValueType, data]);
|
|
7567
|
-
const accessibleDescription = (0,
|
|
7613
|
+
const accessibleDescription = (0, import_react31.useMemo)(() => {
|
|
7568
7614
|
if (ariaLabel) return ariaLabel;
|
|
7569
7615
|
const seriesNames = data.map((s) => s.name).join(", ");
|
|
7570
7616
|
return `Area chart with ${data.length} series: ${seriesNames}`;
|
|
7571
7617
|
}, [data, ariaLabel]);
|
|
7572
|
-
return /* @__PURE__ */ (0,
|
|
7618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(
|
|
7573
7619
|
"div",
|
|
7574
7620
|
{
|
|
7575
7621
|
ref: containerRef,
|
|
7576
7622
|
className: `relative ${className}`,
|
|
7577
7623
|
style: { width, height: "auto" },
|
|
7578
7624
|
children: [
|
|
7579
|
-
/* @__PURE__ */ (0,
|
|
7625
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(
|
|
7580
7626
|
"svg",
|
|
7581
7627
|
{
|
|
7582
7628
|
width,
|
|
@@ -7586,10 +7632,10 @@ var AreaChart = ({
|
|
|
7586
7632
|
"aria-label": accessibleDescription,
|
|
7587
7633
|
className: "bg-[hsl(var(--card))]",
|
|
7588
7634
|
children: [
|
|
7589
|
-
/* @__PURE__ */ (0,
|
|
7635
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("defs", { children: [
|
|
7590
7636
|
data.map((series, i) => {
|
|
7591
7637
|
const color = series.color || colors[i % colors.length];
|
|
7592
|
-
return /* @__PURE__ */ (0,
|
|
7638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(
|
|
7593
7639
|
"linearGradient",
|
|
7594
7640
|
{
|
|
7595
7641
|
id: `area-gradient-${i}`,
|
|
@@ -7598,14 +7644,14 @@ var AreaChart = ({
|
|
|
7598
7644
|
x2: "0",
|
|
7599
7645
|
y2: "1",
|
|
7600
7646
|
children: [
|
|
7601
|
-
/* @__PURE__ */ (0,
|
|
7602
|
-
/* @__PURE__ */ (0,
|
|
7647
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)("stop", { offset: "0%", stopColor: color, stopOpacity: series.fillOpacity ?? fillOpacity }),
|
|
7648
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)("stop", { offset: "100%", stopColor: color, stopOpacity: 0.05 })
|
|
7603
7649
|
]
|
|
7604
7650
|
},
|
|
7605
7651
|
`gradient-${i}`
|
|
7606
7652
|
);
|
|
7607
7653
|
}),
|
|
7608
|
-
/* @__PURE__ */ (0,
|
|
7654
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)("style", { children: `
|
|
7609
7655
|
@keyframes fadeIn {
|
|
7610
7656
|
from { opacity: 0; }
|
|
7611
7657
|
to { opacity: 1; }
|
|
@@ -7616,8 +7662,8 @@ var AreaChart = ({
|
|
|
7616
7662
|
}
|
|
7617
7663
|
` })
|
|
7618
7664
|
] }),
|
|
7619
|
-
/* @__PURE__ */ (0,
|
|
7620
|
-
showGrid && /* @__PURE__ */ (0,
|
|
7665
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
7666
|
+
showGrid && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7621
7667
|
CartesianGrid,
|
|
7622
7668
|
{
|
|
7623
7669
|
_chartDimensions: { width: chartWidth, height: chartHeight },
|
|
@@ -7630,8 +7676,8 @@ var AreaChart = ({
|
|
|
7630
7676
|
const { areaPath, linePath } = areaPaths[seriesIndex];
|
|
7631
7677
|
const color = series.color || colors[seriesIndex % colors.length];
|
|
7632
7678
|
const strokeWidth = series.strokeWidth || CHART_DEFAULTS.line.strokeWidth;
|
|
7633
|
-
return /* @__PURE__ */ (0,
|
|
7634
|
-
/* @__PURE__ */ (0,
|
|
7679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("g", { children: [
|
|
7680
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7635
7681
|
"path",
|
|
7636
7682
|
{
|
|
7637
7683
|
d: areaPath,
|
|
@@ -7642,7 +7688,7 @@ var AreaChart = ({
|
|
|
7642
7688
|
} : void 0
|
|
7643
7689
|
}
|
|
7644
7690
|
),
|
|
7645
|
-
/* @__PURE__ */ (0,
|
|
7691
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7646
7692
|
"path",
|
|
7647
7693
|
{
|
|
7648
7694
|
d: linePath,
|
|
@@ -7666,7 +7712,7 @@ var AreaChart = ({
|
|
|
7666
7712
|
if (!showSeriesDots) return null;
|
|
7667
7713
|
return points.map((point, pointIndex) => {
|
|
7668
7714
|
const isHovered = hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex;
|
|
7669
|
-
return /* @__PURE__ */ (0,
|
|
7715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7670
7716
|
"circle",
|
|
7671
7717
|
{
|
|
7672
7718
|
cx: point.x,
|
|
@@ -7688,8 +7734,8 @@ var AreaChart = ({
|
|
|
7688
7734
|
);
|
|
7689
7735
|
});
|
|
7690
7736
|
}),
|
|
7691
|
-
showXAxis && /* @__PURE__ */ (0,
|
|
7692
|
-
/* @__PURE__ */ (0,
|
|
7737
|
+
showXAxis && /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("g", { transform: `translate(0, ${chartHeight})`, children: [
|
|
7738
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7693
7739
|
"line",
|
|
7694
7740
|
{
|
|
7695
7741
|
x1: 0,
|
|
@@ -7701,9 +7747,9 @@ var AreaChart = ({
|
|
|
7701
7747
|
),
|
|
7702
7748
|
xTicks.map((tick, i) => {
|
|
7703
7749
|
const x = xValueType === "string" ? xScale(tick.value, tick.index) : xScale(xValueType === "date" ? new Date(tick.value) : tick.value, 0);
|
|
7704
|
-
return /* @__PURE__ */ (0,
|
|
7705
|
-
/* @__PURE__ */ (0,
|
|
7706
|
-
/* @__PURE__ */ (0,
|
|
7750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("g", { transform: `translate(${x}, 0)`, children: [
|
|
7751
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)("line", { y2: 6, className: "stroke-[hsl(var(--border))]" }),
|
|
7752
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7707
7753
|
"text",
|
|
7708
7754
|
{
|
|
7709
7755
|
y: 20,
|
|
@@ -7715,7 +7761,7 @@ var AreaChart = ({
|
|
|
7715
7761
|
)
|
|
7716
7762
|
] }, `x-tick-${i}`);
|
|
7717
7763
|
}),
|
|
7718
|
-
xAxisLabel && /* @__PURE__ */ (0,
|
|
7764
|
+
xAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7719
7765
|
"text",
|
|
7720
7766
|
{
|
|
7721
7767
|
x: chartWidth / 2,
|
|
@@ -7728,8 +7774,8 @@ var AreaChart = ({
|
|
|
7728
7774
|
}
|
|
7729
7775
|
)
|
|
7730
7776
|
] }),
|
|
7731
|
-
showYAxis && /* @__PURE__ */ (0,
|
|
7732
|
-
/* @__PURE__ */ (0,
|
|
7777
|
+
showYAxis && /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("g", { children: [
|
|
7778
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7733
7779
|
"line",
|
|
7734
7780
|
{
|
|
7735
7781
|
x1: 0,
|
|
@@ -7739,9 +7785,9 @@ var AreaChart = ({
|
|
|
7739
7785
|
className: "stroke-[hsl(var(--border))]"
|
|
7740
7786
|
}
|
|
7741
7787
|
),
|
|
7742
|
-
yTicks.map((tick, i) => /* @__PURE__ */ (0,
|
|
7743
|
-
/* @__PURE__ */ (0,
|
|
7744
|
-
/* @__PURE__ */ (0,
|
|
7788
|
+
yTicks.map((tick, i) => /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("g", { transform: `translate(0, ${yScale(tick)})`, children: [
|
|
7789
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)("line", { x2: -6, className: "stroke-[hsl(var(--border))]" }),
|
|
7790
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7745
7791
|
"text",
|
|
7746
7792
|
{
|
|
7747
7793
|
x: -12,
|
|
@@ -7753,7 +7799,7 @@ var AreaChart = ({
|
|
|
7753
7799
|
}
|
|
7754
7800
|
)
|
|
7755
7801
|
] }, `y-tick-${i}`)),
|
|
7756
|
-
yAxisLabel && /* @__PURE__ */ (0,
|
|
7802
|
+
yAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7757
7803
|
"text",
|
|
7758
7804
|
{
|
|
7759
7805
|
x: -chartHeight / 2,
|
|
@@ -7771,8 +7817,8 @@ var AreaChart = ({
|
|
|
7771
7817
|
]
|
|
7772
7818
|
}
|
|
7773
7819
|
),
|
|
7774
|
-
showLegend && /* @__PURE__ */ (0,
|
|
7775
|
-
showTooltip && /* @__PURE__ */ (0,
|
|
7820
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(Legend, { items: legendItems, layout: "horizontal", align: "center" }),
|
|
7821
|
+
showTooltip && /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
7776
7822
|
ChartTooltip,
|
|
7777
7823
|
{
|
|
7778
7824
|
...tooltipData,
|
|
@@ -7786,8 +7832,8 @@ var AreaChart = ({
|
|
|
7786
7832
|
};
|
|
7787
7833
|
|
|
7788
7834
|
// src/charts/PieChart.tsx
|
|
7789
|
-
var
|
|
7790
|
-
var
|
|
7835
|
+
var import_react32 = require("react");
|
|
7836
|
+
var import_jsx_runtime117 = require("react/jsx-runtime");
|
|
7791
7837
|
var PieChart = ({
|
|
7792
7838
|
data,
|
|
7793
7839
|
width: providedWidth,
|
|
@@ -7816,9 +7862,9 @@ var PieChart = ({
|
|
|
7816
7862
|
colors = CHART_DEFAULTS.colors,
|
|
7817
7863
|
ariaLabel
|
|
7818
7864
|
}) => {
|
|
7819
|
-
const containerRef = (0,
|
|
7820
|
-
const [hoveredSlice, setHoveredSlice] = (0,
|
|
7821
|
-
const [activeSlice, setActiveSlice] = (0,
|
|
7865
|
+
const containerRef = (0, import_react32.useRef)(null);
|
|
7866
|
+
const [hoveredSlice, setHoveredSlice] = (0, import_react32.useState)(null);
|
|
7867
|
+
const [activeSlice, setActiveSlice] = (0, import_react32.useState)(null);
|
|
7822
7868
|
const { tooltipData, showTooltip: showTooltipFn, hideTooltip } = useTooltip();
|
|
7823
7869
|
const width = providedWidth || 400;
|
|
7824
7870
|
const height = providedHeight || 400;
|
|
@@ -7829,11 +7875,11 @@ var PieChart = ({
|
|
|
7829
7875
|
const outerRadius = providedOuterRadius || maxRadius;
|
|
7830
7876
|
const innerRadius = providedInnerRadius ?? (donut ? outerRadius * 0.6 : 0);
|
|
7831
7877
|
const isDonut = innerRadius > 0;
|
|
7832
|
-
const total = (0,
|
|
7878
|
+
const total = (0, import_react32.useMemo)(
|
|
7833
7879
|
() => data.reduce((sum, d) => sum + d.value, 0),
|
|
7834
7880
|
[data]
|
|
7835
7881
|
);
|
|
7836
|
-
const slices = (0,
|
|
7882
|
+
const slices = (0, import_react32.useMemo)(() => {
|
|
7837
7883
|
const angleRange = endAngle - startAngle;
|
|
7838
7884
|
let currentAngle = startAngle;
|
|
7839
7885
|
return data.map((item, index) => {
|
|
@@ -7869,7 +7915,7 @@ var PieChart = ({
|
|
|
7869
7915
|
};
|
|
7870
7916
|
});
|
|
7871
7917
|
}, [data, total, startAngle, endAngle, paddingAngle, centerX, centerY, outerRadius, innerRadius, isDonut, colors]);
|
|
7872
|
-
const handleSliceEnter = (0,
|
|
7918
|
+
const handleSliceEnter = (0, import_react32.useCallback)((e, index) => {
|
|
7873
7919
|
const slice = slices[index];
|
|
7874
7920
|
setHoveredSlice(index);
|
|
7875
7921
|
if (showTooltip && containerRef.current) {
|
|
@@ -7891,16 +7937,16 @@ var PieChart = ({
|
|
|
7891
7937
|
}
|
|
7892
7938
|
onSliceHover?.(data[index], index);
|
|
7893
7939
|
}, [slices, data, showTooltip, showTooltipFn, onSliceHover]);
|
|
7894
|
-
const handleSliceLeave = (0,
|
|
7940
|
+
const handleSliceLeave = (0, import_react32.useCallback)(() => {
|
|
7895
7941
|
setHoveredSlice(null);
|
|
7896
7942
|
hideTooltip();
|
|
7897
7943
|
onSliceHover?.(null, -1);
|
|
7898
7944
|
}, [hideTooltip, onSliceHover]);
|
|
7899
|
-
const handleSliceClick = (0,
|
|
7945
|
+
const handleSliceClick = (0, import_react32.useCallback)((index) => {
|
|
7900
7946
|
setActiveSlice((prev) => prev === index ? null : index);
|
|
7901
7947
|
onSliceClick?.(data[index], index);
|
|
7902
7948
|
}, [data, onSliceClick]);
|
|
7903
|
-
const getLabelText = (0,
|
|
7949
|
+
const getLabelText = (0, import_react32.useCallback)((slice) => {
|
|
7904
7950
|
if (labelFormatter) {
|
|
7905
7951
|
return labelFormatter(data[slice.index], slice.percent);
|
|
7906
7952
|
}
|
|
@@ -7915,7 +7961,7 @@ var PieChart = ({
|
|
|
7915
7961
|
return `${slice.percent.toFixed(1)}%`;
|
|
7916
7962
|
}
|
|
7917
7963
|
}, [labelType, labelFormatter, data]);
|
|
7918
|
-
const legendItems = (0,
|
|
7964
|
+
const legendItems = (0, import_react32.useMemo)(
|
|
7919
7965
|
() => data.map((item, i) => ({
|
|
7920
7966
|
name: `${item.label}${showPercentages ? ` (${(item.value / total * 100).toFixed(1)}%)` : ""}`,
|
|
7921
7967
|
color: item.color || colors[i % colors.length],
|
|
@@ -7923,19 +7969,19 @@ var PieChart = ({
|
|
|
7923
7969
|
})),
|
|
7924
7970
|
[data, colors, total, showPercentages]
|
|
7925
7971
|
);
|
|
7926
|
-
const accessibleDescription = (0,
|
|
7972
|
+
const accessibleDescription = (0, import_react32.useMemo)(() => {
|
|
7927
7973
|
if (ariaLabel) return ariaLabel;
|
|
7928
7974
|
const sliceNames = data.map((d) => `${d.label}: ${d.value}`).join(", ");
|
|
7929
7975
|
return `${isDonut ? "Donut" : "Pie"} chart with ${data.length} slices: ${sliceNames}`;
|
|
7930
7976
|
}, [data, isDonut, ariaLabel]);
|
|
7931
|
-
return /* @__PURE__ */ (0,
|
|
7977
|
+
return /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)(
|
|
7932
7978
|
"div",
|
|
7933
7979
|
{
|
|
7934
7980
|
ref: containerRef,
|
|
7935
7981
|
className: `relative inline-flex flex-col items-center ${className}`,
|
|
7936
7982
|
style: { width },
|
|
7937
7983
|
children: [
|
|
7938
|
-
/* @__PURE__ */ (0,
|
|
7984
|
+
/* @__PURE__ */ (0, import_jsx_runtime117.jsxs)(
|
|
7939
7985
|
"svg",
|
|
7940
7986
|
{
|
|
7941
7987
|
width,
|
|
@@ -7945,7 +7991,7 @@ var PieChart = ({
|
|
|
7945
7991
|
"aria-label": accessibleDescription,
|
|
7946
7992
|
className: "bg-[hsl(var(--card))]",
|
|
7947
7993
|
children: [
|
|
7948
|
-
/* @__PURE__ */ (0,
|
|
7994
|
+
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)("style", { children: `
|
|
7949
7995
|
@keyframes rotateIn {
|
|
7950
7996
|
from {
|
|
7951
7997
|
transform: rotate(-90deg);
|
|
@@ -7961,7 +8007,7 @@ var PieChart = ({
|
|
|
7961
8007
|
to { opacity: 1; }
|
|
7962
8008
|
}
|
|
7963
8009
|
` }) }),
|
|
7964
|
-
/* @__PURE__ */ (0,
|
|
8010
|
+
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)("g", { style: animate ? {
|
|
7965
8011
|
transformOrigin: `${centerX}px ${centerY}px`,
|
|
7966
8012
|
animation: `rotateIn ${animationDuration}ms ease-out forwards`
|
|
7967
8013
|
} : void 0, children: slices.map((slice) => {
|
|
@@ -7969,8 +8015,8 @@ var PieChart = ({
|
|
|
7969
8015
|
const isActive = activeSlice === slice.index;
|
|
7970
8016
|
const scale = isHovered || isActive ? 1.03 : 1;
|
|
7971
8017
|
const transform = `translate(${centerX}px, ${centerY}px) scale(${scale}) translate(${-centerX}px, ${-centerY}px)`;
|
|
7972
|
-
return /* @__PURE__ */ (0,
|
|
7973
|
-
/* @__PURE__ */ (0,
|
|
8018
|
+
return /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)("g", { children: [
|
|
8019
|
+
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
7974
8020
|
"path",
|
|
7975
8021
|
{
|
|
7976
8022
|
d: slice.path,
|
|
@@ -7984,7 +8030,7 @@ var PieChart = ({
|
|
|
7984
8030
|
onClick: () => handleSliceClick(slice.index)
|
|
7985
8031
|
}
|
|
7986
8032
|
),
|
|
7987
|
-
showLabels && slice.percent >= minLabelPercent && /* @__PURE__ */ (0,
|
|
8033
|
+
showLabels && slice.percent >= minLabelPercent && /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
7988
8034
|
"text",
|
|
7989
8035
|
{
|
|
7990
8036
|
x: slice.labelX,
|
|
@@ -8003,8 +8049,8 @@ var PieChart = ({
|
|
|
8003
8049
|
)
|
|
8004
8050
|
] }, slice.index);
|
|
8005
8051
|
}) }),
|
|
8006
|
-
isDonut && (centerLabel || centerValue !== void 0) && /* @__PURE__ */ (0,
|
|
8007
|
-
centerValue !== void 0 && /* @__PURE__ */ (0,
|
|
8052
|
+
isDonut && (centerLabel || centerValue !== void 0) && /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)("g", { children: [
|
|
8053
|
+
centerValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
8008
8054
|
"text",
|
|
8009
8055
|
{
|
|
8010
8056
|
x: centerX,
|
|
@@ -8017,7 +8063,7 @@ var PieChart = ({
|
|
|
8017
8063
|
children: typeof centerValue === "number" ? formatNumber(centerValue) : centerValue
|
|
8018
8064
|
}
|
|
8019
8065
|
),
|
|
8020
|
-
centerLabel && (typeof centerLabel === "string" ? /* @__PURE__ */ (0,
|
|
8066
|
+
centerLabel && (typeof centerLabel === "string" ? /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
8021
8067
|
"text",
|
|
8022
8068
|
{
|
|
8023
8069
|
x: centerX,
|
|
@@ -8028,7 +8074,7 @@ var PieChart = ({
|
|
|
8028
8074
|
className: "fill-[hsl(var(--muted-foreground))]",
|
|
8029
8075
|
children: centerLabel
|
|
8030
8076
|
}
|
|
8031
|
-
) : /* @__PURE__ */ (0,
|
|
8077
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
8032
8078
|
"foreignObject",
|
|
8033
8079
|
{
|
|
8034
8080
|
x: centerX - innerRadius * 0.7,
|
|
@@ -8042,7 +8088,7 @@ var PieChart = ({
|
|
|
8042
8088
|
]
|
|
8043
8089
|
}
|
|
8044
8090
|
),
|
|
8045
|
-
showLegend && /* @__PURE__ */ (0,
|
|
8091
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
8046
8092
|
Legend,
|
|
8047
8093
|
{
|
|
8048
8094
|
items: legendItems,
|
|
@@ -8053,7 +8099,7 @@ var PieChart = ({
|
|
|
8053
8099
|
onMouseLeave: () => setHoveredSlice(null)
|
|
8054
8100
|
}
|
|
8055
8101
|
),
|
|
8056
|
-
showTooltip && /* @__PURE__ */ (0,
|
|
8102
|
+
showTooltip && /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
8057
8103
|
ChartTooltip,
|
|
8058
8104
|
{
|
|
8059
8105
|
...tooltipData,
|
|
@@ -8067,8 +8113,8 @@ var PieChart = ({
|
|
|
8067
8113
|
};
|
|
8068
8114
|
|
|
8069
8115
|
// src/charts/ScatterChart.tsx
|
|
8070
|
-
var
|
|
8071
|
-
var
|
|
8116
|
+
var import_react33 = __toESM(require("react"));
|
|
8117
|
+
var import_jsx_runtime118 = require("react/jsx-runtime");
|
|
8072
8118
|
function linearRegression(points) {
|
|
8073
8119
|
const n = points.length;
|
|
8074
8120
|
if (n === 0) return { slope: 0, intercept: 0 };
|
|
@@ -8089,7 +8135,7 @@ var renderShape = (shape, x, y, size, color, commonProps) => {
|
|
|
8089
8135
|
const { className, stroke, strokeWidth, onMouseEnter, onMouseLeave, onClick } = commonProps;
|
|
8090
8136
|
switch (shape) {
|
|
8091
8137
|
case "square":
|
|
8092
|
-
return /* @__PURE__ */ (0,
|
|
8138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8093
8139
|
"rect",
|
|
8094
8140
|
{
|
|
8095
8141
|
x: x - size / 2,
|
|
@@ -8108,7 +8154,7 @@ var renderShape = (shape, x, y, size, color, commonProps) => {
|
|
|
8108
8154
|
case "triangle": {
|
|
8109
8155
|
const h = size * 0.866;
|
|
8110
8156
|
const points = `${x},${y - h / 2} ${x - size / 2},${y + h / 2} ${x + size / 2},${y + h / 2}`;
|
|
8111
|
-
return /* @__PURE__ */ (0,
|
|
8157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8112
8158
|
"polygon",
|
|
8113
8159
|
{
|
|
8114
8160
|
points,
|
|
@@ -8125,7 +8171,7 @@ var renderShape = (shape, x, y, size, color, commonProps) => {
|
|
|
8125
8171
|
case "diamond": {
|
|
8126
8172
|
const d = size / 1.414;
|
|
8127
8173
|
const diamondPoints = `${x},${y - d} ${x + d},${y} ${x},${y + d} ${x - d},${y}`;
|
|
8128
|
-
return /* @__PURE__ */ (0,
|
|
8174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8129
8175
|
"polygon",
|
|
8130
8176
|
{
|
|
8131
8177
|
points: diamondPoints,
|
|
@@ -8141,7 +8187,7 @@ var renderShape = (shape, x, y, size, color, commonProps) => {
|
|
|
8141
8187
|
}
|
|
8142
8188
|
case "circle":
|
|
8143
8189
|
default:
|
|
8144
|
-
return /* @__PURE__ */ (0,
|
|
8190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8145
8191
|
"circle",
|
|
8146
8192
|
{
|
|
8147
8193
|
cx: x,
|
|
@@ -8191,12 +8237,12 @@ var ScatterChart = ({
|
|
|
8191
8237
|
colors = CHART_DEFAULTS.colors,
|
|
8192
8238
|
ariaLabel
|
|
8193
8239
|
}) => {
|
|
8194
|
-
const containerRef = (0,
|
|
8195
|
-
const [hoveredPoint, setHoveredPoint] = (0,
|
|
8240
|
+
const containerRef = (0, import_react33.useRef)(null);
|
|
8241
|
+
const [hoveredPoint, setHoveredPoint] = (0, import_react33.useState)(null);
|
|
8196
8242
|
const { tooltipData, showTooltip: showTooltipFn, hideTooltip } = useTooltip();
|
|
8197
8243
|
const width = providedWidth || 800;
|
|
8198
8244
|
const height = providedHeight || 400;
|
|
8199
|
-
const padding = (0,
|
|
8245
|
+
const padding = (0, import_react33.useMemo)(() => ({
|
|
8200
8246
|
top: customPadding?.top ?? CHART_DEFAULTS.padding.top,
|
|
8201
8247
|
right: customPadding?.right ?? CHART_DEFAULTS.padding.right,
|
|
8202
8248
|
bottom: customPadding?.bottom ?? (showXAxis ? 60 : CHART_DEFAULTS.padding.bottom),
|
|
@@ -8204,52 +8250,52 @@ var ScatterChart = ({
|
|
|
8204
8250
|
}), [customPadding, showXAxis, showYAxis]);
|
|
8205
8251
|
const chartWidth = width - padding.left - padding.right;
|
|
8206
8252
|
const chartHeight = height - padding.top - padding.bottom;
|
|
8207
|
-
const allPoints = (0,
|
|
8253
|
+
const allPoints = (0, import_react33.useMemo)(
|
|
8208
8254
|
() => data.flatMap((series) => series.data),
|
|
8209
8255
|
[data]
|
|
8210
8256
|
);
|
|
8211
|
-
const xDomainCalc = (0,
|
|
8257
|
+
const xDomainCalc = (0, import_react33.useMemo)(() => {
|
|
8212
8258
|
if (xDomain) return xDomain;
|
|
8213
8259
|
const xValues = allPoints.map((p) => p.x);
|
|
8214
8260
|
return calculateDomain(xValues, { includeZero: false, padding: 0.1 });
|
|
8215
8261
|
}, [allPoints, xDomain]);
|
|
8216
|
-
const yDomainCalc = (0,
|
|
8262
|
+
const yDomainCalc = (0, import_react33.useMemo)(() => {
|
|
8217
8263
|
if (yDomain) return yDomain;
|
|
8218
8264
|
const yValues = allPoints.map((p) => p.y);
|
|
8219
8265
|
return calculateDomain(yValues, { includeZero: false, padding: 0.1 });
|
|
8220
8266
|
}, [allPoints, yDomain]);
|
|
8221
|
-
const zDomain = (0,
|
|
8267
|
+
const zDomain = (0, import_react33.useMemo)(() => {
|
|
8222
8268
|
if (!bubble) return [0, 1];
|
|
8223
8269
|
const zValues = allPoints.map((p) => p.z || 0).filter((z) => z > 0);
|
|
8224
8270
|
if (zValues.length === 0) return [0, 1];
|
|
8225
8271
|
return [Math.min(...zValues), Math.max(...zValues)];
|
|
8226
8272
|
}, [allPoints, bubble]);
|
|
8227
|
-
const xScale = (0,
|
|
8273
|
+
const xScale = (0, import_react33.useMemo)(
|
|
8228
8274
|
() => scaleLinear({
|
|
8229
8275
|
domain: xDomainCalc,
|
|
8230
8276
|
range: [0, chartWidth]
|
|
8231
8277
|
}),
|
|
8232
8278
|
[xDomainCalc, chartWidth]
|
|
8233
8279
|
);
|
|
8234
|
-
const yScale = (0,
|
|
8280
|
+
const yScale = (0, import_react33.useMemo)(
|
|
8235
8281
|
() => scaleLinear({
|
|
8236
8282
|
domain: yDomainCalc,
|
|
8237
8283
|
range: [chartHeight, 0]
|
|
8238
8284
|
}),
|
|
8239
8285
|
[yDomainCalc, chartHeight]
|
|
8240
8286
|
);
|
|
8241
|
-
const sizeScale = (0,
|
|
8287
|
+
const sizeScale = (0, import_react33.useMemo)(() => {
|
|
8242
8288
|
if (!bubble) return () => pointSize;
|
|
8243
8289
|
return scaleLinear({
|
|
8244
8290
|
domain: zDomain,
|
|
8245
8291
|
range: [minBubbleSize, maxBubbleSize]
|
|
8246
8292
|
});
|
|
8247
8293
|
}, [bubble, zDomain, minBubbleSize, maxBubbleSize, pointSize]);
|
|
8248
|
-
const xTicks = (0,
|
|
8249
|
-
const yTicks = (0,
|
|
8250
|
-
const xFormatter = (0,
|
|
8251
|
-
const yFormatter = (0,
|
|
8252
|
-
const trendLines = (0,
|
|
8294
|
+
const xTicks = (0, import_react33.useMemo)(() => getTicks(xDomainCalc, xAxisTickCount), [xDomainCalc, xAxisTickCount]);
|
|
8295
|
+
const yTicks = (0, import_react33.useMemo)(() => getTicks(yDomainCalc, yAxisTickCount), [yDomainCalc, yAxisTickCount]);
|
|
8296
|
+
const xFormatter = (0, import_react33.useMemo)(() => formatXValue || createTickFormatter(xDomainCalc), [formatXValue, xDomainCalc]);
|
|
8297
|
+
const yFormatter = (0, import_react33.useMemo)(() => formatYValue || createTickFormatter(yDomainCalc), [formatYValue, yDomainCalc]);
|
|
8298
|
+
const trendLines = (0, import_react33.useMemo)(() => {
|
|
8253
8299
|
if (!showTrendLine) return [];
|
|
8254
8300
|
return data.map((series) => {
|
|
8255
8301
|
const regression = linearRegression(series.data);
|
|
@@ -8265,7 +8311,7 @@ var ScatterChart = ({
|
|
|
8265
8311
|
};
|
|
8266
8312
|
});
|
|
8267
8313
|
}, [data, showTrendLine, xDomainCalc, xScale, yScale]);
|
|
8268
|
-
const handlePointEnter = (0,
|
|
8314
|
+
const handlePointEnter = (0, import_react33.useCallback)((e, seriesIndex, pointIndex) => {
|
|
8269
8315
|
const series = data[seriesIndex];
|
|
8270
8316
|
const point = series.data[pointIndex];
|
|
8271
8317
|
setHoveredPoint({ seriesIndex, pointIndex });
|
|
@@ -8289,16 +8335,16 @@ var ScatterChart = ({
|
|
|
8289
8335
|
}
|
|
8290
8336
|
onPointHover?.(point, seriesIndex, pointIndex);
|
|
8291
8337
|
}, [data, showTooltip, colors, bubble, showTooltipFn, onPointHover]);
|
|
8292
|
-
const handlePointLeave = (0,
|
|
8338
|
+
const handlePointLeave = (0, import_react33.useCallback)(() => {
|
|
8293
8339
|
setHoveredPoint(null);
|
|
8294
8340
|
hideTooltip();
|
|
8295
8341
|
onPointHover?.(null, -1, -1);
|
|
8296
8342
|
}, [hideTooltip, onPointHover]);
|
|
8297
|
-
const handlePointClick = (0,
|
|
8343
|
+
const handlePointClick = (0, import_react33.useCallback)((seriesIndex, pointIndex) => {
|
|
8298
8344
|
const point = data[seriesIndex].data[pointIndex];
|
|
8299
8345
|
onPointClick?.(point, seriesIndex, pointIndex);
|
|
8300
8346
|
}, [data, onPointClick]);
|
|
8301
|
-
const legendItems = (0,
|
|
8347
|
+
const legendItems = (0, import_react33.useMemo)(
|
|
8302
8348
|
() => data.map((series, i) => ({
|
|
8303
8349
|
name: series.name,
|
|
8304
8350
|
color: series.color || colors[i % colors.length],
|
|
@@ -8306,14 +8352,14 @@ var ScatterChart = ({
|
|
|
8306
8352
|
})),
|
|
8307
8353
|
[data, colors]
|
|
8308
8354
|
);
|
|
8309
|
-
const referenceElements = (0,
|
|
8355
|
+
const referenceElements = (0, import_react33.useMemo)(() => {
|
|
8310
8356
|
if (!children) return null;
|
|
8311
8357
|
const chartDimensions = { width: chartWidth, height: chartHeight, padding };
|
|
8312
8358
|
const scales = { xScale, yScale };
|
|
8313
|
-
return
|
|
8314
|
-
if (!
|
|
8359
|
+
return import_react33.default.Children.map(children, (child) => {
|
|
8360
|
+
if (!import_react33.default.isValidElement(child)) return child;
|
|
8315
8361
|
if (child.type === ReferenceLine || child.type === ReferenceArea || child.type === CartesianGrid) {
|
|
8316
|
-
return
|
|
8362
|
+
return import_react33.default.cloneElement(child, {
|
|
8317
8363
|
_chartDimensions: chartDimensions,
|
|
8318
8364
|
_scales: scales
|
|
8319
8365
|
});
|
|
@@ -8321,19 +8367,19 @@ var ScatterChart = ({
|
|
|
8321
8367
|
return child;
|
|
8322
8368
|
});
|
|
8323
8369
|
}, [children, chartWidth, chartHeight, padding, xScale, yScale]);
|
|
8324
|
-
const accessibleDescription = (0,
|
|
8370
|
+
const accessibleDescription = (0, import_react33.useMemo)(() => {
|
|
8325
8371
|
if (ariaLabel) return ariaLabel;
|
|
8326
8372
|
const totalPoints = data.reduce((sum, s) => sum + s.data.length, 0);
|
|
8327
8373
|
return `Scatter chart with ${data.length} series and ${totalPoints} data points`;
|
|
8328
8374
|
}, [data, ariaLabel]);
|
|
8329
|
-
return /* @__PURE__ */ (0,
|
|
8375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime118.jsxs)(
|
|
8330
8376
|
"div",
|
|
8331
8377
|
{
|
|
8332
8378
|
ref: containerRef,
|
|
8333
8379
|
className: `relative ${className}`,
|
|
8334
8380
|
style: { width, height: "auto" },
|
|
8335
8381
|
children: [
|
|
8336
|
-
/* @__PURE__ */ (0,
|
|
8382
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsxs)(
|
|
8337
8383
|
"svg",
|
|
8338
8384
|
{
|
|
8339
8385
|
width,
|
|
@@ -8343,7 +8389,7 @@ var ScatterChart = ({
|
|
|
8343
8389
|
"aria-label": accessibleDescription,
|
|
8344
8390
|
className: "bg-[hsl(var(--card))]",
|
|
8345
8391
|
children: [
|
|
8346
|
-
/* @__PURE__ */ (0,
|
|
8392
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime118.jsx)("style", { children: `
|
|
8347
8393
|
@keyframes popIn {
|
|
8348
8394
|
from {
|
|
8349
8395
|
transform: scale(0);
|
|
@@ -8355,8 +8401,8 @@ var ScatterChart = ({
|
|
|
8355
8401
|
}
|
|
8356
8402
|
}
|
|
8357
8403
|
` }) }),
|
|
8358
|
-
/* @__PURE__ */ (0,
|
|
8359
|
-
showGrid && /* @__PURE__ */ (0,
|
|
8404
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsxs)("g", { transform: `translate(${padding.left}, ${padding.top})`, children: [
|
|
8405
|
+
showGrid && /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8360
8406
|
CartesianGrid,
|
|
8361
8407
|
{
|
|
8362
8408
|
_chartDimensions: { width: chartWidth, height: chartHeight },
|
|
@@ -8365,7 +8411,7 @@ var ScatterChart = ({
|
|
|
8365
8411
|
}
|
|
8366
8412
|
),
|
|
8367
8413
|
referenceElements,
|
|
8368
|
-
showTrendLine && trendLines.map((line, i) => /* @__PURE__ */ (0,
|
|
8414
|
+
showTrendLine && trendLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8369
8415
|
"line",
|
|
8370
8416
|
{
|
|
8371
8417
|
x1: line.x1,
|
|
@@ -8389,7 +8435,7 @@ var ScatterChart = ({
|
|
|
8389
8435
|
const size = bubble && point.z !== void 0 ? sizeScale(point.z) : baseSize;
|
|
8390
8436
|
const isHovered = hoveredPoint?.seriesIndex === seriesIndex && hoveredPoint?.pointIndex === pointIndex;
|
|
8391
8437
|
const displaySize = isHovered ? size * 1.3 : size;
|
|
8392
|
-
return /* @__PURE__ */ (0,
|
|
8438
|
+
return /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8393
8439
|
"g",
|
|
8394
8440
|
{
|
|
8395
8441
|
style: animate ? {
|
|
@@ -8410,8 +8456,8 @@ var ScatterChart = ({
|
|
|
8410
8456
|
);
|
|
8411
8457
|
});
|
|
8412
8458
|
}),
|
|
8413
|
-
showXAxis && /* @__PURE__ */ (0,
|
|
8414
|
-
/* @__PURE__ */ (0,
|
|
8459
|
+
showXAxis && /* @__PURE__ */ (0, import_jsx_runtime118.jsxs)("g", { transform: `translate(0, ${chartHeight})`, children: [
|
|
8460
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8415
8461
|
"line",
|
|
8416
8462
|
{
|
|
8417
8463
|
x1: 0,
|
|
@@ -8421,9 +8467,9 @@ var ScatterChart = ({
|
|
|
8421
8467
|
className: "stroke-[hsl(var(--border))]"
|
|
8422
8468
|
}
|
|
8423
8469
|
),
|
|
8424
|
-
xTicks.map((tick, i) => /* @__PURE__ */ (0,
|
|
8425
|
-
/* @__PURE__ */ (0,
|
|
8426
|
-
/* @__PURE__ */ (0,
|
|
8470
|
+
xTicks.map((tick, i) => /* @__PURE__ */ (0, import_jsx_runtime118.jsxs)("g", { transform: `translate(${xScale(tick)}, 0)`, children: [
|
|
8471
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)("line", { y2: 6, className: "stroke-[hsl(var(--border))]" }),
|
|
8472
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8427
8473
|
"text",
|
|
8428
8474
|
{
|
|
8429
8475
|
y: 20,
|
|
@@ -8434,7 +8480,7 @@ var ScatterChart = ({
|
|
|
8434
8480
|
}
|
|
8435
8481
|
)
|
|
8436
8482
|
] }, `x-tick-${i}`)),
|
|
8437
|
-
xAxisLabel && /* @__PURE__ */ (0,
|
|
8483
|
+
xAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8438
8484
|
"text",
|
|
8439
8485
|
{
|
|
8440
8486
|
x: chartWidth / 2,
|
|
@@ -8447,8 +8493,8 @@ var ScatterChart = ({
|
|
|
8447
8493
|
}
|
|
8448
8494
|
)
|
|
8449
8495
|
] }),
|
|
8450
|
-
showYAxis && /* @__PURE__ */ (0,
|
|
8451
|
-
/* @__PURE__ */ (0,
|
|
8496
|
+
showYAxis && /* @__PURE__ */ (0, import_jsx_runtime118.jsxs)("g", { children: [
|
|
8497
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8452
8498
|
"line",
|
|
8453
8499
|
{
|
|
8454
8500
|
x1: 0,
|
|
@@ -8458,9 +8504,9 @@ var ScatterChart = ({
|
|
|
8458
8504
|
className: "stroke-[hsl(var(--border))]"
|
|
8459
8505
|
}
|
|
8460
8506
|
),
|
|
8461
|
-
yTicks.map((tick, i) => /* @__PURE__ */ (0,
|
|
8462
|
-
/* @__PURE__ */ (0,
|
|
8463
|
-
/* @__PURE__ */ (0,
|
|
8507
|
+
yTicks.map((tick, i) => /* @__PURE__ */ (0, import_jsx_runtime118.jsxs)("g", { transform: `translate(0, ${yScale(tick)})`, children: [
|
|
8508
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)("line", { x2: -6, className: "stroke-[hsl(var(--border))]" }),
|
|
8509
|
+
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8464
8510
|
"text",
|
|
8465
8511
|
{
|
|
8466
8512
|
x: -12,
|
|
@@ -8472,7 +8518,7 @@ var ScatterChart = ({
|
|
|
8472
8518
|
}
|
|
8473
8519
|
)
|
|
8474
8520
|
] }, `y-tick-${i}`)),
|
|
8475
|
-
yAxisLabel && /* @__PURE__ */ (0,
|
|
8521
|
+
yAxisLabel && /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8476
8522
|
"text",
|
|
8477
8523
|
{
|
|
8478
8524
|
x: -chartHeight / 2,
|
|
@@ -8490,8 +8536,8 @@ var ScatterChart = ({
|
|
|
8490
8536
|
]
|
|
8491
8537
|
}
|
|
8492
8538
|
),
|
|
8493
|
-
showLegend && /* @__PURE__ */ (0,
|
|
8494
|
-
showTooltip && /* @__PURE__ */ (0,
|
|
8539
|
+
showLegend && /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(Legend, { items: legendItems, layout: "horizontal", align: "center" }),
|
|
8540
|
+
showTooltip && /* @__PURE__ */ (0, import_jsx_runtime118.jsx)(
|
|
8495
8541
|
ChartTooltip,
|
|
8496
8542
|
{
|
|
8497
8543
|
...tooltipData,
|
|
@@ -8505,8 +8551,8 @@ var ScatterChart = ({
|
|
|
8505
8551
|
};
|
|
8506
8552
|
|
|
8507
8553
|
// src/charts/components/ResponsiveContainer.tsx
|
|
8508
|
-
var
|
|
8509
|
-
var
|
|
8554
|
+
var import_react34 = __toESM(require("react"));
|
|
8555
|
+
var import_jsx_runtime119 = require("react/jsx-runtime");
|
|
8510
8556
|
var ResponsiveContainer = ({
|
|
8511
8557
|
width = "100%",
|
|
8512
8558
|
height,
|
|
@@ -8520,13 +8566,13 @@ var ResponsiveContainer = ({
|
|
|
8520
8566
|
children,
|
|
8521
8567
|
onResize
|
|
8522
8568
|
}) => {
|
|
8523
|
-
const containerRef = (0,
|
|
8524
|
-
const [dimensions, setDimensions] = (0,
|
|
8569
|
+
const containerRef = (0, import_react34.useRef)(null);
|
|
8570
|
+
const [dimensions, setDimensions] = (0, import_react34.useState)({
|
|
8525
8571
|
width: 0,
|
|
8526
8572
|
height: 0
|
|
8527
8573
|
});
|
|
8528
|
-
const debounceTimerRef = (0,
|
|
8529
|
-
const calculateDimensions = (0,
|
|
8574
|
+
const debounceTimerRef = (0, import_react34.useRef)(null);
|
|
8575
|
+
const calculateDimensions = (0, import_react34.useCallback)((containerWidth, containerHeight) => {
|
|
8530
8576
|
let finalWidth = containerWidth;
|
|
8531
8577
|
let finalHeight = containerHeight;
|
|
8532
8578
|
if (aspect && !height) {
|
|
@@ -8542,7 +8588,7 @@ var ResponsiveContainer = ({
|
|
|
8542
8588
|
}
|
|
8543
8589
|
return { width: finalWidth, height: finalHeight };
|
|
8544
8590
|
}, [aspect, height, minWidth, minHeight, maxWidth, maxHeight]);
|
|
8545
|
-
const handleResize = (0,
|
|
8591
|
+
const handleResize = (0, import_react34.useCallback)((entries) => {
|
|
8546
8592
|
const entry = entries[0];
|
|
8547
8593
|
if (!entry) return;
|
|
8548
8594
|
const { width: containerWidth, height: containerHeight } = entry.contentRect;
|
|
@@ -8560,7 +8606,7 @@ var ResponsiveContainer = ({
|
|
|
8560
8606
|
updateDimensions();
|
|
8561
8607
|
}
|
|
8562
8608
|
}, [calculateDimensions, debounce, onResize]);
|
|
8563
|
-
(0,
|
|
8609
|
+
(0, import_react34.useEffect)(() => {
|
|
8564
8610
|
const container = containerRef.current;
|
|
8565
8611
|
if (!container) return;
|
|
8566
8612
|
const observer = new ResizeObserver(handleResize);
|
|
@@ -8584,7 +8630,7 @@ var ResponsiveContainer = ({
|
|
|
8584
8630
|
maxHeight: maxHeight ? `${maxHeight}px` : void 0
|
|
8585
8631
|
};
|
|
8586
8632
|
if (dimensions.width === 0 || dimensions.height === 0) {
|
|
8587
|
-
return /* @__PURE__ */ (0,
|
|
8633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
|
|
8588
8634
|
"div",
|
|
8589
8635
|
{
|
|
8590
8636
|
ref: containerRef,
|
|
@@ -8593,14 +8639,14 @@ var ResponsiveContainer = ({
|
|
|
8593
8639
|
}
|
|
8594
8640
|
);
|
|
8595
8641
|
}
|
|
8596
|
-
const chartElement =
|
|
8642
|
+
const chartElement = import_react34.default.cloneElement(
|
|
8597
8643
|
children,
|
|
8598
8644
|
{
|
|
8599
8645
|
width: dimensions.width,
|
|
8600
8646
|
height: dimensions.height
|
|
8601
8647
|
}
|
|
8602
8648
|
);
|
|
8603
|
-
return /* @__PURE__ */ (0,
|
|
8649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime119.jsx)(
|
|
8604
8650
|
"div",
|
|
8605
8651
|
{
|
|
8606
8652
|
ref: containerRef,
|
|
@@ -8612,8 +8658,8 @@ var ResponsiveContainer = ({
|
|
|
8612
8658
|
};
|
|
8613
8659
|
|
|
8614
8660
|
// src/components/Heatmap.tsx
|
|
8615
|
-
var
|
|
8616
|
-
var
|
|
8661
|
+
var import_react35 = __toESM(require("react"));
|
|
8662
|
+
var import_jsx_runtime120 = require("react/jsx-runtime");
|
|
8617
8663
|
var COLOR_SCALES = {
|
|
8618
8664
|
blue: {
|
|
8619
8665
|
light: ["#eff6ff", "#dbeafe", "#bfdbfe", "#93c5fd", "#60a5fa", "#3b82f6", "#2563eb", "#1d4ed8", "#1e40af"],
|
|
@@ -8656,9 +8702,9 @@ var Heatmap = ({
|
|
|
8656
8702
|
formatValue = (v) => v.toFixed(0),
|
|
8657
8703
|
formatTooltip
|
|
8658
8704
|
}) => {
|
|
8659
|
-
const [hoveredCell, setHoveredCell] = (0,
|
|
8660
|
-
const [isDarkMode, setIsDarkMode] = (0,
|
|
8661
|
-
|
|
8705
|
+
const [hoveredCell, setHoveredCell] = (0, import_react35.useState)(null);
|
|
8706
|
+
const [isDarkMode, setIsDarkMode] = (0, import_react35.useState)(false);
|
|
8707
|
+
import_react35.default.useEffect(() => {
|
|
8662
8708
|
const checkDarkMode = () => {
|
|
8663
8709
|
setIsDarkMode(document.documentElement.classList.contains("dark"));
|
|
8664
8710
|
};
|
|
@@ -8667,7 +8713,7 @@ var Heatmap = ({
|
|
|
8667
8713
|
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
8668
8714
|
return () => observer.disconnect();
|
|
8669
8715
|
}, []);
|
|
8670
|
-
const { uniqueX, uniqueY, dataMap, minValue, maxValue } = (0,
|
|
8716
|
+
const { uniqueX, uniqueY, dataMap, minValue, maxValue } = (0, import_react35.useMemo)(() => {
|
|
8671
8717
|
const xSet = /* @__PURE__ */ new Set();
|
|
8672
8718
|
const ySet = /* @__PURE__ */ new Set();
|
|
8673
8719
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -8718,15 +8764,15 @@ var Heatmap = ({
|
|
|
8718
8764
|
const labelHeight = 30;
|
|
8719
8765
|
const width = labelWidth + uniqueX.length * (cellSize + cellGap);
|
|
8720
8766
|
const height = labelHeight + uniqueY.length * (cellSize + cellGap);
|
|
8721
|
-
return /* @__PURE__ */ (0,
|
|
8722
|
-
/* @__PURE__ */ (0,
|
|
8767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("div", { className: `relative inline-block ${className}`, children: [
|
|
8768
|
+
/* @__PURE__ */ (0, import_jsx_runtime120.jsxs)(
|
|
8723
8769
|
"svg",
|
|
8724
8770
|
{
|
|
8725
8771
|
width,
|
|
8726
8772
|
height,
|
|
8727
8773
|
className: "select-none",
|
|
8728
8774
|
children: [
|
|
8729
|
-
uniqueX.map((label, i) => /* @__PURE__ */ (0,
|
|
8775
|
+
uniqueX.map((label, i) => /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8730
8776
|
"text",
|
|
8731
8777
|
{
|
|
8732
8778
|
x: labelWidth + i * (cellSize + cellGap) + cellSize / 2,
|
|
@@ -8738,7 +8784,7 @@ var Heatmap = ({
|
|
|
8738
8784
|
},
|
|
8739
8785
|
`x-${label}`
|
|
8740
8786
|
)),
|
|
8741
|
-
uniqueY.map((label, j) => /* @__PURE__ */ (0,
|
|
8787
|
+
uniqueY.map((label, j) => /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8742
8788
|
"text",
|
|
8743
8789
|
{
|
|
8744
8790
|
x: labelWidth - 8,
|
|
@@ -8756,8 +8802,8 @@ var Heatmap = ({
|
|
|
8756
8802
|
const point = data.find((d) => String(d.x) === xLabel && String(d.y) === yLabel);
|
|
8757
8803
|
const x = labelWidth + i * (cellSize + cellGap);
|
|
8758
8804
|
const y = labelHeight + j * (cellSize + cellGap);
|
|
8759
|
-
return /* @__PURE__ */ (0,
|
|
8760
|
-
/* @__PURE__ */ (0,
|
|
8805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("g", { children: [
|
|
8806
|
+
/* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8761
8807
|
"rect",
|
|
8762
8808
|
{
|
|
8763
8809
|
x,
|
|
@@ -8780,7 +8826,7 @@ var Heatmap = ({
|
|
|
8780
8826
|
}
|
|
8781
8827
|
}
|
|
8782
8828
|
),
|
|
8783
|
-
showValues && value !== void 0 && /* @__PURE__ */ (0,
|
|
8829
|
+
showValues && value !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8784
8830
|
"text",
|
|
8785
8831
|
{
|
|
8786
8832
|
x: x + cellSize / 2,
|
|
@@ -8797,7 +8843,7 @@ var Heatmap = ({
|
|
|
8797
8843
|
]
|
|
8798
8844
|
}
|
|
8799
8845
|
),
|
|
8800
|
-
showTooltip && hoveredCell && /* @__PURE__ */ (0,
|
|
8846
|
+
showTooltip && hoveredCell && /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)(
|
|
8801
8847
|
"div",
|
|
8802
8848
|
{
|
|
8803
8849
|
className: "absolute z-50 px-3 py-2 text-sm bg-[hsl(var(--popover))] text-[hsl(var(--popover-foreground))] border border-[hsl(var(--border))] rounded-lg shadow-lg pointer-events-none whitespace-nowrap",
|
|
@@ -8808,7 +8854,7 @@ var Heatmap = ({
|
|
|
8808
8854
|
},
|
|
8809
8855
|
children: [
|
|
8810
8856
|
getTooltipContent(hoveredCell.point),
|
|
8811
|
-
/* @__PURE__ */ (0,
|
|
8857
|
+
/* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8812
8858
|
"div",
|
|
8813
8859
|
{
|
|
8814
8860
|
className: "absolute w-2 h-2 bg-[hsl(var(--popover))] rotate-45",
|
|
@@ -8839,9 +8885,9 @@ var CalendarHeatmap = ({
|
|
|
8839
8885
|
onCellClick,
|
|
8840
8886
|
formatTooltip
|
|
8841
8887
|
}) => {
|
|
8842
|
-
const [hoveredCell, setHoveredCell] = (0,
|
|
8843
|
-
const [isDarkMode, setIsDarkMode] = (0,
|
|
8844
|
-
|
|
8888
|
+
const [hoveredCell, setHoveredCell] = (0, import_react35.useState)(null);
|
|
8889
|
+
const [isDarkMode, setIsDarkMode] = (0, import_react35.useState)(false);
|
|
8890
|
+
import_react35.default.useEffect(() => {
|
|
8845
8891
|
const checkDarkMode = () => {
|
|
8846
8892
|
setIsDarkMode(document.documentElement.classList.contains("dark"));
|
|
8847
8893
|
};
|
|
@@ -8850,7 +8896,7 @@ var CalendarHeatmap = ({
|
|
|
8850
8896
|
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
8851
8897
|
return () => observer.disconnect();
|
|
8852
8898
|
}, []);
|
|
8853
|
-
const { weeks, minValue, maxValue, dataMap, monthLabels } = (0,
|
|
8899
|
+
const { weeks, minValue, maxValue, dataMap, monthLabels } = (0, import_react35.useMemo)(() => {
|
|
8854
8900
|
const map = /* @__PURE__ */ new Map();
|
|
8855
8901
|
let min = Infinity;
|
|
8856
8902
|
let max = -Infinity;
|
|
@@ -8910,9 +8956,9 @@ var CalendarHeatmap = ({
|
|
|
8910
8956
|
const monthLabelHeight = showMonthLabels ? 20 : 0;
|
|
8911
8957
|
const width = dayLabelWidth + weeks.length * (cellSize + cellGap);
|
|
8912
8958
|
const height = monthLabelHeight + 7 * (cellSize + cellGap);
|
|
8913
|
-
return /* @__PURE__ */ (0,
|
|
8914
|
-
/* @__PURE__ */ (0,
|
|
8915
|
-
showMonthLabels && monthLabels.map(({ label, weekIndex }, i) => /* @__PURE__ */ (0,
|
|
8959
|
+
return /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("div", { className: `relative inline-block ${className}`, children: [
|
|
8960
|
+
/* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("svg", { width, height, className: "select-none", children: [
|
|
8961
|
+
showMonthLabels && monthLabels.map(({ label, weekIndex }, i) => /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8916
8962
|
"text",
|
|
8917
8963
|
{
|
|
8918
8964
|
x: dayLabelWidth + weekIndex * (cellSize + cellGap),
|
|
@@ -8923,7 +8969,7 @@ var CalendarHeatmap = ({
|
|
|
8923
8969
|
},
|
|
8924
8970
|
`month-${i}`
|
|
8925
8971
|
)),
|
|
8926
|
-
showDayLabels && [1, 3, 5].map((dayIndex) => /* @__PURE__ */ (0,
|
|
8972
|
+
showDayLabels && [1, 3, 5].map((dayIndex) => /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8927
8973
|
"text",
|
|
8928
8974
|
{
|
|
8929
8975
|
x: dayLabelWidth - 6,
|
|
@@ -8941,7 +8987,7 @@ var CalendarHeatmap = ({
|
|
|
8941
8987
|
const value = dataMap.get(key);
|
|
8942
8988
|
const x = dayLabelWidth + weekIndex * (cellSize + cellGap);
|
|
8943
8989
|
const y = monthLabelHeight + dayIndex * (cellSize + cellGap);
|
|
8944
|
-
return /* @__PURE__ */ (0,
|
|
8990
|
+
return /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8945
8991
|
"rect",
|
|
8946
8992
|
{
|
|
8947
8993
|
x,
|
|
@@ -8966,7 +9012,7 @@ var CalendarHeatmap = ({
|
|
|
8966
9012
|
})
|
|
8967
9013
|
)
|
|
8968
9014
|
] }),
|
|
8969
|
-
hoveredCell && /* @__PURE__ */ (0,
|
|
9015
|
+
hoveredCell && /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)(
|
|
8970
9016
|
"div",
|
|
8971
9017
|
{
|
|
8972
9018
|
className: "absolute z-50 px-3 py-2 text-sm bg-[hsl(var(--popover))] text-[hsl(var(--popover-foreground))] border border-[hsl(var(--border))] rounded-lg shadow-lg pointer-events-none whitespace-nowrap",
|
|
@@ -8977,7 +9023,7 @@ var CalendarHeatmap = ({
|
|
|
8977
9023
|
},
|
|
8978
9024
|
children: [
|
|
8979
9025
|
getTooltipContent(hoveredCell.date, hoveredCell.value),
|
|
8980
|
-
/* @__PURE__ */ (0,
|
|
9026
|
+
/* @__PURE__ */ (0, import_jsx_runtime120.jsx)(
|
|
8981
9027
|
"div",
|
|
8982
9028
|
{
|
|
8983
9029
|
className: "absolute w-2 h-2 bg-[hsl(var(--popover))] rotate-45",
|
|
@@ -9066,6 +9112,7 @@ function getThemeScript() {
|
|
|
9066
9112
|
ChevronUpIcon,
|
|
9067
9113
|
CloseIcon,
|
|
9068
9114
|
CloudIcon,
|
|
9115
|
+
Code,
|
|
9069
9116
|
CodeIcon,
|
|
9070
9117
|
CopyIcon,
|
|
9071
9118
|
DatabaseIcon,
|