@underverse-ui/underverse 1.0.57 → 1.0.59
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/api-reference.json +2 -170
- package/dist/index.cjs +602 -2268
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -209
- package/dist/index.d.ts +1 -209
- package/dist/index.js +588 -2247
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -172,7 +172,7 @@ var variantStyles = {
|
|
|
172
172
|
danger: "bg-destructive text-destructive-foreground border-destructive/20",
|
|
173
173
|
destructive: "bg-destructive text-destructive-foreground border-destructive/20",
|
|
174
174
|
info: "bg-info text-info-foreground border-info/20",
|
|
175
|
-
outline: "bg-transparent text-foreground border-border",
|
|
175
|
+
outline: "bg-transparent text-foreground border-border/50",
|
|
176
176
|
ghost: "bg-transparent text-foreground border-transparent",
|
|
177
177
|
transparent: "bg-transparent text-foreground border-transparent",
|
|
178
178
|
gradient: "bg-linear-to-r from-primary to-secondary text-primary-foreground border-transparent"
|
|
@@ -494,7 +494,7 @@ var Card = React2.forwardRef(
|
|
|
494
494
|
"div",
|
|
495
495
|
{
|
|
496
496
|
className: cn(
|
|
497
|
-
"relative flex items-center p-4 md:p-6 pt-0 border-t border-border mt-4 max-md:mt-3 max-md:p-3 max-md:pt-0",
|
|
497
|
+
"relative flex items-center p-4 md:p-6 pt-0 border-t border-border/50 mt-4 max-md:mt-3 max-md:p-3 max-md:pt-0",
|
|
498
498
|
footerClassName
|
|
499
499
|
),
|
|
500
500
|
children: footer
|
|
@@ -1634,12 +1634,12 @@ var Input = forwardRef3(
|
|
|
1634
1634
|
error: "bg-destructive/10 border-destructive focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-destructive focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:border-transparent"
|
|
1635
1635
|
},
|
|
1636
1636
|
outlined: {
|
|
1637
|
-
container: "bg-transparent border border-border hover:border-accent-foreground/30",
|
|
1637
|
+
container: "bg-transparent border border-border/50 hover:border-accent-foreground/30",
|
|
1638
1638
|
focus: "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:border-transparent",
|
|
1639
1639
|
error: "border-destructive focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-destructive focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:border-transparent"
|
|
1640
1640
|
},
|
|
1641
1641
|
minimal: {
|
|
1642
|
-
container: "bg-transparent border-0 border-b border-border hover:border-accent-foreground/30",
|
|
1642
|
+
container: "bg-transparent border-0 border-b border-border/50 hover:border-accent-foreground/30",
|
|
1643
1643
|
focus: "focus-visible:outline-none focus-visible:border-ring focus-visible:ring-0 rounded-none",
|
|
1644
1644
|
error: "border-destructive focus-visible:outline-none focus-visible:border-destructive"
|
|
1645
1645
|
}
|
|
@@ -1992,7 +1992,7 @@ var NumberInput = forwardRef3(
|
|
|
1992
1992
|
lg: { width: "w-11", icon: { width: 12, height: 7, path: { up: "M6 1L11 6H1L6 1Z", down: "M6 6L1 1H11L6 6Z" } } }
|
|
1993
1993
|
};
|
|
1994
1994
|
const ss = stepperSizeStyles[inputSize];
|
|
1995
|
-
const stepperAddon = showSteppers ? /* @__PURE__ */ jsxs5("div", { className: cn("absolute right-0 inset-y-0 flex flex-col border-l border-border rounded-r-full overflow-hidden", ss.width), children: [
|
|
1995
|
+
const stepperAddon = showSteppers ? /* @__PURE__ */ jsxs5("div", { className: cn("absolute right-0 inset-y-0 flex flex-col border-l border-border/50 rounded-r-full overflow-hidden", ss.width), children: [
|
|
1996
1996
|
/* @__PURE__ */ jsx7(
|
|
1997
1997
|
"button",
|
|
1998
1998
|
{
|
|
@@ -2091,8 +2091,8 @@ var Textarea = forwardRef3(
|
|
|
2091
2091
|
const variantStyles6 = {
|
|
2092
2092
|
default: "bg-background border border-input hover:border-accent-foreground/20 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:border-transparent",
|
|
2093
2093
|
filled: "bg-muted/50 border border-transparent hover:bg-muted/70 focus-visible:outline-none focus-visible:bg-background focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:border-transparent",
|
|
2094
|
-
outlined: "bg-transparent border border-border hover:border-accent-foreground/30 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:border-transparent",
|
|
2095
|
-
minimal: "bg-transparent border-0 border-b border-border hover:border-accent-foreground/30 focus-visible:outline-none focus-visible:border-ring focus-visible:ring-0 rounded-none"
|
|
2094
|
+
outlined: "bg-transparent border border-border/50 hover:border-accent-foreground/30 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:border-transparent",
|
|
2095
|
+
minimal: "bg-transparent border-0 border-b border-border/50 hover:border-accent-foreground/30 focus-visible:outline-none focus-visible:border-ring focus-visible:ring-0 rounded-none"
|
|
2096
2096
|
};
|
|
2097
2097
|
const resizeClasses = {
|
|
2098
2098
|
none: "resize-none",
|
|
@@ -2550,7 +2550,7 @@ var Switch = ({
|
|
|
2550
2550
|
className: cn(
|
|
2551
2551
|
"absolute top-0.5 left-0.5 rounded-full transition-transform duration-200 ease-out shadow-sm",
|
|
2552
2552
|
sizeClasses2[size].handle,
|
|
2553
|
-
"bg-background border border-border",
|
|
2553
|
+
"bg-background border border-border/50",
|
|
2554
2554
|
checked ? sizeClasses2[size].translate : "translate-x-0",
|
|
2555
2555
|
!disabled && "hover:scale-[1.02]",
|
|
2556
2556
|
isPressed && "scale-95",
|
|
@@ -3643,7 +3643,7 @@ import * as React14 from "react";
|
|
|
3643
3643
|
import { createPortal as createPortal2 } from "react-dom";
|
|
3644
3644
|
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3645
3645
|
var variantStyles3 = {
|
|
3646
|
-
default: "bg-popover text-popover-foreground border-border",
|
|
3646
|
+
default: "bg-popover text-popover-foreground border-border/50",
|
|
3647
3647
|
info: "bg-info text-info-foreground border-info/20",
|
|
3648
3648
|
warning: "bg-warning text-warning-foreground border-warning/20",
|
|
3649
3649
|
error: "bg-destructive text-destructive-foreground border-destructive/20",
|
|
@@ -4562,7 +4562,7 @@ var Sheet = ({
|
|
|
4562
4562
|
{
|
|
4563
4563
|
className: cn(
|
|
4564
4564
|
"fixed flex flex-col bg-background text-foreground shadow-2xl",
|
|
4565
|
-
"border-border transition-all duration-300 ease-out",
|
|
4565
|
+
"border-border/50 transition-all duration-300 ease-out",
|
|
4566
4566
|
positionStyles2[side],
|
|
4567
4567
|
sizeStyles4[size][side],
|
|
4568
4568
|
// Borders based on side
|
|
@@ -4579,7 +4579,7 @@ var Sheet = ({
|
|
|
4579
4579
|
transition: "transform 300ms cubic-bezier(0.4, 0, 0.2, 1)"
|
|
4580
4580
|
},
|
|
4581
4581
|
children: [
|
|
4582
|
-
(title || description || header || showClose) && /* @__PURE__ */ jsx19("div", { className: "shrink-0 border-b border-border", children: header || /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between p-4", children: [
|
|
4582
|
+
(title || description || header || showClose) && /* @__PURE__ */ jsx19("div", { className: "shrink-0 border-b border-border/50", children: header || /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between p-4", children: [
|
|
4583
4583
|
/* @__PURE__ */ jsxs15("div", { className: "flex-1", children: [
|
|
4584
4584
|
title && /* @__PURE__ */ jsx19("h2", { className: "text-lg font-semibold text-foreground", children: title }),
|
|
4585
4585
|
description && /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground mt-1", children: description })
|
|
@@ -4598,7 +4598,7 @@ var Sheet = ({
|
|
|
4598
4598
|
children
|
|
4599
4599
|
}
|
|
4600
4600
|
),
|
|
4601
|
-
footer && /* @__PURE__ */ jsx19("div", { className: "shrink-0 border-t border-border p-4", children: footer })
|
|
4601
|
+
footer && /* @__PURE__ */ jsx19("div", { className: "shrink-0 border-t border-border/50 p-4", children: footer })
|
|
4602
4602
|
]
|
|
4603
4603
|
}
|
|
4604
4604
|
)
|
|
@@ -4616,7 +4616,7 @@ var BottomSheet = ({ snapPoints = ["25%", "50%", "90%"], defaultSnap = 1, ...pro
|
|
|
4616
4616
|
};
|
|
4617
4617
|
var SidebarSheet = ({ navigation, children, ...props }) => {
|
|
4618
4618
|
return /* @__PURE__ */ jsxs15(Sheet, { ...props, side: "left", variant: "push", size: "md", children: [
|
|
4619
|
-
navigation && /* @__PURE__ */ jsx19("div", { className: "border-b border-border pb-4 mb-4", children: navigation }),
|
|
4619
|
+
navigation && /* @__PURE__ */ jsx19("div", { className: "border-b border-border/50 pb-4 mb-4", children: navigation }),
|
|
4620
4620
|
children
|
|
4621
4621
|
] });
|
|
4622
4622
|
};
|
|
@@ -4628,7 +4628,7 @@ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
|
4628
4628
|
var variantConfig = {
|
|
4629
4629
|
default: {
|
|
4630
4630
|
icon: Info2,
|
|
4631
|
-
containerClassName: "bg-muted/50 border-border",
|
|
4631
|
+
containerClassName: "bg-muted/50 border-border/50",
|
|
4632
4632
|
iconClassName: "text-muted-foreground",
|
|
4633
4633
|
iconBgClassName: "bg-muted",
|
|
4634
4634
|
accentBarClassName: "bg-muted-foreground"
|
|
@@ -10349,7 +10349,7 @@ var DateTimePicker = ({
|
|
|
10349
10349
|
)
|
|
10350
10350
|
] })
|
|
10351
10351
|
] }),
|
|
10352
|
-
/* @__PURE__ */ jsxs27("div", { className: cn(sizeStyles8[size].padding, "border-t border-border flex justify-between items-center bg-muted/20"), children: [
|
|
10352
|
+
/* @__PURE__ */ jsxs27("div", { className: cn(sizeStyles8[size].padding, "border-t border-border/50 flex justify-between items-center bg-muted/20"), children: [
|
|
10353
10353
|
/* @__PURE__ */ jsx35(Button_default, { variant: "ghost", size: sizeStyles8[size].buttonSize, onClick: handleClear, className: "text-muted-foreground hover:text-foreground", children: clearLabel || t?.("clear") || "Clear" }),
|
|
10354
10354
|
/* @__PURE__ */ jsx35(Button_default, { size: sizeStyles8[size].buttonSize, onClick: handleApply, children: doneLabel || t?.("done") || "Done" })
|
|
10355
10355
|
] })
|
|
@@ -11124,7 +11124,7 @@ function CalendarTimelineHeader(props) {
|
|
|
11124
11124
|
)
|
|
11125
11125
|
] })
|
|
11126
11126
|
] }),
|
|
11127
|
-
/* @__PURE__ */ jsxs29("div", { className: "p-3 border-t border-border flex justify-between items-center bg-muted/20", children: [
|
|
11127
|
+
/* @__PURE__ */ jsxs29("div", { className: "p-3 border-t border-border/50 flex justify-between items-center bg-muted/20", children: [
|
|
11128
11128
|
/* @__PURE__ */ jsx37(
|
|
11129
11129
|
Button_default,
|
|
11130
11130
|
{
|
|
@@ -12892,7 +12892,7 @@ function CalendarTimeline({
|
|
|
12892
12892
|
{
|
|
12893
12893
|
className: cn(
|
|
12894
12894
|
"rounded-2xl md:rounded-3xl overflow-hidden bg-card text-card-foreground backdrop-blur-sm",
|
|
12895
|
-
"border border-border shadow-sm md:hover:shadow-md",
|
|
12895
|
+
"border border-border/50 shadow-sm md:hover:shadow-md",
|
|
12896
12896
|
"transition-[transform,box-shadow,border-color,background-color] duration-300 ease-soft",
|
|
12897
12897
|
densityClass,
|
|
12898
12898
|
className
|
|
@@ -13922,7 +13922,7 @@ var RadioGroupItem = React38.forwardRef(
|
|
|
13922
13922
|
"inline-flex items-center justify-center gap-2 rounded-lg border font-medium transition-all duration-200",
|
|
13923
13923
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
13924
13924
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
13925
|
-
isSelected ? "border-primary bg-primary text-primary-foreground shadow-sm" : "border-border bg-background hover:bg-accent hover:text-accent-foreground",
|
|
13925
|
+
isSelected ? "border-primary bg-primary text-primary-foreground shadow-sm" : "border-border/50 bg-background hover:bg-accent hover:text-accent-foreground",
|
|
13926
13926
|
sizeStyles7[size].padding,
|
|
13927
13927
|
sizeStyles7[size].text,
|
|
13928
13928
|
className
|
|
@@ -14203,7 +14203,7 @@ var Slider = React39.forwardRef(
|
|
|
14203
14203
|
{
|
|
14204
14204
|
className: cn(
|
|
14205
14205
|
"absolute pointer-events-none transition-all duration-200 ease-out",
|
|
14206
|
-
"bg-popover text-popover-foreground rounded-lg shadow-lg border border-border",
|
|
14206
|
+
"bg-popover text-popover-foreground rounded-lg shadow-lg border border-border/50",
|
|
14207
14207
|
"whitespace-nowrap font-medium -translate-x-1/2 z-50",
|
|
14208
14208
|
sizeStyles8.tooltip,
|
|
14209
14209
|
shouldShow ? "opacity-100 -translate-y-10 scale-100" : "opacity-0 -translate-y-8 scale-95",
|
|
@@ -14691,10 +14691,10 @@ function OverlayControls({
|
|
|
14691
14691
|
noFocus: true
|
|
14692
14692
|
}
|
|
14693
14693
|
),
|
|
14694
|
-
previewData && /* @__PURE__ */ jsx45("div", { className: "absolute bottom-full mb-2 transform -translate-x-1/2 pointer-events-none z-30", style: { left: `${previewData.x}px` }, children: previewData.url ? /* @__PURE__ */ jsxs37("div", { className: "bg-background/95 backdrop-blur rounded-xl border border-border shadow-lg overflow-hidden", children: [
|
|
14694
|
+
previewData && /* @__PURE__ */ jsx45("div", { className: "absolute bottom-full mb-2 transform -translate-x-1/2 pointer-events-none z-30", style: { left: `${previewData.x}px` }, children: previewData.url ? /* @__PURE__ */ jsxs37("div", { className: "bg-background/95 backdrop-blur rounded-xl border border-border/50 shadow-lg overflow-hidden", children: [
|
|
14695
14695
|
/* @__PURE__ */ jsx45("img", { src: previewData.url, alt: "Preview", className: "w-40 h-24 object-cover" }),
|
|
14696
14696
|
/* @__PURE__ */ jsx45("div", { className: "px-2 py-1 text-xs font-mono text-center bg-background/80", children: formatTime3(previewData.time) })
|
|
14697
|
-
] }) : /* @__PURE__ */ jsx45("div", { className: "px-3 py-1.5 rounded-md bg-background/90 backdrop-blur border border-border shadow-lg", children: /* @__PURE__ */ jsx45("div", { className: "text-xs font-mono text-center", children: formatTime3(previewData.time) }) }) })
|
|
14697
|
+
] }) : /* @__PURE__ */ jsx45("div", { className: "px-3 py-1.5 rounded-md bg-background/90 backdrop-blur border border-border/50 shadow-lg", children: /* @__PURE__ */ jsx45("div", { className: "text-xs font-mono text-center", children: formatTime3(previewData.time) }) }) })
|
|
14698
14698
|
] }),
|
|
14699
14699
|
showControlsBar && /* @__PURE__ */ jsxs37("div", { className: "mt-2 flex items-center justify-between gap-2", children: [
|
|
14700
14700
|
/* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
|
|
@@ -14731,7 +14731,7 @@ function OverlayControls({
|
|
|
14731
14731
|
children: /* @__PURE__ */ jsx45(RotateCw, { className: "w-4 h-4" })
|
|
14732
14732
|
}
|
|
14733
14733
|
),
|
|
14734
|
-
(showTime ?? true) && /* @__PURE__ */ jsxs37("span", { className: "px-3 py-1 rounded-full text-xs font-mono bg-background/60 text-foreground shadow-sm border border-border whitespace-nowrap", children: [
|
|
14734
|
+
(showTime ?? true) && /* @__PURE__ */ jsxs37("span", { className: "px-3 py-1 rounded-full text-xs font-mono bg-background/60 text-foreground shadow-sm border border-border/50 whitespace-nowrap", children: [
|
|
14735
14735
|
formatTime3(dragValue),
|
|
14736
14736
|
" / ",
|
|
14737
14737
|
formatTime3(max)
|
|
@@ -14793,7 +14793,7 @@ function OverlayControls({
|
|
|
14793
14793
|
]
|
|
14794
14794
|
}
|
|
14795
14795
|
),
|
|
14796
|
-
rateOpen && /* @__PURE__ */ jsx45("div", { className: "absolute bottom-9 right-0 bg-background/90 backdrop-blur rounded-md border border-border shadow-lg p-1 z-30", children: [0.5, 0.75, 1, 1.25, 1.5].map((r) => /* @__PURE__ */ jsxs37(
|
|
14796
|
+
rateOpen && /* @__PURE__ */ jsx45("div", { className: "absolute bottom-9 right-0 bg-background/90 backdrop-blur rounded-md border border-border/50 shadow-lg p-1 z-30", children: [0.5, 0.75, 1, 1.25, 1.5].map((r) => /* @__PURE__ */ jsxs37(
|
|
14797
14797
|
"button",
|
|
14798
14798
|
{
|
|
14799
14799
|
onClick: () => {
|
|
@@ -15497,7 +15497,7 @@ function ImageUpload({
|
|
|
15497
15497
|
{
|
|
15498
15498
|
className: cn(
|
|
15499
15499
|
"relative border-2 border-dashed rounded-2xl md:rounded-3xl p-8 text-center transition-all duration-200",
|
|
15500
|
-
isDragging && !disabled ? "border-primary bg-primary/5 scale-[1.02]" : "border-border hover:border-primary/50",
|
|
15500
|
+
isDragging && !disabled ? "border-primary bg-primary/5 scale-[1.02]" : "border-border/50 hover:border-primary/50",
|
|
15501
15501
|
disabled && "opacity-50 cursor-not-allowed",
|
|
15502
15502
|
uploading && "pointer-events-none"
|
|
15503
15503
|
),
|
|
@@ -15534,7 +15534,7 @@ function ImageUpload({
|
|
|
15534
15534
|
),
|
|
15535
15535
|
showPreview && uploadedImages.length > 0 && /* @__PURE__ */ jsxs39("div", { className: "space-y-3", children: [
|
|
15536
15536
|
/* @__PURE__ */ jsx47("h4", { className: "text-sm font-medium", children: "Uploaded Images" }),
|
|
15537
|
-
/* @__PURE__ */ jsx47("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4", children: uploadedImages.map((image) => /* @__PURE__ */ jsxs39("div", { className: "relative group bg-card border border-border rounded-2xl md:rounded-3xl p-3", children: [
|
|
15537
|
+
/* @__PURE__ */ jsx47("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4", children: uploadedImages.map((image) => /* @__PURE__ */ jsxs39("div", { className: "relative group bg-card border border-border/50 rounded-2xl md:rounded-3xl p-3", children: [
|
|
15538
15538
|
/* @__PURE__ */ jsx47(
|
|
15539
15539
|
Button_default,
|
|
15540
15540
|
{
|
|
@@ -15882,7 +15882,7 @@ function FileUpload({
|
|
|
15882
15882
|
"div",
|
|
15883
15883
|
{
|
|
15884
15884
|
className: cn(
|
|
15885
|
-
"group relative flex items-center gap-3 bg-card/50 backdrop-blur-sm border border-border rounded-xl",
|
|
15885
|
+
"group relative flex items-center gap-3 bg-card/50 backdrop-blur-sm border border-border/50 rounded-xl",
|
|
15886
15886
|
"transition-all duration-200 hover:bg-card hover:shadow-md hover:border-primary/20",
|
|
15887
15887
|
file.status === "error" && "border-destructive/50 bg-destructive/5",
|
|
15888
15888
|
file.status === "uploading" && "border-primary/30",
|
|
@@ -15965,13 +15965,13 @@ function FileUpload({
|
|
|
15965
15965
|
"border-2 border-dashed rounded-2xl",
|
|
15966
15966
|
currentSize.padding,
|
|
15967
15967
|
"text-center transition-all duration-300",
|
|
15968
|
-
isDragging && !disabled ? "border-primary bg-primary/5 scale-[1.01] shadow-lg shadow-primary/10" : "border-border hover:border-primary/50 hover:bg-muted/30",
|
|
15968
|
+
isDragging && !disabled ? "border-primary bg-primary/5 scale-[1.01] shadow-lg shadow-primary/10" : "border-border/50 hover:border-primary/50 hover:bg-muted/30",
|
|
15969
15969
|
disabled && "opacity-50 cursor-not-allowed"
|
|
15970
15970
|
),
|
|
15971
15971
|
compact: cn(
|
|
15972
15972
|
"border border-dashed rounded-xl p-4",
|
|
15973
15973
|
"flex items-center gap-4 transition-all duration-200",
|
|
15974
|
-
isDragging && !disabled ? "border-primary bg-primary/5" : "border-border hover:border-primary/50",
|
|
15974
|
+
isDragging && !disabled ? "border-primary bg-primary/5" : "border-border/50 hover:border-primary/50",
|
|
15975
15975
|
disabled && "opacity-50 cursor-not-allowed"
|
|
15976
15976
|
),
|
|
15977
15977
|
minimal: cn(
|
|
@@ -16718,12 +16718,12 @@ var ListRoot = React44.forwardRef(
|
|
|
16718
16718
|
const hasChildren = childCount > 0;
|
|
16719
16719
|
const variantClasses3 = {
|
|
16720
16720
|
plain: "",
|
|
16721
|
-
outlined: "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border shadow-sm max-md:rounded-xl",
|
|
16721
|
+
outlined: "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border/50 shadow-sm max-md:rounded-xl",
|
|
16722
16722
|
soft: "rounded-2xl md:rounded-3xl bg-muted/40 border border-border/60 max-md:rounded-xl",
|
|
16723
|
-
bordered: "border border-border rounded-2xl md:rounded-3xl max-md:rounded-xl",
|
|
16724
|
-
card: "rounded-2xl md:rounded-3xl bg-card shadow-md border border-border max-md:rounded-xl max-md:shadow-sm",
|
|
16723
|
+
bordered: "border border-border/50 rounded-2xl md:rounded-3xl max-md:rounded-xl",
|
|
16724
|
+
card: "rounded-2xl md:rounded-3xl bg-card shadow-md border border-border/50 max-md:rounded-xl max-md:shadow-sm",
|
|
16725
16725
|
flush: "",
|
|
16726
|
-
striped: "rounded-2xl md:rounded-3xl border border-border overflow-hidden max-md:rounded-xl"
|
|
16726
|
+
striped: "rounded-2xl md:rounded-3xl border border-border/50 overflow-hidden max-md:rounded-xl"
|
|
16727
16727
|
};
|
|
16728
16728
|
if (loading2) {
|
|
16729
16729
|
return /* @__PURE__ */ jsx51(
|
|
@@ -17306,8 +17306,8 @@ var TimelineItem = React46.forwardRef(
|
|
|
17306
17306
|
const padding = ctx.dense ? sz.densePadY : sz.padY;
|
|
17307
17307
|
const variantClasses3 = {
|
|
17308
17308
|
default: "",
|
|
17309
|
-
outlined: "rounded-xl border border-border bg-card shadow-sm px-4 py-3",
|
|
17310
|
-
card: "rounded-2xl border border-border bg-card shadow-md px-5 py-4",
|
|
17309
|
+
outlined: "rounded-xl border border-border/50 bg-card shadow-sm px-4 py-3",
|
|
17310
|
+
card: "rounded-2xl border border-border/50 bg-card shadow-md px-5 py-4",
|
|
17311
17311
|
minimal: "border-l-2 pl-4 py-2",
|
|
17312
17312
|
modern: "rounded-xl bg-linear-to-r from-card to-muted/20 border border-border/50 px-5 py-4 backdrop-blur-sm",
|
|
17313
17313
|
gradient: "rounded-2xl bg-linear-to-br from-primary/10 via-card to-accent/10 border border-primary/20 px-5 py-4 shadow-lg"
|
|
@@ -17600,7 +17600,7 @@ var Swatch = ({
|
|
|
17600
17600
|
"button",
|
|
17601
17601
|
{
|
|
17602
17602
|
type: "button",
|
|
17603
|
-
className: cn(sizeClasses2[size], "rounded-lg border border-border shadow-sm hover:scale-110 transition-transform", onClick && "cursor-pointer"),
|
|
17603
|
+
className: cn(sizeClasses2[size], "rounded-lg border border-border/50 shadow-sm hover:scale-110 transition-transform", onClick && "cursor-pointer"),
|
|
17604
17604
|
style: { backgroundColor: color },
|
|
17605
17605
|
onClick,
|
|
17606
17606
|
"aria-label": ariaLabel
|
|
@@ -17734,7 +17734,7 @@ function ColorPicker({
|
|
|
17734
17734
|
/* @__PURE__ */ jsx54(
|
|
17735
17735
|
"span",
|
|
17736
17736
|
{
|
|
17737
|
-
className: cn("rounded-md border border-border shadow-sm", size === "sm" ? "h-4 w-4" : size === "lg" ? "h-6 w-6" : "h-5 w-5"),
|
|
17737
|
+
className: cn("rounded-md border border-border/50 shadow-sm", size === "sm" ? "h-4 w-4" : size === "lg" ? "h-6 w-6" : "h-5 w-5"),
|
|
17738
17738
|
style: { backgroundColor: withAlpha ? `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})` : hexForInput }
|
|
17739
17739
|
}
|
|
17740
17740
|
),
|
|
@@ -17759,7 +17759,7 @@ function ColorPicker({
|
|
|
17759
17759
|
placement: "bottom-start",
|
|
17760
17760
|
matchTriggerWidth: variant === "minimal",
|
|
17761
17761
|
contentWidth: contentWidthByVariant[variant],
|
|
17762
|
-
contentClassName: cn("p-3 rounded-2xl md:rounded-3xl border border-border bg-card shadow-lg", contentClassName),
|
|
17762
|
+
contentClassName: cn("p-3 rounded-2xl md:rounded-3xl border border-border/50 bg-card shadow-lg", contentClassName),
|
|
17763
17763
|
children: /* @__PURE__ */ jsxs46("div", { className: "space-y-3", children: [
|
|
17764
17764
|
variant !== "minimal" && /* @__PURE__ */ jsxs46("div", { className: "flex items-center gap-2", children: [
|
|
17765
17765
|
/* @__PURE__ */ jsx54(
|
|
@@ -17768,7 +17768,7 @@ function ColorPicker({
|
|
|
17768
17768
|
type: "color",
|
|
17769
17769
|
value: hexForInput,
|
|
17770
17770
|
onChange: handleNativeChange,
|
|
17771
|
-
className: "h-9 w-9 rounded-lg cursor-pointer border border-border"
|
|
17771
|
+
className: "h-9 w-9 rounded-lg cursor-pointer border border-border/50"
|
|
17772
17772
|
}
|
|
17773
17773
|
),
|
|
17774
17774
|
/* @__PURE__ */ jsxs46(
|
|
@@ -17776,7 +17776,7 @@ function ColorPicker({
|
|
|
17776
17776
|
{
|
|
17777
17777
|
type: "button",
|
|
17778
17778
|
onClick: tryEyedropper,
|
|
17779
|
-
className: cn("h-9 px-3 rounded-lg border border-border text-xs hover:bg-accent/10 transition-colors flex items-center gap-1.5"),
|
|
17779
|
+
className: cn("h-9 px-3 rounded-lg border border-border/50 text-xs hover:bg-accent/10 transition-colors flex items-center gap-1.5"),
|
|
17780
17780
|
children: [
|
|
17781
17781
|
/* @__PURE__ */ jsx54(Pipette, { className: "w-3.5 h-3.5" }),
|
|
17782
17782
|
variant === "full" && "Pick"
|
|
@@ -17789,7 +17789,7 @@ function ColorPicker({
|
|
|
17789
17789
|
type: "button",
|
|
17790
17790
|
onClick: copyToClipboard,
|
|
17791
17791
|
className: cn(
|
|
17792
|
-
"h-9 px-3 rounded-lg border border-border text-xs hover:bg-accent/10 transition-colors flex items-center gap-1.5",
|
|
17792
|
+
"h-9 px-3 rounded-lg border border-border/50 text-xs hover:bg-accent/10 transition-colors flex items-center gap-1.5",
|
|
17793
17793
|
copied && "bg-success/10 border-success/30"
|
|
17794
17794
|
),
|
|
17795
17795
|
children: [
|
|
@@ -17803,7 +17803,7 @@ function ColorPicker({
|
|
|
17803
17803
|
{
|
|
17804
17804
|
type: "button",
|
|
17805
17805
|
onClick: clear,
|
|
17806
|
-
className: "ml-auto h-9 px-2 rounded-lg border border-border text-xs hover:bg-destructive/10 transition-colors flex items-center gap-1",
|
|
17806
|
+
className: "ml-auto h-9 px-2 rounded-lg border border-border/50 text-xs hover:bg-destructive/10 transition-colors flex items-center gap-1",
|
|
17807
17807
|
children: [
|
|
17808
17808
|
/* @__PURE__ */ jsx54(X15, { className: "w-3.5 h-3.5" }),
|
|
17809
17809
|
variant === "full" && "Clear"
|
|
@@ -17829,7 +17829,7 @@ function ColorPicker({
|
|
|
17829
17829
|
type: "button",
|
|
17830
17830
|
onClick: copyToClipboard,
|
|
17831
17831
|
className: cn(
|
|
17832
|
-
"h-9 w-9 rounded-lg border border-border hover:bg-accent/10 transition-colors flex items-center justify-center",
|
|
17832
|
+
"h-9 w-9 rounded-lg border border-border/50 hover:bg-accent/10 transition-colors flex items-center justify-center",
|
|
17833
17833
|
copied && "bg-success/10 border-success/30"
|
|
17834
17834
|
),
|
|
17835
17835
|
children: copied ? /* @__PURE__ */ jsx54(Check9, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ jsx54(Copy, { className: "w-3.5 h-3.5" })
|
|
@@ -18178,7 +18178,7 @@ var MusicPlayer = ({
|
|
|
18178
18178
|
}
|
|
18179
18179
|
}
|
|
18180
18180
|
}, [currentSongIndex, currentSong.startTime, isPlaying]);
|
|
18181
|
-
return /* @__PURE__ */ jsxs47("div", { className: `underverse-music-player bg-card dark:bg-card border border-border rounded-2xl shadow-2xl overflow-hidden ${className}`, children: [
|
|
18181
|
+
return /* @__PURE__ */ jsxs47("div", { className: `underverse-music-player bg-card dark:bg-card border border-border/50 rounded-2xl shadow-2xl overflow-hidden ${className}`, children: [
|
|
18182
18182
|
/* @__PURE__ */ jsx55("audio", { ref: audioRef, src: currentSong.audioUrl, onTimeUpdate: handleTimeUpdate, onLoadedMetadata: handleLoadedMetadata, onEnded: playNext }),
|
|
18183
18183
|
/* @__PURE__ */ jsxs47("div", { className: "p-6", children: [
|
|
18184
18184
|
/* @__PURE__ */ jsxs47("div", { className: "text-center mb-6", children: [
|
|
@@ -18256,7 +18256,7 @@ var MusicPlayer = ({
|
|
|
18256
18256
|
}
|
|
18257
18257
|
) })
|
|
18258
18258
|
] }),
|
|
18259
|
-
showPlaylist && /* @__PURE__ */ jsx55("div", { className: "bg-muted/50 backdrop-blur-sm max-h-96 overflow-y-auto border-t border-border", children: /* @__PURE__ */ jsxs47("div", { className: "p-4", children: [
|
|
18259
|
+
showPlaylist && /* @__PURE__ */ jsx55("div", { className: "bg-muted/50 backdrop-blur-sm max-h-96 overflow-y-auto border-t border-border/50", children: /* @__PURE__ */ jsxs47("div", { className: "p-4", children: [
|
|
18260
18260
|
/* @__PURE__ */ jsxs47("h3", { className: "text-lg font-semibold text-foreground mb-3", children: [
|
|
18261
18261
|
"Playlist (",
|
|
18262
18262
|
playlist.length,
|
|
@@ -18339,12 +18339,12 @@ function joinAreas(areas) {
|
|
|
18339
18339
|
}
|
|
18340
18340
|
function getVariantClasses(variant = "default", outlined) {
|
|
18341
18341
|
if (outlined) {
|
|
18342
|
-
return "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border shadow-sm";
|
|
18342
|
+
return "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border/50 shadow-sm";
|
|
18343
18343
|
}
|
|
18344
18344
|
const variants = {
|
|
18345
18345
|
default: "",
|
|
18346
|
-
bordered: "border border-border rounded-2xl md:rounded-3xl",
|
|
18347
|
-
card: "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border shadow-sm",
|
|
18346
|
+
bordered: "border border-border/50 rounded-2xl md:rounded-3xl",
|
|
18347
|
+
card: "rounded-2xl md:rounded-3xl bg-card text-card-foreground border border-border/50 shadow-sm",
|
|
18348
18348
|
flat: "bg-muted/30 rounded-2xl md:rounded-3xl",
|
|
18349
18349
|
glass: "bg-background/80 backdrop-blur-sm border border-border/50 rounded-2xl md:rounded-3xl shadow-lg"
|
|
18350
18350
|
};
|
|
@@ -18497,1675 +18497,23 @@ GridItem.displayName = "Grid.Item";
|
|
|
18497
18497
|
var Grid = Object.assign(GridRoot, { Item: GridItem });
|
|
18498
18498
|
var Grid_default = Grid;
|
|
18499
18499
|
|
|
18500
|
-
// src/components/LineChart.tsx
|
|
18501
|
-
import { useMemo as useMemo19, useState as useState39, useRef as useRef23, useCallback as useCallback16 } from "react";
|
|
18502
|
-
|
|
18503
|
-
// src/components/ChartTooltip.tsx
|
|
18504
|
-
import { useEffect as useEffect28, useState as useState38, useRef as useRef22 } from "react";
|
|
18505
|
-
import { createPortal as createPortal6 } from "react-dom";
|
|
18506
|
-
import { Fragment as Fragment21, jsx as jsx57, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
18507
|
-
function ChartTooltip({
|
|
18508
|
-
x,
|
|
18509
|
-
y,
|
|
18510
|
-
visible,
|
|
18511
|
-
label,
|
|
18512
|
-
value,
|
|
18513
|
-
color,
|
|
18514
|
-
secondaryLabel,
|
|
18515
|
-
secondaryValue,
|
|
18516
|
-
items,
|
|
18517
|
-
containerRef,
|
|
18518
|
-
formatter
|
|
18519
|
-
}) {
|
|
18520
|
-
const [isMounted, setIsMounted] = useState38(false);
|
|
18521
|
-
const [position, setPosition] = useState38(null);
|
|
18522
|
-
const tooltipRef = useRef22(null);
|
|
18523
|
-
useEffect28(() => {
|
|
18524
|
-
setIsMounted(true);
|
|
18525
|
-
}, []);
|
|
18526
|
-
useEffect28(() => {
|
|
18527
|
-
if (visible && containerRef?.current) {
|
|
18528
|
-
const rect = containerRef.current.getBoundingClientRect();
|
|
18529
|
-
const tw = tooltipRef.current?.offsetWidth ?? 160;
|
|
18530
|
-
const th = tooltipRef.current?.offsetHeight ?? 80;
|
|
18531
|
-
let left = rect.left + x + 12;
|
|
18532
|
-
let top = rect.top + y - th / 2;
|
|
18533
|
-
if (left + tw > window.innerWidth - 8) {
|
|
18534
|
-
left = rect.left + x - tw - 12;
|
|
18535
|
-
}
|
|
18536
|
-
if (top + th > window.innerHeight - 8) {
|
|
18537
|
-
top = window.innerHeight - th - 8;
|
|
18538
|
-
}
|
|
18539
|
-
if (top < 8) top = 8;
|
|
18540
|
-
if (left < 8) left = 8;
|
|
18541
|
-
setPosition({ top, left });
|
|
18542
|
-
}
|
|
18543
|
-
}, [visible, x, y, containerRef]);
|
|
18544
|
-
if (!visible || !isMounted || !position) return null;
|
|
18545
|
-
const tooltipContent = /* @__PURE__ */ jsxs49(
|
|
18546
|
-
"div",
|
|
18547
|
-
{
|
|
18548
|
-
ref: tooltipRef,
|
|
18549
|
-
style: {
|
|
18550
|
-
position: "fixed",
|
|
18551
|
-
top: position.top,
|
|
18552
|
-
left: position.left,
|
|
18553
|
-
zIndex: 99999,
|
|
18554
|
-
pointerEvents: "none",
|
|
18555
|
-
animation: "chartTooltipFadeIn 0.15s ease-out"
|
|
18556
|
-
},
|
|
18557
|
-
children: [
|
|
18558
|
-
/* @__PURE__ */ jsxs49(
|
|
18559
|
-
"div",
|
|
18560
|
-
{
|
|
18561
|
-
className: cn("bg-popover text-popover-foreground border border-border", "rounded-2xl shadow-xl px-3 py-2 text-sm", "backdrop-blur-sm"),
|
|
18562
|
-
style: {
|
|
18563
|
-
minWidth: "80px",
|
|
18564
|
-
width: "max-content",
|
|
18565
|
-
boxShadow: "0 10px 25px -3px rgba(0, 0, 0, 0.5), 0 4px 10px -2px rgba(0, 0, 0, 0.3)"
|
|
18566
|
-
},
|
|
18567
|
-
children: [
|
|
18568
|
-
label && /* @__PURE__ */ jsx57("div", { className: "text-muted-foreground text-xs mb-1", children: label }),
|
|
18569
|
-
items && items.length > 0 ? /* @__PURE__ */ jsx57("div", { className: "flex flex-col gap-1", children: items.map((item, i) => /* @__PURE__ */ jsxs49("div", { className: "flex items-center gap-2", children: [
|
|
18570
|
-
item.color && /* @__PURE__ */ jsx57("div", { className: "w-2 h-2 rounded-full shrink-0", style: { backgroundColor: item.color } }),
|
|
18571
|
-
/* @__PURE__ */ jsxs49("span", { className: "text-muted-foreground", children: [
|
|
18572
|
-
item.label,
|
|
18573
|
-
":"
|
|
18574
|
-
] }),
|
|
18575
|
-
/* @__PURE__ */ jsx57("span", { className: "font-semibold ml-auto", children: formatter ? formatter(item.value) : item.value })
|
|
18576
|
-
] }, i)) }) : /* @__PURE__ */ jsxs49(Fragment21, { children: [
|
|
18577
|
-
/* @__PURE__ */ jsxs49("div", { className: "flex items-center gap-2", children: [
|
|
18578
|
-
color && /* @__PURE__ */ jsx57("div", { className: "w-2 h-2 rounded-full shrink-0", style: { backgroundColor: color } }),
|
|
18579
|
-
/* @__PURE__ */ jsx57("span", { className: "font-semibold", children: formatter && value != null ? formatter(value) : value })
|
|
18580
|
-
] }),
|
|
18581
|
-
secondaryLabel && /* @__PURE__ */ jsxs49("div", { className: "text-muted-foreground text-xs mt-1", children: [
|
|
18582
|
-
secondaryLabel,
|
|
18583
|
-
": ",
|
|
18584
|
-
secondaryValue
|
|
18585
|
-
] })
|
|
18586
|
-
] })
|
|
18587
|
-
]
|
|
18588
|
-
}
|
|
18589
|
-
),
|
|
18590
|
-
/* @__PURE__ */ jsx57("style", { children: `
|
|
18591
|
-
@keyframes chartTooltipFadeIn {
|
|
18592
|
-
from { opacity: 0; transform: translateX(-5px); }
|
|
18593
|
-
to { opacity: 1; transform: translateX(0); }
|
|
18594
|
-
}
|
|
18595
|
-
` })
|
|
18596
|
-
]
|
|
18597
|
-
}
|
|
18598
|
-
);
|
|
18599
|
-
return createPortal6(tooltipContent, document.body);
|
|
18600
|
-
}
|
|
18601
|
-
|
|
18602
|
-
// src/utils/chart-utils.ts
|
|
18603
|
-
import * as React51 from "react";
|
|
18604
|
-
function getCatmullRomSpline(points, tension = 0.5) {
|
|
18605
|
-
if (points.length < 2) return "";
|
|
18606
|
-
if (points.length === 2) {
|
|
18607
|
-
return `M ${points[0].x} ${points[0].y} L ${points[1].x} ${points[1].y}`;
|
|
18608
|
-
}
|
|
18609
|
-
let path = `M ${points[0].x} ${points[0].y}`;
|
|
18610
|
-
for (let i = 0; i < points.length - 1; i++) {
|
|
18611
|
-
const p0 = points[Math.max(0, i - 1)];
|
|
18612
|
-
const p1 = points[i];
|
|
18613
|
-
const p2 = points[i + 1];
|
|
18614
|
-
const p3 = points[Math.min(points.length - 1, i + 2)];
|
|
18615
|
-
const cp1x = p1.x + (p2.x - p0.x) * tension / 6;
|
|
18616
|
-
const cp1y = p1.y + (p2.y - p0.y) * tension / 6;
|
|
18617
|
-
const cp2x = p2.x - (p3.x - p1.x) * tension / 6;
|
|
18618
|
-
const cp2y = p2.y - (p3.y - p1.y) * tension / 6;
|
|
18619
|
-
path += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
|
|
18620
|
-
}
|
|
18621
|
-
return path;
|
|
18622
|
-
}
|
|
18623
|
-
function getPathLength(points) {
|
|
18624
|
-
return points.reduce((acc, p, i) => {
|
|
18625
|
-
if (i === 0) return 0;
|
|
18626
|
-
const prev = points[i - 1];
|
|
18627
|
-
return acc + Math.sqrt((p.x - prev.x) ** 2 + (p.y - prev.y) ** 2);
|
|
18628
|
-
}, 0);
|
|
18629
|
-
}
|
|
18630
|
-
|
|
18631
|
-
// src/components/LineChart.tsx
|
|
18632
|
-
import { Fragment as Fragment22, jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
18633
|
-
function LineChart({
|
|
18634
|
-
data,
|
|
18635
|
-
series,
|
|
18636
|
-
width = 400,
|
|
18637
|
-
height = 200,
|
|
18638
|
-
color = "currentColor",
|
|
18639
|
-
fillColor,
|
|
18640
|
-
showDots = true,
|
|
18641
|
-
showGrid = true,
|
|
18642
|
-
showLabels = true,
|
|
18643
|
-
showValues = false,
|
|
18644
|
-
showLegend,
|
|
18645
|
-
animated = true,
|
|
18646
|
-
curved = true,
|
|
18647
|
-
formatValue,
|
|
18648
|
-
referenceLines = [],
|
|
18649
|
-
labelClassName,
|
|
18650
|
-
className = ""
|
|
18651
|
-
}) {
|
|
18652
|
-
const svgRef = useRef23(null);
|
|
18653
|
-
const clipId = useRef23(`line-clip-${Math.random().toString(36).slice(2, 8)}`).current;
|
|
18654
|
-
const padding = { top: 20, right: 20, bottom: 40, left: 40 };
|
|
18655
|
-
const chartWidth = width - padding.left - padding.right;
|
|
18656
|
-
const chartHeight = height - padding.top - padding.bottom;
|
|
18657
|
-
const [hoveredPoint, setHoveredPoint] = useState39(null);
|
|
18658
|
-
const [hiddenSeries, setHiddenSeries] = useState39(/* @__PURE__ */ new Set());
|
|
18659
|
-
const toggleSeries = useCallback16((name) => {
|
|
18660
|
-
setHiddenSeries((prev) => {
|
|
18661
|
-
const next = new Set(prev);
|
|
18662
|
-
if (next.has(name)) next.delete(name);
|
|
18663
|
-
else next.add(name);
|
|
18664
|
-
return next;
|
|
18665
|
-
});
|
|
18666
|
-
}, []);
|
|
18667
|
-
const normalizedSeries = useMemo19(() => {
|
|
18668
|
-
if (series && series.length > 0) return series;
|
|
18669
|
-
if (data && data.length > 0) return [{ name: "", data, color, fillColor }];
|
|
18670
|
-
return [];
|
|
18671
|
-
}, [series, data, color, fillColor]);
|
|
18672
|
-
const isMultiSeries = normalizedSeries.length > 1;
|
|
18673
|
-
const { minValue, maxValue, processedSeries, labels } = useMemo19(() => {
|
|
18674
|
-
if (!normalizedSeries.length || !normalizedSeries[0]?.data?.length) {
|
|
18675
|
-
return { minValue: 0, maxValue: 0, processedSeries: [], labels: [] };
|
|
18676
|
-
}
|
|
18677
|
-
const allLabels = normalizedSeries[0].data.map((d) => d.label);
|
|
18678
|
-
const allValues = normalizedSeries.flatMap((s) => s.data.map((d) => d.value));
|
|
18679
|
-
const min = Math.min(...allValues);
|
|
18680
|
-
const max = Math.max(...allValues);
|
|
18681
|
-
const range = max - min || 1;
|
|
18682
|
-
const processed = normalizedSeries.map((s) => {
|
|
18683
|
-
const pts = s.data.map((d, i) => ({
|
|
18684
|
-
x: padding.left + i / (s.data.length - 1 || 1) * chartWidth,
|
|
18685
|
-
y: padding.top + chartHeight - (d.value - min) / range * chartHeight,
|
|
18686
|
-
...d
|
|
18687
|
-
}));
|
|
18688
|
-
let linePath = "";
|
|
18689
|
-
let areaPath = "";
|
|
18690
|
-
if (curved && pts.length > 2) {
|
|
18691
|
-
linePath = getCatmullRomSpline(pts);
|
|
18692
|
-
areaPath = `${linePath} L ${pts[pts.length - 1].x} ${padding.top + chartHeight} L ${pts[0].x} ${padding.top + chartHeight} Z`;
|
|
18693
|
-
} else {
|
|
18694
|
-
linePath = pts.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
|
|
18695
|
-
areaPath = `M ${pts[0].x} ${padding.top + chartHeight} ` + pts.map((p) => `L ${p.x} ${p.y}`).join(" ") + ` L ${pts[pts.length - 1].x} ${padding.top + chartHeight} Z`;
|
|
18696
|
-
}
|
|
18697
|
-
const lineLength = getPathLength(pts);
|
|
18698
|
-
return { ...s, points: pts, linePath, areaPath, lineLength };
|
|
18699
|
-
});
|
|
18700
|
-
return { minValue: min, maxValue: max, processedSeries: processed, labels: allLabels };
|
|
18701
|
-
}, [normalizedSeries, chartWidth, chartHeight, curved, padding.left, padding.top]);
|
|
18702
|
-
const gridLines = useMemo19(() => {
|
|
18703
|
-
const lines = [];
|
|
18704
|
-
const steps = 5;
|
|
18705
|
-
for (let i = 0; i <= steps; i++) {
|
|
18706
|
-
const y = padding.top + i / steps * chartHeight;
|
|
18707
|
-
const value = maxValue - i / steps * (maxValue - minValue);
|
|
18708
|
-
lines.push({ y, value });
|
|
18709
|
-
}
|
|
18710
|
-
return lines;
|
|
18711
|
-
}, [minValue, maxValue, chartHeight, padding.top]);
|
|
18712
|
-
return /* @__PURE__ */ jsxs50(Fragment22, { children: [
|
|
18713
|
-
/* @__PURE__ */ jsxs50("svg", { ref: svgRef, width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
|
|
18714
|
-
/* @__PURE__ */ jsx58("defs", { children: /* @__PURE__ */ jsx58("clipPath", { id: clipId, children: /* @__PURE__ */ jsx58("rect", { x: padding.left, y: padding.top, width: chartWidth, height: chartHeight }) }) }),
|
|
18715
|
-
showGrid && /* @__PURE__ */ jsx58("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ jsxs50("g", { children: [
|
|
18716
|
-
/* @__PURE__ */ jsx58("line", { x1: padding.left, y1: line.y, x2: width - padding.right, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
|
|
18717
|
-
/* @__PURE__ */ jsx58(
|
|
18718
|
-
"text",
|
|
18719
|
-
{
|
|
18720
|
-
x: padding.left - 8,
|
|
18721
|
-
y: line.y + 4,
|
|
18722
|
-
textAnchor: "end",
|
|
18723
|
-
fontSize: "10",
|
|
18724
|
-
fill: "currentColor",
|
|
18725
|
-
className: labelClassName || "text-muted-foreground",
|
|
18726
|
-
children: formatValue ? formatValue(line.value) : line.value.toFixed(0)
|
|
18727
|
-
}
|
|
18728
|
-
)
|
|
18729
|
-
] }, i)) }),
|
|
18730
|
-
/* @__PURE__ */ jsxs50("g", { clipPath: `url(#${clipId})`, children: [
|
|
18731
|
-
processedSeries.map(
|
|
18732
|
-
(s, si) => s.fillColor && s.areaPath && /* @__PURE__ */ jsx58(
|
|
18733
|
-
"path",
|
|
18734
|
-
{
|
|
18735
|
-
d: s.areaPath,
|
|
18736
|
-
fill: s.fillColor,
|
|
18737
|
-
className: "transition-opacity duration-300",
|
|
18738
|
-
opacity: hiddenSeries.has(s.name) ? 0 : 0.15,
|
|
18739
|
-
style: animated ? { opacity: 0, animation: `fadeIn 0.6s ease-out ${si * 0.1}s forwards` } : void 0
|
|
18740
|
-
},
|
|
18741
|
-
`area-${si}`
|
|
18742
|
-
)
|
|
18743
|
-
),
|
|
18744
|
-
processedSeries.map((s, si) => /* @__PURE__ */ jsx58(
|
|
18745
|
-
"path",
|
|
18746
|
-
{
|
|
18747
|
-
d: s.linePath,
|
|
18748
|
-
fill: "none",
|
|
18749
|
-
stroke: s.color,
|
|
18750
|
-
strokeWidth: 2,
|
|
18751
|
-
strokeLinecap: "round",
|
|
18752
|
-
strokeLinejoin: "round",
|
|
18753
|
-
className: "transition-opacity duration-300",
|
|
18754
|
-
opacity: hiddenSeries.has(s.name) ? 0 : 1,
|
|
18755
|
-
style: animated ? {
|
|
18756
|
-
strokeDasharray: s.lineLength,
|
|
18757
|
-
strokeDashoffset: s.lineLength,
|
|
18758
|
-
animation: `drawLine 1s ease-out ${si * 0.15}s forwards`
|
|
18759
|
-
} : void 0
|
|
18760
|
-
},
|
|
18761
|
-
`line-${si}`
|
|
18762
|
-
))
|
|
18763
|
-
] }),
|
|
18764
|
-
showDots && processedSeries.map(
|
|
18765
|
-
(s, si) => !hiddenSeries.has(s.name) && s.points.map((point, i) => /* @__PURE__ */ jsxs50(
|
|
18766
|
-
"g",
|
|
18767
|
-
{
|
|
18768
|
-
onMouseEnter: () => {
|
|
18769
|
-
if (isMultiSeries) {
|
|
18770
|
-
const items = processedSeries.filter((ps) => !hiddenSeries.has(ps.name)).map((ps) => ({
|
|
18771
|
-
label: ps.name,
|
|
18772
|
-
value: ps.points[i]?.value ?? 0,
|
|
18773
|
-
color: ps.color
|
|
18774
|
-
}));
|
|
18775
|
-
setHoveredPoint({ x: point.x, y: point.y, label: point.label, value: point.value, items });
|
|
18776
|
-
} else {
|
|
18777
|
-
setHoveredPoint({ x: point.x, y: point.y, label: point.label, value: point.value });
|
|
18778
|
-
}
|
|
18779
|
-
},
|
|
18780
|
-
onMouseLeave: () => setHoveredPoint(null),
|
|
18781
|
-
className: "cursor-pointer",
|
|
18782
|
-
children: [
|
|
18783
|
-
/* @__PURE__ */ jsx58(
|
|
18784
|
-
"circle",
|
|
18785
|
-
{
|
|
18786
|
-
cx: point.x,
|
|
18787
|
-
cy: point.y,
|
|
18788
|
-
r: hoveredPoint?.x === point.x ? 6 : 4,
|
|
18789
|
-
fill: s.color,
|
|
18790
|
-
className: `transition-all duration-150 ${animated ? "animate-[scaleIn_0.3s_ease-out]" : ""}`,
|
|
18791
|
-
style: animated ? { animationDelay: `${si * 0.15 + i * 0.05}s`, animationFillMode: "both" } : void 0
|
|
18792
|
-
}
|
|
18793
|
-
),
|
|
18794
|
-
/* @__PURE__ */ jsx58("circle", { cx: point.x, cy: point.y, r: 16, fill: "transparent" }),
|
|
18795
|
-
showValues && /* @__PURE__ */ jsx58(
|
|
18796
|
-
"text",
|
|
18797
|
-
{
|
|
18798
|
-
x: point.x,
|
|
18799
|
-
y: point.y - 12,
|
|
18800
|
-
textAnchor: "middle",
|
|
18801
|
-
fontSize: "10",
|
|
18802
|
-
fontWeight: "500",
|
|
18803
|
-
className: "text-foreground",
|
|
18804
|
-
fill: "currentColor",
|
|
18805
|
-
children: formatValue ? formatValue(point.value) : point.value
|
|
18806
|
-
}
|
|
18807
|
-
)
|
|
18808
|
-
]
|
|
18809
|
-
},
|
|
18810
|
-
`dot-${si}-${i}`
|
|
18811
|
-
))
|
|
18812
|
-
),
|
|
18813
|
-
referenceLines.map((ref, i) => {
|
|
18814
|
-
const range = maxValue - minValue || 1;
|
|
18815
|
-
const y = padding.top + chartHeight - (ref.value - minValue) / range * chartHeight;
|
|
18816
|
-
return /* @__PURE__ */ jsxs50("g", { className: "pointer-events-none", children: [
|
|
18817
|
-
/* @__PURE__ */ jsx58(
|
|
18818
|
-
"line",
|
|
18819
|
-
{
|
|
18820
|
-
x1: padding.left,
|
|
18821
|
-
y1: y,
|
|
18822
|
-
x2: padding.left + chartWidth,
|
|
18823
|
-
y2: y,
|
|
18824
|
-
stroke: ref.color || "#ef4444",
|
|
18825
|
-
strokeWidth: 1.5,
|
|
18826
|
-
strokeDasharray: ref.strokeDasharray || "6 4",
|
|
18827
|
-
opacity: 0.7
|
|
18828
|
-
}
|
|
18829
|
-
),
|
|
18830
|
-
ref.label && /* @__PURE__ */ jsx58("text", { x: padding.left + chartWidth + 4, y: y + 4, fontSize: "10", fill: ref.color || "#ef4444", fontWeight: "500", children: ref.label })
|
|
18831
|
-
] }, `ref-${i}`);
|
|
18832
|
-
}),
|
|
18833
|
-
hoveredPoint && /* @__PURE__ */ jsx58("g", { className: "pointer-events-none", children: /* @__PURE__ */ jsx58(
|
|
18834
|
-
"line",
|
|
18835
|
-
{
|
|
18836
|
-
x1: hoveredPoint.x,
|
|
18837
|
-
y1: padding.top,
|
|
18838
|
-
x2: hoveredPoint.x,
|
|
18839
|
-
y2: padding.top + chartHeight,
|
|
18840
|
-
stroke: "currentColor",
|
|
18841
|
-
strokeWidth: 1,
|
|
18842
|
-
strokeDasharray: "4 4",
|
|
18843
|
-
opacity: 0.3,
|
|
18844
|
-
className: "text-foreground"
|
|
18845
|
-
}
|
|
18846
|
-
) }),
|
|
18847
|
-
showLabels && labels.map((lbl, i) => {
|
|
18848
|
-
const x = padding.left + i / (labels.length - 1 || 1) * chartWidth;
|
|
18849
|
-
return /* @__PURE__ */ jsx58(
|
|
18850
|
-
"text",
|
|
18851
|
-
{
|
|
18852
|
-
x,
|
|
18853
|
-
y: height - 10,
|
|
18854
|
-
textAnchor: "middle",
|
|
18855
|
-
fontSize: "10",
|
|
18856
|
-
className: labelClassName || "text-muted-foreground",
|
|
18857
|
-
fill: "currentColor",
|
|
18858
|
-
children: lbl
|
|
18859
|
-
},
|
|
18860
|
-
i
|
|
18861
|
-
);
|
|
18862
|
-
}),
|
|
18863
|
-
/* @__PURE__ */ jsx58("style", { children: `
|
|
18864
|
-
@keyframes drawLine {
|
|
18865
|
-
to { stroke-dashoffset: 0; }
|
|
18866
|
-
}
|
|
18867
|
-
@keyframes scaleIn {
|
|
18868
|
-
from { transform: scale(0); opacity: 0; }
|
|
18869
|
-
to { transform: scale(1); opacity: 1; }
|
|
18870
|
-
}
|
|
18871
|
-
@keyframes fadeIn {
|
|
18872
|
-
from { opacity: 0; }
|
|
18873
|
-
to { opacity: 0.15; }
|
|
18874
|
-
}
|
|
18875
|
-
` })
|
|
18876
|
-
] }),
|
|
18877
|
-
(showLegend ?? isMultiSeries) && isMultiSeries && /* @__PURE__ */ jsx58("div", { className: "flex items-center justify-center gap-6 mt-2", children: normalizedSeries.map((s, i) => /* @__PURE__ */ jsxs50("div", { className: "flex items-center gap-2 text-sm cursor-pointer select-none", onClick: () => toggleSeries(s.name), children: [
|
|
18878
|
-
/* @__PURE__ */ jsx58(
|
|
18879
|
-
"div",
|
|
18880
|
-
{
|
|
18881
|
-
className: "w-3 h-3 rounded-md transition-opacity",
|
|
18882
|
-
style: { backgroundColor: s.color, opacity: hiddenSeries.has(s.name) ? 0.3 : 1 }
|
|
18883
|
-
}
|
|
18884
|
-
),
|
|
18885
|
-
/* @__PURE__ */ jsx58("span", { className: hiddenSeries.has(s.name) ? "text-muted-foreground/40 line-through" : "text-muted-foreground", children: s.name })
|
|
18886
|
-
] }, i)) }),
|
|
18887
|
-
/* @__PURE__ */ jsx58(
|
|
18888
|
-
ChartTooltip,
|
|
18889
|
-
{
|
|
18890
|
-
x: hoveredPoint?.x ?? 0,
|
|
18891
|
-
y: hoveredPoint?.y ?? 0,
|
|
18892
|
-
visible: !!hoveredPoint,
|
|
18893
|
-
label: hoveredPoint?.label,
|
|
18894
|
-
value: !isMultiSeries ? hoveredPoint?.value : void 0,
|
|
18895
|
-
items: isMultiSeries ? hoveredPoint?.items : void 0,
|
|
18896
|
-
color: !isMultiSeries ? processedSeries[0]?.color || color : void 0,
|
|
18897
|
-
containerRef: svgRef,
|
|
18898
|
-
formatter: formatValue ? (v) => formatValue(Number(v)) : void 0
|
|
18899
|
-
}
|
|
18900
|
-
)
|
|
18901
|
-
] });
|
|
18902
|
-
}
|
|
18903
|
-
|
|
18904
|
-
// src/components/BarChart.tsx
|
|
18905
|
-
import { useMemo as useMemo20, useState as useState40, useRef as useRef24 } from "react";
|
|
18906
|
-
import { Fragment as Fragment23, jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
18907
|
-
function BarChart({
|
|
18908
|
-
data,
|
|
18909
|
-
series,
|
|
18910
|
-
width = 400,
|
|
18911
|
-
height = 200,
|
|
18912
|
-
color = "currentColor",
|
|
18913
|
-
showLabels = true,
|
|
18914
|
-
showValues = true,
|
|
18915
|
-
showGrid = true,
|
|
18916
|
-
showLegend,
|
|
18917
|
-
horizontal = false,
|
|
18918
|
-
animated = true,
|
|
18919
|
-
stacked = false,
|
|
18920
|
-
barRadius = 4,
|
|
18921
|
-
barGap = 0.3,
|
|
18922
|
-
formatValue,
|
|
18923
|
-
labelClassName,
|
|
18924
|
-
className = ""
|
|
18925
|
-
}) {
|
|
18926
|
-
const svgRef = useRef24(null);
|
|
18927
|
-
const padding = useMemo20(
|
|
18928
|
-
() => horizontal ? { top: 20, right: 40, bottom: 20, left: 80 } : { top: 20, right: 20, bottom: 40, left: 40 },
|
|
18929
|
-
[horizontal]
|
|
18930
|
-
);
|
|
18931
|
-
const chartWidth = width - padding.left - padding.right;
|
|
18932
|
-
const chartHeight = height - padding.top - padding.bottom;
|
|
18933
|
-
const [hoveredBar, setHoveredBar] = useState40(null);
|
|
18934
|
-
const normalizedSeries = useMemo20(() => {
|
|
18935
|
-
if (series && series.length > 0) return series;
|
|
18936
|
-
if (data && data.length > 0) return [{ name: "", data, color }];
|
|
18937
|
-
return [];
|
|
18938
|
-
}, [series, data, color]);
|
|
18939
|
-
const isMultiSeries = normalizedSeries.length > 1;
|
|
18940
|
-
const { maxValue, barGroups, gridLines } = useMemo20(() => {
|
|
18941
|
-
if (!normalizedSeries.length || !normalizedSeries[0]?.data?.length) {
|
|
18942
|
-
return { maxValue: 0, barGroups: [], gridLines: [] };
|
|
18943
|
-
}
|
|
18944
|
-
const allLabels = normalizedSeries[0].data.map((d) => d.label);
|
|
18945
|
-
const seriesCount = normalizedSeries.length;
|
|
18946
|
-
const labelCount = allLabels.length;
|
|
18947
|
-
let max = 0;
|
|
18948
|
-
if (stacked) {
|
|
18949
|
-
for (let li = 0; li < labelCount; li++) {
|
|
18950
|
-
const stackVal = normalizedSeries.reduce((sum, s) => sum + (s.data[li]?.value || 0), 0);
|
|
18951
|
-
max = Math.max(max, stackVal);
|
|
18952
|
-
}
|
|
18953
|
-
} else {
|
|
18954
|
-
max = Math.max(...normalizedSeries.flatMap((s) => s.data.map((d) => d.value)));
|
|
18955
|
-
}
|
|
18956
|
-
const groups = allLabels.map((label, li) => {
|
|
18957
|
-
if (horizontal) {
|
|
18958
|
-
const groupH = chartHeight / labelCount;
|
|
18959
|
-
const gap = groupH * barGap;
|
|
18960
|
-
const usable = groupH - gap;
|
|
18961
|
-
if (stacked) {
|
|
18962
|
-
let cum = 0;
|
|
18963
|
-
const bars = normalizedSeries.map((s) => {
|
|
18964
|
-
const val = s.data[li]?.value || 0;
|
|
18965
|
-
const w = val / max * chartWidth;
|
|
18966
|
-
const bar = {
|
|
18967
|
-
x: padding.left + cum,
|
|
18968
|
-
y: padding.top + li * groupH + gap / 2,
|
|
18969
|
-
width: w,
|
|
18970
|
-
height: usable,
|
|
18971
|
-
value: val,
|
|
18972
|
-
color: s.data[li]?.color || s.color,
|
|
18973
|
-
seriesName: s.name,
|
|
18974
|
-
label
|
|
18975
|
-
};
|
|
18976
|
-
cum += w;
|
|
18977
|
-
return bar;
|
|
18978
|
-
});
|
|
18979
|
-
return { label, bars };
|
|
18980
|
-
} else {
|
|
18981
|
-
const bH = usable / seriesCount;
|
|
18982
|
-
const bars = normalizedSeries.map((s, si) => {
|
|
18983
|
-
const val = s.data[li]?.value || 0;
|
|
18984
|
-
return {
|
|
18985
|
-
x: padding.left,
|
|
18986
|
-
y: padding.top + li * groupH + gap / 2 + si * bH,
|
|
18987
|
-
width: val / max * chartWidth,
|
|
18988
|
-
height: bH,
|
|
18989
|
-
value: val,
|
|
18990
|
-
color: s.data[li]?.color || s.color,
|
|
18991
|
-
seriesName: s.name,
|
|
18992
|
-
label
|
|
18993
|
-
};
|
|
18994
|
-
});
|
|
18995
|
-
return { label, bars };
|
|
18996
|
-
}
|
|
18997
|
-
} else {
|
|
18998
|
-
const groupW = chartWidth / labelCount;
|
|
18999
|
-
const gap = groupW * barGap;
|
|
19000
|
-
const usable = groupW - gap;
|
|
19001
|
-
if (stacked) {
|
|
19002
|
-
let cum = 0;
|
|
19003
|
-
const bars = normalizedSeries.map((s) => {
|
|
19004
|
-
const val = s.data[li]?.value || 0;
|
|
19005
|
-
const h = val / max * chartHeight;
|
|
19006
|
-
const bar = {
|
|
19007
|
-
x: padding.left + li * groupW + gap / 2,
|
|
19008
|
-
y: padding.top + chartHeight - cum - h,
|
|
19009
|
-
width: usable,
|
|
19010
|
-
height: h,
|
|
19011
|
-
value: val,
|
|
19012
|
-
color: s.data[li]?.color || s.color,
|
|
19013
|
-
seriesName: s.name,
|
|
19014
|
-
label
|
|
19015
|
-
};
|
|
19016
|
-
cum += h;
|
|
19017
|
-
return bar;
|
|
19018
|
-
});
|
|
19019
|
-
return { label, bars };
|
|
19020
|
-
} else {
|
|
19021
|
-
const bW = usable / seriesCount;
|
|
19022
|
-
const bars = normalizedSeries.map((s, si) => {
|
|
19023
|
-
const val = s.data[li]?.value || 0;
|
|
19024
|
-
return {
|
|
19025
|
-
x: padding.left + li * groupW + gap / 2 + si * bW,
|
|
19026
|
-
y: padding.top + chartHeight - val / max * chartHeight,
|
|
19027
|
-
width: bW,
|
|
19028
|
-
height: val / max * chartHeight,
|
|
19029
|
-
value: val,
|
|
19030
|
-
color: s.data[li]?.color || s.color,
|
|
19031
|
-
seriesName: s.name,
|
|
19032
|
-
label
|
|
19033
|
-
};
|
|
19034
|
-
});
|
|
19035
|
-
return { label, bars };
|
|
19036
|
-
}
|
|
19037
|
-
}
|
|
19038
|
-
});
|
|
19039
|
-
const lines = [];
|
|
19040
|
-
const steps = 5;
|
|
19041
|
-
for (let i = 0; i <= steps; i++) {
|
|
19042
|
-
const value = i / steps * max;
|
|
19043
|
-
if (horizontal) {
|
|
19044
|
-
lines.push({ x: padding.left + i / steps * chartWidth, y1: padding.top, y2: height - padding.bottom, value });
|
|
19045
|
-
} else {
|
|
19046
|
-
lines.push({ y: padding.top + chartHeight - i / steps * chartHeight, x1: padding.left, x2: width - padding.right, value });
|
|
19047
|
-
}
|
|
19048
|
-
}
|
|
19049
|
-
return { maxValue: max, barGroups: groups, gridLines: lines };
|
|
19050
|
-
}, [normalizedSeries, chartWidth, chartHeight, horizontal, stacked, barGap, padding, width, height]);
|
|
19051
|
-
return /* @__PURE__ */ jsxs51(Fragment23, { children: [
|
|
19052
|
-
/* @__PURE__ */ jsxs51("svg", { ref: svgRef, width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
|
|
19053
|
-
showGrid && /* @__PURE__ */ jsx59("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ jsx59("g", { children: horizontal ? /* @__PURE__ */ jsxs51(Fragment23, { children: [
|
|
19054
|
-
/* @__PURE__ */ jsx59("line", { x1: line.x, y1: line.y1, x2: line.x, y2: line.y2, stroke: "currentColor", strokeDasharray: "4 4" }),
|
|
19055
|
-
/* @__PURE__ */ jsx59(
|
|
19056
|
-
"text",
|
|
19057
|
-
{
|
|
19058
|
-
x: line.x,
|
|
19059
|
-
y: height - 8,
|
|
19060
|
-
textAnchor: "middle",
|
|
19061
|
-
fontSize: "10",
|
|
19062
|
-
className: labelClassName || "text-muted-foreground",
|
|
19063
|
-
fill: "currentColor",
|
|
19064
|
-
children: formatValue ? formatValue(line.value) : line.value.toFixed(0)
|
|
19065
|
-
}
|
|
19066
|
-
)
|
|
19067
|
-
] }) : /* @__PURE__ */ jsxs51(Fragment23, { children: [
|
|
19068
|
-
/* @__PURE__ */ jsx59("line", { x1: line.x1, y1: line.y, x2: line.x2, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
|
|
19069
|
-
/* @__PURE__ */ jsx59(
|
|
19070
|
-
"text",
|
|
19071
|
-
{
|
|
19072
|
-
x: padding.left - 8,
|
|
19073
|
-
y: line.y + 4,
|
|
19074
|
-
textAnchor: "end",
|
|
19075
|
-
fontSize: "10",
|
|
19076
|
-
className: labelClassName || "text-muted-foreground",
|
|
19077
|
-
fill: "currentColor",
|
|
19078
|
-
children: formatValue ? formatValue(line.value) : line.value.toFixed(0)
|
|
19079
|
-
}
|
|
19080
|
-
)
|
|
19081
|
-
] }) }, i)) }),
|
|
19082
|
-
barGroups.map((group, gi) => /* @__PURE__ */ jsxs51("g", { children: [
|
|
19083
|
-
group.bars.map((bar, bi) => {
|
|
19084
|
-
const animDelay = gi * 0.08 + bi * 0.04;
|
|
19085
|
-
return /* @__PURE__ */ jsxs51(
|
|
19086
|
-
"g",
|
|
19087
|
-
{
|
|
19088
|
-
onMouseEnter: () => setHoveredBar({
|
|
19089
|
-
x: horizontal ? bar.x + bar.width : bar.x + bar.width / 2,
|
|
19090
|
-
y: horizontal ? bar.y + bar.height / 2 : bar.y,
|
|
19091
|
-
label: bar.label,
|
|
19092
|
-
value: bar.value,
|
|
19093
|
-
color: bar.color,
|
|
19094
|
-
seriesName: bar.seriesName
|
|
19095
|
-
}),
|
|
19096
|
-
onMouseLeave: () => setHoveredBar(null),
|
|
19097
|
-
className: "cursor-pointer",
|
|
19098
|
-
children: [
|
|
19099
|
-
/* @__PURE__ */ jsxs51(
|
|
19100
|
-
"rect",
|
|
19101
|
-
{
|
|
19102
|
-
x: bar.x,
|
|
19103
|
-
y: bar.y,
|
|
19104
|
-
width: bar.width,
|
|
19105
|
-
height: bar.height,
|
|
19106
|
-
rx: barRadius,
|
|
19107
|
-
ry: barRadius,
|
|
19108
|
-
fill: bar.color,
|
|
19109
|
-
className: `transition-all duration-150 ${hoveredBar?.label === bar.label && hoveredBar?.seriesName === bar.seriesName ? "opacity-80" : ""}`,
|
|
19110
|
-
style: animated ? {
|
|
19111
|
-
animation: horizontal ? `growWidth 0.5s ease-out ${animDelay}s forwards` : `growHeight 0.5s ease-out ${animDelay}s forwards`,
|
|
19112
|
-
...horizontal ? { width: 0 } : { height: 0, y: padding.top + chartHeight }
|
|
19113
|
-
} : void 0,
|
|
19114
|
-
children: [
|
|
19115
|
-
/* @__PURE__ */ jsx59(
|
|
19116
|
-
"animate",
|
|
19117
|
-
{
|
|
19118
|
-
attributeName: horizontal ? "width" : "height",
|
|
19119
|
-
from: "0",
|
|
19120
|
-
to: horizontal ? bar.width : bar.height,
|
|
19121
|
-
dur: "0.5s",
|
|
19122
|
-
begin: `${animDelay}s`,
|
|
19123
|
-
fill: "freeze"
|
|
19124
|
-
}
|
|
19125
|
-
),
|
|
19126
|
-
!horizontal && /* @__PURE__ */ jsx59("animate", { attributeName: "y", from: padding.top + chartHeight, to: bar.y, dur: "0.5s", begin: `${animDelay}s`, fill: "freeze" })
|
|
19127
|
-
]
|
|
19128
|
-
}
|
|
19129
|
-
),
|
|
19130
|
-
showValues && /* @__PURE__ */ jsx59(
|
|
19131
|
-
"text",
|
|
19132
|
-
{
|
|
19133
|
-
x: horizontal ? bar.x + bar.width + 8 : bar.x + bar.width / 2,
|
|
19134
|
-
y: horizontal ? bar.y + bar.height / 2 + 4 : bar.y - 8,
|
|
19135
|
-
textAnchor: horizontal ? "start" : "middle",
|
|
19136
|
-
fontSize: "11",
|
|
19137
|
-
fontWeight: "500",
|
|
19138
|
-
className: "text-foreground",
|
|
19139
|
-
fill: "currentColor",
|
|
19140
|
-
style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${animDelay + 0.3}s forwards` } : void 0,
|
|
19141
|
-
children: formatValue ? formatValue(bar.value) : bar.value
|
|
19142
|
-
}
|
|
19143
|
-
)
|
|
19144
|
-
]
|
|
19145
|
-
},
|
|
19146
|
-
bi
|
|
19147
|
-
);
|
|
19148
|
-
}),
|
|
19149
|
-
showLabels && /* @__PURE__ */ jsx59(
|
|
19150
|
-
"text",
|
|
19151
|
-
{
|
|
19152
|
-
x: horizontal ? padding.left - 8 : padding.left + (gi + 0.5) * (chartWidth / barGroups.length),
|
|
19153
|
-
y: horizontal ? padding.top + (gi + 0.5) * (chartHeight / barGroups.length) + 4 : height - 10,
|
|
19154
|
-
textAnchor: horizontal ? "end" : "middle",
|
|
19155
|
-
fontSize: "10",
|
|
19156
|
-
className: labelClassName || "text-muted-foreground",
|
|
19157
|
-
fill: "currentColor",
|
|
19158
|
-
children: group.label
|
|
19159
|
-
}
|
|
19160
|
-
)
|
|
19161
|
-
] }, gi)),
|
|
19162
|
-
/* @__PURE__ */ jsx59("style", { children: `
|
|
19163
|
-
@keyframes growHeight {
|
|
19164
|
-
from { height: 0; }
|
|
19165
|
-
}
|
|
19166
|
-
@keyframes growWidth {
|
|
19167
|
-
from { width: 0; }
|
|
19168
|
-
}
|
|
19169
|
-
@keyframes fadeIn {
|
|
19170
|
-
from { opacity: 0; }
|
|
19171
|
-
to { opacity: 1; }
|
|
19172
|
-
}
|
|
19173
|
-
` })
|
|
19174
|
-
] }),
|
|
19175
|
-
(showLegend ?? isMultiSeries) && isMultiSeries && /* @__PURE__ */ jsx59("div", { className: "flex items-center justify-center gap-6 mt-2", children: normalizedSeries.map((s, i) => /* @__PURE__ */ jsxs51("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
19176
|
-
/* @__PURE__ */ jsx59("div", { className: "w-3 h-3 rounded-md", style: { backgroundColor: s.color } }),
|
|
19177
|
-
/* @__PURE__ */ jsx59("span", { className: "text-muted-foreground", children: s.name })
|
|
19178
|
-
] }, i)) }),
|
|
19179
|
-
/* @__PURE__ */ jsx59(
|
|
19180
|
-
ChartTooltip,
|
|
19181
|
-
{
|
|
19182
|
-
x: hoveredBar?.x ?? 0,
|
|
19183
|
-
y: hoveredBar?.y ?? 0,
|
|
19184
|
-
visible: !!hoveredBar,
|
|
19185
|
-
label: hoveredBar?.seriesName ? `${hoveredBar.label} \u2014 ${hoveredBar.seriesName}` : hoveredBar?.label,
|
|
19186
|
-
value: hoveredBar?.value,
|
|
19187
|
-
color: hoveredBar?.color,
|
|
19188
|
-
containerRef: svgRef,
|
|
19189
|
-
formatter: formatValue ? (v) => formatValue(Number(v)) : void 0
|
|
19190
|
-
}
|
|
19191
|
-
)
|
|
19192
|
-
] });
|
|
19193
|
-
}
|
|
19194
|
-
|
|
19195
|
-
// src/components/PieChart.tsx
|
|
19196
|
-
import { useMemo as useMemo21, useState as useState41, useRef as useRef25 } from "react";
|
|
19197
|
-
import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
19198
|
-
function PieChart({
|
|
19199
|
-
data,
|
|
19200
|
-
size = 200,
|
|
19201
|
-
donut = false,
|
|
19202
|
-
donutWidth = 40,
|
|
19203
|
-
showLabels = true,
|
|
19204
|
-
showLegend = true,
|
|
19205
|
-
showPercentage = true,
|
|
19206
|
-
animated = true,
|
|
19207
|
-
startAngle = -90,
|
|
19208
|
-
renderCenter,
|
|
19209
|
-
formatValue,
|
|
19210
|
-
labelClassName,
|
|
19211
|
-
className = ""
|
|
19212
|
-
}) {
|
|
19213
|
-
const containerRef = useRef25(null);
|
|
19214
|
-
const center = size / 2;
|
|
19215
|
-
const radius = size / 2 - 10;
|
|
19216
|
-
const innerRadius = donut ? radius - donutWidth : 0;
|
|
19217
|
-
const { segments, total } = useMemo21(() => {
|
|
19218
|
-
if (!data.length) return { segments: [], total: 0 };
|
|
19219
|
-
const sum = data.reduce((acc, d) => acc + d.value, 0);
|
|
19220
|
-
let currentAngle = startAngle;
|
|
19221
|
-
const segs = data.map((d, i) => {
|
|
19222
|
-
const percentage = d.value / sum;
|
|
19223
|
-
const angle = percentage * 360;
|
|
19224
|
-
const startRad = currentAngle * Math.PI / 180;
|
|
19225
|
-
const endRad = (currentAngle + angle) * Math.PI / 180;
|
|
19226
|
-
const midRad = (currentAngle + angle / 2) * Math.PI / 180;
|
|
19227
|
-
const largeArc = angle > 180 ? 1 : 0;
|
|
19228
|
-
const x1 = center + radius * Math.cos(startRad);
|
|
19229
|
-
const y1 = center + radius * Math.sin(startRad);
|
|
19230
|
-
const x2 = center + radius * Math.cos(endRad);
|
|
19231
|
-
const y2 = center + radius * Math.sin(endRad);
|
|
19232
|
-
const x3 = center + innerRadius * Math.cos(endRad);
|
|
19233
|
-
const y3 = center + innerRadius * Math.sin(endRad);
|
|
19234
|
-
const x4 = center + innerRadius * Math.cos(startRad);
|
|
19235
|
-
const y4 = center + innerRadius * Math.sin(startRad);
|
|
19236
|
-
const labelRadius = radius + 20;
|
|
19237
|
-
const labelX = center + labelRadius * Math.cos(midRad);
|
|
19238
|
-
const labelY = center + labelRadius * Math.sin(midRad);
|
|
19239
|
-
let path;
|
|
19240
|
-
if (donut) {
|
|
19241
|
-
path = [
|
|
19242
|
-
`M ${x1} ${y1}`,
|
|
19243
|
-
`A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}`,
|
|
19244
|
-
`L ${x3} ${y3}`,
|
|
19245
|
-
`A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${x4} ${y4}`,
|
|
19246
|
-
"Z"
|
|
19247
|
-
].join(" ");
|
|
19248
|
-
} else {
|
|
19249
|
-
path = [`M ${center} ${center}`, `L ${x1} ${y1}`, `A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}`, "Z"].join(" ");
|
|
19250
|
-
}
|
|
19251
|
-
currentAngle += angle;
|
|
19252
|
-
return {
|
|
19253
|
-
path,
|
|
19254
|
-
...d,
|
|
19255
|
-
percentage,
|
|
19256
|
-
labelX,
|
|
19257
|
-
labelY,
|
|
19258
|
-
midAngle: currentAngle - angle / 2
|
|
19259
|
-
};
|
|
19260
|
-
});
|
|
19261
|
-
return { segments: segs, total: sum };
|
|
19262
|
-
}, [data, center, radius, innerRadius, donut, startAngle]);
|
|
19263
|
-
const [hoveredSegment, setHoveredSegment] = useState41(null);
|
|
19264
|
-
return /* @__PURE__ */ jsxs52("div", { ref: containerRef, className: `relative flex items-center gap-6 ${className}`, children: [
|
|
19265
|
-
/* @__PURE__ */ jsxs52("svg", { width: size + 40, height: size + 40, className: "overflow-visible", style: { fontFamily: "inherit" }, children: [
|
|
19266
|
-
/* @__PURE__ */ jsxs52("g", { transform: `translate(20, 20)`, children: [
|
|
19267
|
-
segments.map((seg, i) => /* @__PURE__ */ jsxs52(
|
|
19268
|
-
"g",
|
|
19269
|
-
{
|
|
19270
|
-
onMouseEnter: () => setHoveredSegment({
|
|
19271
|
-
x: seg.labelX + 20,
|
|
19272
|
-
y: seg.labelY + 20,
|
|
19273
|
-
label: seg.label,
|
|
19274
|
-
value: seg.value,
|
|
19275
|
-
percentage: seg.percentage,
|
|
19276
|
-
color: seg.color
|
|
19277
|
-
}),
|
|
19278
|
-
onMouseLeave: () => setHoveredSegment(null),
|
|
19279
|
-
children: [
|
|
19280
|
-
/* @__PURE__ */ jsx60(
|
|
19281
|
-
"path",
|
|
19282
|
-
{
|
|
19283
|
-
d: seg.path,
|
|
19284
|
-
fill: seg.color,
|
|
19285
|
-
className: `transition-all duration-150 cursor-pointer ${hoveredSegment?.label === seg.label ? "opacity-80" : ""}`,
|
|
19286
|
-
style: {
|
|
19287
|
-
transformOrigin: `${center}px ${center}px`,
|
|
19288
|
-
transform: hoveredSegment?.label === seg.label ? "scale(1.05)" : "scale(1)",
|
|
19289
|
-
...animated ? {
|
|
19290
|
-
opacity: hoveredSegment?.label === seg.label ? 0.8 : 0,
|
|
19291
|
-
animation: `pieSlice 0.5s ease-out ${i * 0.1}s forwards`
|
|
19292
|
-
} : void 0
|
|
19293
|
-
}
|
|
19294
|
-
}
|
|
19295
|
-
),
|
|
19296
|
-
showLabels && /* @__PURE__ */ jsx60(
|
|
19297
|
-
"text",
|
|
19298
|
-
{
|
|
19299
|
-
x: seg.labelX,
|
|
19300
|
-
y: seg.labelY,
|
|
19301
|
-
textAnchor: seg.labelX > center ? "start" : "end",
|
|
19302
|
-
fontSize: "10",
|
|
19303
|
-
className: labelClassName || "text-foreground",
|
|
19304
|
-
fill: "currentColor",
|
|
19305
|
-
style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.3}s forwards` } : void 0,
|
|
19306
|
-
children: showPercentage ? `${(seg.percentage * 100).toFixed(0)}%` : formatValue ? formatValue(seg.value) : seg.value
|
|
19307
|
-
}
|
|
19308
|
-
)
|
|
19309
|
-
]
|
|
19310
|
-
},
|
|
19311
|
-
i
|
|
19312
|
-
)),
|
|
19313
|
-
donut && (renderCenter ? /* @__PURE__ */ jsx60("foreignObject", { x: center - donutWidth, y: center - donutWidth / 2, width: donutWidth * 2, height: donutWidth, children: /* @__PURE__ */ jsx60("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: "100%" }, children: renderCenter(total) }) }) : /* @__PURE__ */ jsxs52("g", { children: [
|
|
19314
|
-
/* @__PURE__ */ jsx60("text", { x: center, y: center - 5, textAnchor: "middle", fontSize: "12", className: "text-muted-foreground", fill: "currentColor", children: "Total" }),
|
|
19315
|
-
/* @__PURE__ */ jsx60("text", { x: center, y: center + 15, textAnchor: "middle", fontSize: "18", fontWeight: "600", className: "text-foreground", fill: "currentColor", children: formatValue ? formatValue(total) : total })
|
|
19316
|
-
] }))
|
|
19317
|
-
] }),
|
|
19318
|
-
/* @__PURE__ */ jsx60("style", { children: `
|
|
19319
|
-
@keyframes pieSlice {
|
|
19320
|
-
from {
|
|
19321
|
-
opacity: 0;
|
|
19322
|
-
transform: scale(0);
|
|
19323
|
-
}
|
|
19324
|
-
to {
|
|
19325
|
-
opacity: 1;
|
|
19326
|
-
transform: scale(1);
|
|
19327
|
-
}
|
|
19328
|
-
}
|
|
19329
|
-
@keyframes fadeIn {
|
|
19330
|
-
from { opacity: 0; }
|
|
19331
|
-
to { opacity: 1; }
|
|
19332
|
-
}
|
|
19333
|
-
` })
|
|
19334
|
-
] }),
|
|
19335
|
-
showLegend && /* @__PURE__ */ jsx60("div", { className: "flex flex-col gap-2", children: segments.map((seg, i) => /* @__PURE__ */ jsxs52(
|
|
19336
|
-
"div",
|
|
19337
|
-
{
|
|
19338
|
-
className: "flex items-center gap-2 text-sm",
|
|
19339
|
-
style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.3}s forwards` } : void 0,
|
|
19340
|
-
children: [
|
|
19341
|
-
/* @__PURE__ */ jsx60("div", { className: "w-3 h-3 rounded-md shrink-0", style: { backgroundColor: seg.color } }),
|
|
19342
|
-
/* @__PURE__ */ jsx60("span", { className: "text-muted-foreground", children: seg.label }),
|
|
19343
|
-
/* @__PURE__ */ jsx60("span", { className: "text-foreground font-medium ml-auto", children: showPercentage ? `${(seg.percentage * 100).toFixed(0)}%` : formatValue ? formatValue(seg.value) : seg.value })
|
|
19344
|
-
]
|
|
19345
|
-
},
|
|
19346
|
-
i
|
|
19347
|
-
)) }),
|
|
19348
|
-
/* @__PURE__ */ jsx60(
|
|
19349
|
-
ChartTooltip,
|
|
19350
|
-
{
|
|
19351
|
-
x: hoveredSegment?.x ?? center,
|
|
19352
|
-
y: hoveredSegment?.y ?? center,
|
|
19353
|
-
visible: !!hoveredSegment,
|
|
19354
|
-
label: hoveredSegment?.label,
|
|
19355
|
-
value: `${hoveredSegment?.value} (${((hoveredSegment?.percentage ?? 0) * 100).toFixed(1)}%)`,
|
|
19356
|
-
color: hoveredSegment?.color,
|
|
19357
|
-
containerRef
|
|
19358
|
-
}
|
|
19359
|
-
)
|
|
19360
|
-
] });
|
|
19361
|
-
}
|
|
19362
|
-
|
|
19363
|
-
// src/components/AreaChart.tsx
|
|
19364
|
-
import { useMemo as useMemo22, useState as useState42, useRef as useRef26, useCallback as useCallback18 } from "react";
|
|
19365
|
-
import { jsx as jsx61, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
19366
|
-
function AreaChart({
|
|
19367
|
-
series,
|
|
19368
|
-
width = 400,
|
|
19369
|
-
height = 200,
|
|
19370
|
-
showDots = true,
|
|
19371
|
-
showGrid = true,
|
|
19372
|
-
showLabels = true,
|
|
19373
|
-
showLegend = true,
|
|
19374
|
-
animated = true,
|
|
19375
|
-
stacked = false,
|
|
19376
|
-
curved = true,
|
|
19377
|
-
formatValue,
|
|
19378
|
-
emptyText = "No data",
|
|
19379
|
-
labelClassName,
|
|
19380
|
-
className = ""
|
|
19381
|
-
}) {
|
|
19382
|
-
const containerRef = useRef26(null);
|
|
19383
|
-
const clipId = useRef26(`area-clip-${Math.random().toString(36).slice(2, 8)}`).current;
|
|
19384
|
-
const padding = useMemo22(() => ({ top: 20, right: 20, bottom: 40, left: 50 }), []);
|
|
19385
|
-
const chartWidth = width - padding.left - padding.right;
|
|
19386
|
-
const chartHeight = height - padding.top - padding.bottom;
|
|
19387
|
-
const [hoveredPoint, setHoveredPoint] = useState42(null);
|
|
19388
|
-
const [hiddenSeries, setHiddenSeries] = useState42(/* @__PURE__ */ new Set());
|
|
19389
|
-
const toggleSeries = useCallback18((name) => {
|
|
19390
|
-
setHiddenSeries((prev) => {
|
|
19391
|
-
const next = new Set(prev);
|
|
19392
|
-
if (next.has(name)) next.delete(name);
|
|
19393
|
-
else next.add(name);
|
|
19394
|
-
return next;
|
|
19395
|
-
});
|
|
19396
|
-
}, []);
|
|
19397
|
-
const { processedSeries, gridLines, maxValue, labels } = useMemo22(() => {
|
|
19398
|
-
if (!series.length || !series[0]?.data?.length) {
|
|
19399
|
-
return { processedSeries: [], gridLines: [], maxValue: 0, labels: [] };
|
|
19400
|
-
}
|
|
19401
|
-
const allLabels = series[0].data.map((d) => d.label);
|
|
19402
|
-
const dataLength = series[0].data.length;
|
|
19403
|
-
let max = 0;
|
|
19404
|
-
if (stacked) {
|
|
19405
|
-
for (let i = 0; i < dataLength; i++) {
|
|
19406
|
-
const stackedValue = series.reduce((sum, s) => sum + (s.data[i]?.value || 0), 0);
|
|
19407
|
-
max = Math.max(max, stackedValue);
|
|
19408
|
-
}
|
|
19409
|
-
} else {
|
|
19410
|
-
max = Math.max(...series.flatMap((s) => s.data.map((d) => d.value)));
|
|
19411
|
-
}
|
|
19412
|
-
const processed = series.map((s, seriesIndex) => {
|
|
19413
|
-
const points = s.data.map((d, i) => {
|
|
19414
|
-
const x = padding.left + i / (dataLength - 1) * chartWidth;
|
|
19415
|
-
let y;
|
|
19416
|
-
if (stacked && seriesIndex > 0) {
|
|
19417
|
-
const stackedBase = series.slice(0, seriesIndex).reduce((sum, prevS) => sum + (prevS.data[i]?.value || 0), 0);
|
|
19418
|
-
const stackedValue = stackedBase + d.value;
|
|
19419
|
-
y = padding.top + chartHeight - stackedValue / max * chartHeight;
|
|
19420
|
-
} else {
|
|
19421
|
-
y = padding.top + chartHeight - d.value / max * chartHeight;
|
|
19422
|
-
}
|
|
19423
|
-
return { x, y, value: d.value, label: d.label };
|
|
19424
|
-
});
|
|
19425
|
-
const linePath = curved ? getCatmullRomSpline(points) : `M ${points.map((p) => `${p.x} ${p.y}`).join(" L ")}`;
|
|
19426
|
-
let areaPath;
|
|
19427
|
-
if (stacked && seriesIndex > 0) {
|
|
19428
|
-
const prevSeriesPoints = series.slice(0, seriesIndex).reduce((acc, prevS) => {
|
|
19429
|
-
return prevS.data.map((d, i) => {
|
|
19430
|
-
const prevVal = acc[i] || 0;
|
|
19431
|
-
return prevVal + d.value;
|
|
19432
|
-
});
|
|
19433
|
-
}, []).map((val, i) => ({
|
|
19434
|
-
x: padding.left + i / (dataLength - 1) * chartWidth,
|
|
19435
|
-
y: padding.top + chartHeight - val / max * chartHeight
|
|
19436
|
-
}));
|
|
19437
|
-
const reversedPrevPoints = [...prevSeriesPoints].reverse();
|
|
19438
|
-
areaPath = `${linePath} L ${reversedPrevPoints.map((p) => `${p.x} ${p.y}`).join(" L ")} Z`;
|
|
19439
|
-
} else {
|
|
19440
|
-
areaPath = `${linePath} L ${padding.left + chartWidth} ${padding.top + chartHeight} L ${padding.left} ${padding.top + chartHeight} Z`;
|
|
19441
|
-
}
|
|
19442
|
-
return {
|
|
19443
|
-
...s,
|
|
19444
|
-
points,
|
|
19445
|
-
linePath,
|
|
19446
|
-
areaPath,
|
|
19447
|
-
lineLength: points.reduce((acc, p, i) => {
|
|
19448
|
-
if (i === 0) return 0;
|
|
19449
|
-
const prev = points[i - 1];
|
|
19450
|
-
return acc + Math.sqrt(Math.pow(p.x - prev.x, 2) + Math.pow(p.y - prev.y, 2));
|
|
19451
|
-
}, 0)
|
|
19452
|
-
};
|
|
19453
|
-
});
|
|
19454
|
-
const lines = [];
|
|
19455
|
-
const steps = 5;
|
|
19456
|
-
for (let i = 0; i <= steps; i++) {
|
|
19457
|
-
const value = i / steps * max;
|
|
19458
|
-
lines.push({
|
|
19459
|
-
y: padding.top + chartHeight - i / steps * chartHeight,
|
|
19460
|
-
value
|
|
19461
|
-
});
|
|
19462
|
-
}
|
|
19463
|
-
return { processedSeries: processed, gridLines: lines, maxValue: max, labels: allLabels };
|
|
19464
|
-
}, [series, chartWidth, chartHeight, padding, stacked, curved]);
|
|
19465
|
-
return /* @__PURE__ */ jsxs53("div", { ref: containerRef, className: `relative flex flex-col gap-4 ${className}`, children: [
|
|
19466
|
-
/* @__PURE__ */ jsxs53("svg", { width, height, className: "overflow-visible", style: { fontFamily: "inherit" }, children: [
|
|
19467
|
-
/* @__PURE__ */ jsx61("defs", { children: /* @__PURE__ */ jsx61("clipPath", { id: clipId, children: /* @__PURE__ */ jsx61("rect", { x: padding.left, y: padding.top, width: chartWidth, height: chartHeight }) }) }),
|
|
19468
|
-
showGrid && /* @__PURE__ */ jsx61("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ jsxs53("g", { children: [
|
|
19469
|
-
/* @__PURE__ */ jsx61("line", { x1: padding.left, y1: line.y, x2: width - padding.right, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
|
|
19470
|
-
/* @__PURE__ */ jsx61(
|
|
19471
|
-
"text",
|
|
19472
|
-
{
|
|
19473
|
-
x: padding.left - 8,
|
|
19474
|
-
y: line.y + 4,
|
|
19475
|
-
textAnchor: "end",
|
|
19476
|
-
fontSize: "10",
|
|
19477
|
-
className: labelClassName || "text-muted-foreground",
|
|
19478
|
-
fill: "currentColor",
|
|
19479
|
-
children: formatValue ? formatValue(line.value) : line.value.toFixed(0)
|
|
19480
|
-
}
|
|
19481
|
-
)
|
|
19482
|
-
] }, i)) }),
|
|
19483
|
-
/* @__PURE__ */ jsx61("g", { clipPath: `url(#${clipId})`, children: [...processedSeries].reverse().map((s, i) => /* @__PURE__ */ jsx61(
|
|
19484
|
-
"path",
|
|
19485
|
-
{
|
|
19486
|
-
d: s.areaPath,
|
|
19487
|
-
fill: s.color,
|
|
19488
|
-
fillOpacity: hiddenSeries.has(s.name) ? 0 : s.fillOpacity ?? 0.3,
|
|
19489
|
-
className: "transition-all duration-300",
|
|
19490
|
-
style: animated ? {
|
|
19491
|
-
opacity: 0,
|
|
19492
|
-
animation: `fadeIn 0.5s ease-out ${i * 0.1}s forwards`
|
|
19493
|
-
} : void 0
|
|
19494
|
-
},
|
|
19495
|
-
`area-${i}`
|
|
19496
|
-
)) }),
|
|
19497
|
-
/* @__PURE__ */ jsx61("g", { clipPath: `url(#${clipId})`, children: processedSeries.map((s, i) => /* @__PURE__ */ jsx61(
|
|
19498
|
-
"path",
|
|
19499
|
-
{
|
|
19500
|
-
d: s.linePath,
|
|
19501
|
-
fill: "none",
|
|
19502
|
-
stroke: s.color,
|
|
19503
|
-
strokeWidth: 2,
|
|
19504
|
-
strokeLinecap: "round",
|
|
19505
|
-
strokeLinejoin: "round",
|
|
19506
|
-
className: "transition-opacity duration-300",
|
|
19507
|
-
opacity: hiddenSeries.has(s.name) ? 0 : 1,
|
|
19508
|
-
style: animated ? {
|
|
19509
|
-
strokeDasharray: s.lineLength,
|
|
19510
|
-
strokeDashoffset: s.lineLength,
|
|
19511
|
-
animation: `drawLine 1s ease-out ${i * 0.1}s forwards`
|
|
19512
|
-
} : void 0
|
|
19513
|
-
},
|
|
19514
|
-
`line-${i}`
|
|
19515
|
-
)) }),
|
|
19516
|
-
showDots && processedSeries.map(
|
|
19517
|
-
(s, seriesIdx) => !hiddenSeries.has(s.name) && s.points.map((point, i) => /* @__PURE__ */ jsxs53(
|
|
19518
|
-
"g",
|
|
19519
|
-
{
|
|
19520
|
-
onMouseEnter: () => {
|
|
19521
|
-
const items = processedSeries.map((ps) => ({
|
|
19522
|
-
label: ps.name,
|
|
19523
|
-
value: ps.points[i]?.value ?? 0,
|
|
19524
|
-
color: ps.color
|
|
19525
|
-
}));
|
|
19526
|
-
setHoveredPoint({
|
|
19527
|
-
x: point.x,
|
|
19528
|
-
y: point.y,
|
|
19529
|
-
label: point.label,
|
|
19530
|
-
items
|
|
19531
|
-
});
|
|
19532
|
-
},
|
|
19533
|
-
onMouseLeave: () => setHoveredPoint(null),
|
|
19534
|
-
className: "cursor-pointer",
|
|
19535
|
-
children: [
|
|
19536
|
-
/* @__PURE__ */ jsx61(
|
|
19537
|
-
"circle",
|
|
19538
|
-
{
|
|
19539
|
-
cx: point.x,
|
|
19540
|
-
cy: point.y,
|
|
19541
|
-
r: hoveredPoint?.x === point.x ? 6 : 4,
|
|
19542
|
-
fill: s.color,
|
|
19543
|
-
className: "transition-all duration-150",
|
|
19544
|
-
style: animated ? {
|
|
19545
|
-
transform: "scale(0)",
|
|
19546
|
-
opacity: 0,
|
|
19547
|
-
transformOrigin: `${point.x}px ${point.y}px`,
|
|
19548
|
-
animation: `dotPop 0.3s ease-out ${seriesIdx * 0.1 + i * 0.05 + 0.5}s forwards`
|
|
19549
|
-
} : void 0
|
|
19550
|
-
}
|
|
19551
|
-
),
|
|
19552
|
-
/* @__PURE__ */ jsx61("circle", { cx: point.x, cy: point.y, r: 12, fill: "transparent" })
|
|
19553
|
-
]
|
|
19554
|
-
},
|
|
19555
|
-
`dot-${seriesIdx}-${i}`
|
|
19556
|
-
))
|
|
19557
|
-
),
|
|
19558
|
-
showLabels && /* @__PURE__ */ jsx61("g", { className: labelClassName || "text-muted-foreground", children: labels.map((label, i) => {
|
|
19559
|
-
const x = padding.left + i / (labels.length - 1) * chartWidth;
|
|
19560
|
-
return /* @__PURE__ */ jsx61("text", { x, y: height - 10, textAnchor: "middle", fontSize: "10", fill: "currentColor", children: label }, i);
|
|
19561
|
-
}) }),
|
|
19562
|
-
hoveredPoint && /* @__PURE__ */ jsx61("g", { className: "pointer-events-none", children: /* @__PURE__ */ jsx61(
|
|
19563
|
-
"line",
|
|
19564
|
-
{
|
|
19565
|
-
x1: hoveredPoint.x,
|
|
19566
|
-
y1: padding.top,
|
|
19567
|
-
x2: hoveredPoint.x,
|
|
19568
|
-
y2: padding.top + chartHeight,
|
|
19569
|
-
stroke: "currentColor",
|
|
19570
|
-
strokeWidth: 1,
|
|
19571
|
-
strokeDasharray: "4 4",
|
|
19572
|
-
opacity: 0.3,
|
|
19573
|
-
className: "text-foreground"
|
|
19574
|
-
}
|
|
19575
|
-
) }),
|
|
19576
|
-
/* @__PURE__ */ jsx61("style", { children: `
|
|
19577
|
-
@keyframes drawLine {
|
|
19578
|
-
to {
|
|
19579
|
-
stroke-dashoffset: 0;
|
|
19580
|
-
}
|
|
19581
|
-
}
|
|
19582
|
-
@keyframes fadeIn {
|
|
19583
|
-
from { opacity: 0; }
|
|
19584
|
-
to { opacity: 1; }
|
|
19585
|
-
}
|
|
19586
|
-
@keyframes dotPop {
|
|
19587
|
-
from {
|
|
19588
|
-
transform: scale(0);
|
|
19589
|
-
opacity: 0;
|
|
19590
|
-
}
|
|
19591
|
-
to {
|
|
19592
|
-
transform: scale(1);
|
|
19593
|
-
opacity: 1;
|
|
19594
|
-
}
|
|
19595
|
-
}
|
|
19596
|
-
` })
|
|
19597
|
-
] }),
|
|
19598
|
-
showLegend && /* @__PURE__ */ jsx61("div", { className: "flex items-center justify-center gap-6", children: series.map((s, i) => /* @__PURE__ */ jsxs53(
|
|
19599
|
-
"div",
|
|
19600
|
-
{
|
|
19601
|
-
className: "flex items-center gap-2 text-sm cursor-pointer select-none",
|
|
19602
|
-
style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.5}s forwards` } : void 0,
|
|
19603
|
-
onClick: () => toggleSeries(s.name),
|
|
19604
|
-
children: [
|
|
19605
|
-
/* @__PURE__ */ jsx61(
|
|
19606
|
-
"div",
|
|
19607
|
-
{
|
|
19608
|
-
className: "w-3 h-3 rounded-md transition-opacity",
|
|
19609
|
-
style: { backgroundColor: s.color, opacity: hiddenSeries.has(s.name) ? 0.3 : 1 }
|
|
19610
|
-
}
|
|
19611
|
-
),
|
|
19612
|
-
/* @__PURE__ */ jsx61("span", { className: hiddenSeries.has(s.name) ? "text-muted-foreground/40 line-through" : "text-muted-foreground", children: s.name })
|
|
19613
|
-
]
|
|
19614
|
-
},
|
|
19615
|
-
i
|
|
19616
|
-
)) }),
|
|
19617
|
-
/* @__PURE__ */ jsx61(
|
|
19618
|
-
ChartTooltip,
|
|
19619
|
-
{
|
|
19620
|
-
x: hoveredPoint?.x ?? 0,
|
|
19621
|
-
y: hoveredPoint?.y ?? 0,
|
|
19622
|
-
visible: !!hoveredPoint,
|
|
19623
|
-
label: hoveredPoint?.label,
|
|
19624
|
-
items: hoveredPoint?.items,
|
|
19625
|
-
containerRef
|
|
19626
|
-
}
|
|
19627
|
-
)
|
|
19628
|
-
] });
|
|
19629
|
-
}
|
|
19630
|
-
|
|
19631
|
-
// src/components/Sparkline.tsx
|
|
19632
|
-
import { useMemo as useMemo23 } from "react";
|
|
19633
|
-
import { jsx as jsx62, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
19634
|
-
function Sparkline({
|
|
19635
|
-
data,
|
|
19636
|
-
width = 100,
|
|
19637
|
-
height = 30,
|
|
19638
|
-
color = "currentColor",
|
|
19639
|
-
fillColor,
|
|
19640
|
-
showFill = true,
|
|
19641
|
-
showDots = false,
|
|
19642
|
-
showEndDot = true,
|
|
19643
|
-
animated = true,
|
|
19644
|
-
curved = true,
|
|
19645
|
-
strokeWidth = 2,
|
|
19646
|
-
className = ""
|
|
19647
|
-
}) {
|
|
19648
|
-
const padding = 4;
|
|
19649
|
-
const chartWidth = width - padding * 2;
|
|
19650
|
-
const chartHeight = height - padding * 2;
|
|
19651
|
-
const { points, linePath, areaPath, lineLength, trend } = useMemo23(() => {
|
|
19652
|
-
const normalizedData = data.map((d) => typeof d === "number" ? d : d.value);
|
|
19653
|
-
if (!normalizedData.length) {
|
|
19654
|
-
return { points: [], linePath: "", areaPath: "", lineLength: 0, trend: 0 };
|
|
19655
|
-
}
|
|
19656
|
-
const min = Math.min(...normalizedData);
|
|
19657
|
-
const max = Math.max(...normalizedData);
|
|
19658
|
-
const range = max - min || 1;
|
|
19659
|
-
const pts = normalizedData.map((value, i) => ({
|
|
19660
|
-
x: padding + i / (normalizedData.length - 1) * chartWidth,
|
|
19661
|
-
y: padding + chartHeight - (value - min) / range * chartHeight,
|
|
19662
|
-
value
|
|
19663
|
-
}));
|
|
19664
|
-
const line = curved ? getCatmullRomSpline(pts) : `M ${pts.map((p) => `${p.x} ${p.y}`).join(" L ")}`;
|
|
19665
|
-
const area = `${line} L ${padding + chartWidth} ${padding + chartHeight} L ${padding} ${padding + chartHeight} Z`;
|
|
19666
|
-
const length = pts.reduce((acc, p, i) => {
|
|
19667
|
-
if (i === 0) return 0;
|
|
19668
|
-
const prev = pts[i - 1];
|
|
19669
|
-
return acc + Math.sqrt(Math.pow(p.x - prev.x, 2) + Math.pow(p.y - prev.y, 2));
|
|
19670
|
-
}, 0);
|
|
19671
|
-
const trendValue = normalizedData[normalizedData.length - 1] - normalizedData[0];
|
|
19672
|
-
return { points: pts, linePath: line, areaPath: area, lineLength: length, trend: trendValue };
|
|
19673
|
-
}, [data, chartWidth, chartHeight, padding, curved]);
|
|
19674
|
-
const effectiveFillColor = fillColor || color;
|
|
19675
|
-
return /* @__PURE__ */ jsxs54("svg", { width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
|
|
19676
|
-
showFill && /* @__PURE__ */ jsx62(
|
|
19677
|
-
"path",
|
|
19678
|
-
{
|
|
19679
|
-
d: areaPath,
|
|
19680
|
-
fill: effectiveFillColor,
|
|
19681
|
-
fillOpacity: 0.1,
|
|
19682
|
-
style: animated ? { opacity: 0, animation: "fadeIn 0.5s ease-out 0.3s forwards" } : void 0
|
|
19683
|
-
}
|
|
19684
|
-
),
|
|
19685
|
-
/* @__PURE__ */ jsx62(
|
|
19686
|
-
"path",
|
|
19687
|
-
{
|
|
19688
|
-
d: linePath,
|
|
19689
|
-
fill: "none",
|
|
19690
|
-
stroke: color,
|
|
19691
|
-
strokeWidth,
|
|
19692
|
-
strokeLinecap: "round",
|
|
19693
|
-
strokeLinejoin: "round",
|
|
19694
|
-
style: animated ? {
|
|
19695
|
-
strokeDasharray: lineLength,
|
|
19696
|
-
strokeDashoffset: lineLength,
|
|
19697
|
-
animation: "drawLine 0.8s ease-out forwards"
|
|
19698
|
-
} : void 0
|
|
19699
|
-
}
|
|
19700
|
-
),
|
|
19701
|
-
showDots && points.map((point, i) => /* @__PURE__ */ jsx62(
|
|
19702
|
-
"circle",
|
|
19703
|
-
{
|
|
19704
|
-
cx: point.x,
|
|
19705
|
-
cy: point.y,
|
|
19706
|
-
r: 2,
|
|
19707
|
-
fill: color,
|
|
19708
|
-
style: animated ? {
|
|
19709
|
-
opacity: 0,
|
|
19710
|
-
animation: `fadeIn 0.3s ease-out ${i * 0.05 + 0.5}s forwards`
|
|
19711
|
-
} : void 0
|
|
19712
|
-
},
|
|
19713
|
-
i
|
|
19714
|
-
)),
|
|
19715
|
-
showEndDot && !showDots && points.length > 0 && /* @__PURE__ */ jsx62(
|
|
19716
|
-
"circle",
|
|
19717
|
-
{
|
|
19718
|
-
cx: points[points.length - 1].x,
|
|
19719
|
-
cy: points[points.length - 1].y,
|
|
19720
|
-
r: 3,
|
|
19721
|
-
fill: color,
|
|
19722
|
-
style: animated ? {
|
|
19723
|
-
opacity: 0,
|
|
19724
|
-
transform: "scale(0)",
|
|
19725
|
-
transformOrigin: `${points[points.length - 1].x}px ${points[points.length - 1].y}px`,
|
|
19726
|
-
animation: "dotPop 0.3s ease-out 0.6s forwards"
|
|
19727
|
-
} : void 0
|
|
19728
|
-
}
|
|
19729
|
-
),
|
|
19730
|
-
/* @__PURE__ */ jsx62("style", { children: `
|
|
19731
|
-
@keyframes drawLine {
|
|
19732
|
-
to {
|
|
19733
|
-
stroke-dashoffset: 0;
|
|
19734
|
-
}
|
|
19735
|
-
}
|
|
19736
|
-
@keyframes fadeIn {
|
|
19737
|
-
from { opacity: 0; }
|
|
19738
|
-
to { opacity: 1; }
|
|
19739
|
-
}
|
|
19740
|
-
@keyframes dotPop {
|
|
19741
|
-
from {
|
|
19742
|
-
transform: scale(0);
|
|
19743
|
-
opacity: 0;
|
|
19744
|
-
}
|
|
19745
|
-
to {
|
|
19746
|
-
transform: scale(1);
|
|
19747
|
-
opacity: 1;
|
|
19748
|
-
}
|
|
19749
|
-
}
|
|
19750
|
-
` })
|
|
19751
|
-
] });
|
|
19752
|
-
}
|
|
19753
|
-
|
|
19754
|
-
// src/components/RadarChart.tsx
|
|
19755
|
-
import { useMemo as useMemo24, useState as useState43, useRef as useRef27, useCallback as useCallback19 } from "react";
|
|
19756
|
-
import { jsx as jsx63, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
19757
|
-
function RadarChart({
|
|
19758
|
-
series,
|
|
19759
|
-
size = 300,
|
|
19760
|
-
levels = 5,
|
|
19761
|
-
showLabels = true,
|
|
19762
|
-
showLegend = true,
|
|
19763
|
-
showValues = false,
|
|
19764
|
-
animated = true,
|
|
19765
|
-
formatValue,
|
|
19766
|
-
labelClassName,
|
|
19767
|
-
className = ""
|
|
19768
|
-
}) {
|
|
19769
|
-
const containerRef = useRef27(null);
|
|
19770
|
-
const center = size / 2;
|
|
19771
|
-
const radius = size / 2 - 40;
|
|
19772
|
-
const [hoveredPoint, setHoveredPoint] = useState43(null);
|
|
19773
|
-
const [hiddenSeries, setHiddenSeries] = useState43(/* @__PURE__ */ new Set());
|
|
19774
|
-
const toggleSeries = useCallback19((name) => {
|
|
19775
|
-
setHiddenSeries((prev) => {
|
|
19776
|
-
const next = new Set(prev);
|
|
19777
|
-
if (next.has(name)) next.delete(name);
|
|
19778
|
-
else next.add(name);
|
|
19779
|
-
return next;
|
|
19780
|
-
});
|
|
19781
|
-
}, []);
|
|
19782
|
-
const { axes, processedSeries, levelPaths } = useMemo24(() => {
|
|
19783
|
-
if (!series.length || !series[0]?.data?.length) {
|
|
19784
|
-
return { axes: [], processedSeries: [], levelPaths: [] };
|
|
19785
|
-
}
|
|
19786
|
-
const axisLabels = series[0].data.map((d) => d.axis);
|
|
19787
|
-
const axisCount = axisLabels.length;
|
|
19788
|
-
const angleStep = 2 * Math.PI / axisCount;
|
|
19789
|
-
const maxValue = Math.max(...series.flatMap((s) => s.data.map((d) => d.value)));
|
|
19790
|
-
const axesData = axisLabels.map((label, i) => {
|
|
19791
|
-
const angle = i * angleStep - Math.PI / 2;
|
|
19792
|
-
const x = center + radius * Math.cos(angle);
|
|
19793
|
-
const y = center + radius * Math.sin(angle);
|
|
19794
|
-
const labelX = center + (radius + 20) * Math.cos(angle);
|
|
19795
|
-
const labelY = center + (radius + 20) * Math.sin(angle);
|
|
19796
|
-
return { label, x, y, labelX, labelY, angle };
|
|
19797
|
-
});
|
|
19798
|
-
const levelsData = [];
|
|
19799
|
-
for (let l = 1; l <= levels; l++) {
|
|
19800
|
-
const levelRadius = l / levels * radius;
|
|
19801
|
-
const points = axisLabels.map((_, i) => {
|
|
19802
|
-
const angle = i * angleStep - Math.PI / 2;
|
|
19803
|
-
return {
|
|
19804
|
-
x: center + levelRadius * Math.cos(angle),
|
|
19805
|
-
y: center + levelRadius * Math.sin(angle)
|
|
19806
|
-
};
|
|
19807
|
-
});
|
|
19808
|
-
levelsData.push({
|
|
19809
|
-
path: `M ${points.map((p) => `${p.x} ${p.y}`).join(" L ")} Z`,
|
|
19810
|
-
level: l,
|
|
19811
|
-
value: l / levels * maxValue
|
|
19812
|
-
});
|
|
19813
|
-
}
|
|
19814
|
-
const processed = series.map((s) => {
|
|
19815
|
-
const points = s.data.map((d, i) => {
|
|
19816
|
-
const angle = i * angleStep - Math.PI / 2;
|
|
19817
|
-
const r = d.value / maxValue * radius;
|
|
19818
|
-
return {
|
|
19819
|
-
x: center + r * Math.cos(angle),
|
|
19820
|
-
y: center + r * Math.sin(angle),
|
|
19821
|
-
value: d.value
|
|
19822
|
-
};
|
|
19823
|
-
});
|
|
19824
|
-
return {
|
|
19825
|
-
...s,
|
|
19826
|
-
points,
|
|
19827
|
-
path: `M ${points.map((p) => `${p.x} ${p.y}`).join(" L ")} Z`
|
|
19828
|
-
};
|
|
19829
|
-
});
|
|
19830
|
-
return { axes: axesData, processedSeries: processed, levelPaths: levelsData };
|
|
19831
|
-
}, [series, center, radius, levels]);
|
|
19832
|
-
return /* @__PURE__ */ jsxs55("div", { ref: containerRef, className: `relative flex flex-col gap-4 ${className}`, children: [
|
|
19833
|
-
/* @__PURE__ */ jsxs55("svg", { width: size, height: size, className: "overflow-visible", style: { fontFamily: "inherit" }, children: [
|
|
19834
|
-
/* @__PURE__ */ jsx63("g", { className: "text-muted-foreground/20", children: levelPaths.map((level, i) => /* @__PURE__ */ jsx63("path", { d: level.path, fill: "none", stroke: "currentColor", strokeWidth: 1 }, i)) }),
|
|
19835
|
-
/* @__PURE__ */ jsx63("g", { className: "text-muted-foreground/30", children: axes.map((axis, i) => /* @__PURE__ */ jsx63("line", { x1: center, y1: center, x2: axis.x, y2: axis.y, stroke: "currentColor", strokeWidth: 1 }, i)) }),
|
|
19836
|
-
processedSeries.map(
|
|
19837
|
-
(s, i) => !hiddenSeries.has(s.name) && /* @__PURE__ */ jsxs55("g", { children: [
|
|
19838
|
-
/* @__PURE__ */ jsx63(
|
|
19839
|
-
"path",
|
|
19840
|
-
{
|
|
19841
|
-
d: s.path,
|
|
19842
|
-
fill: s.color,
|
|
19843
|
-
fillOpacity: s.fillOpacity ?? 0.2,
|
|
19844
|
-
stroke: s.color,
|
|
19845
|
-
strokeWidth: 2,
|
|
19846
|
-
strokeLinejoin: "round",
|
|
19847
|
-
className: "transition-all duration-300",
|
|
19848
|
-
style: animated ? {
|
|
19849
|
-
opacity: 0,
|
|
19850
|
-
transform: "scale(0)",
|
|
19851
|
-
transformOrigin: `${center}px ${center}px`,
|
|
19852
|
-
animation: `radarPop 0.5s ease-out ${i * 0.15}s forwards`
|
|
19853
|
-
} : void 0
|
|
19854
|
-
}
|
|
19855
|
-
),
|
|
19856
|
-
s.points.map((point, j) => /* @__PURE__ */ jsxs55(
|
|
19857
|
-
"g",
|
|
19858
|
-
{
|
|
19859
|
-
onMouseEnter: () => {
|
|
19860
|
-
const items = processedSeries.map((ps) => ({
|
|
19861
|
-
label: ps.name,
|
|
19862
|
-
value: ps.points[j]?.value ?? 0,
|
|
19863
|
-
color: ps.color
|
|
19864
|
-
}));
|
|
19865
|
-
setHoveredPoint({
|
|
19866
|
-
x: point.x,
|
|
19867
|
-
y: point.y,
|
|
19868
|
-
axis: series[0]?.data[j]?.axis ?? "",
|
|
19869
|
-
items
|
|
19870
|
-
});
|
|
19871
|
-
},
|
|
19872
|
-
onMouseLeave: () => setHoveredPoint(null),
|
|
19873
|
-
className: "cursor-pointer",
|
|
19874
|
-
children: [
|
|
19875
|
-
/* @__PURE__ */ jsx63(
|
|
19876
|
-
"circle",
|
|
19877
|
-
{
|
|
19878
|
-
cx: point.x,
|
|
19879
|
-
cy: point.y,
|
|
19880
|
-
r: hoveredPoint?.axis === series[0]?.data[j]?.axis ? 6 : 4,
|
|
19881
|
-
fill: s.color,
|
|
19882
|
-
className: "transition-all duration-150",
|
|
19883
|
-
style: animated ? {
|
|
19884
|
-
opacity: 0,
|
|
19885
|
-
transform: "scale(0)",
|
|
19886
|
-
transformOrigin: `${point.x}px ${point.y}px`,
|
|
19887
|
-
animation: `dotPop 0.3s ease-out ${i * 0.15 + j * 0.05 + 0.3}s forwards`
|
|
19888
|
-
} : void 0
|
|
19889
|
-
}
|
|
19890
|
-
),
|
|
19891
|
-
/* @__PURE__ */ jsx63("circle", { cx: point.x, cy: point.y, r: 12, fill: "transparent" })
|
|
19892
|
-
]
|
|
19893
|
-
},
|
|
19894
|
-
j
|
|
19895
|
-
)),
|
|
19896
|
-
showValues && s.points.map((point, j) => /* @__PURE__ */ jsx63(
|
|
19897
|
-
"text",
|
|
19898
|
-
{
|
|
19899
|
-
x: point.x,
|
|
19900
|
-
y: point.y - 10,
|
|
19901
|
-
textAnchor: "middle",
|
|
19902
|
-
fontSize: "10",
|
|
19903
|
-
fontWeight: "500",
|
|
19904
|
-
className: "text-foreground",
|
|
19905
|
-
fill: "currentColor",
|
|
19906
|
-
style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.15 + 0.5}s forwards` } : void 0,
|
|
19907
|
-
children: point.value
|
|
19908
|
-
},
|
|
19909
|
-
`val-${j}`
|
|
19910
|
-
))
|
|
19911
|
-
] }, i)
|
|
19912
|
-
),
|
|
19913
|
-
showLabels && /* @__PURE__ */ jsx63("g", { className: labelClassName || "text-muted-foreground", children: axes.map((axis, i) => /* @__PURE__ */ jsx63("text", { x: axis.labelX, y: axis.labelY, textAnchor: "middle", dominantBaseline: "middle", fontSize: "11", fill: "currentColor", children: axis.label }, i)) }),
|
|
19914
|
-
/* @__PURE__ */ jsx63("style", { children: `
|
|
19915
|
-
@keyframes radarPop {
|
|
19916
|
-
from {
|
|
19917
|
-
opacity: 0;
|
|
19918
|
-
transform: scale(0);
|
|
19919
|
-
}
|
|
19920
|
-
to {
|
|
19921
|
-
opacity: 1;
|
|
19922
|
-
transform: scale(1);
|
|
19923
|
-
}
|
|
19924
|
-
}
|
|
19925
|
-
@keyframes dotPop {
|
|
19926
|
-
from {
|
|
19927
|
-
transform: scale(0);
|
|
19928
|
-
opacity: 0;
|
|
19929
|
-
}
|
|
19930
|
-
to {
|
|
19931
|
-
transform: scale(1);
|
|
19932
|
-
opacity: 1;
|
|
19933
|
-
}
|
|
19934
|
-
}
|
|
19935
|
-
@keyframes fadeIn {
|
|
19936
|
-
from { opacity: 0; }
|
|
19937
|
-
to { opacity: 1; }
|
|
19938
|
-
}
|
|
19939
|
-
` })
|
|
19940
|
-
] }),
|
|
19941
|
-
showLegend && /* @__PURE__ */ jsx63("div", { className: "flex items-center justify-center gap-6", children: series.map((s, i) => /* @__PURE__ */ jsxs55(
|
|
19942
|
-
"div",
|
|
19943
|
-
{
|
|
19944
|
-
className: "flex items-center gap-2 text-sm cursor-pointer select-none",
|
|
19945
|
-
style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.5}s forwards` } : void 0,
|
|
19946
|
-
onClick: () => toggleSeries(s.name),
|
|
19947
|
-
children: [
|
|
19948
|
-
/* @__PURE__ */ jsx63(
|
|
19949
|
-
"div",
|
|
19950
|
-
{
|
|
19951
|
-
className: "w-3 h-3 rounded-md transition-opacity",
|
|
19952
|
-
style: { backgroundColor: s.color, opacity: hiddenSeries.has(s.name) ? 0.3 : 1 }
|
|
19953
|
-
}
|
|
19954
|
-
),
|
|
19955
|
-
/* @__PURE__ */ jsx63("span", { className: hiddenSeries.has(s.name) ? "text-muted-foreground/40 line-through" : "text-muted-foreground", children: s.name })
|
|
19956
|
-
]
|
|
19957
|
-
},
|
|
19958
|
-
i
|
|
19959
|
-
)) }),
|
|
19960
|
-
/* @__PURE__ */ jsx63(
|
|
19961
|
-
ChartTooltip,
|
|
19962
|
-
{
|
|
19963
|
-
x: hoveredPoint?.x ?? 0,
|
|
19964
|
-
y: hoveredPoint?.y ?? 0,
|
|
19965
|
-
visible: !!hoveredPoint,
|
|
19966
|
-
label: hoveredPoint?.axis,
|
|
19967
|
-
items: hoveredPoint?.items,
|
|
19968
|
-
containerRef
|
|
19969
|
-
}
|
|
19970
|
-
)
|
|
19971
|
-
] });
|
|
19972
|
-
}
|
|
19973
|
-
|
|
19974
|
-
// src/components/GaugeChart.tsx
|
|
19975
|
-
import { useMemo as useMemo25 } from "react";
|
|
19976
|
-
import { jsx as jsx64, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
19977
|
-
function GaugeChart({
|
|
19978
|
-
value,
|
|
19979
|
-
min = 0,
|
|
19980
|
-
max = 100,
|
|
19981
|
-
size = 200,
|
|
19982
|
-
thickness = 20,
|
|
19983
|
-
color = "currentColor",
|
|
19984
|
-
backgroundColor,
|
|
19985
|
-
showValue = true,
|
|
19986
|
-
showMinMax = true,
|
|
19987
|
-
label,
|
|
19988
|
-
animated = true,
|
|
19989
|
-
startAngle = -135,
|
|
19990
|
-
endAngle = 135,
|
|
19991
|
-
zones,
|
|
19992
|
-
formatValue,
|
|
19993
|
-
labelClassName,
|
|
19994
|
-
className = ""
|
|
19995
|
-
}) {
|
|
19996
|
-
const center = size / 2;
|
|
19997
|
-
const radius = center - thickness / 2 - 10;
|
|
19998
|
-
const { backgroundPath, valuePath, percentage, needleAngle, zonePaths } = useMemo25(() => {
|
|
19999
|
-
const normalizedValue = Math.min(Math.max(value, min), max);
|
|
20000
|
-
const pct = (normalizedValue - min) / (max - min);
|
|
20001
|
-
const totalAngle = endAngle - startAngle;
|
|
20002
|
-
const currentAngle = startAngle + pct * totalAngle;
|
|
20003
|
-
const polarToCartesian = (angle) => {
|
|
20004
|
-
const radians = angle * Math.PI / 180;
|
|
20005
|
-
return {
|
|
20006
|
-
x: center + radius * Math.cos(radians),
|
|
20007
|
-
y: center + radius * Math.sin(radians)
|
|
20008
|
-
};
|
|
20009
|
-
};
|
|
20010
|
-
const createArc = (start, end) => {
|
|
20011
|
-
const startPoint = polarToCartesian(start);
|
|
20012
|
-
const endPoint = polarToCartesian(end);
|
|
20013
|
-
const largeArc = Math.abs(end - start) > 180 ? 1 : 0;
|
|
20014
|
-
return `M ${startPoint.x} ${startPoint.y} A ${radius} ${radius} 0 ${largeArc} 1 ${endPoint.x} ${endPoint.y}`;
|
|
20015
|
-
};
|
|
20016
|
-
const zonePaths2 = (zones ?? []).map((zone) => {
|
|
20017
|
-
const zoneStart = startAngle + (Math.max(zone.min, min) - min) / (max - min) * totalAngle;
|
|
20018
|
-
const zoneEnd = startAngle + (Math.min(zone.max, max) - min) / (max - min) * totalAngle;
|
|
20019
|
-
return { path: createArc(zoneStart, zoneEnd), color: zone.color };
|
|
20020
|
-
});
|
|
20021
|
-
return {
|
|
20022
|
-
backgroundPath: createArc(startAngle, endAngle),
|
|
20023
|
-
valuePath: createArc(startAngle, currentAngle),
|
|
20024
|
-
percentage: pct,
|
|
20025
|
-
needleAngle: currentAngle,
|
|
20026
|
-
zonePaths: zonePaths2
|
|
20027
|
-
};
|
|
20028
|
-
}, [value, min, max, center, radius, startAngle, endAngle, zones]);
|
|
20029
|
-
const needleLength = radius - 10;
|
|
20030
|
-
const needleAngleRad = needleAngle * Math.PI / 180;
|
|
20031
|
-
const needleX = center + needleLength * Math.cos(needleAngleRad);
|
|
20032
|
-
const needleY = center + needleLength * Math.sin(needleAngleRad);
|
|
20033
|
-
return /* @__PURE__ */ jsxs56("svg", { width: size, height: size * 0.7, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
|
|
20034
|
-
/* @__PURE__ */ jsx64(
|
|
20035
|
-
"path",
|
|
20036
|
-
{
|
|
20037
|
-
d: backgroundPath,
|
|
20038
|
-
fill: "none",
|
|
20039
|
-
stroke: backgroundColor || "currentColor",
|
|
20040
|
-
strokeWidth: thickness,
|
|
20041
|
-
strokeLinecap: "round",
|
|
20042
|
-
className: !backgroundColor ? "text-muted-foreground/20" : ""
|
|
20043
|
-
}
|
|
20044
|
-
),
|
|
20045
|
-
zonePaths.map((zone, i) => /* @__PURE__ */ jsx64("path", { d: zone.path, fill: "none", stroke: zone.color, strokeWidth: thickness, strokeLinecap: "round", opacity: 0.35 }, `zone-${i}`)),
|
|
20046
|
-
/* @__PURE__ */ jsx64(
|
|
20047
|
-
"path",
|
|
20048
|
-
{
|
|
20049
|
-
d: valuePath,
|
|
20050
|
-
fill: "none",
|
|
20051
|
-
stroke: color,
|
|
20052
|
-
strokeWidth: thickness,
|
|
20053
|
-
strokeLinecap: "round",
|
|
20054
|
-
style: animated ? {
|
|
20055
|
-
strokeDasharray: "1000",
|
|
20056
|
-
strokeDashoffset: 1e3,
|
|
20057
|
-
animation: "drawArc 1s ease-out forwards"
|
|
20058
|
-
} : void 0
|
|
20059
|
-
}
|
|
20060
|
-
),
|
|
20061
|
-
/* @__PURE__ */ jsxs56(
|
|
20062
|
-
"g",
|
|
20063
|
-
{
|
|
20064
|
-
style: animated ? {
|
|
20065
|
-
transform: `rotate(${startAngle}deg)`,
|
|
20066
|
-
transformOrigin: `${center}px ${center}px`,
|
|
20067
|
-
animation: `needleRotate 1s ease-out forwards`,
|
|
20068
|
-
["--needle-end"]: `${needleAngle}deg`
|
|
20069
|
-
} : {
|
|
20070
|
-
transform: `rotate(${needleAngle}deg)`,
|
|
20071
|
-
transformOrigin: `${center}px ${center}px`
|
|
20072
|
-
},
|
|
20073
|
-
children: [
|
|
20074
|
-
/* @__PURE__ */ jsx64("line", { x1: center, y1: center, x2: center + needleLength, y2: center, stroke: color, strokeWidth: 3, strokeLinecap: "round" }),
|
|
20075
|
-
/* @__PURE__ */ jsx64("circle", { cx: center, cy: center, r: 8, fill: color }),
|
|
20076
|
-
/* @__PURE__ */ jsx64("circle", { cx: center, cy: center, r: 4, className: "text-background", fill: "currentColor" })
|
|
20077
|
-
]
|
|
20078
|
-
}
|
|
20079
|
-
),
|
|
20080
|
-
showMinMax && /* @__PURE__ */ jsxs56("g", { className: labelClassName || "text-muted-foreground", children: [
|
|
20081
|
-
/* @__PURE__ */ jsx64(
|
|
20082
|
-
"text",
|
|
20083
|
-
{
|
|
20084
|
-
x: center + (radius + 20) * Math.cos(startAngle * Math.PI / 180),
|
|
20085
|
-
y: center + (radius + 20) * Math.sin(startAngle * Math.PI / 180) + 5,
|
|
20086
|
-
textAnchor: "middle",
|
|
20087
|
-
fontSize: "10",
|
|
20088
|
-
fill: "currentColor",
|
|
20089
|
-
children: min
|
|
20090
|
-
}
|
|
20091
|
-
),
|
|
20092
|
-
/* @__PURE__ */ jsx64(
|
|
20093
|
-
"text",
|
|
20094
|
-
{
|
|
20095
|
-
x: center + (radius + 20) * Math.cos(endAngle * Math.PI / 180),
|
|
20096
|
-
y: center + (radius + 20) * Math.sin(endAngle * Math.PI / 180) + 5,
|
|
20097
|
-
textAnchor: "middle",
|
|
20098
|
-
fontSize: "10",
|
|
20099
|
-
fill: "currentColor",
|
|
20100
|
-
children: max
|
|
20101
|
-
}
|
|
20102
|
-
)
|
|
20103
|
-
] }),
|
|
20104
|
-
showValue && /* @__PURE__ */ jsxs56("g", { children: [
|
|
20105
|
-
/* @__PURE__ */ jsx64(
|
|
20106
|
-
"text",
|
|
20107
|
-
{
|
|
20108
|
-
x: center,
|
|
20109
|
-
y: center + 35,
|
|
20110
|
-
textAnchor: "middle",
|
|
20111
|
-
fontSize: "24",
|
|
20112
|
-
fontWeight: "600",
|
|
20113
|
-
className: "text-foreground",
|
|
20114
|
-
fill: "currentColor",
|
|
20115
|
-
style: animated ? { opacity: 0, animation: "fadeIn 0.5s ease-out 0.5s forwards" } : void 0,
|
|
20116
|
-
children: formatValue ? formatValue(value) : value
|
|
20117
|
-
}
|
|
20118
|
-
),
|
|
20119
|
-
label && /* @__PURE__ */ jsx64(
|
|
20120
|
-
"text",
|
|
20121
|
-
{
|
|
20122
|
-
x: center,
|
|
20123
|
-
y: center + 55,
|
|
20124
|
-
textAnchor: "middle",
|
|
20125
|
-
fontSize: "12",
|
|
20126
|
-
className: "text-muted-foreground",
|
|
20127
|
-
fill: "currentColor",
|
|
20128
|
-
style: animated ? { opacity: 0, animation: "fadeIn 0.5s ease-out 0.6s forwards" } : void 0,
|
|
20129
|
-
children: label
|
|
20130
|
-
}
|
|
20131
|
-
)
|
|
20132
|
-
] }),
|
|
20133
|
-
/* @__PURE__ */ jsx64("style", { children: `
|
|
20134
|
-
@keyframes drawArc {
|
|
20135
|
-
to {
|
|
20136
|
-
stroke-dashoffset: 0;
|
|
20137
|
-
}
|
|
20138
|
-
}
|
|
20139
|
-
@keyframes needleRotate {
|
|
20140
|
-
to {
|
|
20141
|
-
transform: rotate(var(--needle-end));
|
|
20142
|
-
}
|
|
20143
|
-
}
|
|
20144
|
-
@keyframes fadeIn {
|
|
20145
|
-
from { opacity: 0; }
|
|
20146
|
-
to { opacity: 1; }
|
|
20147
|
-
}
|
|
20148
|
-
` })
|
|
20149
|
-
] });
|
|
20150
|
-
}
|
|
20151
|
-
|
|
20152
18500
|
// src/components/ClientOnly.tsx
|
|
20153
|
-
import { useEffect as
|
|
20154
|
-
import { Fragment as
|
|
18501
|
+
import { useEffect as useEffect28, useState as useState38 } from "react";
|
|
18502
|
+
import { Fragment as Fragment21, jsx as jsx57 } from "react/jsx-runtime";
|
|
20155
18503
|
function ClientOnly({ children, fallback = null }) {
|
|
20156
|
-
const [hasMounted, setHasMounted] =
|
|
20157
|
-
|
|
18504
|
+
const [hasMounted, setHasMounted] = useState38(false);
|
|
18505
|
+
useEffect28(() => {
|
|
20158
18506
|
setHasMounted(true);
|
|
20159
18507
|
}, []);
|
|
20160
18508
|
if (!hasMounted) {
|
|
20161
|
-
return /* @__PURE__ */
|
|
18509
|
+
return /* @__PURE__ */ jsx57(Fragment21, { children: fallback });
|
|
20162
18510
|
}
|
|
20163
|
-
return /* @__PURE__ */
|
|
18511
|
+
return /* @__PURE__ */ jsx57(Fragment21, { children });
|
|
20164
18512
|
}
|
|
20165
18513
|
|
|
20166
18514
|
// src/components/Loading.tsx
|
|
20167
18515
|
import { Activity as Activity3 } from "lucide-react";
|
|
20168
|
-
import { jsx as
|
|
18516
|
+
import { jsx as jsx58, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
20169
18517
|
var LoadingSpinner = ({
|
|
20170
18518
|
size = "md",
|
|
20171
18519
|
className,
|
|
@@ -20181,7 +18529,7 @@ var LoadingSpinner = ({
|
|
|
20181
18529
|
foreground: "text-foreground",
|
|
20182
18530
|
muted: "text-muted-foreground"
|
|
20183
18531
|
};
|
|
20184
|
-
return /* @__PURE__ */
|
|
18532
|
+
return /* @__PURE__ */ jsx58(
|
|
20185
18533
|
Activity3,
|
|
20186
18534
|
{
|
|
20187
18535
|
className: cn(
|
|
@@ -20202,7 +18550,7 @@ var LoadingDots = ({
|
|
|
20202
18550
|
foreground: "bg-foreground",
|
|
20203
18551
|
muted: "bg-muted-foreground"
|
|
20204
18552
|
};
|
|
20205
|
-
return /* @__PURE__ */
|
|
18553
|
+
return /* @__PURE__ */ jsx58("div", { className: cn("flex items-center space-x-1", className), children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx58(
|
|
20206
18554
|
"div",
|
|
20207
18555
|
{
|
|
20208
18556
|
className: cn(
|
|
@@ -20224,7 +18572,7 @@ var LoadingBar = ({
|
|
|
20224
18572
|
label
|
|
20225
18573
|
}) => {
|
|
20226
18574
|
const pct = progress ? Math.min(Math.max(progress, 0), 100) : void 0;
|
|
20227
|
-
return /* @__PURE__ */
|
|
18575
|
+
return /* @__PURE__ */ jsx58(
|
|
20228
18576
|
"div",
|
|
20229
18577
|
{
|
|
20230
18578
|
className: cn("w-full bg-muted rounded-full h-2", className),
|
|
@@ -20233,7 +18581,7 @@ var LoadingBar = ({
|
|
|
20233
18581
|
"aria-valuemax": pct === void 0 ? void 0 : 100,
|
|
20234
18582
|
"aria-valuenow": pct === void 0 ? void 0 : Math.round(pct),
|
|
20235
18583
|
"aria-label": label || "Loading",
|
|
20236
|
-
children: /* @__PURE__ */
|
|
18584
|
+
children: /* @__PURE__ */ jsx58(
|
|
20237
18585
|
"div",
|
|
20238
18586
|
{
|
|
20239
18587
|
className: cn(
|
|
@@ -20250,12 +18598,12 @@ var LoadingBar = ({
|
|
|
20250
18598
|
};
|
|
20251
18599
|
|
|
20252
18600
|
// src/components/Table.tsx
|
|
20253
|
-
import
|
|
20254
|
-
import { jsx as
|
|
18601
|
+
import React50 from "react";
|
|
18602
|
+
import { jsx as jsx59, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
20255
18603
|
var TABLE_BASE_CLASS = "w-full caption-bottom text-sm";
|
|
20256
18604
|
var TABLE_CONTAINER_BASE_CLASS = [
|
|
20257
18605
|
"relative w-full overflow-auto",
|
|
20258
|
-
"rounded-2xl md:rounded-3xl border border-border",
|
|
18606
|
+
"rounded-2xl md:rounded-3xl border border-border/50",
|
|
20259
18607
|
"bg-card text-card-foreground shadow-sm",
|
|
20260
18608
|
"backdrop-blur-sm transition-all duration-300"
|
|
20261
18609
|
].join(" ");
|
|
@@ -20268,10 +18616,10 @@ function assignRef3(ref, value) {
|
|
|
20268
18616
|
ref.current = value;
|
|
20269
18617
|
}
|
|
20270
18618
|
}
|
|
20271
|
-
var TableContainer =
|
|
20272
|
-
const containerRef =
|
|
18619
|
+
var TableContainer = React50.forwardRef(({ className, useOverlayScrollbar = false, ...props }, ref) => {
|
|
18620
|
+
const containerRef = React50.useRef(null);
|
|
20273
18621
|
useOverlayScrollbarTarget(containerRef, { enabled: useOverlayScrollbar });
|
|
20274
|
-
return /* @__PURE__ */
|
|
18622
|
+
return /* @__PURE__ */ jsx59(
|
|
20275
18623
|
"div",
|
|
20276
18624
|
{
|
|
20277
18625
|
ref: (node) => {
|
|
@@ -20284,30 +18632,30 @@ var TableContainer = React59.forwardRef(({ className, useOverlayScrollbar = fals
|
|
|
20284
18632
|
);
|
|
20285
18633
|
});
|
|
20286
18634
|
TableContainer.displayName = "TableContainer";
|
|
20287
|
-
var Table =
|
|
18635
|
+
var Table = React50.forwardRef(
|
|
20288
18636
|
({ className, containerClassName, disableContainer = false, useOverlayScrollbar = false, ...props }, ref) => {
|
|
20289
18637
|
if (disableContainer) {
|
|
20290
|
-
return /* @__PURE__ */
|
|
18638
|
+
return /* @__PURE__ */ jsx59("table", { ref, className: cn(TABLE_BASE_CLASS, className), ...props });
|
|
20291
18639
|
}
|
|
20292
|
-
return /* @__PURE__ */
|
|
18640
|
+
return /* @__PURE__ */ jsx59(TableContainer, { className: containerClassName, useOverlayScrollbar, children: /* @__PURE__ */ jsx59("table", { ref, className: cn(TABLE_BASE_CLASS, className), ...props }) });
|
|
20293
18641
|
}
|
|
20294
18642
|
);
|
|
20295
18643
|
Table.displayName = "Table";
|
|
20296
|
-
var TableHeader =
|
|
18644
|
+
var TableHeader = React50.forwardRef(({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ jsxs50("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-border/50", "bg-muted", className), ...props, children: [
|
|
20297
18645
|
children,
|
|
20298
18646
|
filterRow
|
|
20299
18647
|
] }));
|
|
20300
18648
|
TableHeader.displayName = "TableHeader";
|
|
20301
|
-
var TableBody =
|
|
18649
|
+
var TableBody = React50.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx59("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
|
|
20302
18650
|
TableBody.displayName = "TableBody";
|
|
20303
|
-
var TableFooter =
|
|
18651
|
+
var TableFooter = React50.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx59("tfoot", { ref, className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props }));
|
|
20304
18652
|
TableFooter.displayName = "TableFooter";
|
|
20305
|
-
var TableRow =
|
|
18653
|
+
var TableRow = React50.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx59(
|
|
20306
18654
|
"tr",
|
|
20307
18655
|
{
|
|
20308
18656
|
ref,
|
|
20309
18657
|
className: cn(
|
|
20310
|
-
"border-b border-border transition-all duration-300",
|
|
18658
|
+
"border-b border-border/50 transition-all duration-300",
|
|
20311
18659
|
"hover:bg-muted/30 hover:shadow-sm",
|
|
20312
18660
|
"data-[state=selected]:bg-muted/50",
|
|
20313
18661
|
className
|
|
@@ -20316,7 +18664,7 @@ var TableRow = React59.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
20316
18664
|
}
|
|
20317
18665
|
));
|
|
20318
18666
|
TableRow.displayName = "TableRow";
|
|
20319
|
-
var TableHead =
|
|
18667
|
+
var TableHead = React50.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx59(
|
|
20320
18668
|
"th",
|
|
20321
18669
|
{
|
|
20322
18670
|
ref,
|
|
@@ -20325,16 +18673,16 @@ var TableHead = React59.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
20325
18673
|
}
|
|
20326
18674
|
));
|
|
20327
18675
|
TableHead.displayName = "TableHead";
|
|
20328
|
-
var TableCell =
|
|
18676
|
+
var TableCell = React50.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx59("td", { ref, className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className), ...props }));
|
|
20329
18677
|
TableCell.displayName = "TableCell";
|
|
20330
|
-
var TableCaption =
|
|
18678
|
+
var TableCaption = React50.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx59("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
|
|
20331
18679
|
TableCaption.displayName = "TableCaption";
|
|
20332
18680
|
|
|
20333
18681
|
// src/components/DataTable/DataTable.tsx
|
|
20334
|
-
import
|
|
18682
|
+
import React59 from "react";
|
|
20335
18683
|
|
|
20336
18684
|
// src/components/DataTable/components/DataTableBody.tsx
|
|
20337
|
-
import { jsx as
|
|
18685
|
+
import { jsx as jsx60, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
20338
18686
|
function DataTableBodyRows({
|
|
20339
18687
|
leafColumns,
|
|
20340
18688
|
displayedData,
|
|
@@ -20349,10 +18697,10 @@ function DataTableBodyRows({
|
|
|
20349
18697
|
getStickyCellClass,
|
|
20350
18698
|
t
|
|
20351
18699
|
}) {
|
|
20352
|
-
return /* @__PURE__ */
|
|
20353
|
-
/* @__PURE__ */
|
|
20354
|
-
/* @__PURE__ */
|
|
20355
|
-
/* @__PURE__ */
|
|
18700
|
+
return /* @__PURE__ */ jsx60(TableBody, { children: loading2 ? /* @__PURE__ */ jsx60(TableRow, { children: /* @__PURE__ */ jsx60(TableCell, { colSpan: leafColumns.length, className: "text-center py-8", children: /* @__PURE__ */ jsxs51("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
|
|
18701
|
+
/* @__PURE__ */ jsxs51("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
18702
|
+
/* @__PURE__ */ jsx60("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
18703
|
+
/* @__PURE__ */ jsx60(
|
|
20356
18704
|
"path",
|
|
20357
18705
|
{
|
|
20358
18706
|
className: "opacity-75",
|
|
@@ -20361,13 +18709,13 @@ function DataTableBodyRows({
|
|
|
20361
18709
|
}
|
|
20362
18710
|
)
|
|
20363
18711
|
] }),
|
|
20364
|
-
/* @__PURE__ */
|
|
18712
|
+
/* @__PURE__ */ jsxs51("span", { className: "text-sm", children: [
|
|
20365
18713
|
t("loading"),
|
|
20366
18714
|
"\u2026"
|
|
20367
18715
|
] })
|
|
20368
|
-
] }) }) }) : displayedData.length === 0 ? /* @__PURE__ */
|
|
18716
|
+
] }) }) }) : displayedData.length === 0 ? /* @__PURE__ */ jsx60(TableRow, { children: /* @__PURE__ */ jsx60(TableCell, { colSpan: leafColumns.length, className: "text-center py-6 text-muted-foreground", children: t("noData") }) }) : displayedData.map((row, idx) => {
|
|
20369
18717
|
const isStripedRow = striped && idx % 2 === 0;
|
|
20370
|
-
return /* @__PURE__ */
|
|
18718
|
+
return /* @__PURE__ */ jsx60(
|
|
20371
18719
|
TableRow,
|
|
20372
18720
|
{
|
|
20373
18721
|
className: cn(densityRowClass, isStripedRow ? "bg-surface-1" : "bg-surface-0"),
|
|
@@ -20380,7 +18728,7 @@ function DataTableBodyRows({
|
|
|
20380
18728
|
const prevCol = colIdx > 0 ? leafColumns[colIdx - 1] : null;
|
|
20381
18729
|
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
20382
18730
|
const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
|
|
20383
|
-
return /* @__PURE__ */
|
|
18731
|
+
return /* @__PURE__ */ jsx60(
|
|
20384
18732
|
TableCell,
|
|
20385
18733
|
{
|
|
20386
18734
|
style: getStickyColumnStyle(col),
|
|
@@ -20403,9 +18751,9 @@ function DataTableBodyRows({
|
|
|
20403
18751
|
}
|
|
20404
18752
|
|
|
20405
18753
|
// src/components/DataTable/components/DataTableHeader.tsx
|
|
20406
|
-
import
|
|
18754
|
+
import React51 from "react";
|
|
20407
18755
|
import { Filter as FilterIcon } from "lucide-react";
|
|
20408
|
-
import { Fragment as
|
|
18756
|
+
import { Fragment as Fragment22, jsx as jsx61, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
20409
18757
|
function DataTableHeader({
|
|
20410
18758
|
headerRows,
|
|
20411
18759
|
headerAlign,
|
|
@@ -20423,13 +18771,13 @@ function DataTableHeader({
|
|
|
20423
18771
|
getStickyHeaderCellStyle,
|
|
20424
18772
|
t
|
|
20425
18773
|
}) {
|
|
20426
|
-
const renderFilterControl =
|
|
18774
|
+
const renderFilterControl = React51.useCallback(
|
|
20427
18775
|
(col) => {
|
|
20428
18776
|
if (!col.filter) return null;
|
|
20429
18777
|
const key = col.key;
|
|
20430
18778
|
const commonProps = { className: "w-full", size };
|
|
20431
18779
|
if (col.filter.type === "text") {
|
|
20432
|
-
return /* @__PURE__ */
|
|
18780
|
+
return /* @__PURE__ */ jsx61(
|
|
20433
18781
|
Input_default,
|
|
20434
18782
|
{
|
|
20435
18783
|
...commonProps,
|
|
@@ -20443,7 +18791,7 @@ function DataTableHeader({
|
|
|
20443
18791
|
);
|
|
20444
18792
|
}
|
|
20445
18793
|
if (col.filter.type === "select") {
|
|
20446
|
-
return /* @__PURE__ */
|
|
18794
|
+
return /* @__PURE__ */ jsx61(
|
|
20447
18795
|
Combobox,
|
|
20448
18796
|
{
|
|
20449
18797
|
options: ["", ...col.filter.options || []],
|
|
@@ -20459,7 +18807,7 @@ function DataTableHeader({
|
|
|
20459
18807
|
);
|
|
20460
18808
|
}
|
|
20461
18809
|
if (col.filter.type === "date") {
|
|
20462
|
-
return /* @__PURE__ */
|
|
18810
|
+
return /* @__PURE__ */ jsx61(
|
|
20463
18811
|
DatePicker,
|
|
20464
18812
|
{
|
|
20465
18813
|
size,
|
|
@@ -20476,10 +18824,10 @@ function DataTableHeader({
|
|
|
20476
18824
|
},
|
|
20477
18825
|
[filters, setCurPage, setFilters, size]
|
|
20478
18826
|
);
|
|
20479
|
-
const renderHeaderContent =
|
|
18827
|
+
const renderHeaderContent = React51.useCallback(
|
|
20480
18828
|
(col, isLeaf) => {
|
|
20481
18829
|
if (!isLeaf) {
|
|
20482
|
-
return /* @__PURE__ */
|
|
18830
|
+
return /* @__PURE__ */ jsx61(
|
|
20483
18831
|
"div",
|
|
20484
18832
|
{
|
|
20485
18833
|
className: cn(
|
|
@@ -20489,15 +18837,15 @@ function DataTableHeader({
|
|
|
20489
18837
|
col.align === "center" && "justify-center",
|
|
20490
18838
|
!col.align && "justify-start"
|
|
20491
18839
|
),
|
|
20492
|
-
children: /* @__PURE__ */
|
|
18840
|
+
children: /* @__PURE__ */ jsx61("span", { className: cn("font-medium whitespace-nowrap", headerTitleClass), children: col.title })
|
|
20493
18841
|
}
|
|
20494
18842
|
);
|
|
20495
18843
|
}
|
|
20496
18844
|
const isRightAlign = col.align === "right" || !col.align && headerAlign === "right";
|
|
20497
18845
|
const isCenterAlign = col.align === "center" || !col.align && headerAlign === "center";
|
|
20498
|
-
const titleContent = /* @__PURE__ */
|
|
20499
|
-
/* @__PURE__ */
|
|
20500
|
-
col.sortable && /* @__PURE__ */
|
|
18846
|
+
const titleContent = /* @__PURE__ */ jsxs52("div", { className: "flex items-center gap-1", children: [
|
|
18847
|
+
/* @__PURE__ */ jsx61("span", { className: cn("font-medium whitespace-nowrap", headerTitleClass), children: col.title }),
|
|
18848
|
+
col.sortable && /* @__PURE__ */ jsx61(
|
|
20501
18849
|
"button",
|
|
20502
18850
|
{
|
|
20503
18851
|
className: cn(
|
|
@@ -20514,8 +18862,8 @@ function DataTableHeader({
|
|
|
20514
18862
|
},
|
|
20515
18863
|
"aria-label": "Sort",
|
|
20516
18864
|
title: `Sort by ${String(col.title)}`,
|
|
20517
|
-
children: /* @__PURE__ */
|
|
20518
|
-
/* @__PURE__ */
|
|
18865
|
+
children: /* @__PURE__ */ jsxs52("svg", { viewBox: "0 0 20 20", fill: "none", className: cn("inline-block", sortIconClass), children: [
|
|
18866
|
+
/* @__PURE__ */ jsx61(
|
|
20519
18867
|
"path",
|
|
20520
18868
|
{
|
|
20521
18869
|
d: "M7 8l3-3 3 3",
|
|
@@ -20526,7 +18874,7 @@ function DataTableHeader({
|
|
|
20526
18874
|
opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
|
|
20527
18875
|
}
|
|
20528
18876
|
),
|
|
20529
|
-
/* @__PURE__ */
|
|
18877
|
+
/* @__PURE__ */ jsx61(
|
|
20530
18878
|
"path",
|
|
20531
18879
|
{
|
|
20532
18880
|
d: "M7 12l3 3 3-3",
|
|
@@ -20541,11 +18889,11 @@ function DataTableHeader({
|
|
|
20541
18889
|
}
|
|
20542
18890
|
)
|
|
20543
18891
|
] });
|
|
20544
|
-
const filterContent = col.filter ? /* @__PURE__ */
|
|
18892
|
+
const filterContent = col.filter ? /* @__PURE__ */ jsx61(
|
|
20545
18893
|
Popover,
|
|
20546
18894
|
{
|
|
20547
18895
|
placement: "bottom-start",
|
|
20548
|
-
trigger: /* @__PURE__ */
|
|
18896
|
+
trigger: /* @__PURE__ */ jsx61(
|
|
20549
18897
|
"button",
|
|
20550
18898
|
{
|
|
20551
18899
|
className: cn(
|
|
@@ -20554,13 +18902,13 @@ function DataTableHeader({
|
|
|
20554
18902
|
),
|
|
20555
18903
|
"aria-label": "Filter",
|
|
20556
18904
|
title: `Filter by ${String(col.title)}`,
|
|
20557
|
-
children: /* @__PURE__ */
|
|
18905
|
+
children: /* @__PURE__ */ jsx61(FilterIcon, { className: "w-4 h-4" })
|
|
20558
18906
|
}
|
|
20559
18907
|
),
|
|
20560
|
-
children: /* @__PURE__ */
|
|
20561
|
-
/* @__PURE__ */
|
|
20562
|
-
/* @__PURE__ */
|
|
20563
|
-
filters[col.key] !== void 0 && filters[col.key] !== null && filters[col.key] !== "" && /* @__PURE__ */
|
|
18908
|
+
children: /* @__PURE__ */ jsxs52("div", { className: "p-3 w-64 space-y-3", children: [
|
|
18909
|
+
/* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-between", children: [
|
|
18910
|
+
/* @__PURE__ */ jsx61("div", { className: "text-sm font-medium", children: col.title }),
|
|
18911
|
+
filters[col.key] !== void 0 && filters[col.key] !== null && filters[col.key] !== "" && /* @__PURE__ */ jsx61(
|
|
20564
18912
|
"button",
|
|
20565
18913
|
{
|
|
20566
18914
|
onClick: () => {
|
|
@@ -20576,7 +18924,7 @@ function DataTableHeader({
|
|
|
20576
18924
|
] })
|
|
20577
18925
|
}
|
|
20578
18926
|
) : null;
|
|
20579
|
-
return /* @__PURE__ */
|
|
18927
|
+
return /* @__PURE__ */ jsx61(
|
|
20580
18928
|
"div",
|
|
20581
18929
|
{
|
|
20582
18930
|
className: cn(
|
|
@@ -20586,10 +18934,10 @@ function DataTableHeader({
|
|
|
20586
18934
|
isCenterAlign && "justify-center",
|
|
20587
18935
|
!isRightAlign && !isCenterAlign && "justify-start"
|
|
20588
18936
|
),
|
|
20589
|
-
children: isRightAlign ? /* @__PURE__ */
|
|
18937
|
+
children: isRightAlign ? /* @__PURE__ */ jsxs52(Fragment22, { children: [
|
|
20590
18938
|
filterContent,
|
|
20591
18939
|
titleContent
|
|
20592
|
-
] }) : /* @__PURE__ */
|
|
18940
|
+
] }) : /* @__PURE__ */ jsxs52(Fragment22, { children: [
|
|
20593
18941
|
titleContent,
|
|
20594
18942
|
filterContent
|
|
20595
18943
|
] })
|
|
@@ -20610,13 +18958,13 @@ function DataTableHeader({
|
|
|
20610
18958
|
t
|
|
20611
18959
|
]
|
|
20612
18960
|
);
|
|
20613
|
-
return /* @__PURE__ */
|
|
18961
|
+
return /* @__PURE__ */ jsx61(Fragment22, { children: headerRows.map((row, rowIndex) => /* @__PURE__ */ jsx61(TableRow, { children: row.map((headerCell, cellIndex) => {
|
|
20614
18962
|
const { column: col, colSpan, rowSpan, isLeaf } = headerCell;
|
|
20615
18963
|
const prevCell = cellIndex > 0 ? row[cellIndex - 1] : null;
|
|
20616
18964
|
const prevCol = prevCell?.column;
|
|
20617
18965
|
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
20618
18966
|
const showBorderLeft = columnDividers && cellIndex > 0 && !isAfterFixedLeft && !col.fixed;
|
|
20619
|
-
return /* @__PURE__ */
|
|
18967
|
+
return /* @__PURE__ */ jsx61(
|
|
20620
18968
|
TableHead,
|
|
20621
18969
|
{
|
|
20622
18970
|
colSpan,
|
|
@@ -20639,8 +18987,8 @@ function DataTableHeader({
|
|
|
20639
18987
|
}
|
|
20640
18988
|
|
|
20641
18989
|
// src/components/DataTable/components/Pagination.tsx
|
|
20642
|
-
import
|
|
20643
|
-
import { jsx as
|
|
18990
|
+
import React52 from "react";
|
|
18991
|
+
import { jsx as jsx62, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
20644
18992
|
function DataTablePagination({
|
|
20645
18993
|
totalItems,
|
|
20646
18994
|
curPage,
|
|
@@ -20651,7 +18999,7 @@ function DataTablePagination({
|
|
|
20651
18999
|
size
|
|
20652
19000
|
}) {
|
|
20653
19001
|
const totalPages = Math.ceil(totalItems / curPageSize);
|
|
20654
|
-
const pages =
|
|
19002
|
+
const pages = React52.useMemo(() => {
|
|
20655
19003
|
const result = [];
|
|
20656
19004
|
if (totalPages <= 5) {
|
|
20657
19005
|
for (let i = 1; i <= totalPages; i++) result.push(i);
|
|
@@ -20673,16 +19021,16 @@ function DataTablePagination({
|
|
|
20673
19021
|
const pageBtnClass = size === "sm" ? "h-6 min-w-6 px-1.5 rounded-full text-[11px] font-medium transition-colors" : size === "lg" ? "h-8 min-w-8 px-2.5 rounded-full text-sm font-medium transition-colors" : "h-7 min-w-7 px-2 rounded-full text-xs font-medium transition-colors";
|
|
20674
19022
|
const containerTextClass = size === "sm" ? "text-[11px]" : size === "lg" ? "text-sm" : "text-xs";
|
|
20675
19023
|
const pageSizeClass = size === "sm" ? "w-16" : size === "lg" ? "w-24" : "w-20";
|
|
20676
|
-
return /* @__PURE__ */
|
|
20677
|
-
/* @__PURE__ */
|
|
19024
|
+
return /* @__PURE__ */ jsxs53("div", { className: cn("flex items-center justify-between gap-2 px-1 pt-3 text-muted-foreground", containerTextClass), children: [
|
|
19025
|
+
/* @__PURE__ */ jsxs53("div", { className: "tabular-nums", children: [
|
|
20678
19026
|
(curPage - 1) * curPageSize + 1,
|
|
20679
19027
|
"-",
|
|
20680
19028
|
Math.min(curPage * curPageSize, totalItems),
|
|
20681
19029
|
"/",
|
|
20682
19030
|
totalItems
|
|
20683
19031
|
] }),
|
|
20684
|
-
/* @__PURE__ */
|
|
20685
|
-
/* @__PURE__ */
|
|
19032
|
+
/* @__PURE__ */ jsxs53("div", { className: "flex items-center gap-0.5", children: [
|
|
19033
|
+
/* @__PURE__ */ jsx62(
|
|
20686
19034
|
Button_default,
|
|
20687
19035
|
{
|
|
20688
19036
|
variant: "ghost",
|
|
@@ -20690,11 +19038,11 @@ function DataTablePagination({
|
|
|
20690
19038
|
className: navBtnClass,
|
|
20691
19039
|
onClick: () => setCurPage(Math.max(1, curPage - 1)),
|
|
20692
19040
|
disabled: curPage === 1,
|
|
20693
|
-
children: /* @__PURE__ */
|
|
19041
|
+
children: /* @__PURE__ */ jsx62("svg", { className: navIconClass, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx62("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
20694
19042
|
}
|
|
20695
19043
|
),
|
|
20696
19044
|
pages.map(
|
|
20697
|
-
(p, i) => p === "..." ? /* @__PURE__ */
|
|
19045
|
+
(p, i) => p === "..." ? /* @__PURE__ */ jsx62("span", { className: "px-1 text-muted-foreground/60", children: "\u2026" }, `dots-${i}`) : /* @__PURE__ */ jsx62(
|
|
20698
19046
|
"button",
|
|
20699
19047
|
{
|
|
20700
19048
|
onClick: () => setCurPage(p),
|
|
@@ -20704,7 +19052,7 @@ function DataTablePagination({
|
|
|
20704
19052
|
p
|
|
20705
19053
|
)
|
|
20706
19054
|
),
|
|
20707
|
-
/* @__PURE__ */
|
|
19055
|
+
/* @__PURE__ */ jsx62(
|
|
20708
19056
|
Button_default,
|
|
20709
19057
|
{
|
|
20710
19058
|
variant: "ghost",
|
|
@@ -20712,11 +19060,11 @@ function DataTablePagination({
|
|
|
20712
19060
|
className: navBtnClass,
|
|
20713
19061
|
onClick: () => setCurPage(Math.min(totalPages, curPage + 1)),
|
|
20714
19062
|
disabled: curPage === totalPages,
|
|
20715
|
-
children: /* @__PURE__ */
|
|
19063
|
+
children: /* @__PURE__ */ jsx62("svg", { className: navIconClass, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx62("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
20716
19064
|
}
|
|
20717
19065
|
)
|
|
20718
19066
|
] }),
|
|
20719
|
-
pageSizeOptions && /* @__PURE__ */
|
|
19067
|
+
pageSizeOptions && /* @__PURE__ */ jsx62(
|
|
20720
19068
|
Combobox,
|
|
20721
19069
|
{
|
|
20722
19070
|
options: pageSizeOptions.map(String),
|
|
@@ -20733,7 +19081,7 @@ function DataTablePagination({
|
|
|
20733
19081
|
}
|
|
20734
19082
|
|
|
20735
19083
|
// src/components/DataTable/components/Toolbar.tsx
|
|
20736
|
-
import
|
|
19084
|
+
import React53 from "react";
|
|
20737
19085
|
|
|
20738
19086
|
// src/components/DataTable/utils/headers.ts
|
|
20739
19087
|
function isLeafColumn(col) {
|
|
@@ -20833,7 +19181,7 @@ function getLeafColumnsWithFixedInheritance(columns, inheritedFixed) {
|
|
|
20833
19181
|
}
|
|
20834
19182
|
|
|
20835
19183
|
// src/components/DataTable/components/Toolbar.tsx
|
|
20836
|
-
import { jsx as
|
|
19184
|
+
import { jsx as jsx63, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
20837
19185
|
function DataTableToolbar({
|
|
20838
19186
|
caption,
|
|
20839
19187
|
toolbar,
|
|
@@ -20854,15 +19202,15 @@ function DataTableToolbar({
|
|
|
20854
19202
|
const controlButtonClass = size === "sm" ? "h-7 px-2 text-xs" : size === "lg" ? "h-9 px-3 text-sm" : "h-8 px-2";
|
|
20855
19203
|
const iconClass = size === "sm" ? "w-3.5 h-3.5 mr-1" : "w-4 h-4 mr-1";
|
|
20856
19204
|
const captionClass = size === "sm" ? "text-xs" : size === "lg" ? "text-sm" : "text-sm";
|
|
20857
|
-
const leafCols =
|
|
20858
|
-
return /* @__PURE__ */
|
|
20859
|
-
/* @__PURE__ */
|
|
20860
|
-
/* @__PURE__ */
|
|
20861
|
-
enableDensityToggle && /* @__PURE__ */
|
|
19205
|
+
const leafCols = React53.useMemo(() => getLeafColumns(columns), [columns]);
|
|
19206
|
+
return /* @__PURE__ */ jsxs54("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
|
|
19207
|
+
/* @__PURE__ */ jsx63("div", { className: captionClass + " text-muted-foreground", children: caption }),
|
|
19208
|
+
/* @__PURE__ */ jsxs54("div", { className: "flex items-center gap-2", children: [
|
|
19209
|
+
enableDensityToggle && /* @__PURE__ */ jsx63(
|
|
20862
19210
|
DropdownMenu_default,
|
|
20863
19211
|
{
|
|
20864
|
-
trigger: /* @__PURE__ */
|
|
20865
|
-
/* @__PURE__ */
|
|
19212
|
+
trigger: /* @__PURE__ */ jsxs54(Button_default, { variant: "ghost", size: controlButtonSize, className: controlButtonClass, children: [
|
|
19213
|
+
/* @__PURE__ */ jsx63("svg", { className: iconClass, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx63("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
|
|
20866
19214
|
labels?.density || t("density")
|
|
20867
19215
|
] }),
|
|
20868
19216
|
items: [
|
|
@@ -20872,11 +19220,11 @@ function DataTableToolbar({
|
|
|
20872
19220
|
]
|
|
20873
19221
|
}
|
|
20874
19222
|
),
|
|
20875
|
-
enableColumnVisibilityToggle && /* @__PURE__ */
|
|
19223
|
+
enableColumnVisibilityToggle && /* @__PURE__ */ jsx63(
|
|
20876
19224
|
DropdownMenu_default,
|
|
20877
19225
|
{
|
|
20878
|
-
trigger: /* @__PURE__ */
|
|
20879
|
-
/* @__PURE__ */
|
|
19226
|
+
trigger: /* @__PURE__ */ jsxs54(Button_default, { variant: "ghost", size: controlButtonSize, className: controlButtonClass, children: [
|
|
19227
|
+
/* @__PURE__ */ jsx63("svg", { className: iconClass, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx63(
|
|
20880
19228
|
"path",
|
|
20881
19229
|
{
|
|
20882
19230
|
strokeLinecap: "round",
|
|
@@ -20887,26 +19235,26 @@ function DataTableToolbar({
|
|
|
20887
19235
|
) }),
|
|
20888
19236
|
labels?.columns || t("columns")
|
|
20889
19237
|
] }),
|
|
20890
|
-
children: leafCols.map((c) => /* @__PURE__ */
|
|
19238
|
+
children: leafCols.map((c) => /* @__PURE__ */ jsxs54(
|
|
20891
19239
|
DropdownMenuItem,
|
|
20892
19240
|
{
|
|
20893
19241
|
onClick: () => {
|
|
20894
19242
|
setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
|
|
20895
19243
|
},
|
|
20896
19244
|
children: [
|
|
20897
|
-
/* @__PURE__ */
|
|
20898
|
-
/* @__PURE__ */
|
|
19245
|
+
/* @__PURE__ */ jsx63("input", { type: "checkbox", className: "mr-2 rounded-md border-border/50", readOnly: true, checked: visibleCols.includes(c.key) }),
|
|
19246
|
+
/* @__PURE__ */ jsx63("span", { className: "truncate", children: c.title })
|
|
20899
19247
|
]
|
|
20900
19248
|
},
|
|
20901
19249
|
c.key
|
|
20902
19250
|
))
|
|
20903
19251
|
}
|
|
20904
19252
|
),
|
|
20905
|
-
enableHeaderAlignToggle && /* @__PURE__ */
|
|
19253
|
+
enableHeaderAlignToggle && /* @__PURE__ */ jsx63(
|
|
20906
19254
|
DropdownMenu_default,
|
|
20907
19255
|
{
|
|
20908
|
-
trigger: /* @__PURE__ */
|
|
20909
|
-
/* @__PURE__ */
|
|
19256
|
+
trigger: /* @__PURE__ */ jsxs54(Button_default, { variant: "ghost", size: controlButtonSize, className: controlButtonClass, children: [
|
|
19257
|
+
/* @__PURE__ */ jsx63("svg", { className: iconClass, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx63("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h10M4 18h16" }) }),
|
|
20910
19258
|
labels?.headerAlign || t("headerAlign")
|
|
20911
19259
|
] }),
|
|
20912
19260
|
items: [
|
|
@@ -20922,10 +19270,10 @@ function DataTableToolbar({
|
|
|
20922
19270
|
}
|
|
20923
19271
|
|
|
20924
19272
|
// src/components/DataTable/hooks/useDebounced.ts
|
|
20925
|
-
import
|
|
19273
|
+
import React54 from "react";
|
|
20926
19274
|
function useDebounced(value, delay = 300) {
|
|
20927
|
-
const [debounced, setDebounced] =
|
|
20928
|
-
|
|
19275
|
+
const [debounced, setDebounced] = React54.useState(value);
|
|
19276
|
+
React54.useEffect(() => {
|
|
20929
19277
|
const id = setTimeout(() => setDebounced(value), delay);
|
|
20930
19278
|
return () => clearTimeout(id);
|
|
20931
19279
|
}, [value, delay]);
|
|
@@ -20933,7 +19281,7 @@ function useDebounced(value, delay = 300) {
|
|
|
20933
19281
|
}
|
|
20934
19282
|
|
|
20935
19283
|
// src/components/DataTable/hooks/useDataTableModel.ts
|
|
20936
|
-
import
|
|
19284
|
+
import React55 from "react";
|
|
20937
19285
|
|
|
20938
19286
|
// src/components/DataTable/utils/columns.ts
|
|
20939
19287
|
function getColumnWidth(col, fallback = 150) {
|
|
@@ -20961,22 +19309,22 @@ function useDataTableModel({
|
|
|
20961
19309
|
isServerMode,
|
|
20962
19310
|
total
|
|
20963
19311
|
}) {
|
|
20964
|
-
const visibleColsSet =
|
|
20965
|
-
const allLeafColumns =
|
|
20966
|
-
const columnMap =
|
|
19312
|
+
const visibleColsSet = React55.useMemo(() => new Set(visibleCols), [visibleCols]);
|
|
19313
|
+
const allLeafColumns = React55.useMemo(() => getLeafColumns(columns), [columns]);
|
|
19314
|
+
const columnMap = React55.useMemo(() => {
|
|
20967
19315
|
return new Map(allLeafColumns.map((column) => [column.key, column]));
|
|
20968
19316
|
}, [allLeafColumns]);
|
|
20969
|
-
const visibleColumns =
|
|
19317
|
+
const visibleColumns = React55.useMemo(() => {
|
|
20970
19318
|
return filterVisibleColumns(columns, visibleColsSet);
|
|
20971
19319
|
}, [columns, visibleColsSet]);
|
|
20972
|
-
const leafColumns =
|
|
19320
|
+
const leafColumns = React55.useMemo(() => {
|
|
20973
19321
|
return getLeafColumnsWithFixedInheritance(visibleColumns);
|
|
20974
19322
|
}, [visibleColumns]);
|
|
20975
|
-
const headerRows =
|
|
20976
|
-
const totalColumnsWidth =
|
|
19323
|
+
const headerRows = React55.useMemo(() => buildHeaderRows(visibleColumns), [visibleColumns]);
|
|
19324
|
+
const totalColumnsWidth = React55.useMemo(() => {
|
|
20977
19325
|
return leafColumns.reduce((sum, column) => sum + getColumnWidth(column), 0);
|
|
20978
19326
|
}, [leafColumns]);
|
|
20979
|
-
const processedData =
|
|
19327
|
+
const processedData = React55.useMemo(() => {
|
|
20980
19328
|
if (isServerMode) return data;
|
|
20981
19329
|
let result = [...data];
|
|
20982
19330
|
if (Object.keys(filters).length > 0) {
|
|
@@ -21008,7 +19356,7 @@ function useDataTableModel({
|
|
|
21008
19356
|
return result;
|
|
21009
19357
|
}, [columnMap, data, filters, isServerMode, sort]);
|
|
21010
19358
|
const totalItems = isServerMode ? total : processedData.length;
|
|
21011
|
-
const displayedData =
|
|
19359
|
+
const displayedData = React55.useMemo(() => {
|
|
21012
19360
|
if (isServerMode) return data;
|
|
21013
19361
|
const start = (curPage - 1) * curPageSize;
|
|
21014
19362
|
return processedData.slice(start, start + curPageSize);
|
|
@@ -21024,13 +19372,13 @@ function useDataTableModel({
|
|
|
21024
19372
|
}
|
|
21025
19373
|
|
|
21026
19374
|
// src/components/DataTable/hooks/useDataTableState.ts
|
|
21027
|
-
import
|
|
19375
|
+
import React57 from "react";
|
|
21028
19376
|
|
|
21029
19377
|
// src/components/DataTable/hooks/usePageSizeStorage.ts
|
|
21030
|
-
import
|
|
19378
|
+
import React56 from "react";
|
|
21031
19379
|
function usePageSizeStorage({ pageSize, storageKey }) {
|
|
21032
|
-
const loadedFromStorage =
|
|
21033
|
-
const [curPageSize, setCurPageSize] =
|
|
19380
|
+
const loadedFromStorage = React56.useRef(false);
|
|
19381
|
+
const [curPageSize, setCurPageSize] = React56.useState(() => {
|
|
21034
19382
|
if (typeof window === "undefined" || !storageKey) return pageSize;
|
|
21035
19383
|
try {
|
|
21036
19384
|
const saved = localStorage.getItem(`datatable_${storageKey}_pageSize`);
|
|
@@ -21045,11 +19393,11 @@ function usePageSizeStorage({ pageSize, storageKey }) {
|
|
|
21045
19393
|
}
|
|
21046
19394
|
return pageSize;
|
|
21047
19395
|
});
|
|
21048
|
-
const hasMounted =
|
|
21049
|
-
|
|
19396
|
+
const hasMounted = React56.useRef(false);
|
|
19397
|
+
React56.useEffect(() => {
|
|
21050
19398
|
hasMounted.current = true;
|
|
21051
19399
|
}, []);
|
|
21052
|
-
|
|
19400
|
+
React56.useEffect(() => {
|
|
21053
19401
|
if (typeof window === "undefined" || !storageKey) return;
|
|
21054
19402
|
if (!hasMounted.current) return;
|
|
21055
19403
|
try {
|
|
@@ -21057,7 +19405,7 @@ function usePageSizeStorage({ pageSize, storageKey }) {
|
|
|
21057
19405
|
} catch {
|
|
21058
19406
|
}
|
|
21059
19407
|
}, [curPageSize, storageKey]);
|
|
21060
|
-
|
|
19408
|
+
React56.useEffect(() => {
|
|
21061
19409
|
if (storageKey && loadedFromStorage.current) return;
|
|
21062
19410
|
setCurPageSize(pageSize);
|
|
21063
19411
|
}, [pageSize, storageKey]);
|
|
@@ -21077,17 +19425,17 @@ function useDataTableState({
|
|
|
21077
19425
|
size,
|
|
21078
19426
|
storageKey
|
|
21079
19427
|
}) {
|
|
21080
|
-
const allLeafColumns =
|
|
21081
|
-
const defaultVisibleLeafKeys =
|
|
21082
|
-
const knownLeafKeysRef =
|
|
21083
|
-
const [headerAlign, setHeaderAlign] =
|
|
21084
|
-
const [visibleCols, setVisibleCols] =
|
|
21085
|
-
const [filters, setFilters] =
|
|
21086
|
-
const [sort, setSort] =
|
|
21087
|
-
const [density, setDensity] =
|
|
21088
|
-
const [curPage, setCurPage] =
|
|
19428
|
+
const allLeafColumns = React57.useMemo(() => getLeafColumns(columns), [columns]);
|
|
19429
|
+
const defaultVisibleLeafKeys = React57.useMemo(() => allLeafColumns.filter((column) => column.visible !== false).map((column) => column.key), [allLeafColumns]);
|
|
19430
|
+
const knownLeafKeysRef = React57.useRef(new Set(defaultVisibleLeafKeys));
|
|
19431
|
+
const [headerAlign, setHeaderAlign] = React57.useState("left");
|
|
19432
|
+
const [visibleCols, setVisibleCols] = React57.useState(defaultVisibleLeafKeys);
|
|
19433
|
+
const [filters, setFilters] = React57.useState({});
|
|
19434
|
+
const [sort, setSort] = React57.useState(null);
|
|
19435
|
+
const [density, setDensity] = React57.useState(() => SIZE_TO_DENSITY[size]);
|
|
19436
|
+
const [curPage, setCurPage] = React57.useState(page);
|
|
21089
19437
|
const { curPageSize, setCurPageSize } = usePageSizeStorage({ pageSize, storageKey });
|
|
21090
|
-
|
|
19438
|
+
React57.useEffect(() => {
|
|
21091
19439
|
const knownLeafKeys = knownLeafKeysRef.current;
|
|
21092
19440
|
setVisibleCols((prev) => {
|
|
21093
19441
|
const prevSet = new Set(prev);
|
|
@@ -21095,10 +19443,10 @@ function useDataTableState({
|
|
|
21095
19443
|
});
|
|
21096
19444
|
knownLeafKeysRef.current = new Set(allLeafColumns.map((column) => column.key));
|
|
21097
19445
|
}, [allLeafColumns]);
|
|
21098
|
-
|
|
19446
|
+
React57.useEffect(() => {
|
|
21099
19447
|
setCurPage(page);
|
|
21100
19448
|
}, [page]);
|
|
21101
|
-
|
|
19449
|
+
React57.useEffect(() => {
|
|
21102
19450
|
setDensity(SIZE_TO_DENSITY[size]);
|
|
21103
19451
|
}, [size]);
|
|
21104
19452
|
return {
|
|
@@ -21120,7 +19468,7 @@ function useDataTableState({
|
|
|
21120
19468
|
}
|
|
21121
19469
|
|
|
21122
19470
|
// src/components/DataTable/hooks/useStickyColumns.ts
|
|
21123
|
-
import
|
|
19471
|
+
import React58 from "react";
|
|
21124
19472
|
|
|
21125
19473
|
// src/components/DataTable/utils/sticky.ts
|
|
21126
19474
|
function buildStickyLayout(visibleColumns) {
|
|
@@ -21167,8 +19515,8 @@ function resolveGroupStickyPosition(column, positions) {
|
|
|
21167
19515
|
|
|
21168
19516
|
// src/components/DataTable/hooks/useStickyColumns.ts
|
|
21169
19517
|
function useStickyColumns(visibleColumns) {
|
|
21170
|
-
const { positions, leftBoundaryKey, rightBoundaryKey } =
|
|
21171
|
-
const getStickyColumnStyle =
|
|
19518
|
+
const { positions, leftBoundaryKey, rightBoundaryKey } = React58.useMemo(() => buildStickyLayout(visibleColumns), [visibleColumns]);
|
|
19519
|
+
const getStickyColumnStyle = React58.useCallback(
|
|
21172
19520
|
(col) => {
|
|
21173
19521
|
const pos = resolveStickyPosition(col, positions);
|
|
21174
19522
|
if (!pos) return {};
|
|
@@ -21179,7 +19527,7 @@ function useStickyColumns(visibleColumns) {
|
|
|
21179
19527
|
},
|
|
21180
19528
|
[positions]
|
|
21181
19529
|
);
|
|
21182
|
-
const getBoundaryShadowClass =
|
|
19530
|
+
const getBoundaryShadowClass = React58.useCallback(
|
|
21183
19531
|
(col) => {
|
|
21184
19532
|
if (col.fixed === "left" && col.key === leftBoundaryKey) {
|
|
21185
19533
|
return "border-r border-border/80 shadow-[10px_0_16px_-10px_rgba(0,0,0,0.55)]";
|
|
@@ -21191,14 +19539,14 @@ function useStickyColumns(visibleColumns) {
|
|
|
21191
19539
|
},
|
|
21192
19540
|
[leftBoundaryKey, rightBoundaryKey]
|
|
21193
19541
|
);
|
|
21194
|
-
const getStickyHeaderClass =
|
|
19542
|
+
const getStickyHeaderClass = React58.useCallback(
|
|
21195
19543
|
(col) => {
|
|
21196
19544
|
if (!col.fixed) return "";
|
|
21197
19545
|
return cn("sticky", col.fixed === "left" && "left-0", col.fixed === "right" && "right-0", getBoundaryShadowClass(col), "z-50 !bg-muted");
|
|
21198
19546
|
},
|
|
21199
19547
|
[getBoundaryShadowClass]
|
|
21200
19548
|
);
|
|
21201
|
-
const getStickyCellClass =
|
|
19549
|
+
const getStickyCellClass = React58.useCallback(
|
|
21202
19550
|
(col, isStripedRow) => {
|
|
21203
19551
|
if (!col.fixed) return "";
|
|
21204
19552
|
return cn(
|
|
@@ -21211,7 +19559,7 @@ function useStickyColumns(visibleColumns) {
|
|
|
21211
19559
|
},
|
|
21212
19560
|
[getBoundaryShadowClass]
|
|
21213
19561
|
);
|
|
21214
|
-
const getStickyHeaderCellStyle =
|
|
19562
|
+
const getStickyHeaderCellStyle = React58.useCallback(
|
|
21215
19563
|
(headerCell) => {
|
|
21216
19564
|
const col = headerCell.column;
|
|
21217
19565
|
if (headerCell.isLeaf) {
|
|
@@ -21309,7 +19657,7 @@ function validateColumns(columns) {
|
|
|
21309
19657
|
}
|
|
21310
19658
|
|
|
21311
19659
|
// src/components/DataTable/DataTable.tsx
|
|
21312
|
-
import { jsx as
|
|
19660
|
+
import { jsx as jsx64, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
21313
19661
|
function DataTable({
|
|
21314
19662
|
columns,
|
|
21315
19663
|
data,
|
|
@@ -21358,7 +19706,7 @@ function DataTable({
|
|
|
21358
19706
|
size,
|
|
21359
19707
|
storageKey
|
|
21360
19708
|
});
|
|
21361
|
-
|
|
19709
|
+
React59.useEffect(() => {
|
|
21362
19710
|
if (process.env.NODE_ENV === "development") {
|
|
21363
19711
|
const warnings = validateColumns(columns);
|
|
21364
19712
|
warnings.forEach((w) => console.warn(`[DataTable] ${w}`));
|
|
@@ -21366,8 +19714,8 @@ function DataTable({
|
|
|
21366
19714
|
}, [columns]);
|
|
21367
19715
|
const debouncedFilters = useDebounced(filters, 350);
|
|
21368
19716
|
const isServerMode = Boolean(onQueryChange);
|
|
21369
|
-
const hasEmittedQuery =
|
|
21370
|
-
|
|
19717
|
+
const hasEmittedQuery = React59.useRef(false);
|
|
19718
|
+
React59.useEffect(() => {
|
|
21371
19719
|
if (!onQueryChange) return;
|
|
21372
19720
|
if (!hasEmittedQuery.current) {
|
|
21373
19721
|
hasEmittedQuery.current = true;
|
|
@@ -21375,7 +19723,7 @@ function DataTable({
|
|
|
21375
19723
|
}
|
|
21376
19724
|
onQueryChange({ filters: debouncedFilters, sort, page: curPage, pageSize: curPageSize });
|
|
21377
19725
|
}, [debouncedFilters, sort, curPage, curPageSize, onQueryChange]);
|
|
21378
|
-
|
|
19726
|
+
React59.useEffect(() => {
|
|
21379
19727
|
if (process.env.NODE_ENV !== "development" || rowKey) return;
|
|
21380
19728
|
const hasQueryFeatures = columns.some((column) => column.sortable || column.filter) || Boolean(pageSizeOptions?.length) || isServerMode;
|
|
21381
19729
|
if (!hasQueryFeatures) return;
|
|
@@ -21403,10 +19751,10 @@ function DataTable({
|
|
|
21403
19751
|
if (typeof rowKey === "function") return String(rowKey(row));
|
|
21404
19752
|
return String(row[rowKey]);
|
|
21405
19753
|
};
|
|
21406
|
-
const viewportRef =
|
|
19754
|
+
const viewportRef = React59.useRef(null);
|
|
21407
19755
|
useOverlayScrollbarTarget(viewportRef, { enabled: useOverlayScrollbar });
|
|
21408
|
-
return /* @__PURE__ */
|
|
21409
|
-
/* @__PURE__ */
|
|
19756
|
+
return /* @__PURE__ */ jsxs55("div", { className: cn("space-y-2", className), children: [
|
|
19757
|
+
/* @__PURE__ */ jsx64(
|
|
21410
19758
|
DataTableToolbar,
|
|
21411
19759
|
{
|
|
21412
19760
|
caption,
|
|
@@ -21425,20 +19773,20 @@ function DataTable({
|
|
|
21425
19773
|
t
|
|
21426
19774
|
}
|
|
21427
19775
|
),
|
|
21428
|
-
/* @__PURE__ */
|
|
19776
|
+
/* @__PURE__ */ jsx64(
|
|
21429
19777
|
"div",
|
|
21430
19778
|
{
|
|
21431
19779
|
className: cn(
|
|
21432
19780
|
"relative rounded-2xl md:rounded-3xl border border-border/50 bg-card overflow-hidden",
|
|
21433
19781
|
loading2 && "opacity-60 pointer-events-none"
|
|
21434
19782
|
),
|
|
21435
|
-
children: /* @__PURE__ */
|
|
19783
|
+
children: /* @__PURE__ */ jsx64(
|
|
21436
19784
|
"div",
|
|
21437
19785
|
{
|
|
21438
19786
|
ref: viewportRef,
|
|
21439
19787
|
className: cn("w-full overflow-x-auto", stickyHeader && "overflow-y-auto"),
|
|
21440
19788
|
style: stickyHeader ? { maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight } : void 0,
|
|
21441
|
-
children: /* @__PURE__ */
|
|
19789
|
+
children: /* @__PURE__ */ jsxs55(
|
|
21442
19790
|
Table,
|
|
21443
19791
|
{
|
|
21444
19792
|
disableContainer: true,
|
|
@@ -21448,7 +19796,7 @@ function DataTable({
|
|
|
21448
19796
|
),
|
|
21449
19797
|
style: { minWidth: totalColumnsWidth > 0 ? `${totalColumnsWidth}px` : void 0 },
|
|
21450
19798
|
children: [
|
|
21451
|
-
/* @__PURE__ */
|
|
19799
|
+
/* @__PURE__ */ jsx64(TableHeader, { children: /* @__PURE__ */ jsx64(
|
|
21452
19800
|
DataTableHeader,
|
|
21453
19801
|
{
|
|
21454
19802
|
headerRows,
|
|
@@ -21468,7 +19816,7 @@ function DataTable({
|
|
|
21468
19816
|
t
|
|
21469
19817
|
}
|
|
21470
19818
|
) }),
|
|
21471
|
-
/* @__PURE__ */
|
|
19819
|
+
/* @__PURE__ */ jsx64(
|
|
21472
19820
|
DataTableBodyRows,
|
|
21473
19821
|
{
|
|
21474
19822
|
leafColumns,
|
|
@@ -21492,7 +19840,7 @@ function DataTable({
|
|
|
21492
19840
|
)
|
|
21493
19841
|
}
|
|
21494
19842
|
),
|
|
21495
|
-
/* @__PURE__ */
|
|
19843
|
+
/* @__PURE__ */ jsx64(
|
|
21496
19844
|
DataTablePagination,
|
|
21497
19845
|
{
|
|
21498
19846
|
totalItems,
|
|
@@ -21509,10 +19857,10 @@ function DataTable({
|
|
|
21509
19857
|
var DataTable_default = DataTable;
|
|
21510
19858
|
|
|
21511
19859
|
// src/components/Form.tsx
|
|
21512
|
-
import * as
|
|
19860
|
+
import * as React60 from "react";
|
|
21513
19861
|
import { Controller, FormProvider, useFormContext, useForm } from "react-hook-form";
|
|
21514
|
-
import { jsx as
|
|
21515
|
-
var FormConfigContext =
|
|
19862
|
+
import { jsx as jsx65, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
19863
|
+
var FormConfigContext = React60.createContext({ size: "md" });
|
|
21516
19864
|
var FormWrapper = ({
|
|
21517
19865
|
children,
|
|
21518
19866
|
onSubmit,
|
|
@@ -21525,24 +19873,24 @@ var FormWrapper = ({
|
|
|
21525
19873
|
const methods = useForm({
|
|
21526
19874
|
defaultValues: initialValues
|
|
21527
19875
|
});
|
|
21528
|
-
|
|
19876
|
+
React60.useEffect(() => {
|
|
21529
19877
|
if (initialValues) {
|
|
21530
19878
|
methods.reset(initialValues);
|
|
21531
19879
|
}
|
|
21532
19880
|
}, [JSON.stringify(initialValues)]);
|
|
21533
19881
|
const { validationSchema: _, ...formProps } = props;
|
|
21534
|
-
return /* @__PURE__ */
|
|
19882
|
+
return /* @__PURE__ */ jsx65(FormProvider, { ...methods, children: /* @__PURE__ */ jsx65(FormConfigContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx65("form", { onSubmit: methods.handleSubmit(onSubmit), className, ...formProps, children }) }) });
|
|
21535
19883
|
};
|
|
21536
19884
|
var Form = FormWrapper;
|
|
21537
|
-
var FormFieldContext =
|
|
19885
|
+
var FormFieldContext = React60.createContext({});
|
|
21538
19886
|
var FormField = ({
|
|
21539
19887
|
...props
|
|
21540
19888
|
}) => {
|
|
21541
|
-
return /* @__PURE__ */
|
|
19889
|
+
return /* @__PURE__ */ jsx65(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx65(Controller, { ...props }) });
|
|
21542
19890
|
};
|
|
21543
19891
|
var useFormField = () => {
|
|
21544
|
-
const fieldContext =
|
|
21545
|
-
const itemContext =
|
|
19892
|
+
const fieldContext = React60.useContext(FormFieldContext);
|
|
19893
|
+
const itemContext = React60.useContext(FormItemContext);
|
|
21546
19894
|
const { getFieldState, formState } = useFormContext();
|
|
21547
19895
|
if (!fieldContext) {
|
|
21548
19896
|
throw new Error("useFormField must be used within FormField");
|
|
@@ -21558,27 +19906,27 @@ var useFormField = () => {
|
|
|
21558
19906
|
...fieldState
|
|
21559
19907
|
};
|
|
21560
19908
|
};
|
|
21561
|
-
var FormItemContext =
|
|
21562
|
-
var FormItem =
|
|
21563
|
-
const id =
|
|
21564
|
-
return /* @__PURE__ */
|
|
19909
|
+
var FormItemContext = React60.createContext({});
|
|
19910
|
+
var FormItem = React60.forwardRef(({ className, ...props }, ref) => {
|
|
19911
|
+
const id = React60.useId();
|
|
19912
|
+
return /* @__PURE__ */ jsx65(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx65("div", { ref, className: cn("space-y-2", className), ...props }) });
|
|
21565
19913
|
});
|
|
21566
19914
|
FormItem.displayName = "FormItem";
|
|
21567
|
-
var FormLabel =
|
|
19915
|
+
var FormLabel = React60.forwardRef(
|
|
21568
19916
|
({ className, children, required, ...props }, ref) => {
|
|
21569
19917
|
const { error, formItemId } = useFormField();
|
|
21570
|
-
const config =
|
|
19918
|
+
const config = React60.useContext(FormConfigContext);
|
|
21571
19919
|
const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
|
|
21572
|
-
return /* @__PURE__ */
|
|
19920
|
+
return /* @__PURE__ */ jsxs56(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props, children: [
|
|
21573
19921
|
children,
|
|
21574
|
-
required && /* @__PURE__ */
|
|
19922
|
+
required && /* @__PURE__ */ jsx65("span", { className: "text-destructive ml-1", children: "*" })
|
|
21575
19923
|
] });
|
|
21576
19924
|
}
|
|
21577
19925
|
);
|
|
21578
19926
|
FormLabel.displayName = "FormLabel";
|
|
21579
|
-
var FormControl =
|
|
19927
|
+
var FormControl = React60.forwardRef(({ ...props }, ref) => {
|
|
21580
19928
|
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
21581
|
-
return /* @__PURE__ */
|
|
19929
|
+
return /* @__PURE__ */ jsx65(
|
|
21582
19930
|
"div",
|
|
21583
19931
|
{
|
|
21584
19932
|
ref,
|
|
@@ -21590,37 +19938,37 @@ var FormControl = React69.forwardRef(({ ...props }, ref) => {
|
|
|
21590
19938
|
);
|
|
21591
19939
|
});
|
|
21592
19940
|
FormControl.displayName = "FormControl";
|
|
21593
|
-
var FormDescription =
|
|
19941
|
+
var FormDescription = React60.forwardRef(({ className, ...props }, ref) => {
|
|
21594
19942
|
const { formDescriptionId } = useFormField();
|
|
21595
|
-
return /* @__PURE__ */
|
|
19943
|
+
return /* @__PURE__ */ jsx65("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
|
|
21596
19944
|
});
|
|
21597
19945
|
FormDescription.displayName = "FormDescription";
|
|
21598
|
-
var FormMessage =
|
|
19946
|
+
var FormMessage = React60.forwardRef(({ className, children, ...props }, ref) => {
|
|
21599
19947
|
const { error, formMessageId } = useFormField();
|
|
21600
19948
|
const body = error ? String(error?.message) : children;
|
|
21601
19949
|
if (!body) {
|
|
21602
19950
|
return null;
|
|
21603
19951
|
}
|
|
21604
|
-
return /* @__PURE__ */
|
|
19952
|
+
return /* @__PURE__ */ jsx65("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
|
|
21605
19953
|
});
|
|
21606
19954
|
FormMessage.displayName = "FormMessage";
|
|
21607
|
-
var FormInput =
|
|
19955
|
+
var FormInput = React60.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ jsx65(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx65(
|
|
21608
19956
|
FormField,
|
|
21609
19957
|
{
|
|
21610
19958
|
name,
|
|
21611
|
-
render: ({ field }) => /* @__PURE__ */
|
|
21612
|
-
/* @__PURE__ */
|
|
21613
|
-
/* @__PURE__ */
|
|
19959
|
+
render: ({ field }) => /* @__PURE__ */ jsxs56(FormItem, { children: [
|
|
19960
|
+
/* @__PURE__ */ jsx65(FormControl, { children: /* @__PURE__ */ jsx65(Input_default, { size: props.size ?? size, ...field, ...props }) }),
|
|
19961
|
+
/* @__PURE__ */ jsx65(FormMessage, {})
|
|
21614
19962
|
] })
|
|
21615
19963
|
}
|
|
21616
19964
|
) }));
|
|
21617
19965
|
FormInput.displayName = "FormInput";
|
|
21618
|
-
var FormCheckbox =
|
|
19966
|
+
var FormCheckbox = React60.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ jsx65(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx65(
|
|
21619
19967
|
FormField,
|
|
21620
19968
|
{
|
|
21621
19969
|
name,
|
|
21622
|
-
render: ({ field }) => /* @__PURE__ */
|
|
21623
|
-
/* @__PURE__ */
|
|
19970
|
+
render: ({ field }) => /* @__PURE__ */ jsxs56(FormItem, { children: [
|
|
19971
|
+
/* @__PURE__ */ jsx65(FormControl, { children: /* @__PURE__ */ jsx65(
|
|
21624
19972
|
Checkbox,
|
|
21625
19973
|
{
|
|
21626
19974
|
ref,
|
|
@@ -21634,21 +19982,21 @@ var FormCheckbox = React69.forwardRef(({ name, ...props }, ref) => /* @__PURE__
|
|
|
21634
19982
|
...props
|
|
21635
19983
|
}
|
|
21636
19984
|
) }),
|
|
21637
|
-
/* @__PURE__ */
|
|
19985
|
+
/* @__PURE__ */ jsx65(FormMessage, {})
|
|
21638
19986
|
] })
|
|
21639
19987
|
}
|
|
21640
19988
|
) }));
|
|
21641
19989
|
FormCheckbox.displayName = "FormCheckbox";
|
|
21642
|
-
var FormActions =
|
|
19990
|
+
var FormActions = React60.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx65("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
|
|
21643
19991
|
FormActions.displayName = "FormActions";
|
|
21644
|
-
var FormSubmitButton =
|
|
21645
|
-
({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */
|
|
19992
|
+
var FormSubmitButton = React60.forwardRef(
|
|
19993
|
+
({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */ jsx65(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ jsx65(Button_default, { ref, type: "submit", size: props.size ?? size, disabled: loading2, ...props, children }) })
|
|
21646
19994
|
);
|
|
21647
19995
|
FormSubmitButton.displayName = "FormSubmitButton";
|
|
21648
19996
|
|
|
21649
19997
|
// src/components/NotificationModal.tsx
|
|
21650
19998
|
import { ExternalLink } from "lucide-react";
|
|
21651
|
-
import { jsx as
|
|
19999
|
+
import { jsx as jsx66, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
21652
20000
|
function NotificationModal({ isOpen, onClose, notification, titleText, openLinkText, closeText }) {
|
|
21653
20001
|
const t = useSmartTranslations("Common");
|
|
21654
20002
|
if (!notification) return null;
|
|
@@ -21669,20 +20017,20 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
|
|
|
21669
20017
|
onClose();
|
|
21670
20018
|
}
|
|
21671
20019
|
};
|
|
21672
|
-
return /* @__PURE__ */
|
|
21673
|
-
/* @__PURE__ */
|
|
21674
|
-
/* @__PURE__ */
|
|
21675
|
-
/* @__PURE__ */
|
|
20020
|
+
return /* @__PURE__ */ jsx66(Modal_default, { isOpen, onClose, title: titleText || t("notifications"), size: "md", children: /* @__PURE__ */ jsxs57("div", { className: "space-y-4", children: [
|
|
20021
|
+
/* @__PURE__ */ jsxs57("div", { className: "flex items-center gap-2 pb-2 border-b border-border/50", children: [
|
|
20022
|
+
/* @__PURE__ */ jsx66("div", { className: cn("w-2 h-2 rounded-full", !notification.is_read ? "bg-primary" : "bg-border") }),
|
|
20023
|
+
/* @__PURE__ */ jsx66("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
|
|
21676
20024
|
] }),
|
|
21677
|
-
notification.title && /* @__PURE__ */
|
|
21678
|
-
notification.body && /* @__PURE__ */
|
|
21679
|
-
/* @__PURE__ */
|
|
21680
|
-
/* @__PURE__ */
|
|
21681
|
-
hasLink && /* @__PURE__ */
|
|
21682
|
-
/* @__PURE__ */
|
|
20025
|
+
notification.title && /* @__PURE__ */ jsx66("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
|
|
20026
|
+
notification.body && /* @__PURE__ */ jsx66("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
|
|
20027
|
+
/* @__PURE__ */ jsx66("div", { className: "text-xs text-muted-foreground border-t border-border/50 pt-2", children: formatTime3(notification.created_at) }),
|
|
20028
|
+
/* @__PURE__ */ jsxs57("div", { className: "flex gap-2 justify-end pt-2", children: [
|
|
20029
|
+
hasLink && /* @__PURE__ */ jsxs57(Button_default, { variant: "primary", size: "sm", onClick: handleLinkClick, className: "gap-2", children: [
|
|
20030
|
+
/* @__PURE__ */ jsx66(ExternalLink, { className: "w-4 h-4" }),
|
|
21683
20031
|
openLinkText || t("openLink")
|
|
21684
20032
|
] }),
|
|
21685
|
-
/* @__PURE__ */
|
|
20033
|
+
/* @__PURE__ */ jsx66(Button_default, { variant: "ghost", size: "sm", onClick: onClose, children: closeText || t("close") })
|
|
21686
20034
|
] })
|
|
21687
20035
|
] }) });
|
|
21688
20036
|
}
|
|
@@ -21690,7 +20038,7 @@ var NotificationModal_default = NotificationModal;
|
|
|
21690
20038
|
|
|
21691
20039
|
// src/components/AccessDenied.tsx
|
|
21692
20040
|
import { Ban, Lock, ShieldAlert } from "lucide-react";
|
|
21693
|
-
import { jsx as
|
|
20041
|
+
import { jsx as jsx67, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
21694
20042
|
var VARIANT_STYLES = {
|
|
21695
20043
|
destructive: { bg: "bg-destructive/5", border: "border-destructive/20", text: "text-destructive" },
|
|
21696
20044
|
warning: { bg: "bg-warning/5", border: "border-warning/20", text: "text-warning" },
|
|
@@ -21711,32 +20059,32 @@ function AccessDenied({
|
|
|
21711
20059
|
}) {
|
|
21712
20060
|
const styles = VARIANT_STYLES[variant];
|
|
21713
20061
|
const UsedIcon = Icon || DEFAULT_ICONS[variant];
|
|
21714
|
-
return /* @__PURE__ */
|
|
21715
|
-
/* @__PURE__ */
|
|
21716
|
-
/* @__PURE__ */
|
|
21717
|
-
/* @__PURE__ */
|
|
21718
|
-
/* @__PURE__ */
|
|
20062
|
+
return /* @__PURE__ */ jsx67(Card_default, { className: cn("p-8 text-center shadow-sm", styles.bg, styles.border, className), children: /* @__PURE__ */ jsxs58("div", { className: "flex flex-col items-center gap-4", children: [
|
|
20063
|
+
/* @__PURE__ */ jsx67("div", { className: cn("p-3 rounded-lg", styles.bg.replace("/5", "/10")), children: /* @__PURE__ */ jsx67(UsedIcon, { className: cn("w-8 h-8", styles.text) }) }),
|
|
20064
|
+
/* @__PURE__ */ jsxs58("div", { children: [
|
|
20065
|
+
/* @__PURE__ */ jsx67("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
|
|
20066
|
+
/* @__PURE__ */ jsx67("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
|
|
21719
20067
|
] }),
|
|
21720
|
-
children && /* @__PURE__ */
|
|
20068
|
+
children && /* @__PURE__ */ jsx67("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
|
|
21721
20069
|
] }) });
|
|
21722
20070
|
}
|
|
21723
20071
|
|
|
21724
20072
|
// src/components/ThemeToggleHeadless.tsx
|
|
21725
20073
|
import { Moon as Moon2, Sun as Sun2, Monitor } from "lucide-react";
|
|
21726
|
-
import { useEffect as
|
|
21727
|
-
import { createPortal as
|
|
21728
|
-
import { Fragment as
|
|
20074
|
+
import { useEffect as useEffect30, useRef as useRef22, useState as useState39 } from "react";
|
|
20075
|
+
import { createPortal as createPortal6 } from "react-dom";
|
|
20076
|
+
import { Fragment as Fragment23, jsx as jsx68, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
21729
20077
|
function ThemeToggleHeadless({
|
|
21730
20078
|
theme,
|
|
21731
20079
|
onChange,
|
|
21732
20080
|
labels,
|
|
21733
20081
|
className
|
|
21734
20082
|
}) {
|
|
21735
|
-
const [isOpen, setIsOpen] =
|
|
21736
|
-
const [mounted, setMounted] =
|
|
21737
|
-
const triggerRef =
|
|
21738
|
-
const [dropdownPosition, setDropdownPosition] =
|
|
21739
|
-
|
|
20083
|
+
const [isOpen, setIsOpen] = useState39(false);
|
|
20084
|
+
const [mounted, setMounted] = useState39(false);
|
|
20085
|
+
const triggerRef = useRef22(null);
|
|
20086
|
+
const [dropdownPosition, setDropdownPosition] = useState39(null);
|
|
20087
|
+
useEffect30(() => setMounted(true), []);
|
|
21740
20088
|
const themes = [
|
|
21741
20089
|
{ value: "light", label: labels?.light ?? "Light", icon: Sun2 },
|
|
21742
20090
|
{ value: "dark", label: labels?.dark ?? "Dark", icon: Moon2 },
|
|
@@ -21754,8 +20102,8 @@ function ThemeToggleHeadless({
|
|
|
21754
20102
|
const top = rect.bottom + scrollTop + 8;
|
|
21755
20103
|
return { top, left, width };
|
|
21756
20104
|
};
|
|
21757
|
-
return /* @__PURE__ */
|
|
21758
|
-
/* @__PURE__ */
|
|
20105
|
+
return /* @__PURE__ */ jsxs59("div", { className: cn("relative", className), children: [
|
|
20106
|
+
/* @__PURE__ */ jsx68(
|
|
21759
20107
|
Button_default,
|
|
21760
20108
|
{
|
|
21761
20109
|
variant: "ghost",
|
|
@@ -21773,25 +20121,25 @@ function ThemeToggleHeadless({
|
|
|
21773
20121
|
"aria-haspopup": "menu",
|
|
21774
20122
|
"aria-expanded": isOpen,
|
|
21775
20123
|
"aria-label": labels?.heading ?? "Theme",
|
|
21776
|
-
children: /* @__PURE__ */
|
|
20124
|
+
children: /* @__PURE__ */ jsx68(CurrentIcon, { className: "h-5 w-5" })
|
|
21777
20125
|
}
|
|
21778
20126
|
),
|
|
21779
|
-
isOpen && /* @__PURE__ */
|
|
21780
|
-
typeof window !== "undefined" &&
|
|
21781
|
-
typeof window !== "undefined" && dropdownPosition &&
|
|
21782
|
-
/* @__PURE__ */
|
|
20127
|
+
isOpen && /* @__PURE__ */ jsxs59(Fragment23, { children: [
|
|
20128
|
+
typeof window !== "undefined" && createPortal6(/* @__PURE__ */ jsx68("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
|
|
20129
|
+
typeof window !== "undefined" && dropdownPosition && createPortal6(
|
|
20130
|
+
/* @__PURE__ */ jsx68(
|
|
21783
20131
|
"div",
|
|
21784
20132
|
{
|
|
21785
|
-
className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
|
|
20133
|
+
className: "z-9999 bg-card border border-border/50 rounded-lg shadow-lg overflow-hidden",
|
|
21786
20134
|
style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
|
|
21787
20135
|
onMouseDown: (e) => e.stopPropagation(),
|
|
21788
20136
|
role: "menu",
|
|
21789
|
-
children: /* @__PURE__ */
|
|
21790
|
-
/* @__PURE__ */
|
|
20137
|
+
children: /* @__PURE__ */ jsxs59("div", { className: "p-2", children: [
|
|
20138
|
+
/* @__PURE__ */ jsx68("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border/50 mb-2", children: labels?.heading ?? "Theme" }),
|
|
21791
20139
|
themes.map((opt) => {
|
|
21792
20140
|
const Icon = opt.icon;
|
|
21793
20141
|
const active = theme === opt.value;
|
|
21794
|
-
return /* @__PURE__ */
|
|
20142
|
+
return /* @__PURE__ */ jsxs59(
|
|
21795
20143
|
Button_default,
|
|
21796
20144
|
{
|
|
21797
20145
|
variant: "ghost",
|
|
@@ -21807,9 +20155,9 @@ function ThemeToggleHeadless({
|
|
|
21807
20155
|
role: "menuitemradio",
|
|
21808
20156
|
"aria-checked": active,
|
|
21809
20157
|
children: [
|
|
21810
|
-
/* @__PURE__ */
|
|
21811
|
-
/* @__PURE__ */
|
|
21812
|
-
active && /* @__PURE__ */
|
|
20158
|
+
/* @__PURE__ */ jsx68(Icon, { className: "h-4 w-4" }),
|
|
20159
|
+
/* @__PURE__ */ jsx68("span", { className: "flex-1 text-left", children: opt.label }),
|
|
20160
|
+
active && /* @__PURE__ */ jsx68("div", { className: "w-2 h-2 rounded-full bg-primary" })
|
|
21813
20161
|
]
|
|
21814
20162
|
},
|
|
21815
20163
|
opt.value
|
|
@@ -21825,10 +20173,10 @@ function ThemeToggleHeadless({
|
|
|
21825
20173
|
}
|
|
21826
20174
|
|
|
21827
20175
|
// src/components/LanguageSwitcherHeadless.tsx
|
|
21828
|
-
import { useRef as
|
|
21829
|
-
import { createPortal as
|
|
20176
|
+
import { useRef as useRef23, useState as useState40 } from "react";
|
|
20177
|
+
import { createPortal as createPortal7 } from "react-dom";
|
|
21830
20178
|
import { Globe } from "lucide-react";
|
|
21831
|
-
import { Fragment as
|
|
20179
|
+
import { Fragment as Fragment24, jsx as jsx69, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
21832
20180
|
function LanguageSwitcherHeadless({
|
|
21833
20181
|
locales,
|
|
21834
20182
|
currentLocale,
|
|
@@ -21836,9 +20184,9 @@ function LanguageSwitcherHeadless({
|
|
|
21836
20184
|
labels,
|
|
21837
20185
|
className
|
|
21838
20186
|
}) {
|
|
21839
|
-
const [isOpen, setIsOpen] =
|
|
21840
|
-
const [dropdownPosition, setDropdownPosition] =
|
|
21841
|
-
const triggerButtonRef =
|
|
20187
|
+
const [isOpen, setIsOpen] = useState40(false);
|
|
20188
|
+
const [dropdownPosition, setDropdownPosition] = useState40(null);
|
|
20189
|
+
const triggerButtonRef = useRef23(null);
|
|
21842
20190
|
const currentLanguage = locales.find((l) => l.code === currentLocale) || locales[0];
|
|
21843
20191
|
const calculatePosition = () => {
|
|
21844
20192
|
const rect = triggerButtonRef.current?.getBoundingClientRect();
|
|
@@ -21850,8 +20198,8 @@ function LanguageSwitcherHeadless({
|
|
|
21850
20198
|
const top = rect.bottom + scrollTop + 8;
|
|
21851
20199
|
return { top, left, width };
|
|
21852
20200
|
};
|
|
21853
|
-
return /* @__PURE__ */
|
|
21854
|
-
/* @__PURE__ */
|
|
20201
|
+
return /* @__PURE__ */ jsxs60("div", { className: cn("relative", className), children: [
|
|
20202
|
+
/* @__PURE__ */ jsx69(
|
|
21855
20203
|
Button_default,
|
|
21856
20204
|
{
|
|
21857
20205
|
variant: "ghost",
|
|
@@ -21870,22 +20218,22 @@ function LanguageSwitcherHeadless({
|
|
|
21870
20218
|
"aria-expanded": isOpen,
|
|
21871
20219
|
"aria-label": labels?.heading ?? "Language",
|
|
21872
20220
|
title: labels?.heading ?? "Language",
|
|
21873
|
-
children: /* @__PURE__ */
|
|
20221
|
+
children: /* @__PURE__ */ jsx69(Globe, { className: "h-5 w-5" })
|
|
21874
20222
|
}
|
|
21875
20223
|
),
|
|
21876
|
-
isOpen && /* @__PURE__ */
|
|
21877
|
-
typeof window !== "undefined" &&
|
|
21878
|
-
typeof window !== "undefined" && dropdownPosition &&
|
|
21879
|
-
/* @__PURE__ */
|
|
20224
|
+
isOpen && /* @__PURE__ */ jsxs60(Fragment24, { children: [
|
|
20225
|
+
typeof window !== "undefined" && createPortal7(/* @__PURE__ */ jsx69("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
|
|
20226
|
+
typeof window !== "undefined" && dropdownPosition && createPortal7(
|
|
20227
|
+
/* @__PURE__ */ jsx69(
|
|
21880
20228
|
"div",
|
|
21881
20229
|
{
|
|
21882
|
-
className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
|
|
20230
|
+
className: "z-9999 bg-card border border-border/50 rounded-lg shadow-lg overflow-hidden",
|
|
21883
20231
|
style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
|
|
21884
20232
|
onMouseDown: (e) => e.stopPropagation(),
|
|
21885
20233
|
role: "menu",
|
|
21886
|
-
children: /* @__PURE__ */
|
|
21887
|
-
/* @__PURE__ */
|
|
21888
|
-
locales.map((language) => /* @__PURE__ */
|
|
20234
|
+
children: /* @__PURE__ */ jsxs60("div", { className: "p-2", children: [
|
|
20235
|
+
/* @__PURE__ */ jsx69("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border/50 mb-2", children: labels?.heading ?? "Language" }),
|
|
20236
|
+
locales.map((language) => /* @__PURE__ */ jsxs60(
|
|
21889
20237
|
Button_default,
|
|
21890
20238
|
{
|
|
21891
20239
|
variant: "ghost",
|
|
@@ -21898,9 +20246,9 @@ function LanguageSwitcherHeadless({
|
|
|
21898
20246
|
role: "menuitemradio",
|
|
21899
20247
|
"aria-checked": currentLocale === language.code,
|
|
21900
20248
|
children: [
|
|
21901
|
-
language.flag && /* @__PURE__ */
|
|
21902
|
-
/* @__PURE__ */
|
|
21903
|
-
currentLocale === language.code && /* @__PURE__ */
|
|
20249
|
+
language.flag && /* @__PURE__ */ jsx69("span", { className: "text-lg", children: language.flag }),
|
|
20250
|
+
/* @__PURE__ */ jsx69("span", { className: "flex-1 text-left", children: language.name }),
|
|
20251
|
+
currentLocale === language.code && /* @__PURE__ */ jsx69("div", { className: "w-2 h-2 rounded-full bg-primary" })
|
|
21904
20252
|
]
|
|
21905
20253
|
},
|
|
21906
20254
|
language.code
|
|
@@ -21932,8 +20280,8 @@ var VARIANT_STYLES_ALERT = {
|
|
|
21932
20280
|
};
|
|
21933
20281
|
|
|
21934
20282
|
// ../../lib/i18n/translation-adapter.tsx
|
|
21935
|
-
import * as
|
|
21936
|
-
import { jsx as
|
|
20283
|
+
import * as React62 from "react";
|
|
20284
|
+
import { jsx as jsx70 } from "react/jsx-runtime";
|
|
21937
20285
|
var defaultTranslations2 = {
|
|
21938
20286
|
en: {
|
|
21939
20287
|
Common: {
|
|
@@ -22297,9 +20645,9 @@ function resolveTranslationValue2(translations, namespace, key) {
|
|
|
22297
20645
|
const value = resolveObjectPath2(namespaceValue, key);
|
|
22298
20646
|
return typeof value === "string" ? value : null;
|
|
22299
20647
|
}
|
|
22300
|
-
var TranslationContext2 =
|
|
20648
|
+
var TranslationContext2 = React62.createContext(null);
|
|
22301
20649
|
var UnderverseProvider = ({ children, locale = "en", translations }) => {
|
|
22302
|
-
const t =
|
|
20650
|
+
const t = React62.useCallback(
|
|
22303
20651
|
(namespace) => {
|
|
22304
20652
|
return (key) => {
|
|
22305
20653
|
const mergedTranslations = {
|
|
@@ -22311,7 +20659,7 @@ var UnderverseProvider = ({ children, locale = "en", translations }) => {
|
|
|
22311
20659
|
},
|
|
22312
20660
|
[locale, translations]
|
|
22313
20661
|
);
|
|
22314
|
-
return /* @__PURE__ */
|
|
20662
|
+
return /* @__PURE__ */ jsx70(TranslationContext2.Provider, { value: { locale, t }, children });
|
|
22315
20663
|
};
|
|
22316
20664
|
var nextIntlAvailable = false;
|
|
22317
20665
|
var nextIntlUseTranslations = null;
|
|
@@ -22340,7 +20688,7 @@ function getInternalTranslation(namespace, locale) {
|
|
|
22340
20688
|
};
|
|
22341
20689
|
}
|
|
22342
20690
|
function useTranslations(namespace) {
|
|
22343
|
-
const underverseContext =
|
|
20691
|
+
const underverseContext = React62.useContext(TranslationContext2);
|
|
22344
20692
|
if (underverseContext) {
|
|
22345
20693
|
return (key, params) => {
|
|
22346
20694
|
const result = underverseContext.t(namespace)(key);
|
|
@@ -22357,7 +20705,7 @@ function useTranslations(namespace) {
|
|
|
22357
20705
|
return getInternalTranslation(namespace, "en");
|
|
22358
20706
|
}
|
|
22359
20707
|
function useLocale() {
|
|
22360
|
-
const underverseContext =
|
|
20708
|
+
const underverseContext = React62.useContext(TranslationContext2);
|
|
22361
20709
|
if (underverseContext) {
|
|
22362
20710
|
return underverseContext.locale;
|
|
22363
20711
|
}
|
|
@@ -22376,7 +20724,7 @@ function useLocale() {
|
|
|
22376
20724
|
}
|
|
22377
20725
|
|
|
22378
20726
|
// src/components/UEditor/UEditor.tsx
|
|
22379
|
-
import
|
|
20727
|
+
import React71, { useEffect as useEffect37, useImperativeHandle as useImperativeHandle3, useMemo as useMemo22, useRef as useRef30 } from "react";
|
|
22380
20728
|
import { useEditor, EditorContent } from "@tiptap/react";
|
|
22381
20729
|
|
|
22382
20730
|
// src/components/UEditor/extensions.ts
|
|
@@ -22417,7 +20765,7 @@ import { common, createLowlight } from "lowlight";
|
|
|
22417
20765
|
import { Extension } from "@tiptap/core";
|
|
22418
20766
|
import Suggestion from "@tiptap/suggestion";
|
|
22419
20767
|
import { ReactRenderer } from "@tiptap/react";
|
|
22420
|
-
import { forwardRef as forwardRef13, useEffect as
|
|
20768
|
+
import { forwardRef as forwardRef13, useEffect as useEffect31, useImperativeHandle, useRef as useRef24, useState as useState41 } from "react";
|
|
22421
20769
|
import {
|
|
22422
20770
|
FileCode as FileCode2,
|
|
22423
20771
|
Heading1,
|
|
@@ -22432,7 +20780,7 @@ import {
|
|
|
22432
20780
|
Type
|
|
22433
20781
|
} from "lucide-react";
|
|
22434
20782
|
import tippy from "tippy.js";
|
|
22435
|
-
import { jsx as
|
|
20783
|
+
import { jsx as jsx71, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
22436
20784
|
var DEFAULT_MESSAGES = {
|
|
22437
20785
|
noResults: "No results",
|
|
22438
20786
|
basicBlocks: "Basic Blocks",
|
|
@@ -22460,12 +20808,12 @@ var DEFAULT_MESSAGES = {
|
|
|
22460
20808
|
tableDesc: "Insert a table"
|
|
22461
20809
|
};
|
|
22462
20810
|
var CommandList = forwardRef13((props, ref) => {
|
|
22463
|
-
const [selectedIndex, setSelectedIndex] =
|
|
22464
|
-
const listRef =
|
|
22465
|
-
|
|
20811
|
+
const [selectedIndex, setSelectedIndex] = useState41(0);
|
|
20812
|
+
const listRef = useRef24(null);
|
|
20813
|
+
useEffect31(() => {
|
|
22466
20814
|
setSelectedIndex(0);
|
|
22467
20815
|
}, [props.items]);
|
|
22468
|
-
|
|
20816
|
+
useEffect31(() => {
|
|
22469
20817
|
const selectedElement = listRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
|
|
22470
20818
|
selectedElement?.scrollIntoView({ block: "nearest" });
|
|
22471
20819
|
}, [selectedIndex, props.items]);
|
|
@@ -22490,11 +20838,11 @@ var CommandList = forwardRef13((props, ref) => {
|
|
|
22490
20838
|
}
|
|
22491
20839
|
}));
|
|
22492
20840
|
if (props.items.length === 0) {
|
|
22493
|
-
return /* @__PURE__ */
|
|
20841
|
+
return /* @__PURE__ */ jsx71("div", { className: "w-72 p-4 text-center text-sm text-muted-foreground", children: props.messages.noResults });
|
|
22494
20842
|
}
|
|
22495
|
-
return /* @__PURE__ */
|
|
22496
|
-
/* @__PURE__ */
|
|
22497
|
-
/* @__PURE__ */
|
|
20843
|
+
return /* @__PURE__ */ jsxs61("div", { ref: listRef, className: "w-72 max-h-80 overflow-y-auto bg-card border border-border/50 rounded-2xl shadow-lg", children: [
|
|
20844
|
+
/* @__PURE__ */ jsx71("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsx71("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: props.messages.basicBlocks }) }),
|
|
20845
|
+
/* @__PURE__ */ jsx71("div", { className: "p-1", children: props.items.map((item, index) => /* @__PURE__ */ jsxs61(
|
|
22498
20846
|
"button",
|
|
22499
20847
|
{
|
|
22500
20848
|
type: "button",
|
|
@@ -22505,19 +20853,19 @@ var CommandList = forwardRef13((props, ref) => {
|
|
|
22505
20853
|
selectedIndex === index ? "bg-accent" : "hover:bg-accent/50"
|
|
22506
20854
|
),
|
|
22507
20855
|
children: [
|
|
22508
|
-
/* @__PURE__ */
|
|
20856
|
+
/* @__PURE__ */ jsx71(
|
|
22509
20857
|
"div",
|
|
22510
20858
|
{
|
|
22511
20859
|
className: cn(
|
|
22512
20860
|
"flex items-center justify-center w-10 h-10 rounded-lg mr-3 transition-colors",
|
|
22513
20861
|
selectedIndex === index ? "bg-primary/10" : "bg-muted/50 group-hover:bg-muted"
|
|
22514
20862
|
),
|
|
22515
|
-
children: /* @__PURE__ */
|
|
20863
|
+
children: /* @__PURE__ */ jsx71(item.icon, { className: cn("w-5 h-5", selectedIndex === index ? "text-primary" : "text-muted-foreground") })
|
|
22516
20864
|
}
|
|
22517
20865
|
),
|
|
22518
|
-
/* @__PURE__ */
|
|
22519
|
-
/* @__PURE__ */
|
|
22520
|
-
/* @__PURE__ */
|
|
20866
|
+
/* @__PURE__ */ jsxs61("div", { className: "text-left", children: [
|
|
20867
|
+
/* @__PURE__ */ jsx71("div", { className: cn("text-sm font-medium", selectedIndex === index && "text-primary"), children: item.title }),
|
|
20868
|
+
/* @__PURE__ */ jsx71("div", { className: "text-xs text-muted-foreground", children: item.description })
|
|
22521
20869
|
] })
|
|
22522
20870
|
]
|
|
22523
20871
|
},
|
|
@@ -22790,7 +21138,7 @@ import { Extension as Extension3 } from "@tiptap/core";
|
|
|
22790
21138
|
import Suggestion2 from "@tiptap/suggestion";
|
|
22791
21139
|
import { ReactRenderer as ReactRenderer2 } from "@tiptap/react";
|
|
22792
21140
|
import { PluginKey } from "@tiptap/pm/state";
|
|
22793
|
-
import { forwardRef as forwardRef14, useEffect as
|
|
21141
|
+
import { forwardRef as forwardRef14, useEffect as useEffect32, useImperativeHandle as useImperativeHandle2, useState as useState42 } from "react";
|
|
22794
21142
|
import { Smile } from "lucide-react";
|
|
22795
21143
|
import tippy2 from "tippy.js";
|
|
22796
21144
|
|
|
@@ -23560,10 +21908,10 @@ var EMOJI_LIST = [
|
|
|
23560
21908
|
];
|
|
23561
21909
|
|
|
23562
21910
|
// src/components/UEditor/emoji-suggestion.tsx
|
|
23563
|
-
import { jsx as
|
|
21911
|
+
import { jsx as jsx72, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
23564
21912
|
var EmojiList = forwardRef14((props, ref) => {
|
|
23565
|
-
const [selectedIndex, setSelectedIndex] =
|
|
23566
|
-
|
|
21913
|
+
const [selectedIndex, setSelectedIndex] = useState42(0);
|
|
21914
|
+
useEffect32(() => {
|
|
23567
21915
|
setSelectedIndex(0);
|
|
23568
21916
|
}, [props.items]);
|
|
23569
21917
|
useImperativeHandle2(ref, () => ({
|
|
@@ -23595,15 +21943,15 @@ var EmojiList = forwardRef14((props, ref) => {
|
|
|
23595
21943
|
}
|
|
23596
21944
|
}));
|
|
23597
21945
|
if (props.items.length === 0) {
|
|
23598
|
-
return /* @__PURE__ */
|
|
21946
|
+
return /* @__PURE__ */ jsx72("div", { className: "w-80 p-4 text-center text-sm text-muted-foreground bg-card border border-border/50 rounded-2xl shadow-lg", children: "No emoji found" });
|
|
23599
21947
|
}
|
|
23600
|
-
return /* @__PURE__ */
|
|
23601
|
-
/* @__PURE__ */
|
|
23602
|
-
/* @__PURE__ */
|
|
23603
|
-
/* @__PURE__ */
|
|
21948
|
+
return /* @__PURE__ */ jsxs62("div", { className: "w-80 max-h-80 overflow-y-auto bg-card border border-border/50 rounded-2xl shadow-lg", children: [
|
|
21949
|
+
/* @__PURE__ */ jsx72("div", { className: "px-3 py-2 border-b bg-muted/30", children: /* @__PURE__ */ jsxs62("div", { className: "flex items-center gap-2", children: [
|
|
21950
|
+
/* @__PURE__ */ jsx72(Smile, { className: "w-4 h-4 text-primary" }),
|
|
21951
|
+
/* @__PURE__ */ jsx72("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: "Emoji" })
|
|
23604
21952
|
] }) }),
|
|
23605
|
-
/* @__PURE__ */
|
|
23606
|
-
/* @__PURE__ */
|
|
21953
|
+
/* @__PURE__ */ jsxs62("div", { className: "p-3", children: [
|
|
21954
|
+
/* @__PURE__ */ jsx72("div", { className: "grid grid-cols-8 gap-1", children: props.items.slice(0, 64).map((item, index) => /* @__PURE__ */ jsx72(
|
|
23607
21955
|
"button",
|
|
23608
21956
|
{
|
|
23609
21957
|
type: "button",
|
|
@@ -23617,7 +21965,7 @@ var EmojiList = forwardRef14((props, ref) => {
|
|
|
23617
21965
|
},
|
|
23618
21966
|
item.name
|
|
23619
21967
|
)) }),
|
|
23620
|
-
props.items.length > 64 && /* @__PURE__ */
|
|
21968
|
+
props.items.length > 64 && /* @__PURE__ */ jsxs62("div", { className: "mt-2 text-xs text-center text-muted-foreground", children: [
|
|
23621
21969
|
"Showing first 64 of ",
|
|
23622
21970
|
props.items.length,
|
|
23623
21971
|
" emojis"
|
|
@@ -23771,11 +22119,11 @@ var UEditorPlaceholder = Extension4.create({
|
|
|
23771
22119
|
});
|
|
23772
22120
|
|
|
23773
22121
|
// src/components/UEditor/resizable-image.tsx
|
|
23774
|
-
import { useEffect as
|
|
22122
|
+
import { useEffect as useEffect33, useRef as useRef25, useState as useState43 } from "react";
|
|
23775
22123
|
import Image3 from "@tiptap/extension-image";
|
|
23776
22124
|
import { mergeAttributes } from "@tiptap/core";
|
|
23777
22125
|
import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
|
|
23778
|
-
import { jsx as
|
|
22126
|
+
import { jsx as jsx73, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
23779
22127
|
var MIN_IMAGE_SIZE_PX = 40;
|
|
23780
22128
|
var AXIS_LOCK_THRESHOLD_PX = 4;
|
|
23781
22129
|
function toNullableNumber(value) {
|
|
@@ -23791,15 +22139,15 @@ function clamp8(value, min, max) {
|
|
|
23791
22139
|
}
|
|
23792
22140
|
function ResizableImageNodeView(props) {
|
|
23793
22141
|
const { node, selected, updateAttributes, editor, getPos } = props;
|
|
23794
|
-
const wrapperRef =
|
|
23795
|
-
const imgRef =
|
|
23796
|
-
const [isHovered, setIsHovered] =
|
|
23797
|
-
const [isResizing, setIsResizing] =
|
|
22142
|
+
const wrapperRef = useRef25(null);
|
|
22143
|
+
const imgRef = useRef25(null);
|
|
22144
|
+
const [isHovered, setIsHovered] = useState43(false);
|
|
22145
|
+
const [isResizing, setIsResizing] = useState43(false);
|
|
23798
22146
|
const widthAttr = toNullableNumber(node.attrs["width"]);
|
|
23799
22147
|
const heightAttr = toNullableNumber(node.attrs["height"]);
|
|
23800
22148
|
const textAlign = String(node.attrs["textAlign"] ?? "");
|
|
23801
|
-
const dragStateRef =
|
|
23802
|
-
|
|
22149
|
+
const dragStateRef = useRef25(null);
|
|
22150
|
+
useEffect33(() => {
|
|
23803
22151
|
const img = imgRef.current;
|
|
23804
22152
|
if (!img) return;
|
|
23805
22153
|
img.style.width = widthAttr ? `${widthAttr}px` : "";
|
|
@@ -23893,7 +22241,7 @@ function ResizableImageNodeView(props) {
|
|
|
23893
22241
|
const showHandle = selected || isHovered || isResizing;
|
|
23894
22242
|
const wrapperAlignClass = textAlign === "center" ? "mx-auto" : textAlign === "right" ? "ml-auto" : textAlign === "justify" ? "mx-auto" : "";
|
|
23895
22243
|
const wrapperWidthClass = "w-fit";
|
|
23896
|
-
return /* @__PURE__ */
|
|
22244
|
+
return /* @__PURE__ */ jsxs63(
|
|
23897
22245
|
NodeViewWrapper,
|
|
23898
22246
|
{
|
|
23899
22247
|
as: "div",
|
|
@@ -23907,7 +22255,7 @@ function ResizableImageNodeView(props) {
|
|
|
23907
22255
|
},
|
|
23908
22256
|
contentEditable: false,
|
|
23909
22257
|
children: [
|
|
23910
|
-
/* @__PURE__ */
|
|
22258
|
+
/* @__PURE__ */ jsx73(
|
|
23911
22259
|
"img",
|
|
23912
22260
|
{
|
|
23913
22261
|
ref: imgRef,
|
|
@@ -23926,7 +22274,7 @@ function ResizableImageNodeView(props) {
|
|
|
23926
22274
|
}
|
|
23927
22275
|
}
|
|
23928
22276
|
),
|
|
23929
|
-
showHandle && /* @__PURE__ */
|
|
22277
|
+
showHandle && /* @__PURE__ */ jsx73(
|
|
23930
22278
|
"div",
|
|
23931
22279
|
{
|
|
23932
22280
|
"aria-hidden": "true",
|
|
@@ -24130,7 +22478,7 @@ function buildUEditorExtensions({
|
|
|
24130
22478
|
}
|
|
24131
22479
|
|
|
24132
22480
|
// src/components/UEditor/toolbar.tsx
|
|
24133
|
-
import
|
|
22481
|
+
import React69, { useRef as useRef28, useState as useState46 } from "react";
|
|
24134
22482
|
import {
|
|
24135
22483
|
AlignCenter,
|
|
24136
22484
|
AlignJustify,
|
|
@@ -24168,12 +22516,12 @@ import {
|
|
|
24168
22516
|
} from "lucide-react";
|
|
24169
22517
|
|
|
24170
22518
|
// src/components/UEditor/colors.tsx
|
|
24171
|
-
import { useMemo as
|
|
22519
|
+
import { useMemo as useMemo19 } from "react";
|
|
24172
22520
|
import { X as X17 } from "lucide-react";
|
|
24173
|
-
import { jsx as
|
|
22521
|
+
import { jsx as jsx74, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
24174
22522
|
var useEditorColors = () => {
|
|
24175
22523
|
const t = useSmartTranslations("UEditor");
|
|
24176
|
-
const textColors =
|
|
22524
|
+
const textColors = useMemo19(
|
|
24177
22525
|
() => [
|
|
24178
22526
|
{ name: t("colors.default"), color: "inherit", cssClass: "text-foreground" },
|
|
24179
22527
|
{ name: t("colors.muted"), color: "var(--muted-foreground)", cssClass: "text-muted-foreground" },
|
|
@@ -24186,7 +22534,7 @@ var useEditorColors = () => {
|
|
|
24186
22534
|
],
|
|
24187
22535
|
[t]
|
|
24188
22536
|
);
|
|
24189
|
-
const highlightColors =
|
|
22537
|
+
const highlightColors = useMemo19(
|
|
24190
22538
|
() => [
|
|
24191
22539
|
{ name: t("colors.default"), color: "", cssClass: "" },
|
|
24192
22540
|
{ name: t("colors.muted"), color: "var(--muted)", cssClass: "bg-muted" },
|
|
@@ -24207,9 +22555,9 @@ var EditorColorPalette = ({
|
|
|
24207
22555
|
currentColor,
|
|
24208
22556
|
onSelect,
|
|
24209
22557
|
label
|
|
24210
|
-
}) => /* @__PURE__ */
|
|
24211
|
-
/* @__PURE__ */
|
|
24212
|
-
/* @__PURE__ */
|
|
22558
|
+
}) => /* @__PURE__ */ jsxs64("div", { className: "p-2", children: [
|
|
22559
|
+
/* @__PURE__ */ jsx74("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider px-2", children: label }),
|
|
22560
|
+
/* @__PURE__ */ jsx74("div", { className: "grid grid-cols-4 gap-1.5 mt-2", children: colors.map((c) => /* @__PURE__ */ jsxs64(
|
|
24213
22561
|
"button",
|
|
24214
22562
|
{
|
|
24215
22563
|
type: "button",
|
|
@@ -24222,8 +22570,8 @@ var EditorColorPalette = ({
|
|
|
24222
22570
|
style: { backgroundColor: c.color || "transparent" },
|
|
24223
22571
|
title: c.name,
|
|
24224
22572
|
children: [
|
|
24225
|
-
c.color === "" && /* @__PURE__ */
|
|
24226
|
-
c.color === "inherit" && /* @__PURE__ */
|
|
22573
|
+
c.color === "" && /* @__PURE__ */ jsx74(X17, { className: "w-4 h-4 text-muted-foreground" }),
|
|
22574
|
+
c.color === "inherit" && /* @__PURE__ */ jsx74("span", { className: "text-xs font-medium", children: "A" })
|
|
24227
22575
|
]
|
|
24228
22576
|
},
|
|
24229
22577
|
c.name
|
|
@@ -24231,9 +22579,9 @@ var EditorColorPalette = ({
|
|
|
24231
22579
|
] });
|
|
24232
22580
|
|
|
24233
22581
|
// src/components/UEditor/inputs.tsx
|
|
24234
|
-
import { useEffect as
|
|
22582
|
+
import { useEffect as useEffect34, useRef as useRef26, useState as useState44 } from "react";
|
|
24235
22583
|
import { Check as Check10, X as X18 } from "lucide-react";
|
|
24236
|
-
import { jsx as
|
|
22584
|
+
import { jsx as jsx75, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
24237
22585
|
function normalizeUrl(raw) {
|
|
24238
22586
|
const url = raw.trim();
|
|
24239
22587
|
if (!url) return "";
|
|
@@ -24247,9 +22595,9 @@ var LinkInput = ({
|
|
|
24247
22595
|
initialUrl = ""
|
|
24248
22596
|
}) => {
|
|
24249
22597
|
const t = useSmartTranslations("UEditor");
|
|
24250
|
-
const [url, setUrl] =
|
|
24251
|
-
const inputRef =
|
|
24252
|
-
|
|
22598
|
+
const [url, setUrl] = useState44(initialUrl);
|
|
22599
|
+
const inputRef = useRef26(null);
|
|
22600
|
+
useEffect34(() => {
|
|
24253
22601
|
inputRef.current?.focus();
|
|
24254
22602
|
inputRef.current?.select();
|
|
24255
22603
|
}, []);
|
|
@@ -24258,8 +22606,8 @@ var LinkInput = ({
|
|
|
24258
22606
|
const normalized = normalizeUrl(url);
|
|
24259
22607
|
if (normalized) onSubmit(normalized);
|
|
24260
22608
|
};
|
|
24261
|
-
return /* @__PURE__ */
|
|
24262
|
-
/* @__PURE__ */
|
|
22609
|
+
return /* @__PURE__ */ jsxs65("form", { onSubmit: handleSubmit, className: "flex items-center gap-2 p-2", children: [
|
|
22610
|
+
/* @__PURE__ */ jsx75(
|
|
24263
22611
|
"input",
|
|
24264
22612
|
{
|
|
24265
22613
|
ref: inputRef,
|
|
@@ -24270,16 +22618,16 @@ var LinkInput = ({
|
|
|
24270
22618
|
className: "flex-1 px-3 py-2 text-sm bg-muted/50 border-0 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20"
|
|
24271
22619
|
}
|
|
24272
22620
|
),
|
|
24273
|
-
/* @__PURE__ */
|
|
24274
|
-
/* @__PURE__ */
|
|
22621
|
+
/* @__PURE__ */ jsx75("button", { type: "submit", className: "p-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors", children: /* @__PURE__ */ jsx75(Check10, { className: "w-4 h-4" }) }),
|
|
22622
|
+
/* @__PURE__ */ jsx75("button", { type: "button", onClick: onCancel, className: "p-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: /* @__PURE__ */ jsx75(X18, { className: "w-4 h-4" }) })
|
|
24275
22623
|
] });
|
|
24276
22624
|
};
|
|
24277
22625
|
var ImageInput = ({ onSubmit, onCancel }) => {
|
|
24278
22626
|
const t = useSmartTranslations("UEditor");
|
|
24279
|
-
const [url, setUrl] =
|
|
24280
|
-
const [alt, setAlt] =
|
|
24281
|
-
const inputRef =
|
|
24282
|
-
|
|
22627
|
+
const [url, setUrl] = useState44("");
|
|
22628
|
+
const [alt, setAlt] = useState44("");
|
|
22629
|
+
const inputRef = useRef26(null);
|
|
22630
|
+
useEffect34(() => {
|
|
24283
22631
|
inputRef.current?.focus();
|
|
24284
22632
|
}, []);
|
|
24285
22633
|
const handleSubmit = (e) => {
|
|
@@ -24288,10 +22636,10 @@ var ImageInput = ({ onSubmit, onCancel }) => {
|
|
|
24288
22636
|
onSubmit(url, alt);
|
|
24289
22637
|
}
|
|
24290
22638
|
};
|
|
24291
|
-
return /* @__PURE__ */
|
|
24292
|
-
/* @__PURE__ */
|
|
24293
|
-
/* @__PURE__ */
|
|
24294
|
-
/* @__PURE__ */
|
|
22639
|
+
return /* @__PURE__ */ jsxs65("form", { onSubmit: handleSubmit, className: "p-3 space-y-3", children: [
|
|
22640
|
+
/* @__PURE__ */ jsxs65("div", { children: [
|
|
22641
|
+
/* @__PURE__ */ jsx75("label", { className: "text-xs font-medium text-muted-foreground", children: t("imageInput.urlLabel") }),
|
|
22642
|
+
/* @__PURE__ */ jsx75(
|
|
24295
22643
|
"input",
|
|
24296
22644
|
{
|
|
24297
22645
|
ref: inputRef,
|
|
@@ -24303,9 +22651,9 @@ var ImageInput = ({ onSubmit, onCancel }) => {
|
|
|
24303
22651
|
}
|
|
24304
22652
|
)
|
|
24305
22653
|
] }),
|
|
24306
|
-
/* @__PURE__ */
|
|
24307
|
-
/* @__PURE__ */
|
|
24308
|
-
/* @__PURE__ */
|
|
22654
|
+
/* @__PURE__ */ jsxs65("div", { children: [
|
|
22655
|
+
/* @__PURE__ */ jsx75("label", { className: "text-xs font-medium text-muted-foreground", children: t("imageInput.altLabel") }),
|
|
22656
|
+
/* @__PURE__ */ jsx75(
|
|
24309
22657
|
"input",
|
|
24310
22658
|
{
|
|
24311
22659
|
type: "text",
|
|
@@ -24316,8 +22664,8 @@ var ImageInput = ({ onSubmit, onCancel }) => {
|
|
|
24316
22664
|
}
|
|
24317
22665
|
)
|
|
24318
22666
|
] }),
|
|
24319
|
-
/* @__PURE__ */
|
|
24320
|
-
/* @__PURE__ */
|
|
22667
|
+
/* @__PURE__ */ jsxs65("div", { className: "flex gap-2", children: [
|
|
22668
|
+
/* @__PURE__ */ jsx75(
|
|
24321
22669
|
"button",
|
|
24322
22670
|
{
|
|
24323
22671
|
type: "submit",
|
|
@@ -24326,15 +22674,15 @@ var ImageInput = ({ onSubmit, onCancel }) => {
|
|
|
24326
22674
|
children: t("imageInput.addBtn")
|
|
24327
22675
|
}
|
|
24328
22676
|
),
|
|
24329
|
-
/* @__PURE__ */
|
|
22677
|
+
/* @__PURE__ */ jsx75("button", { type: "button", onClick: onCancel, className: "px-4 py-2 rounded-lg hover:bg-muted transition-colors text-muted-foreground", children: t("imageInput.cancelBtn") })
|
|
24330
22678
|
] })
|
|
24331
22679
|
] });
|
|
24332
22680
|
};
|
|
24333
22681
|
|
|
24334
22682
|
// src/components/UEditor/emoji-picker.tsx
|
|
24335
|
-
import { useState as
|
|
22683
|
+
import { useState as useState45, useMemo as useMemo20, useRef as useRef27, useEffect as useEffect35 } from "react";
|
|
24336
22684
|
import { Search as Search6, X as X19, Smile as Smile2, Leaf, Utensils, Dumbbell, Lightbulb, Hash, Flag } from "lucide-react";
|
|
24337
|
-
import { jsx as
|
|
22685
|
+
import { jsx as jsx76, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
24338
22686
|
var CATEGORY_ICONS = {
|
|
24339
22687
|
"smileys_people": Smile2,
|
|
24340
22688
|
"animals_nature": Leaf,
|
|
@@ -24346,12 +22694,12 @@ var CATEGORY_ICONS = {
|
|
|
24346
22694
|
};
|
|
24347
22695
|
var EmojiPicker = ({ onSelect, onClose }) => {
|
|
24348
22696
|
const t = useSmartTranslations("UEditor");
|
|
24349
|
-
const [search, setSearch] =
|
|
24350
|
-
const [activeCategory, setActiveCategory] =
|
|
24351
|
-
const scrollContainerRef =
|
|
24352
|
-
const categoryRefs =
|
|
24353
|
-
const isUserScrolling =
|
|
24354
|
-
const filteredCategories =
|
|
22697
|
+
const [search, setSearch] = useState45("");
|
|
22698
|
+
const [activeCategory, setActiveCategory] = useState45(EMOJI_LIST[0]?.id || "");
|
|
22699
|
+
const scrollContainerRef = useRef27(null);
|
|
22700
|
+
const categoryRefs = useRef27({});
|
|
22701
|
+
const isUserScrolling = useRef27(false);
|
|
22702
|
+
const filteredCategories = useMemo20(() => {
|
|
24355
22703
|
if (!search.trim()) return EMOJI_LIST;
|
|
24356
22704
|
const query = search.toLowerCase();
|
|
24357
22705
|
return EMOJI_LIST.map((category) => ({
|
|
@@ -24365,7 +22713,7 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24365
22713
|
onSelect(emoji);
|
|
24366
22714
|
setSearch("");
|
|
24367
22715
|
};
|
|
24368
|
-
|
|
22716
|
+
useEffect35(() => {
|
|
24369
22717
|
if (search) return;
|
|
24370
22718
|
const container = scrollContainerRef.current;
|
|
24371
22719
|
if (!container) return;
|
|
@@ -24405,13 +22753,13 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24405
22753
|
isUserScrolling.current = true;
|
|
24406
22754
|
}, 500);
|
|
24407
22755
|
};
|
|
24408
|
-
|
|
22756
|
+
useEffect35(() => {
|
|
24409
22757
|
isUserScrolling.current = true;
|
|
24410
22758
|
}, []);
|
|
24411
|
-
return /* @__PURE__ */
|
|
24412
|
-
/* @__PURE__ */
|
|
24413
|
-
/* @__PURE__ */
|
|
24414
|
-
/* @__PURE__ */
|
|
22759
|
+
return /* @__PURE__ */ jsxs66("div", { className: "w-96 bg-card border border-border/50 rounded-2xl shadow-xl overflow-hidden flex flex-col max-h-128", children: [
|
|
22760
|
+
/* @__PURE__ */ jsx76("div", { className: "p-3 border-b bg-muted/30 shrink-0", children: /* @__PURE__ */ jsxs66("div", { className: "relative", children: [
|
|
22761
|
+
/* @__PURE__ */ jsx76(Search6, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" }),
|
|
22762
|
+
/* @__PURE__ */ jsx76(
|
|
24415
22763
|
"input",
|
|
24416
22764
|
{
|
|
24417
22765
|
type: "text",
|
|
@@ -24420,22 +22768,22 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24420
22768
|
onChange: (e) => setSearch(e.target.value),
|
|
24421
22769
|
className: cn(
|
|
24422
22770
|
"w-full pl-9 pr-9 py-2 rounded-lg",
|
|
24423
|
-
"bg-background border border-border",
|
|
22771
|
+
"bg-background border border-border/50",
|
|
24424
22772
|
"text-sm placeholder:text-muted-foreground",
|
|
24425
22773
|
"focus:outline-none focus:ring-2 focus:ring-primary/20"
|
|
24426
22774
|
)
|
|
24427
22775
|
}
|
|
24428
22776
|
),
|
|
24429
|
-
search && /* @__PURE__ */
|
|
22777
|
+
search && /* @__PURE__ */ jsx76(
|
|
24430
22778
|
"button",
|
|
24431
22779
|
{
|
|
24432
22780
|
onClick: () => setSearch(""),
|
|
24433
22781
|
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
24434
|
-
children: /* @__PURE__ */
|
|
22782
|
+
children: /* @__PURE__ */ jsx76(X19, { className: "w-4 h-4" })
|
|
24435
22783
|
}
|
|
24436
22784
|
)
|
|
24437
22785
|
] }) }),
|
|
24438
|
-
/* @__PURE__ */
|
|
22786
|
+
/* @__PURE__ */ jsx76(
|
|
24439
22787
|
"div",
|
|
24440
22788
|
{
|
|
24441
22789
|
ref: scrollContainerRef,
|
|
@@ -24443,9 +22791,9 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24443
22791
|
style: { height: "20rem" },
|
|
24444
22792
|
children: search ? (
|
|
24445
22793
|
// Search Results
|
|
24446
|
-
filteredCategories.length > 0 ? filteredCategories.map((category) => /* @__PURE__ */
|
|
24447
|
-
/* @__PURE__ */
|
|
24448
|
-
/* @__PURE__ */
|
|
22794
|
+
filteredCategories.length > 0 ? filteredCategories.map((category) => /* @__PURE__ */ jsxs66("div", { className: "mb-4", children: [
|
|
22795
|
+
/* @__PURE__ */ jsx76("div", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2 sticky top-0 bg-card py-1", children: category.name }),
|
|
22796
|
+
/* @__PURE__ */ jsx76("div", { className: "grid grid-cols-9 gap-1", children: category.emojis.map((emoji) => /* @__PURE__ */ jsx76(
|
|
24449
22797
|
"button",
|
|
24450
22798
|
{
|
|
24451
22799
|
onClick: () => handleEmojiClick(emoji.emoji),
|
|
@@ -24459,22 +22807,22 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24459
22807
|
},
|
|
24460
22808
|
emoji.name
|
|
24461
22809
|
)) })
|
|
24462
|
-
] }, category.id)) : /* @__PURE__ */
|
|
24463
|
-
/* @__PURE__ */
|
|
24464
|
-
/* @__PURE__ */
|
|
24465
|
-
/* @__PURE__ */
|
|
22810
|
+
] }, category.id)) : /* @__PURE__ */ jsxs66("div", { className: "flex flex-col items-center justify-center h-full text-center", children: [
|
|
22811
|
+
/* @__PURE__ */ jsx76("div", { className: "text-4xl mb-2", children: "\u{1F50D}" }),
|
|
22812
|
+
/* @__PURE__ */ jsx76("div", { className: "text-sm font-medium text-muted-foreground", children: t("emojiPicker.noResults") }),
|
|
22813
|
+
/* @__PURE__ */ jsx76("div", { className: "text-xs text-muted-foreground mt-1", children: t("emojiPicker.tryDifferentSearch") })
|
|
24466
22814
|
] })
|
|
24467
22815
|
) : (
|
|
24468
22816
|
// All Categories - Messenger Style
|
|
24469
|
-
/* @__PURE__ */
|
|
22817
|
+
/* @__PURE__ */ jsx76("div", { className: "space-y-4", children: EMOJI_LIST.map((category) => /* @__PURE__ */ jsxs66(
|
|
24470
22818
|
"div",
|
|
24471
22819
|
{
|
|
24472
22820
|
ref: (el) => {
|
|
24473
22821
|
categoryRefs.current[category.id] = el;
|
|
24474
22822
|
},
|
|
24475
22823
|
children: [
|
|
24476
|
-
/* @__PURE__ */
|
|
24477
|
-
/* @__PURE__ */
|
|
22824
|
+
/* @__PURE__ */ jsx76("div", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2 sticky top-0 bg-card py-1 z-10", children: category.name }),
|
|
22825
|
+
/* @__PURE__ */ jsx76("div", { className: "grid grid-cols-9 gap-1", children: category.emojis.map((emoji) => /* @__PURE__ */ jsx76(
|
|
24478
22826
|
"button",
|
|
24479
22827
|
{
|
|
24480
22828
|
onClick: () => handleEmojiClick(emoji.emoji),
|
|
@@ -24495,9 +22843,9 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24495
22843
|
)
|
|
24496
22844
|
}
|
|
24497
22845
|
),
|
|
24498
|
-
!search && /* @__PURE__ */
|
|
22846
|
+
!search && /* @__PURE__ */ jsx76("div", { className: "flex items-center justify-around px-2 py-2 border-t bg-muted/30 shrink-0", children: EMOJI_LIST.map((category) => {
|
|
24499
22847
|
const IconComponent = CATEGORY_ICONS[category.id] || Smile2;
|
|
24500
|
-
return /* @__PURE__ */
|
|
22848
|
+
return /* @__PURE__ */ jsx76(
|
|
24501
22849
|
"button",
|
|
24502
22850
|
{
|
|
24503
22851
|
onClick: () => handleCategoryClick(category.id),
|
|
@@ -24506,7 +22854,7 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24506
22854
|
activeCategory === category.id ? "text-primary bg-primary/10" : "text-muted-foreground hover:text-foreground hover:bg-accent"
|
|
24507
22855
|
),
|
|
24508
22856
|
title: category.name,
|
|
24509
|
-
children: /* @__PURE__ */
|
|
22857
|
+
children: /* @__PURE__ */ jsx76(IconComponent, { className: "w-5 h-5" })
|
|
24510
22858
|
},
|
|
24511
22859
|
category.id
|
|
24512
22860
|
);
|
|
@@ -24515,7 +22863,7 @@ var EmojiPicker = ({ onSelect, onClose }) => {
|
|
|
24515
22863
|
};
|
|
24516
22864
|
|
|
24517
22865
|
// src/components/UEditor/toolbar.tsx
|
|
24518
|
-
import { Fragment as
|
|
22866
|
+
import { Fragment as Fragment25, jsx as jsx77, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
24519
22867
|
function fileToDataUrl2(file) {
|
|
24520
22868
|
return new Promise((resolve, reject) => {
|
|
24521
22869
|
const reader = new FileReader();
|
|
@@ -24524,8 +22872,8 @@ function fileToDataUrl2(file) {
|
|
|
24524
22872
|
reader.readAsDataURL(file);
|
|
24525
22873
|
});
|
|
24526
22874
|
}
|
|
24527
|
-
var ToolbarButton =
|
|
24528
|
-
const button = /* @__PURE__ */
|
|
22875
|
+
var ToolbarButton = React69.forwardRef(({ onClick, onMouseDown, active, disabled, children, title, className }, ref) => {
|
|
22876
|
+
const button = /* @__PURE__ */ jsx77(
|
|
24529
22877
|
"button",
|
|
24530
22878
|
{
|
|
24531
22879
|
ref,
|
|
@@ -24548,12 +22896,12 @@ var ToolbarButton = React78.forwardRef(({ onClick, onMouseDown, active, disabled
|
|
|
24548
22896
|
}
|
|
24549
22897
|
);
|
|
24550
22898
|
if (title) {
|
|
24551
|
-
return /* @__PURE__ */
|
|
22899
|
+
return /* @__PURE__ */ jsx77(Tooltip, { content: title, placement: "top", delay: { open: 200, close: 0 }, children: button });
|
|
24552
22900
|
}
|
|
24553
22901
|
return button;
|
|
24554
22902
|
});
|
|
24555
22903
|
ToolbarButton.displayName = "ToolbarButton";
|
|
24556
|
-
var ToolbarDivider = () => /* @__PURE__ */
|
|
22904
|
+
var ToolbarDivider = () => /* @__PURE__ */ jsx77("div", { className: "w-px h-6 bg-border/50 mx-1" });
|
|
24557
22905
|
var EditorToolbar = ({
|
|
24558
22906
|
editor,
|
|
24559
22907
|
variant,
|
|
@@ -24562,10 +22910,10 @@ var EditorToolbar = ({
|
|
|
24562
22910
|
}) => {
|
|
24563
22911
|
const t = useSmartTranslations("UEditor");
|
|
24564
22912
|
const { textColors, highlightColors } = useEditorColors();
|
|
24565
|
-
const [showImageInput, setShowImageInput] =
|
|
24566
|
-
const fileInputRef =
|
|
24567
|
-
const [isUploadingImage, setIsUploadingImage] =
|
|
24568
|
-
const [imageUploadError, setImageUploadError] =
|
|
22913
|
+
const [showImageInput, setShowImageInput] = useState46(false);
|
|
22914
|
+
const fileInputRef = useRef28(null);
|
|
22915
|
+
const [isUploadingImage, setIsUploadingImage] = useState46(false);
|
|
22916
|
+
const [imageUploadError, setImageUploadError] = useState46(null);
|
|
24569
22917
|
const insertImageFiles = async (files) => {
|
|
24570
22918
|
if (files.length === 0) return;
|
|
24571
22919
|
setIsUploadingImage(true);
|
|
@@ -24584,31 +22932,31 @@ var EditorToolbar = ({
|
|
|
24584
22932
|
setIsUploadingImage(false);
|
|
24585
22933
|
};
|
|
24586
22934
|
if (variant === "minimal") {
|
|
24587
|
-
return /* @__PURE__ */
|
|
24588
|
-
/* @__PURE__ */
|
|
24589
|
-
/* @__PURE__ */
|
|
24590
|
-
/* @__PURE__ */
|
|
22935
|
+
return /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-1 p-2 border-b bg-muted/30", children: [
|
|
22936
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx77(BoldIcon, { className: "w-4 h-4" }) }),
|
|
22937
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ jsx77(ItalicIcon, { className: "w-4 h-4" }) }),
|
|
22938
|
+
/* @__PURE__ */ jsx77(
|
|
24591
22939
|
ToolbarButton,
|
|
24592
22940
|
{
|
|
24593
22941
|
onClick: () => editor.chain().focus().toggleBulletList().run(),
|
|
24594
22942
|
active: editor.isActive("bulletList"),
|
|
24595
22943
|
title: t("toolbar.bulletList"),
|
|
24596
|
-
children: /* @__PURE__ */
|
|
22944
|
+
children: /* @__PURE__ */ jsx77(ListIcon, { className: "w-4 h-4" })
|
|
24597
22945
|
}
|
|
24598
22946
|
)
|
|
24599
22947
|
] });
|
|
24600
22948
|
}
|
|
24601
|
-
return /* @__PURE__ */
|
|
24602
|
-
/* @__PURE__ */
|
|
22949
|
+
return /* @__PURE__ */ jsxs67("div", { className: "flex flex-wrap items-center gap-1 p-2 border-b bg-linear-to-r from-muted/30 to-transparent", children: [
|
|
22950
|
+
/* @__PURE__ */ jsxs67(
|
|
24603
22951
|
DropdownMenu,
|
|
24604
22952
|
{
|
|
24605
|
-
trigger: /* @__PURE__ */
|
|
22953
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24606
22954
|
}, title: t("toolbar.textStyle"), className: "px-2 w-auto gap-1", children: [
|
|
24607
|
-
/* @__PURE__ */
|
|
24608
|
-
/* @__PURE__ */
|
|
22955
|
+
/* @__PURE__ */ jsx77(Type2, { className: "w-4 h-4" }),
|
|
22956
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24609
22957
|
] }),
|
|
24610
22958
|
children: [
|
|
24611
|
-
/* @__PURE__ */
|
|
22959
|
+
/* @__PURE__ */ jsx77(
|
|
24612
22960
|
DropdownMenuItem,
|
|
24613
22961
|
{
|
|
24614
22962
|
icon: Type2,
|
|
@@ -24617,7 +22965,7 @@ var EditorToolbar = ({
|
|
|
24617
22965
|
active: editor.isActive("paragraph")
|
|
24618
22966
|
}
|
|
24619
22967
|
),
|
|
24620
|
-
/* @__PURE__ */
|
|
22968
|
+
/* @__PURE__ */ jsx77(
|
|
24621
22969
|
DropdownMenuItem,
|
|
24622
22970
|
{
|
|
24623
22971
|
icon: Heading1Icon,
|
|
@@ -24627,7 +22975,7 @@ var EditorToolbar = ({
|
|
|
24627
22975
|
shortcut: "Ctrl+Alt+1"
|
|
24628
22976
|
}
|
|
24629
22977
|
),
|
|
24630
|
-
/* @__PURE__ */
|
|
22978
|
+
/* @__PURE__ */ jsx77(
|
|
24631
22979
|
DropdownMenuItem,
|
|
24632
22980
|
{
|
|
24633
22981
|
icon: Heading2Icon,
|
|
@@ -24637,7 +22985,7 @@ var EditorToolbar = ({
|
|
|
24637
22985
|
shortcut: "Ctrl+Alt+2"
|
|
24638
22986
|
}
|
|
24639
22987
|
),
|
|
24640
|
-
/* @__PURE__ */
|
|
22988
|
+
/* @__PURE__ */ jsx77(
|
|
24641
22989
|
DropdownMenuItem,
|
|
24642
22990
|
{
|
|
24643
22991
|
icon: Heading3Icon,
|
|
@@ -24650,30 +22998,30 @@ var EditorToolbar = ({
|
|
|
24650
22998
|
]
|
|
24651
22999
|
}
|
|
24652
23000
|
),
|
|
24653
|
-
/* @__PURE__ */
|
|
24654
|
-
/* @__PURE__ */
|
|
24655
|
-
/* @__PURE__ */
|
|
24656
|
-
/* @__PURE__ */
|
|
23001
|
+
/* @__PURE__ */ jsx77(ToolbarDivider, {}),
|
|
23002
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx77(BoldIcon, { className: "w-4 h-4" }) }),
|
|
23003
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ jsx77(ItalicIcon, { className: "w-4 h-4" }) }),
|
|
23004
|
+
/* @__PURE__ */ jsx77(
|
|
24657
23005
|
ToolbarButton,
|
|
24658
23006
|
{
|
|
24659
23007
|
onClick: () => editor.chain().focus().toggleUnderline().run(),
|
|
24660
23008
|
active: editor.isActive("underline"),
|
|
24661
23009
|
title: t("toolbar.underline"),
|
|
24662
|
-
children: /* @__PURE__ */
|
|
23010
|
+
children: /* @__PURE__ */ jsx77(UnderlineIcon, { className: "w-4 h-4" })
|
|
24663
23011
|
}
|
|
24664
23012
|
),
|
|
24665
|
-
/* @__PURE__ */
|
|
24666
|
-
/* @__PURE__ */
|
|
24667
|
-
/* @__PURE__ */
|
|
24668
|
-
/* @__PURE__ */
|
|
23013
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), active: editor.isActive("strike"), title: t("toolbar.strike"), children: /* @__PURE__ */ jsx77(StrikethroughIcon, { className: "w-4 h-4" }) }),
|
|
23014
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ jsx77(CodeIcon, { className: "w-4 h-4" }) }),
|
|
23015
|
+
/* @__PURE__ */ jsx77(ToolbarDivider, {}),
|
|
23016
|
+
/* @__PURE__ */ jsx77(
|
|
24669
23017
|
DropdownMenu,
|
|
24670
23018
|
{
|
|
24671
|
-
trigger: /* @__PURE__ */
|
|
23019
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24672
23020
|
}, title: t("colors.textColor"), children: [
|
|
24673
|
-
/* @__PURE__ */
|
|
24674
|
-
/* @__PURE__ */
|
|
23021
|
+
/* @__PURE__ */ jsx77(Palette2, { className: "w-4 h-4" }),
|
|
23022
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24675
23023
|
] }),
|
|
24676
|
-
children: /* @__PURE__ */
|
|
23024
|
+
children: /* @__PURE__ */ jsx77(
|
|
24677
23025
|
EditorColorPalette,
|
|
24678
23026
|
{
|
|
24679
23027
|
colors: textColors,
|
|
@@ -24690,15 +23038,15 @@ var EditorToolbar = ({
|
|
|
24690
23038
|
)
|
|
24691
23039
|
}
|
|
24692
23040
|
),
|
|
24693
|
-
/* @__PURE__ */
|
|
23041
|
+
/* @__PURE__ */ jsx77(
|
|
24694
23042
|
DropdownMenu,
|
|
24695
23043
|
{
|
|
24696
|
-
trigger: /* @__PURE__ */
|
|
23044
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24697
23045
|
}, active: editor.isActive("highlight"), title: t("colors.highlight"), children: [
|
|
24698
|
-
/* @__PURE__ */
|
|
24699
|
-
/* @__PURE__ */
|
|
23046
|
+
/* @__PURE__ */ jsx77(Highlighter, { className: "w-4 h-4" }),
|
|
23047
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24700
23048
|
] }),
|
|
24701
|
-
children: /* @__PURE__ */
|
|
23049
|
+
children: /* @__PURE__ */ jsx77(
|
|
24702
23050
|
EditorColorPalette,
|
|
24703
23051
|
{
|
|
24704
23052
|
colors: highlightColors,
|
|
@@ -24715,13 +23063,13 @@ var EditorToolbar = ({
|
|
|
24715
23063
|
)
|
|
24716
23064
|
}
|
|
24717
23065
|
),
|
|
24718
|
-
/* @__PURE__ */
|
|
24719
|
-
/* @__PURE__ */
|
|
23066
|
+
/* @__PURE__ */ jsx77(ToolbarDivider, {}),
|
|
23067
|
+
/* @__PURE__ */ jsx77(
|
|
24720
23068
|
DropdownMenu,
|
|
24721
23069
|
{
|
|
24722
|
-
trigger: /* @__PURE__ */
|
|
24723
|
-
}, title: t("toolbar.emoji"), children: /* @__PURE__ */
|
|
24724
|
-
children: /* @__PURE__ */
|
|
23070
|
+
trigger: /* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => {
|
|
23071
|
+
}, title: t("toolbar.emoji"), children: /* @__PURE__ */ jsx77(Smile3, { className: "w-4 h-4" }) }),
|
|
23072
|
+
children: /* @__PURE__ */ jsx77(
|
|
24725
23073
|
EmojiPicker,
|
|
24726
23074
|
{
|
|
24727
23075
|
onSelect: (emoji) => {
|
|
@@ -24731,17 +23079,17 @@ var EditorToolbar = ({
|
|
|
24731
23079
|
)
|
|
24732
23080
|
}
|
|
24733
23081
|
),
|
|
24734
|
-
/* @__PURE__ */
|
|
24735
|
-
/* @__PURE__ */
|
|
23082
|
+
/* @__PURE__ */ jsx77(ToolbarDivider, {}),
|
|
23083
|
+
/* @__PURE__ */ jsxs67(
|
|
24736
23084
|
DropdownMenu,
|
|
24737
23085
|
{
|
|
24738
|
-
trigger: /* @__PURE__ */
|
|
23086
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24739
23087
|
}, title: t("toolbar.alignment"), children: [
|
|
24740
|
-
/* @__PURE__ */
|
|
24741
|
-
/* @__PURE__ */
|
|
23088
|
+
/* @__PURE__ */ jsx77(AlignLeft, { className: "w-4 h-4" }),
|
|
23089
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24742
23090
|
] }),
|
|
24743
23091
|
children: [
|
|
24744
|
-
/* @__PURE__ */
|
|
23092
|
+
/* @__PURE__ */ jsx77(
|
|
24745
23093
|
DropdownMenuItem,
|
|
24746
23094
|
{
|
|
24747
23095
|
icon: AlignLeft,
|
|
@@ -24750,7 +23098,7 @@ var EditorToolbar = ({
|
|
|
24750
23098
|
active: editor.isActive({ textAlign: "left" })
|
|
24751
23099
|
}
|
|
24752
23100
|
),
|
|
24753
|
-
/* @__PURE__ */
|
|
23101
|
+
/* @__PURE__ */ jsx77(
|
|
24754
23102
|
DropdownMenuItem,
|
|
24755
23103
|
{
|
|
24756
23104
|
icon: AlignCenter,
|
|
@@ -24759,7 +23107,7 @@ var EditorToolbar = ({
|
|
|
24759
23107
|
active: editor.isActive({ textAlign: "center" })
|
|
24760
23108
|
}
|
|
24761
23109
|
),
|
|
24762
|
-
/* @__PURE__ */
|
|
23110
|
+
/* @__PURE__ */ jsx77(
|
|
24763
23111
|
DropdownMenuItem,
|
|
24764
23112
|
{
|
|
24765
23113
|
icon: AlignRight,
|
|
@@ -24768,7 +23116,7 @@ var EditorToolbar = ({
|
|
|
24768
23116
|
active: editor.isActive({ textAlign: "right" })
|
|
24769
23117
|
}
|
|
24770
23118
|
),
|
|
24771
|
-
/* @__PURE__ */
|
|
23119
|
+
/* @__PURE__ */ jsx77(
|
|
24772
23120
|
DropdownMenuItem,
|
|
24773
23121
|
{
|
|
24774
23122
|
icon: AlignJustify,
|
|
@@ -24780,17 +23128,17 @@ var EditorToolbar = ({
|
|
|
24780
23128
|
]
|
|
24781
23129
|
}
|
|
24782
23130
|
),
|
|
24783
|
-
/* @__PURE__ */
|
|
24784
|
-
/* @__PURE__ */
|
|
23131
|
+
/* @__PURE__ */ jsx77(ToolbarDivider, {}),
|
|
23132
|
+
/* @__PURE__ */ jsxs67(
|
|
24785
23133
|
DropdownMenu,
|
|
24786
23134
|
{
|
|
24787
|
-
trigger: /* @__PURE__ */
|
|
23135
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24788
23136
|
}, title: t("toolbar.bulletList"), children: [
|
|
24789
|
-
/* @__PURE__ */
|
|
24790
|
-
/* @__PURE__ */
|
|
23137
|
+
/* @__PURE__ */ jsx77(ListIcon, { className: "w-4 h-4" }),
|
|
23138
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24791
23139
|
] }),
|
|
24792
23140
|
children: [
|
|
24793
|
-
/* @__PURE__ */
|
|
23141
|
+
/* @__PURE__ */ jsx77(
|
|
24794
23142
|
DropdownMenuItem,
|
|
24795
23143
|
{
|
|
24796
23144
|
icon: ListIcon,
|
|
@@ -24800,7 +23148,7 @@ var EditorToolbar = ({
|
|
|
24800
23148
|
shortcut: "Ctrl+Shift+8"
|
|
24801
23149
|
}
|
|
24802
23150
|
),
|
|
24803
|
-
/* @__PURE__ */
|
|
23151
|
+
/* @__PURE__ */ jsx77(
|
|
24804
23152
|
DropdownMenuItem,
|
|
24805
23153
|
{
|
|
24806
23154
|
icon: ListOrderedIcon,
|
|
@@ -24810,7 +23158,7 @@ var EditorToolbar = ({
|
|
|
24810
23158
|
shortcut: "Ctrl+Shift+7"
|
|
24811
23159
|
}
|
|
24812
23160
|
),
|
|
24813
|
-
/* @__PURE__ */
|
|
23161
|
+
/* @__PURE__ */ jsx77(
|
|
24814
23162
|
DropdownMenuItem,
|
|
24815
23163
|
{
|
|
24816
23164
|
icon: ListTodo2,
|
|
@@ -24823,16 +23171,16 @@ var EditorToolbar = ({
|
|
|
24823
23171
|
]
|
|
24824
23172
|
}
|
|
24825
23173
|
),
|
|
24826
|
-
/* @__PURE__ */
|
|
23174
|
+
/* @__PURE__ */ jsxs67(
|
|
24827
23175
|
DropdownMenu,
|
|
24828
23176
|
{
|
|
24829
|
-
trigger: /* @__PURE__ */
|
|
23177
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24830
23178
|
}, title: t("toolbar.quote"), children: [
|
|
24831
|
-
/* @__PURE__ */
|
|
24832
|
-
/* @__PURE__ */
|
|
23179
|
+
/* @__PURE__ */ jsx77(QuoteIcon, { className: "w-4 h-4" }),
|
|
23180
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24833
23181
|
] }),
|
|
24834
23182
|
children: [
|
|
24835
|
-
/* @__PURE__ */
|
|
23183
|
+
/* @__PURE__ */ jsx77(
|
|
24836
23184
|
DropdownMenuItem,
|
|
24837
23185
|
{
|
|
24838
23186
|
icon: QuoteIcon,
|
|
@@ -24842,7 +23190,7 @@ var EditorToolbar = ({
|
|
|
24842
23190
|
shortcut: "Ctrl+Shift+B"
|
|
24843
23191
|
}
|
|
24844
23192
|
),
|
|
24845
|
-
/* @__PURE__ */
|
|
23193
|
+
/* @__PURE__ */ jsx77(
|
|
24846
23194
|
DropdownMenuItem,
|
|
24847
23195
|
{
|
|
24848
23196
|
icon: FileCode3,
|
|
@@ -24855,15 +23203,15 @@ var EditorToolbar = ({
|
|
|
24855
23203
|
]
|
|
24856
23204
|
}
|
|
24857
23205
|
),
|
|
24858
|
-
/* @__PURE__ */
|
|
23206
|
+
/* @__PURE__ */ jsx77(
|
|
24859
23207
|
DropdownMenu,
|
|
24860
23208
|
{
|
|
24861
|
-
trigger: /* @__PURE__ */
|
|
23209
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24862
23210
|
}, title: t("toolbar.image"), children: [
|
|
24863
|
-
/* @__PURE__ */
|
|
24864
|
-
/* @__PURE__ */
|
|
23211
|
+
/* @__PURE__ */ jsx77(ImageIcon2, { className: "w-4 h-4" }),
|
|
23212
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24865
23213
|
] }),
|
|
24866
|
-
children: showImageInput ? /* @__PURE__ */
|
|
23214
|
+
children: showImageInput ? /* @__PURE__ */ jsx77(
|
|
24867
23215
|
ImageInput,
|
|
24868
23216
|
{
|
|
24869
23217
|
onSubmit: (url, alt) => {
|
|
@@ -24872,9 +23220,9 @@ var EditorToolbar = ({
|
|
|
24872
23220
|
},
|
|
24873
23221
|
onCancel: () => setShowImageInput(false)
|
|
24874
23222
|
}
|
|
24875
|
-
) : /* @__PURE__ */
|
|
24876
|
-
/* @__PURE__ */
|
|
24877
|
-
/* @__PURE__ */
|
|
23223
|
+
) : /* @__PURE__ */ jsxs67(Fragment25, { children: [
|
|
23224
|
+
/* @__PURE__ */ jsx77(DropdownMenuItem, { icon: LinkIcon, label: t("imageInput.addFromUrl"), onClick: () => setShowImageInput(true) }),
|
|
23225
|
+
/* @__PURE__ */ jsx77(
|
|
24878
23226
|
DropdownMenuItem,
|
|
24879
23227
|
{
|
|
24880
23228
|
icon: Upload3,
|
|
@@ -24883,8 +23231,8 @@ var EditorToolbar = ({
|
|
|
24883
23231
|
onClick: () => fileInputRef.current?.click()
|
|
24884
23232
|
}
|
|
24885
23233
|
),
|
|
24886
|
-
imageUploadError && /* @__PURE__ */
|
|
24887
|
-
/* @__PURE__ */
|
|
23234
|
+
imageUploadError && /* @__PURE__ */ jsx77(DropdownMenuItem, { label: imageUploadError, disabled: true, destructive: true }),
|
|
23235
|
+
/* @__PURE__ */ jsx77(
|
|
24888
23236
|
"input",
|
|
24889
23237
|
{
|
|
24890
23238
|
ref: fileInputRef,
|
|
@@ -24902,16 +23250,16 @@ var EditorToolbar = ({
|
|
|
24902
23250
|
] })
|
|
24903
23251
|
}
|
|
24904
23252
|
),
|
|
24905
|
-
/* @__PURE__ */
|
|
23253
|
+
/* @__PURE__ */ jsxs67(
|
|
24906
23254
|
DropdownMenu,
|
|
24907
23255
|
{
|
|
24908
|
-
trigger: /* @__PURE__ */
|
|
23256
|
+
trigger: /* @__PURE__ */ jsxs67(ToolbarButton, { onClick: () => {
|
|
24909
23257
|
}, title: t("toolbar.table"), children: [
|
|
24910
|
-
/* @__PURE__ */
|
|
24911
|
-
/* @__PURE__ */
|
|
23258
|
+
/* @__PURE__ */ jsx77(TableIcon, { className: "w-4 h-4" }),
|
|
23259
|
+
/* @__PURE__ */ jsx77(ChevronDown7, { className: "w-3 h-3" })
|
|
24912
23260
|
] }),
|
|
24913
23261
|
children: [
|
|
24914
|
-
/* @__PURE__ */
|
|
23262
|
+
/* @__PURE__ */ jsx77(
|
|
24915
23263
|
DropdownMenuItem,
|
|
24916
23264
|
{
|
|
24917
23265
|
icon: TableIcon,
|
|
@@ -24919,8 +23267,8 @@ var EditorToolbar = ({
|
|
|
24919
23267
|
onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
|
|
24920
23268
|
}
|
|
24921
23269
|
),
|
|
24922
|
-
/* @__PURE__ */
|
|
24923
|
-
/* @__PURE__ */
|
|
23270
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23271
|
+
/* @__PURE__ */ jsx77(
|
|
24924
23272
|
DropdownMenuItem,
|
|
24925
23273
|
{
|
|
24926
23274
|
icon: ArrowDown,
|
|
@@ -24929,7 +23277,7 @@ var EditorToolbar = ({
|
|
|
24929
23277
|
disabled: !editor.can().addColumnBefore()
|
|
24930
23278
|
}
|
|
24931
23279
|
),
|
|
24932
|
-
/* @__PURE__ */
|
|
23280
|
+
/* @__PURE__ */ jsx77(
|
|
24933
23281
|
DropdownMenuItem,
|
|
24934
23282
|
{
|
|
24935
23283
|
icon: ArrowDown,
|
|
@@ -24938,7 +23286,7 @@ var EditorToolbar = ({
|
|
|
24938
23286
|
disabled: !editor.can().addColumnAfter()
|
|
24939
23287
|
}
|
|
24940
23288
|
),
|
|
24941
|
-
/* @__PURE__ */
|
|
23289
|
+
/* @__PURE__ */ jsx77(
|
|
24942
23290
|
DropdownMenuItem,
|
|
24943
23291
|
{
|
|
24944
23292
|
icon: ArrowRight,
|
|
@@ -24947,7 +23295,7 @@ var EditorToolbar = ({
|
|
|
24947
23295
|
disabled: !editor.can().addRowBefore()
|
|
24948
23296
|
}
|
|
24949
23297
|
),
|
|
24950
|
-
/* @__PURE__ */
|
|
23298
|
+
/* @__PURE__ */ jsx77(
|
|
24951
23299
|
DropdownMenuItem,
|
|
24952
23300
|
{
|
|
24953
23301
|
icon: ArrowRight,
|
|
@@ -24956,8 +23304,8 @@ var EditorToolbar = ({
|
|
|
24956
23304
|
disabled: !editor.can().addRowAfter()
|
|
24957
23305
|
}
|
|
24958
23306
|
),
|
|
24959
|
-
/* @__PURE__ */
|
|
24960
|
-
/* @__PURE__ */
|
|
23307
|
+
/* @__PURE__ */ jsx77("div", { className: "my-1 border-t" }),
|
|
23308
|
+
/* @__PURE__ */ jsx77(
|
|
24961
23309
|
DropdownMenuItem,
|
|
24962
23310
|
{
|
|
24963
23311
|
icon: Trash22,
|
|
@@ -24966,7 +23314,7 @@ var EditorToolbar = ({
|
|
|
24966
23314
|
disabled: !editor.can().deleteColumn()
|
|
24967
23315
|
}
|
|
24968
23316
|
),
|
|
24969
|
-
/* @__PURE__ */
|
|
23317
|
+
/* @__PURE__ */ jsx77(
|
|
24970
23318
|
DropdownMenuItem,
|
|
24971
23319
|
{
|
|
24972
23320
|
icon: Trash22,
|
|
@@ -24975,7 +23323,7 @@ var EditorToolbar = ({
|
|
|
24975
23323
|
disabled: !editor.can().deleteRow()
|
|
24976
23324
|
}
|
|
24977
23325
|
),
|
|
24978
|
-
/* @__PURE__ */
|
|
23326
|
+
/* @__PURE__ */ jsx77(
|
|
24979
23327
|
DropdownMenuItem,
|
|
24980
23328
|
{
|
|
24981
23329
|
icon: Trash22,
|
|
@@ -24987,34 +23335,34 @@ var EditorToolbar = ({
|
|
|
24987
23335
|
]
|
|
24988
23336
|
}
|
|
24989
23337
|
),
|
|
24990
|
-
/* @__PURE__ */
|
|
24991
|
-
/* @__PURE__ */
|
|
23338
|
+
/* @__PURE__ */ jsx77(ToolbarDivider, {}),
|
|
23339
|
+
/* @__PURE__ */ jsx77(
|
|
24992
23340
|
ToolbarButton,
|
|
24993
23341
|
{
|
|
24994
23342
|
onClick: () => editor.chain().focus().toggleSubscript().run(),
|
|
24995
23343
|
active: editor.isActive("subscript"),
|
|
24996
23344
|
title: t("toolbar.subscript"),
|
|
24997
|
-
children: /* @__PURE__ */
|
|
23345
|
+
children: /* @__PURE__ */ jsx77(SubscriptIcon, { className: "w-4 h-4" })
|
|
24998
23346
|
}
|
|
24999
23347
|
),
|
|
25000
|
-
/* @__PURE__ */
|
|
23348
|
+
/* @__PURE__ */ jsx77(
|
|
25001
23349
|
ToolbarButton,
|
|
25002
23350
|
{
|
|
25003
23351
|
onClick: () => editor.chain().focus().toggleSuperscript().run(),
|
|
25004
23352
|
active: editor.isActive("superscript"),
|
|
25005
23353
|
title: t("toolbar.superscript"),
|
|
25006
|
-
children: /* @__PURE__ */
|
|
23354
|
+
children: /* @__PURE__ */ jsx77(SuperscriptIcon, { className: "w-4 h-4" })
|
|
25007
23355
|
}
|
|
25008
23356
|
),
|
|
25009
|
-
/* @__PURE__ */
|
|
25010
|
-
/* @__PURE__ */
|
|
25011
|
-
/* @__PURE__ */
|
|
23357
|
+
/* @__PURE__ */ jsx77(ToolbarDivider, {}),
|
|
23358
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: t("toolbar.undo"), children: /* @__PURE__ */ jsx77(UndoIcon, { className: "w-4 h-4" }) }),
|
|
23359
|
+
/* @__PURE__ */ jsx77(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: t("toolbar.redo"), children: /* @__PURE__ */ jsx77(RedoIcon, { className: "w-4 h-4" }) })
|
|
25012
23360
|
] });
|
|
25013
23361
|
};
|
|
25014
23362
|
|
|
25015
23363
|
// src/components/UEditor/menus.tsx
|
|
25016
|
-
import { useCallback as
|
|
25017
|
-
import { createPortal as
|
|
23364
|
+
import { useCallback as useCallback17, useEffect as useEffect36, useMemo as useMemo21, useRef as useRef29, useState as useState47 } from "react";
|
|
23365
|
+
import { createPortal as createPortal8 } from "react-dom";
|
|
25018
23366
|
import {
|
|
25019
23367
|
Bold as BoldIcon2,
|
|
25020
23368
|
Code as CodeIcon2,
|
|
@@ -25038,12 +23386,12 @@ import {
|
|
|
25038
23386
|
Underline as UnderlineIcon2,
|
|
25039
23387
|
Strikethrough as StrikethroughIcon2
|
|
25040
23388
|
} from "lucide-react";
|
|
25041
|
-
import { jsx as
|
|
23389
|
+
import { jsx as jsx78, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
25042
23390
|
var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
|
|
25043
23391
|
const t = useSmartTranslations("UEditor");
|
|
25044
|
-
const [selectedIndex, setSelectedIndex] =
|
|
25045
|
-
const menuRef =
|
|
25046
|
-
const allCommands =
|
|
23392
|
+
const [selectedIndex, setSelectedIndex] = useState47(0);
|
|
23393
|
+
const menuRef = useRef29(null);
|
|
23394
|
+
const allCommands = useMemo21(
|
|
25047
23395
|
() => [
|
|
25048
23396
|
{
|
|
25049
23397
|
icon: Type3,
|
|
@@ -25114,19 +23462,19 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
|
|
|
25114
23462
|
],
|
|
25115
23463
|
[editor, t]
|
|
25116
23464
|
);
|
|
25117
|
-
const commands =
|
|
23465
|
+
const commands = useMemo21(() => {
|
|
25118
23466
|
if (!filterText) return allCommands;
|
|
25119
23467
|
const lowerFilter = filterText.toLowerCase();
|
|
25120
23468
|
return allCommands.filter((cmd) => cmd.label.toLowerCase().includes(lowerFilter) || cmd.description.toLowerCase().includes(lowerFilter));
|
|
25121
23469
|
}, [allCommands, filterText]);
|
|
25122
|
-
|
|
23470
|
+
useEffect36(() => {
|
|
25123
23471
|
setSelectedIndex(0);
|
|
25124
23472
|
}, [filterText]);
|
|
25125
|
-
|
|
23473
|
+
useEffect36(() => {
|
|
25126
23474
|
const selectedElement = menuRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
|
|
25127
23475
|
selectedElement?.scrollIntoView({ block: "nearest" });
|
|
25128
23476
|
}, [selectedIndex]);
|
|
25129
|
-
const selectCommand =
|
|
23477
|
+
const selectCommand = useCallback17(
|
|
25130
23478
|
(index) => {
|
|
25131
23479
|
const command = commands[index];
|
|
25132
23480
|
if (command) {
|
|
@@ -25136,7 +23484,7 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
|
|
|
25136
23484
|
},
|
|
25137
23485
|
[commands, onClose]
|
|
25138
23486
|
);
|
|
25139
|
-
|
|
23487
|
+
useEffect36(() => {
|
|
25140
23488
|
const handleKeyDown = (e) => {
|
|
25141
23489
|
if (commands.length === 0) return;
|
|
25142
23490
|
if (e.key === "ArrowDown") {
|
|
@@ -25157,11 +23505,11 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
|
|
|
25157
23505
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
25158
23506
|
}, [commands, selectedIndex, selectCommand, onClose]);
|
|
25159
23507
|
if (commands.length === 0) {
|
|
25160
|
-
return /* @__PURE__ */
|
|
23508
|
+
return /* @__PURE__ */ jsx78("div", { className: "w-72 p-4 text-center text-muted-foreground text-sm", children: t("slashCommand.noResults") });
|
|
25161
23509
|
}
|
|
25162
|
-
return /* @__PURE__ */
|
|
25163
|
-
/* @__PURE__ */
|
|
25164
|
-
/* @__PURE__ */
|
|
23510
|
+
return /* @__PURE__ */ jsxs68("div", { ref: menuRef, className: "w-72 max-h-80 overflow-y-auto", children: [
|
|
23511
|
+
/* @__PURE__ */ jsx78("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsx78("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: t("slashCommand.basicBlocks") }) }),
|
|
23512
|
+
/* @__PURE__ */ jsx78("div", { className: "p-1", children: commands.map((cmd, index) => /* @__PURE__ */ jsxs68(
|
|
25165
23513
|
"button",
|
|
25166
23514
|
{
|
|
25167
23515
|
type: "button",
|
|
@@ -25174,19 +23522,19 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
|
|
|
25174
23522
|
selectedIndex === index ? "bg-accent" : "hover:bg-accent/50"
|
|
25175
23523
|
),
|
|
25176
23524
|
children: [
|
|
25177
|
-
/* @__PURE__ */
|
|
23525
|
+
/* @__PURE__ */ jsx78(
|
|
25178
23526
|
"div",
|
|
25179
23527
|
{
|
|
25180
23528
|
className: cn(
|
|
25181
23529
|
"flex items-center justify-center w-10 h-10 rounded-lg mr-3 transition-colors",
|
|
25182
23530
|
selectedIndex === index ? "bg-primary/10" : "bg-muted/50 group-hover:bg-muted"
|
|
25183
23531
|
),
|
|
25184
|
-
children: /* @__PURE__ */
|
|
23532
|
+
children: /* @__PURE__ */ jsx78(cmd.icon, { className: cn("w-5 h-5", selectedIndex === index ? "text-primary" : "text-muted-foreground") })
|
|
25185
23533
|
}
|
|
25186
23534
|
),
|
|
25187
|
-
/* @__PURE__ */
|
|
25188
|
-
/* @__PURE__ */
|
|
25189
|
-
/* @__PURE__ */
|
|
23535
|
+
/* @__PURE__ */ jsxs68("div", { className: "text-left", children: [
|
|
23536
|
+
/* @__PURE__ */ jsx78("div", { className: cn("text-sm font-medium", selectedIndex === index && "text-primary"), children: cmd.label }),
|
|
23537
|
+
/* @__PURE__ */ jsx78("div", { className: "text-xs text-muted-foreground", children: cmd.description })
|
|
25190
23538
|
] })
|
|
25191
23539
|
]
|
|
25192
23540
|
},
|
|
@@ -25196,19 +23544,19 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
|
|
|
25196
23544
|
};
|
|
25197
23545
|
var FloatingMenuContent = ({ editor }) => {
|
|
25198
23546
|
const t = useSmartTranslations("UEditor");
|
|
25199
|
-
const [showCommands, setShowCommands] =
|
|
23547
|
+
const [showCommands, setShowCommands] = useState47(false);
|
|
25200
23548
|
if (showCommands) {
|
|
25201
|
-
return /* @__PURE__ */
|
|
23549
|
+
return /* @__PURE__ */ jsx78(SlashCommandMenu, { editor, onClose: () => setShowCommands(false) });
|
|
25202
23550
|
}
|
|
25203
|
-
return /* @__PURE__ */
|
|
23551
|
+
return /* @__PURE__ */ jsxs68(
|
|
25204
23552
|
"button",
|
|
25205
23553
|
{
|
|
25206
23554
|
type: "button",
|
|
25207
23555
|
onClick: () => setShowCommands(true),
|
|
25208
23556
|
className: "flex items-center gap-1 px-2 py-1.5 rounded-lg hover:bg-accent transition-all group",
|
|
25209
23557
|
children: [
|
|
25210
|
-
/* @__PURE__ */
|
|
25211
|
-
/* @__PURE__ */
|
|
23558
|
+
/* @__PURE__ */ jsx78(Plus3, { className: "w-4 h-4 text-muted-foreground group-hover:text-foreground" }),
|
|
23559
|
+
/* @__PURE__ */ jsx78("span", { className: "text-sm text-muted-foreground group-hover:text-foreground", children: t("floatingMenu.addBlock") })
|
|
25212
23560
|
]
|
|
25213
23561
|
}
|
|
25214
23562
|
);
|
|
@@ -25219,12 +23567,12 @@ var BubbleMenuContent = ({
|
|
|
25219
23567
|
}) => {
|
|
25220
23568
|
const t = useSmartTranslations("UEditor");
|
|
25221
23569
|
const { textColors, highlightColors } = useEditorColors();
|
|
25222
|
-
const [showLinkInput, setShowLinkInput] =
|
|
25223
|
-
const [showEditorColorPalette, setShowEditorColorPalette] =
|
|
25224
|
-
|
|
23570
|
+
const [showLinkInput, setShowLinkInput] = useState47(false);
|
|
23571
|
+
const [showEditorColorPalette, setShowEditorColorPalette] = useState47(false);
|
|
23572
|
+
useEffect36(() => {
|
|
25225
23573
|
onKeepOpenChange?.(showLinkInput);
|
|
25226
23574
|
}, [onKeepOpenChange, showLinkInput]);
|
|
25227
|
-
|
|
23575
|
+
useEffect36(() => {
|
|
25228
23576
|
if (!showLinkInput) return;
|
|
25229
23577
|
const close = () => setShowLinkInput(false);
|
|
25230
23578
|
editor.on("selectionUpdate", close);
|
|
@@ -25235,7 +23583,7 @@ var BubbleMenuContent = ({
|
|
|
25235
23583
|
};
|
|
25236
23584
|
}, [editor, showLinkInput]);
|
|
25237
23585
|
if (showLinkInput) {
|
|
25238
|
-
return /* @__PURE__ */
|
|
23586
|
+
return /* @__PURE__ */ jsx78(
|
|
25239
23587
|
LinkInput,
|
|
25240
23588
|
{
|
|
25241
23589
|
initialUrl: editor.getAttributes("link").href || "",
|
|
@@ -25252,8 +23600,8 @@ var BubbleMenuContent = ({
|
|
|
25252
23600
|
);
|
|
25253
23601
|
}
|
|
25254
23602
|
if (showEditorColorPalette) {
|
|
25255
|
-
return /* @__PURE__ */
|
|
25256
|
-
/* @__PURE__ */
|
|
23603
|
+
return /* @__PURE__ */ jsxs68("div", { className: "w-48", children: [
|
|
23604
|
+
/* @__PURE__ */ jsx78(
|
|
25257
23605
|
EditorColorPalette,
|
|
25258
23606
|
{
|
|
25259
23607
|
colors: textColors,
|
|
@@ -25268,8 +23616,8 @@ var BubbleMenuContent = ({
|
|
|
25268
23616
|
label: t("colors.textColor")
|
|
25269
23617
|
}
|
|
25270
23618
|
),
|
|
25271
|
-
/* @__PURE__ */
|
|
25272
|
-
/* @__PURE__ */
|
|
23619
|
+
/* @__PURE__ */ jsx78("div", { className: "border-t my-1" }),
|
|
23620
|
+
/* @__PURE__ */ jsx78(
|
|
25273
23621
|
EditorColorPalette,
|
|
25274
23622
|
{
|
|
25275
23623
|
colors: highlightColors,
|
|
@@ -25284,7 +23632,7 @@ var BubbleMenuContent = ({
|
|
|
25284
23632
|
label: t("colors.highlight")
|
|
25285
23633
|
}
|
|
25286
23634
|
),
|
|
25287
|
-
/* @__PURE__ */
|
|
23635
|
+
/* @__PURE__ */ jsx78("div", { className: "p-2 border-t", children: /* @__PURE__ */ jsx78(
|
|
25288
23636
|
"button",
|
|
25289
23637
|
{
|
|
25290
23638
|
type: "button",
|
|
@@ -25295,22 +23643,22 @@ var BubbleMenuContent = ({
|
|
|
25295
23643
|
) })
|
|
25296
23644
|
] });
|
|
25297
23645
|
}
|
|
25298
|
-
return /* @__PURE__ */
|
|
25299
|
-
/* @__PURE__ */
|
|
25300
|
-
/* @__PURE__ */
|
|
25301
|
-
/* @__PURE__ */
|
|
23646
|
+
return /* @__PURE__ */ jsxs68("div", { className: "flex items-center gap-0.5 p-1", children: [
|
|
23647
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), active: editor.isActive("bold"), title: t("toolbar.bold"), children: /* @__PURE__ */ jsx78(BoldIcon2, { className: "w-4 h-4" }) }),
|
|
23648
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), active: editor.isActive("italic"), title: t("toolbar.italic"), children: /* @__PURE__ */ jsx78(ItalicIcon2, { className: "w-4 h-4" }) }),
|
|
23649
|
+
/* @__PURE__ */ jsx78(
|
|
25302
23650
|
ToolbarButton,
|
|
25303
23651
|
{
|
|
25304
23652
|
onClick: () => editor.chain().focus().toggleUnderline().run(),
|
|
25305
23653
|
active: editor.isActive("underline"),
|
|
25306
23654
|
title: t("toolbar.underline"),
|
|
25307
|
-
children: /* @__PURE__ */
|
|
23655
|
+
children: /* @__PURE__ */ jsx78(UnderlineIcon2, { className: "w-4 h-4" })
|
|
25308
23656
|
}
|
|
25309
23657
|
),
|
|
25310
|
-
/* @__PURE__ */
|
|
25311
|
-
/* @__PURE__ */
|
|
25312
|
-
/* @__PURE__ */
|
|
25313
|
-
/* @__PURE__ */
|
|
23658
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), active: editor.isActive("strike"), title: t("toolbar.strike"), children: /* @__PURE__ */ jsx78(StrikethroughIcon2, { className: "w-4 h-4" }) }),
|
|
23659
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), active: editor.isActive("code"), title: t("toolbar.code"), children: /* @__PURE__ */ jsx78(CodeIcon2, { className: "w-4 h-4" }) }),
|
|
23660
|
+
/* @__PURE__ */ jsx78("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
23661
|
+
/* @__PURE__ */ jsx78(
|
|
25314
23662
|
ToolbarButton,
|
|
25315
23663
|
{
|
|
25316
23664
|
onMouseDown: () => {
|
|
@@ -25321,41 +23669,41 @@ var BubbleMenuContent = ({
|
|
|
25321
23669
|
},
|
|
25322
23670
|
active: editor.isActive("link"),
|
|
25323
23671
|
title: t("toolbar.link"),
|
|
25324
|
-
children: /* @__PURE__ */
|
|
23672
|
+
children: /* @__PURE__ */ jsx78(LinkIcon2, { className: "w-4 h-4" })
|
|
25325
23673
|
}
|
|
25326
23674
|
),
|
|
25327
|
-
/* @__PURE__ */
|
|
25328
|
-
/* @__PURE__ */
|
|
25329
|
-
/* @__PURE__ */
|
|
23675
|
+
/* @__PURE__ */ jsx78(ToolbarButton, { onClick: () => setShowEditorColorPalette(true), title: t("colors.textColor"), children: /* @__PURE__ */ jsx78(Palette3, { className: "w-4 h-4" }) }),
|
|
23676
|
+
/* @__PURE__ */ jsx78("div", { className: "w-px h-6 bg-border/50 mx-1" }),
|
|
23677
|
+
/* @__PURE__ */ jsx78(
|
|
25330
23678
|
ToolbarButton,
|
|
25331
23679
|
{
|
|
25332
23680
|
onClick: () => editor.chain().focus().toggleSubscript().run(),
|
|
25333
23681
|
active: editor.isActive("subscript"),
|
|
25334
23682
|
title: t("toolbar.subscript"),
|
|
25335
|
-
children: /* @__PURE__ */
|
|
23683
|
+
children: /* @__PURE__ */ jsx78(SubscriptIcon2, { className: "w-4 h-4" })
|
|
25336
23684
|
}
|
|
25337
23685
|
),
|
|
25338
|
-
/* @__PURE__ */
|
|
23686
|
+
/* @__PURE__ */ jsx78(
|
|
25339
23687
|
ToolbarButton,
|
|
25340
23688
|
{
|
|
25341
23689
|
onClick: () => editor.chain().focus().toggleSuperscript().run(),
|
|
25342
23690
|
active: editor.isActive("superscript"),
|
|
25343
23691
|
title: t("toolbar.superscript"),
|
|
25344
|
-
children: /* @__PURE__ */
|
|
23692
|
+
children: /* @__PURE__ */ jsx78(SuperscriptIcon2, { className: "w-4 h-4" })
|
|
25345
23693
|
}
|
|
25346
23694
|
)
|
|
25347
23695
|
] });
|
|
25348
23696
|
};
|
|
25349
23697
|
var CustomBubbleMenu = ({ editor }) => {
|
|
25350
|
-
const [isVisible, setIsVisible] =
|
|
25351
|
-
const [position, setPosition] =
|
|
25352
|
-
const menuRef =
|
|
25353
|
-
const keepOpenRef =
|
|
25354
|
-
const setKeepOpen =
|
|
23698
|
+
const [isVisible, setIsVisible] = useState47(false);
|
|
23699
|
+
const [position, setPosition] = useState47({ top: 0, left: 0 });
|
|
23700
|
+
const menuRef = useRef29(null);
|
|
23701
|
+
const keepOpenRef = useRef29(false);
|
|
23702
|
+
const setKeepOpen = useCallback17((next) => {
|
|
25355
23703
|
keepOpenRef.current = next;
|
|
25356
23704
|
if (next) setIsVisible(true);
|
|
25357
23705
|
}, []);
|
|
25358
|
-
|
|
23706
|
+
useEffect36(() => {
|
|
25359
23707
|
const updatePosition = () => {
|
|
25360
23708
|
const { state, view } = editor;
|
|
25361
23709
|
const { from, to, empty } = state.selection;
|
|
@@ -25383,19 +23731,19 @@ var CustomBubbleMenu = ({ editor }) => {
|
|
|
25383
23731
|
};
|
|
25384
23732
|
}, [editor]);
|
|
25385
23733
|
if (!isVisible) return null;
|
|
25386
|
-
return
|
|
25387
|
-
/* @__PURE__ */
|
|
23734
|
+
return createPortal8(
|
|
23735
|
+
/* @__PURE__ */ jsx78(
|
|
25388
23736
|
"div",
|
|
25389
23737
|
{
|
|
25390
23738
|
ref: menuRef,
|
|
25391
|
-
className: "fixed z-50 flex rounded-2xl border border-border bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
|
|
23739
|
+
className: "fixed z-50 flex rounded-2xl border border-border/50 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 zoom-in-95",
|
|
25392
23740
|
style: {
|
|
25393
23741
|
top: `${position.top}px`,
|
|
25394
23742
|
left: `${position.left}px`,
|
|
25395
23743
|
transform: "translate(-50%, -100%)"
|
|
25396
23744
|
},
|
|
25397
23745
|
onMouseDown: (e) => e.preventDefault(),
|
|
25398
|
-
children: /* @__PURE__ */
|
|
23746
|
+
children: /* @__PURE__ */ jsx78(
|
|
25399
23747
|
BubbleMenuContent,
|
|
25400
23748
|
{
|
|
25401
23749
|
editor,
|
|
@@ -25408,9 +23756,9 @@ var CustomBubbleMenu = ({ editor }) => {
|
|
|
25408
23756
|
);
|
|
25409
23757
|
};
|
|
25410
23758
|
var CustomFloatingMenu = ({ editor }) => {
|
|
25411
|
-
const [isVisible, setIsVisible] =
|
|
25412
|
-
const [position, setPosition] =
|
|
25413
|
-
|
|
23759
|
+
const [isVisible, setIsVisible] = useState47(false);
|
|
23760
|
+
const [position, setPosition] = useState47({ top: 0, left: 0 });
|
|
23761
|
+
useEffect36(() => {
|
|
25414
23762
|
const updatePosition = () => {
|
|
25415
23763
|
const { state, view } = editor;
|
|
25416
23764
|
const { $from, empty } = state.selection;
|
|
@@ -25436,18 +23784,18 @@ var CustomFloatingMenu = ({ editor }) => {
|
|
|
25436
23784
|
};
|
|
25437
23785
|
}, [editor]);
|
|
25438
23786
|
if (!isVisible) return null;
|
|
25439
|
-
return
|
|
25440
|
-
/* @__PURE__ */
|
|
23787
|
+
return createPortal8(
|
|
23788
|
+
/* @__PURE__ */ jsx78(
|
|
25441
23789
|
"div",
|
|
25442
23790
|
{
|
|
25443
|
-
className: "fixed z-50 rounded-2xl border border-border bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 slide-in-from-bottom-2",
|
|
23791
|
+
className: "fixed z-50 rounded-2xl border border-border/50 bg-card text-card-foreground shadow-lg backdrop-blur-sm overflow-hidden animate-in fade-in-0 slide-in-from-bottom-2",
|
|
25444
23792
|
style: {
|
|
25445
23793
|
top: `${position.top}px`,
|
|
25446
23794
|
left: `${position.left}px`,
|
|
25447
23795
|
transform: "translate(-50%, -100%)"
|
|
25448
23796
|
},
|
|
25449
23797
|
onMouseDown: (e) => e.preventDefault(),
|
|
25450
|
-
children: /* @__PURE__ */
|
|
23798
|
+
children: /* @__PURE__ */ jsx78(FloatingMenuContent, { editor })
|
|
25451
23799
|
}
|
|
25452
23800
|
),
|
|
25453
23801
|
document.body
|
|
@@ -25455,25 +23803,25 @@ var CustomFloatingMenu = ({ editor }) => {
|
|
|
25455
23803
|
};
|
|
25456
23804
|
|
|
25457
23805
|
// src/components/UEditor/CharacterCount.tsx
|
|
25458
|
-
import { jsxs as
|
|
23806
|
+
import { jsxs as jsxs69 } from "react/jsx-runtime";
|
|
25459
23807
|
var CharacterCountDisplay = ({ editor, maxCharacters }) => {
|
|
25460
23808
|
const t = useSmartTranslations("UEditor");
|
|
25461
23809
|
const storage = editor.storage;
|
|
25462
23810
|
const characterCount = storage.characterCount?.characters?.() ?? 0;
|
|
25463
23811
|
const wordCount = storage.characterCount?.words?.() ?? 0;
|
|
25464
23812
|
const percentage = maxCharacters ? Math.round(characterCount / maxCharacters * 100) : 0;
|
|
25465
|
-
return /* @__PURE__ */
|
|
25466
|
-
/* @__PURE__ */
|
|
23813
|
+
return /* @__PURE__ */ jsxs69("div", { className: "flex items-center gap-3 px-3 py-2 text-xs text-muted-foreground border-t bg-muted/20", children: [
|
|
23814
|
+
/* @__PURE__ */ jsxs69("span", { children: [
|
|
25467
23815
|
wordCount,
|
|
25468
23816
|
" ",
|
|
25469
23817
|
t("words")
|
|
25470
23818
|
] }),
|
|
25471
|
-
/* @__PURE__ */
|
|
23819
|
+
/* @__PURE__ */ jsxs69("span", { children: [
|
|
25472
23820
|
characterCount,
|
|
25473
23821
|
" ",
|
|
25474
23822
|
t("characters")
|
|
25475
23823
|
] }),
|
|
25476
|
-
maxCharacters && /* @__PURE__ */
|
|
23824
|
+
maxCharacters && /* @__PURE__ */ jsxs69("span", { className: cn(percentage > 90 && "text-destructive", percentage > 100 && "font-bold"), children: [
|
|
25477
23825
|
characterCount,
|
|
25478
23826
|
"/",
|
|
25479
23827
|
maxCharacters
|
|
@@ -25728,8 +24076,8 @@ async function prepareUEditorContentForSave({
|
|
|
25728
24076
|
}
|
|
25729
24077
|
|
|
25730
24078
|
// src/components/UEditor/UEditor.tsx
|
|
25731
|
-
import { jsx as
|
|
25732
|
-
var UEditor =
|
|
24079
|
+
import { jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
24080
|
+
var UEditor = React71.forwardRef(({
|
|
25733
24081
|
content = "",
|
|
25734
24082
|
onChange,
|
|
25735
24083
|
onHtmlChange,
|
|
@@ -25752,8 +24100,8 @@ var UEditor = React80.forwardRef(({
|
|
|
25752
24100
|
}, ref) => {
|
|
25753
24101
|
const t = useSmartTranslations("UEditor");
|
|
25754
24102
|
const effectivePlaceholder = placeholder ?? t("placeholder");
|
|
25755
|
-
const inFlightPrepareRef =
|
|
25756
|
-
const extensions =
|
|
24103
|
+
const inFlightPrepareRef = useRef30(null);
|
|
24104
|
+
const extensions = useMemo22(
|
|
25757
24105
|
() => buildUEditorExtensions({ placeholder: effectivePlaceholder, translate: t, maxCharacters, uploadImage, imageInsertMode, editable }),
|
|
25758
24106
|
[effectivePlaceholder, t, maxCharacters, uploadImage, imageInsertMode, editable]
|
|
25759
24107
|
);
|
|
@@ -25893,7 +24241,7 @@ var UEditor = React80.forwardRef(({
|
|
|
25893
24241
|
}),
|
|
25894
24242
|
[content, editor, uploadImageForSave]
|
|
25895
24243
|
);
|
|
25896
|
-
|
|
24244
|
+
useEffect37(() => {
|
|
25897
24245
|
if (editor && content !== editor.getHTML()) {
|
|
25898
24246
|
if (editor.isEmpty && content) {
|
|
25899
24247
|
editor.commands.setContent(content);
|
|
@@ -25901,7 +24249,7 @@ var UEditor = React80.forwardRef(({
|
|
|
25901
24249
|
}
|
|
25902
24250
|
}, [content, editor]);
|
|
25903
24251
|
if (!editor) {
|
|
25904
|
-
return /* @__PURE__ */
|
|
24252
|
+
return /* @__PURE__ */ jsx79(
|
|
25905
24253
|
"div",
|
|
25906
24254
|
{
|
|
25907
24255
|
className: cn("w-full rounded-lg border bg-background flex items-center justify-center text-muted-foreground", className),
|
|
@@ -25910,11 +24258,11 @@ var UEditor = React80.forwardRef(({
|
|
|
25910
24258
|
}
|
|
25911
24259
|
);
|
|
25912
24260
|
}
|
|
25913
|
-
return /* @__PURE__ */
|
|
24261
|
+
return /* @__PURE__ */ jsxs70(
|
|
25914
24262
|
"div",
|
|
25915
24263
|
{
|
|
25916
24264
|
className: cn(
|
|
25917
|
-
"group relative flex flex-col rounded-2xl md:rounded-3xl border border-border bg-card text-card-foreground overflow-hidden",
|
|
24265
|
+
"group relative flex flex-col rounded-2xl md:rounded-3xl border border-border/50 bg-card text-card-foreground overflow-hidden",
|
|
25918
24266
|
"transition-[transform,box-shadow,border-color,background-color] duration-300 ease-soft",
|
|
25919
24267
|
"shadow-sm focus-within:shadow-md focus-within:border-primary/15",
|
|
25920
24268
|
"backdrop-blur-sm",
|
|
@@ -25922,10 +24270,10 @@ var UEditor = React80.forwardRef(({
|
|
|
25922
24270
|
className
|
|
25923
24271
|
),
|
|
25924
24272
|
children: [
|
|
25925
|
-
editable && showToolbar && /* @__PURE__ */
|
|
25926
|
-
editable && showBubbleMenu && /* @__PURE__ */
|
|
25927
|
-
editable && showFloatingMenu && /* @__PURE__ */
|
|
25928
|
-
/* @__PURE__ */
|
|
24273
|
+
editable && showToolbar && /* @__PURE__ */ jsx79(EditorToolbar, { editor, variant, uploadImage, imageInsertMode }),
|
|
24274
|
+
editable && showBubbleMenu && /* @__PURE__ */ jsx79(CustomBubbleMenu, { editor }),
|
|
24275
|
+
editable && showFloatingMenu && /* @__PURE__ */ jsx79(CustomFloatingMenu, { editor }),
|
|
24276
|
+
/* @__PURE__ */ jsx79(
|
|
25929
24277
|
EditorContent,
|
|
25930
24278
|
{
|
|
25931
24279
|
editor,
|
|
@@ -25936,7 +24284,7 @@ var UEditor = React80.forwardRef(({
|
|
|
25936
24284
|
}
|
|
25937
24285
|
}
|
|
25938
24286
|
),
|
|
25939
|
-
showCharacterCount && /* @__PURE__ */
|
|
24287
|
+
showCharacterCount && /* @__PURE__ */ jsx79(CharacterCountDisplay, { editor, maxCharacters })
|
|
25940
24288
|
]
|
|
25941
24289
|
}
|
|
25942
24290
|
);
|
|
@@ -25952,11 +24300,9 @@ function getUnderverseMessages(locale = "en") {
|
|
|
25952
24300
|
export {
|
|
25953
24301
|
AccessDenied,
|
|
25954
24302
|
Alert_default as Alert,
|
|
25955
|
-
AreaChart,
|
|
25956
24303
|
Avatar_default as Avatar,
|
|
25957
24304
|
Badge_default as Badge,
|
|
25958
24305
|
Badge as BadgeBase,
|
|
25959
|
-
BarChart,
|
|
25960
24306
|
BatteryProgress,
|
|
25961
24307
|
BottomSheet,
|
|
25962
24308
|
Breadcrumb_default as Breadcrumb,
|
|
@@ -25997,7 +24343,6 @@ export {
|
|
|
25997
24343
|
FormLabel,
|
|
25998
24344
|
FormMessage,
|
|
25999
24345
|
FormSubmitButton,
|
|
26000
|
-
GaugeChart,
|
|
26001
24346
|
GlobalLoading,
|
|
26002
24347
|
GradientBadge,
|
|
26003
24348
|
Grid_default as Grid,
|
|
@@ -26009,7 +24354,6 @@ export {
|
|
|
26009
24354
|
Label,
|
|
26010
24355
|
LanguageSwitcherHeadless as LanguageSwitcher,
|
|
26011
24356
|
LanguageSwitcherHeadless,
|
|
26012
|
-
LineChart,
|
|
26013
24357
|
List_default as List,
|
|
26014
24358
|
ListItem,
|
|
26015
24359
|
LoadingBar,
|
|
@@ -26032,12 +24376,10 @@ export {
|
|
|
26032
24376
|
PageLoading,
|
|
26033
24377
|
Pagination,
|
|
26034
24378
|
PasswordInput,
|
|
26035
|
-
PieChart,
|
|
26036
24379
|
PillTabs,
|
|
26037
24380
|
Popover,
|
|
26038
24381
|
Progress,
|
|
26039
24382
|
PulseBadge,
|
|
26040
|
-
RadarChart,
|
|
26041
24383
|
RadioGroup,
|
|
26042
24384
|
RadioGroupItem,
|
|
26043
24385
|
SIZE_STYLES_BTN,
|
|
@@ -26062,7 +24404,6 @@ export {
|
|
|
26062
24404
|
SlideOver,
|
|
26063
24405
|
Slider,
|
|
26064
24406
|
SmartImage,
|
|
26065
|
-
Sparkline,
|
|
26066
24407
|
StatusBadge,
|
|
26067
24408
|
StepProgress,
|
|
26068
24409
|
Switch_default as Switch,
|