@neoptocom/neopto-ui 0.2.1 → 0.4.0
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/CONSUMER_SETUP.md +15 -15
- package/README.md +29 -23
- package/dist/index.cjs +347 -95
- package/dist/index.d.cts +143 -4
- package/dist/index.d.ts +143 -4
- package/dist/index.js +344 -97
- package/dist/styles.css +19 -15
- package/package.json +3 -4
package/dist/index.cjs
CHANGED
|
@@ -116,7 +116,7 @@ function Modal({
|
|
|
116
116
|
return reactDom.createPortal(overlay, container);
|
|
117
117
|
}
|
|
118
118
|
var styles = tailwindVariants.tv({
|
|
119
|
-
base: "text-
|
|
119
|
+
base: "text-current",
|
|
120
120
|
variants: {
|
|
121
121
|
variant: {
|
|
122
122
|
"display-lg": "text-5xl leading-tight",
|
|
@@ -326,6 +326,64 @@ function Icon({
|
|
|
326
326
|
}
|
|
327
327
|
);
|
|
328
328
|
}
|
|
329
|
+
var iconButtonStyles = tailwindVariants.tv({
|
|
330
|
+
base: [
|
|
331
|
+
"flex items-center justify-center rounded-full flex-shrink-0",
|
|
332
|
+
"transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
333
|
+
"focus-visible:ring-cyan-500/40 disabled:cursor-not-allowed disabled:opacity-50"
|
|
334
|
+
].join(" "),
|
|
335
|
+
variants: {
|
|
336
|
+
variant: {
|
|
337
|
+
ghost: "bg-transparent hover:bg-[var(--muted)] active:bg-[var(--muted)]",
|
|
338
|
+
primary: "bg-cyan-500 text-white hover:bg-cyan-400 active:bg-cyan-600",
|
|
339
|
+
secondary: "border border-[var(--border)] bg-[var(--surface)] hover:bg-[var(--muted)] active:bg-[var(--muted)]"
|
|
340
|
+
},
|
|
341
|
+
size: {
|
|
342
|
+
sm: "w-8 h-8",
|
|
343
|
+
md: "w-10 h-10",
|
|
344
|
+
lg: "w-12 h-12"
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
defaultVariants: {
|
|
348
|
+
variant: "ghost",
|
|
349
|
+
size: "md"
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
var IconButton = React2__namespace.forwardRef(
|
|
353
|
+
({
|
|
354
|
+
variant,
|
|
355
|
+
size,
|
|
356
|
+
icon,
|
|
357
|
+
iconSize,
|
|
358
|
+
iconFill = 0,
|
|
359
|
+
iconClassName,
|
|
360
|
+
className,
|
|
361
|
+
...props
|
|
362
|
+
}, ref) => {
|
|
363
|
+
const defaultIconSize = size === "sm" ? "sm" : size === "lg" ? "lg" : "md";
|
|
364
|
+
const effectiveIconSize = iconSize ?? defaultIconSize;
|
|
365
|
+
const defaultIconColorClass = variant === "primary" ? "text-white" : variant === "secondary" ? "text-[var(--fg)]" : "text-[var(--muted-fg)]";
|
|
366
|
+
const finalIconClassName = iconClassName ?? defaultIconColorClass;
|
|
367
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
368
|
+
"button",
|
|
369
|
+
{
|
|
370
|
+
ref,
|
|
371
|
+
className: iconButtonStyles({ variant, size, className }),
|
|
372
|
+
...props,
|
|
373
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
374
|
+
Icon,
|
|
375
|
+
{
|
|
376
|
+
name: icon,
|
|
377
|
+
size: effectiveIconSize,
|
|
378
|
+
fill: iconFill,
|
|
379
|
+
className: finalIconClassName
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
IconButton.displayName = "IconButton";
|
|
329
387
|
function Autocomplete({
|
|
330
388
|
className = "",
|
|
331
389
|
title,
|
|
@@ -478,27 +536,16 @@ function Autocomplete({
|
|
|
478
536
|
}
|
|
479
537
|
),
|
|
480
538
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
481
|
-
|
|
539
|
+
IconButton,
|
|
482
540
|
{
|
|
483
|
-
|
|
541
|
+
icon: selectedOption && !open ? "close" : "expand_more",
|
|
484
542
|
onClick: selectedOption && !open ? handleClear : () => setOpen((s) => !s),
|
|
485
543
|
disabled,
|
|
486
544
|
"aria-label": selectedOption && !open ? "Clear" : open ? "Collapse" : "Expand",
|
|
487
|
-
|
|
488
|
-
"
|
|
489
|
-
|
|
490
|
-
].join(" ")
|
|
491
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
492
|
-
Icon,
|
|
493
|
-
{
|
|
494
|
-
name: selectedOption && !open ? "close" : "expand_more",
|
|
495
|
-
size: "md",
|
|
496
|
-
className: [
|
|
497
|
-
"transition-transform duration-300 text-[var(--muted-fg)]",
|
|
498
|
-
open ? "rotate-180 text-[var(--color-brand)]" : ""
|
|
499
|
-
].join(" ")
|
|
500
|
-
}
|
|
501
|
-
)
|
|
545
|
+
iconClassName: [
|
|
546
|
+
"transition-transform duration-300 text-[var(--muted-fg)]",
|
|
547
|
+
open ? "rotate-180 text-[var(--color-brand)]" : ""
|
|
548
|
+
].join(" ")
|
|
502
549
|
}
|
|
503
550
|
)
|
|
504
551
|
] }) })
|
|
@@ -556,6 +603,7 @@ function Search({
|
|
|
556
603
|
disabled = false,
|
|
557
604
|
maxHeight = 152,
|
|
558
605
|
id,
|
|
606
|
+
children,
|
|
559
607
|
...props
|
|
560
608
|
}) {
|
|
561
609
|
const inputId = id ?? React2.useId();
|
|
@@ -563,6 +611,7 @@ function Search({
|
|
|
563
611
|
const [searchQuery, setSearchQuery] = React2.useState("");
|
|
564
612
|
const [open, setOpen] = React2.useState(false);
|
|
565
613
|
const [activeIndex, setActiveIndex] = React2.useState(-1);
|
|
614
|
+
const [filtersExpanded, setFiltersExpanded] = React2.useState(false);
|
|
566
615
|
const rootRef = React2.useRef(null);
|
|
567
616
|
const listRef = React2.useRef(null);
|
|
568
617
|
const searchTimeoutRef = React2.useRef(null);
|
|
@@ -572,7 +621,7 @@ function Search({
|
|
|
572
621
|
}
|
|
573
622
|
return options;
|
|
574
623
|
}, [options]);
|
|
575
|
-
|
|
624
|
+
React2.useMemo(
|
|
576
625
|
() => normalizedOptions.some((o) => !!o.image),
|
|
577
626
|
[normalizedOptions]
|
|
578
627
|
);
|
|
@@ -653,22 +702,37 @@ function Search({
|
|
|
653
702
|
}
|
|
654
703
|
};
|
|
655
704
|
}, []);
|
|
656
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
705
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
657
706
|
"div",
|
|
658
707
|
{
|
|
659
708
|
ref: rootRef,
|
|
660
709
|
className: ["relative w-full", className].join(" "),
|
|
661
710
|
...props,
|
|
662
|
-
children:
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
711
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
712
|
+
"div",
|
|
713
|
+
{
|
|
714
|
+
className: [
|
|
715
|
+
"w-full min-w-0 border rounded-[24px] bg-[var(--surface)] transition-all",
|
|
716
|
+
"border-[var(--border)] focus-within:border-[var(--color-brand)]",
|
|
717
|
+
disabled ? "opacity-60 cursor-not-allowed" : "",
|
|
718
|
+
!filtersExpanded && "h-12"
|
|
719
|
+
].join(" "),
|
|
720
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex h-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [
|
|
721
|
+
"flex flex-col w-full overflow-hidden transition-all",
|
|
722
|
+
filtersExpanded && children ? "h-auto pb-3" : "h-full"
|
|
723
|
+
].join(" "), children: [
|
|
724
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center h-12 px-2", children: [
|
|
725
|
+
children && /* @__PURE__ */ jsxRuntime.jsx(
|
|
726
|
+
IconButton,
|
|
727
|
+
{
|
|
728
|
+
icon: "filter_list",
|
|
729
|
+
onClick: () => setFiltersExpanded((prev) => !prev),
|
|
730
|
+
disabled,
|
|
731
|
+
"aria-label": filtersExpanded ? "Hide filters" : "Show filters",
|
|
732
|
+
"aria-expanded": filtersExpanded,
|
|
733
|
+
className: "mr-2"
|
|
734
|
+
}
|
|
735
|
+
),
|
|
672
736
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
673
737
|
"input",
|
|
674
738
|
{
|
|
@@ -691,82 +755,35 @@ function Search({
|
|
|
691
755
|
onKeyDown,
|
|
692
756
|
onBlur: () => setTimeout(closeList, 150),
|
|
693
757
|
disabled,
|
|
758
|
+
style: { fontFamily: "var(--font-display)", fontSize: "16px" },
|
|
694
759
|
className: [
|
|
695
|
-
"w-full rounded-full border-0 outline-none bg-transparent",
|
|
696
|
-
"
|
|
697
|
-
"
|
|
760
|
+
"w-full rounded-full border-0 outline-none bg-transparent h-12",
|
|
761
|
+
"leading-tight text-[var(--fg)] placeholder:text-[var(--muted-fg)]",
|
|
762
|
+
"px-2"
|
|
698
763
|
].join(" "),
|
|
699
764
|
placeholder: "Pesquisar",
|
|
700
765
|
onClick: () => !disabled && setOpen(true)
|
|
701
766
|
}
|
|
702
767
|
),
|
|
703
768
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
704
|
-
|
|
769
|
+
IconButton,
|
|
705
770
|
{
|
|
706
|
-
|
|
771
|
+
icon: "search",
|
|
707
772
|
onClick: selectedOption && !open ? handleClear : () => setOpen((s) => !s),
|
|
708
773
|
disabled,
|
|
709
|
-
"aria-label": selectedOption && !open ? "Clear" : open ? "Collapse" : "Expand"
|
|
710
|
-
className: [
|
|
711
|
-
"flex items-center justify-center rounded-full bg-transparent w-10 h-10",
|
|
712
|
-
disabled ? "cursor-not-allowed" : "hover:bg-[var(--muted)]"
|
|
713
|
-
].join(" "),
|
|
714
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
715
|
-
Icon,
|
|
716
|
-
{
|
|
717
|
-
name: "search",
|
|
718
|
-
size: "md",
|
|
719
|
-
className: "text-[var(--muted-fg)]"
|
|
720
|
-
}
|
|
721
|
-
)
|
|
774
|
+
"aria-label": selectedOption && !open ? "Clear" : open ? "Collapse" : "Expand"
|
|
722
775
|
}
|
|
723
776
|
)
|
|
724
|
-
] })
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
{
|
|
730
|
-
className: [
|
|
731
|
-
"absolute z-20 mt-2 w-full overflow-y-auto rounded-lg border border-[var(--border)]",
|
|
732
|
-
"bg-[var(--surface)] text-[var(--fg)] shadow-md backdrop-blur-sm px-3 py-1.5"
|
|
733
|
-
].join(" "),
|
|
734
|
-
style: { maxHeight },
|
|
735
|
-
children: normalizedOptions.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { id: listboxId, role: "listbox", ref: listRef, children: normalizedOptions.map((option, index) => {
|
|
736
|
-
const active = index === activeIndex;
|
|
737
|
-
const selected = selectedOption != null && (typeof selectedOption === "string" ? selectedOption === option.label : selectedOption.label === option.label);
|
|
738
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
739
|
-
"li",
|
|
740
|
-
{
|
|
741
|
-
role: "option",
|
|
742
|
-
"aria-selected": selected,
|
|
743
|
-
className: [
|
|
744
|
-
"flex items-center justify-between px-4 py-2 text-sm cursor-pointer transition-colors",
|
|
745
|
-
active ? "bg-[var(--muted)]" : "",
|
|
746
|
-
index !== normalizedOptions.length - 1 ? "border-b border-[var(--border)]" : ""
|
|
747
|
-
].join(" "),
|
|
748
|
-
onMouseEnter: () => setActiveIndex(index),
|
|
749
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
750
|
-
onClick: () => handleSelect(option),
|
|
751
|
-
children: [
|
|
752
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
753
|
-
anyOptionHasImage && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { name: option.label, src: option.image || void 0 }),
|
|
754
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typo, { variant: "label-lg", className: "font-normal text-[var(--fg)]", children: option.label })
|
|
755
|
-
] }),
|
|
756
|
-
Array.isArray(option.group) && option.group.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(AvatarGroup, { children: option.group.map((member, i) => /* @__PURE__ */ jsxRuntime.jsx(Avatar, { name: member.name, src: member.image || void 0 }, i)) })
|
|
757
|
-
]
|
|
758
|
-
},
|
|
759
|
-
`${option.label}-${index}`
|
|
760
|
-
);
|
|
761
|
-
}) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsxRuntime.jsx(Typo, { variant: "body-sm", className: "text-[var(--muted-fg)]", children: "No results found" }) })
|
|
762
|
-
}
|
|
763
|
-
)
|
|
764
|
-
]
|
|
777
|
+
] }),
|
|
778
|
+
children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full px-4.5 pb-3 pt-2", children })
|
|
779
|
+
] }) })
|
|
780
|
+
}
|
|
781
|
+
)
|
|
765
782
|
}
|
|
766
783
|
);
|
|
767
784
|
}
|
|
768
785
|
var buttonStyles = tailwindVariants.tv({
|
|
769
|
-
base: "cursor-pointer inline-flex items-center justify-center gap-2 rounded-[var(--radius-2xl)] px-[18px] h-12
|
|
786
|
+
base: "cursor-pointer inline-flex items-center justify-center gap-2 rounded-[var(--radius-2xl)] px-[18px] h-12 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-cyan-500/40 disabled:cursor-not-allowed disabled:opacity-50",
|
|
770
787
|
variants: {
|
|
771
788
|
variant: {
|
|
772
789
|
primary: "bg-cyan-500 text-white hover:bg-cyan-400 active:bg-cyan-600 disabled:bg-neutral-400",
|
|
@@ -774,9 +791,9 @@ var buttonStyles = tailwindVariants.tv({
|
|
|
774
791
|
ghost: "bg-transparent text-cyan-500 hover:bg-cyan-50 active:bg-cyan-100 disabled:text-neutral-400"
|
|
775
792
|
},
|
|
776
793
|
size: {
|
|
777
|
-
sm: "h-9 px-3
|
|
778
|
-
md: "h-12 px-[18px]
|
|
779
|
-
lg: "h-14 px-6
|
|
794
|
+
sm: "h-9 px-3",
|
|
795
|
+
md: "h-12 px-[18px]",
|
|
796
|
+
lg: "h-14 px-6"
|
|
780
797
|
},
|
|
781
798
|
fullWidth: {
|
|
782
799
|
true: "w-full"
|
|
@@ -789,14 +806,13 @@ var buttonStyles = tailwindVariants.tv({
|
|
|
789
806
|
});
|
|
790
807
|
var Button = React2__namespace.forwardRef(
|
|
791
808
|
({ variant, size, fullWidth, className, children, icon, ...props }, ref) => {
|
|
792
|
-
const content = icon ? /* @__PURE__ */ jsxRuntime.jsx(Typo, { variant: "body-lg", bold: "semibold", className: "text-base font-semibold", children: icon }) : children;
|
|
793
809
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
794
810
|
"button",
|
|
795
811
|
{
|
|
796
812
|
ref,
|
|
797
813
|
className: buttonStyles({ variant, size, fullWidth, className }),
|
|
798
814
|
...props,
|
|
799
|
-
children
|
|
815
|
+
children
|
|
800
816
|
}
|
|
801
817
|
);
|
|
802
818
|
}
|
|
@@ -822,13 +838,249 @@ function Chip({
|
|
|
822
838
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label })
|
|
823
839
|
] });
|
|
824
840
|
}
|
|
841
|
+
function Counter({
|
|
842
|
+
value = 0,
|
|
843
|
+
onChange,
|
|
844
|
+
min = 0,
|
|
845
|
+
max = 99,
|
|
846
|
+
step = 1,
|
|
847
|
+
className = "",
|
|
848
|
+
...props
|
|
849
|
+
}) {
|
|
850
|
+
const [count, setCount] = React2__namespace.useState(value);
|
|
851
|
+
React2__namespace.useEffect(() => {
|
|
852
|
+
setCount(value);
|
|
853
|
+
}, [value]);
|
|
854
|
+
const handleIncrement = () => {
|
|
855
|
+
const newValue = Math.min(count + step, max);
|
|
856
|
+
setCount(newValue);
|
|
857
|
+
onChange?.(newValue);
|
|
858
|
+
};
|
|
859
|
+
const handleDecrement = () => {
|
|
860
|
+
const newValue = Math.max(count - step, min);
|
|
861
|
+
setCount(newValue);
|
|
862
|
+
onChange?.(newValue);
|
|
863
|
+
};
|
|
864
|
+
const base = "inline-flex w-fit items-center justify-center gap-2 whitespace-nowrap overflow-hidden rounded-full h-7.5 px-2 text-xs font-semibold bg-[var(--muted)] text-[var(--fg)]";
|
|
865
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [base, className].join(" "), ...props, children: [
|
|
866
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-[1.5rem] text-center", children: count }),
|
|
867
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0 -my-1", children: [
|
|
868
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
869
|
+
"button",
|
|
870
|
+
{
|
|
871
|
+
type: "button",
|
|
872
|
+
onClick: handleIncrement,
|
|
873
|
+
disabled: count >= max,
|
|
874
|
+
className: "hover:opacity-70 disabled:opacity-30 disabled:cursor-not-allowed transition-opacity",
|
|
875
|
+
"aria-label": "Increment",
|
|
876
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "keyboard_arrow_up", size: "sm" })
|
|
877
|
+
}
|
|
878
|
+
),
|
|
879
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
880
|
+
"button",
|
|
881
|
+
{
|
|
882
|
+
type: "button",
|
|
883
|
+
onClick: handleDecrement,
|
|
884
|
+
disabled: count <= min,
|
|
885
|
+
className: "hover:opacity-70 disabled:opacity-30 disabled:cursor-not-allowed transition-opacity",
|
|
886
|
+
"aria-label": "Decrement",
|
|
887
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "keyboard_arrow_down", size: "sm" })
|
|
888
|
+
}
|
|
889
|
+
)
|
|
890
|
+
] })
|
|
891
|
+
] });
|
|
892
|
+
}
|
|
893
|
+
var AnimatedBgCircle = ({ colors, delay = 0 }) => {
|
|
894
|
+
const uniqueId = React2.useMemo(() => Math.random().toString(36).substr(2, 9), []);
|
|
895
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 64 64", fill: "none", className: "h-full transition-all duration-500 ease-in-out w-full", children: [
|
|
896
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
897
|
+
@keyframes colorCycle-${uniqueId} {
|
|
898
|
+
0% { fill: ${colors[0]}; }
|
|
899
|
+
25% { fill: ${colors[1]}; }
|
|
900
|
+
50% { fill: ${colors[2]}; }
|
|
901
|
+
75% { fill: ${colors[3]}; }
|
|
902
|
+
100% { fill: ${colors[0]}; }
|
|
903
|
+
}
|
|
904
|
+
@keyframes fadeIn-${uniqueId} {
|
|
905
|
+
0% { opacity: 0; }
|
|
906
|
+
100% { opacity: 1; }
|
|
907
|
+
}
|
|
908
|
+
.animated-circle-${uniqueId} {
|
|
909
|
+
animation:
|
|
910
|
+
fadeIn-${uniqueId} 1.5s ease-in-out 1.5s forwards,
|
|
911
|
+
colorCycle-${uniqueId} 4s infinite linear ${delay}s;
|
|
912
|
+
opacity: 0;
|
|
913
|
+
transition: all 0.5s ease-in-out;
|
|
914
|
+
}
|
|
915
|
+
` }),
|
|
916
|
+
/* @__PURE__ */ jsxRuntime.jsx("g", { style: { mixBlendMode: "overlay" }, filter: "url(#filter0_f_241_319)", children: /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: "32", rx: "20", cy: "32", ry: "20", className: `animated-circle-${uniqueId}` }) }),
|
|
917
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "filter0_f_241_319", filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [
|
|
918
|
+
/* @__PURE__ */ jsxRuntime.jsx("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
|
|
919
|
+
/* @__PURE__ */ jsxRuntime.jsx("feBlend", { mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }),
|
|
920
|
+
/* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "4", result: "effect1_foregroundBlur_241_319" })
|
|
921
|
+
] }) })
|
|
922
|
+
] });
|
|
923
|
+
};
|
|
924
|
+
var AnimatedBgCircle_default = AnimatedBgCircle;
|
|
925
|
+
var AnimatedBgRectangle = ({ colors, delay = 0 }) => {
|
|
926
|
+
const uniqueId = React2.useMemo(() => Math.random().toString(36).substr(2, 9), []);
|
|
927
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
928
|
+
"svg",
|
|
929
|
+
{
|
|
930
|
+
viewBox: "0 0 64 64",
|
|
931
|
+
fill: "none",
|
|
932
|
+
className: "h-full transition-all duration-500 ease-in-out w-full",
|
|
933
|
+
preserveAspectRatio: "none",
|
|
934
|
+
children: [
|
|
935
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
936
|
+
@keyframes colorCycle-${uniqueId} {
|
|
937
|
+
0% { fill: ${colors[0]}; }
|
|
938
|
+
25% { fill: ${colors[1]}; }
|
|
939
|
+
50% { fill: ${colors[2]}; }
|
|
940
|
+
75% { fill: ${colors[3]}; }
|
|
941
|
+
100% { fill: ${colors[0]}; }
|
|
942
|
+
}
|
|
943
|
+
@keyframes fadeIn-${uniqueId} {
|
|
944
|
+
0% { opacity: 0; }
|
|
945
|
+
100% { opacity: 1; }
|
|
946
|
+
}
|
|
947
|
+
.animated-circle-${uniqueId} {
|
|
948
|
+
animation:
|
|
949
|
+
fadeIn-${uniqueId} 1.5s ease-in-out 1.5s forwards,
|
|
950
|
+
colorCycle-${uniqueId} 4s infinite linear ${delay}s;
|
|
951
|
+
opacity: 0;
|
|
952
|
+
transition: all 0.5s ease-in-out;
|
|
953
|
+
}
|
|
954
|
+
` }),
|
|
955
|
+
/* @__PURE__ */ jsxRuntime.jsx("g", { style: { mixBlendMode: "overlay" }, filter: "url(#filter0_f_241_319)", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "10", y: "12", width: "44", height: "40", className: `animated-circle-${uniqueId}` }) }),
|
|
956
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "filter0_f_241_319", filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [
|
|
957
|
+
/* @__PURE__ */ jsxRuntime.jsx("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
|
|
958
|
+
/* @__PURE__ */ jsxRuntime.jsx("feBlend", { mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }),
|
|
959
|
+
/* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "4", result: "effect1_foregroundBlur_241_319" })
|
|
960
|
+
] }) })
|
|
961
|
+
]
|
|
962
|
+
}
|
|
963
|
+
);
|
|
964
|
+
};
|
|
965
|
+
var AnimatedBgRectangle_default = AnimatedBgRectangle;
|
|
966
|
+
var ChatButton = ({
|
|
967
|
+
onOpenChat,
|
|
968
|
+
hasNotification = false,
|
|
969
|
+
notificationMessage = "",
|
|
970
|
+
logoSrc,
|
|
971
|
+
logoAlt = "Chat Agent",
|
|
972
|
+
animationColors = ["#7DADB9", "#3864F5", "#55468D", "#479A8D"]
|
|
973
|
+
}) => {
|
|
974
|
+
const [showText, setShowText] = React2.useState(false);
|
|
975
|
+
const [delayedHasNotification, setDelayedHasNotification] = React2.useState(false);
|
|
976
|
+
const [isMounted, setIsMounted] = React2.useState(false);
|
|
977
|
+
React2.useEffect(() => {
|
|
978
|
+
const timer = setTimeout(() => setIsMounted(true), 250);
|
|
979
|
+
return () => clearTimeout(timer);
|
|
980
|
+
}, []);
|
|
981
|
+
React2.useEffect(() => {
|
|
982
|
+
if (hasNotification) {
|
|
983
|
+
const textTimer = setTimeout(() => setShowText(true), 500);
|
|
984
|
+
setDelayedHasNotification(true);
|
|
985
|
+
return () => clearTimeout(textTimer);
|
|
986
|
+
} else {
|
|
987
|
+
const textHideTimer = setTimeout(() => setShowText(false), 250);
|
|
988
|
+
const backgroundTimer = setTimeout(
|
|
989
|
+
() => setDelayedHasNotification(false),
|
|
990
|
+
350
|
|
991
|
+
);
|
|
992
|
+
return () => {
|
|
993
|
+
clearTimeout(textHideTimer);
|
|
994
|
+
clearTimeout(backgroundTimer);
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
}, [hasNotification]);
|
|
998
|
+
const circleAnimations = [
|
|
999
|
+
{ delay: 0, style: "left-0 top-0" },
|
|
1000
|
+
{ delay: 0.75, style: "right-0 top-0" },
|
|
1001
|
+
{ delay: 1, style: "bottom-0 left-0" },
|
|
1002
|
+
{ delay: 0.25, style: "bottom-0 right-0" }
|
|
1003
|
+
];
|
|
1004
|
+
const rectAnimations = [
|
|
1005
|
+
{ delay: 0, style: "left-0 top-0" },
|
|
1006
|
+
{ delay: 0.75, style: "right-0 top-0" },
|
|
1007
|
+
{ delay: 1, style: "bottom-0 left-0" },
|
|
1008
|
+
{ delay: 0.25, style: "bottom-0 right-0" }
|
|
1009
|
+
];
|
|
1010
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1011
|
+
"div",
|
|
1012
|
+
{
|
|
1013
|
+
className: `flex justify-end items-center fixed bottom-3 right-8 z-40 h-24 transition-all duration-600 ease-in-out ${delayedHasNotification ? "w-[432px]" : "w-24"} ${isMounted ? "opacity-100" : "opacity-0"}`,
|
|
1014
|
+
children: [
|
|
1015
|
+
circleAnimations.map((circle, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1016
|
+
"div",
|
|
1017
|
+
{
|
|
1018
|
+
className: `absolute ${circle.style} h-20 min-w-20 transition-all duration-600 ease-in-out w-20 overflow-visible flex justify-between`,
|
|
1019
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1020
|
+
AnimatedBgCircle_default,
|
|
1021
|
+
{
|
|
1022
|
+
colors: animationColors,
|
|
1023
|
+
delay: circle.delay,
|
|
1024
|
+
stretch: delayedHasNotification
|
|
1025
|
+
}
|
|
1026
|
+
)
|
|
1027
|
+
},
|
|
1028
|
+
`circle-${index}`
|
|
1029
|
+
)),
|
|
1030
|
+
rectAnimations.map((rect, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1031
|
+
"div",
|
|
1032
|
+
{
|
|
1033
|
+
className: `absolute ${rect.style} h-20 transition-all duration-600 ease-in-out ${delayedHasNotification ? "w-[324px] opacity-100 px-0" : "w-20 px-10 opacity-0"} overflow-visible flex justify-between`,
|
|
1034
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(AnimatedBgRectangle_default, { colors: animationColors, delay: rect.delay })
|
|
1035
|
+
},
|
|
1036
|
+
`rect-${index}`
|
|
1037
|
+
)),
|
|
1038
|
+
isMounted && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1039
|
+
"button",
|
|
1040
|
+
{
|
|
1041
|
+
onClick: onOpenChat,
|
|
1042
|
+
className: `flex flex-row-reverse items-center gap-1.5 fixed p-3 rounded-full shadow-md cursor-pointer h-16 mr-4 transition-all duration-600 ease-in-out border-2 border-[var(--border)] ${delayedHasNotification ? "w-[400px]" : "w-16"}`,
|
|
1043
|
+
style: {
|
|
1044
|
+
background: "var(--chat-button-gradient)"
|
|
1045
|
+
},
|
|
1046
|
+
"aria-label": hasNotification ? notificationMessage : "Open chat",
|
|
1047
|
+
children: [
|
|
1048
|
+
logoSrc && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1049
|
+
"img",
|
|
1050
|
+
{
|
|
1051
|
+
src: logoSrc,
|
|
1052
|
+
alt: logoAlt,
|
|
1053
|
+
className: "w-10 h-10 object-contain"
|
|
1054
|
+
}
|
|
1055
|
+
),
|
|
1056
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1057
|
+
Typo,
|
|
1058
|
+
{
|
|
1059
|
+
variant: "label-lg",
|
|
1060
|
+
className: `pl-2 w-80 line-clamp-2 overflow-hidden text-ellipsis text-left transition-opacity duration-300 ${showText ? "opacity-100" : "opacity-0"}`,
|
|
1061
|
+
children: notificationMessage
|
|
1062
|
+
}
|
|
1063
|
+
)
|
|
1064
|
+
]
|
|
1065
|
+
}
|
|
1066
|
+
)
|
|
1067
|
+
]
|
|
1068
|
+
}
|
|
1069
|
+
);
|
|
1070
|
+
};
|
|
1071
|
+
var ChatButton_default = ChatButton;
|
|
825
1072
|
|
|
1073
|
+
exports.AnimatedBgCircle = AnimatedBgCircle_default;
|
|
1074
|
+
exports.AnimatedBgRectangle = AnimatedBgRectangle_default;
|
|
826
1075
|
exports.Autocomplete = Autocomplete;
|
|
827
1076
|
exports.Avatar = Avatar;
|
|
828
1077
|
exports.AvatarGroup = AvatarGroup;
|
|
829
1078
|
exports.Button = Button;
|
|
1079
|
+
exports.ChatButton = ChatButton_default;
|
|
830
1080
|
exports.Chip = Chip;
|
|
1081
|
+
exports.Counter = Counter;
|
|
831
1082
|
exports.Icon = Icon;
|
|
1083
|
+
exports.IconButton = IconButton;
|
|
832
1084
|
exports.Input = Input;
|
|
833
1085
|
exports.Modal = Modal;
|
|
834
1086
|
exports.Search = Search;
|