@sentio/ui-core 0.1.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/dist/index.mjs ADDED
@@ -0,0 +1,3236 @@
1
+ // src/common/BarLoading.tsx
2
+ import { BarLoader } from "react-spinners";
3
+ import { memo } from "react";
4
+ import { cx as classNames } from "class-variance-authority";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function _BarLoading({
7
+ hint = "Loading Sentio",
8
+ loading = true,
9
+ className,
10
+ iconClassName,
11
+ width = 150,
12
+ gray
13
+ }) {
14
+ if (loading) {
15
+ return /* @__PURE__ */ jsxs(
16
+ "div",
17
+ {
18
+ className: classNames(
19
+ "loading-container flex h-full flex-col justify-center overflow-hidden",
20
+ className
21
+ ),
22
+ children: [
23
+ hint && /* @__PURE__ */ jsx("div", { className: "loading-text text-icontent text-gray my-2 text-center font-medium", children: hint }),
24
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center pt-1", children: /* @__PURE__ */ jsx(
25
+ BarLoader,
26
+ {
27
+ color: "#0756D5",
28
+ loading: true,
29
+ height: 5,
30
+ width,
31
+ cssOverride: {
32
+ borderRadius: "4px"
33
+ }
34
+ }
35
+ ) })
36
+ ]
37
+ }
38
+ );
39
+ }
40
+ return null;
41
+ }
42
+ var BarLoading = memo(_BarLoading);
43
+
44
+ // src/common/SpinLoading.tsx
45
+ import { ClipLoader } from "react-spinners";
46
+ import { cx as classNames2 } from "class-variance-authority";
47
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
48
+ var SpinLoading = function Spinner(args) {
49
+ const {
50
+ loading = false,
51
+ children,
52
+ className,
53
+ size = 48,
54
+ showMask,
55
+ maskOpacity = 80
56
+ } = args;
57
+ return /* @__PURE__ */ jsxs2("div", { className: classNames2("relative", className), children: [
58
+ showMask && loading && /* @__PURE__ */ jsx2(
59
+ "div",
60
+ {
61
+ className: classNames2(
62
+ "absolute bottom-0 left-0 right-0 top-0 z-[1]",
63
+ maskOpacity ? `bg-white dark:bg-sentio-gray-100/${maskOpacity}` : "dark:bg-sentio-gray-100 bg-white"
64
+ )
65
+ }
66
+ ),
67
+ /* @__PURE__ */ jsx2("div", { className: "absolute left-[50%] top-[50%] z-[1] -translate-y-6", children: /* @__PURE__ */ jsx2(
68
+ ClipLoader,
69
+ {
70
+ loading,
71
+ color: "#3B82F6",
72
+ size,
73
+ cssOverride: {
74
+ borderWidth: 3
75
+ }
76
+ }
77
+ ) }),
78
+ children
79
+ ] });
80
+ };
81
+
82
+ // src/common/CopyButton.tsx
83
+ import {
84
+ useState,
85
+ useCallback,
86
+ useRef,
87
+ useEffect
88
+ } from "react";
89
+ import copy from "copy-to-clipboard";
90
+ import { cx as classNames3 } from "class-variance-authority";
91
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
92
+ var CopyIcon = (props) => /* @__PURE__ */ jsx3(
93
+ "svg",
94
+ {
95
+ xmlns: "http://www.w3.org/2000/svg",
96
+ fill: "none",
97
+ viewBox: "0 0 24 24",
98
+ strokeWidth: "2",
99
+ stroke: "currentColor",
100
+ ...props,
101
+ children: /* @__PURE__ */ jsx3(
102
+ "path",
103
+ {
104
+ strokeLinecap: "round",
105
+ strokeLinejoin: "round",
106
+ d: "M16.5 8.25V6a2.25 2.25 0 0 0-2.25-2.25H6A2.25 2.25 0 0 0 3.75 6v8.25A2.25 2.25 0 0 0 6 16.5h2.25m8.25-8.25H18a2.25 2.25 0 0 1 2.25 2.25V18A2.25 2.25 0 0 1 18 20.25h-7.5A2.25 2.25 0 0 1 8.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 0 0-2.25 2.25v6"
107
+ }
108
+ )
109
+ }
110
+ );
111
+ var CopySuccessIcon = (props) => /* @__PURE__ */ jsx3(
112
+ "svg",
113
+ {
114
+ xmlns: "http://www.w3.org/2000/svg",
115
+ viewBox: "0 0 24 24",
116
+ fill: "rgb(var(--cyan-600))",
117
+ ...props,
118
+ children: /* @__PURE__ */ jsx3(
119
+ "path",
120
+ {
121
+ fillRule: "evenodd",
122
+ d: "M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z",
123
+ clipRule: "evenodd"
124
+ }
125
+ )
126
+ }
127
+ );
128
+ var CopyButton = ({
129
+ text = "",
130
+ size = 16,
131
+ ml,
132
+ mr,
133
+ placement = "right",
134
+ hover,
135
+ children,
136
+ className
137
+ }) => {
138
+ const [copied, setCopied] = useState(false);
139
+ const [isHovered, setIsHovered] = useState(false);
140
+ const [isMobile, setIsMobile] = useState(false);
141
+ const timeoutRef = useRef(null);
142
+ const iconContainerRef = useRef(null);
143
+ useEffect(() => {
144
+ const checkMobile = () => {
145
+ setIsMobile(window.innerWidth < 640);
146
+ };
147
+ checkMobile();
148
+ window.addEventListener("resize", checkMobile);
149
+ return () => window.removeEventListener("resize", checkMobile);
150
+ }, []);
151
+ const copyToClipboard = useCallback((val) => {
152
+ copy(val);
153
+ setCopied(true);
154
+ if (timeoutRef.current) {
155
+ clearTimeout(timeoutRef.current);
156
+ }
157
+ timeoutRef.current = setTimeout(() => {
158
+ setCopied(false);
159
+ timeoutRef.current = null;
160
+ }, 2e3);
161
+ }, []);
162
+ const onCopy = useCallback(
163
+ (e) => {
164
+ const target = e.target;
165
+ if (target.nodeName.toLowerCase() === "a" && target.getAttribute("href")) {
166
+ return;
167
+ }
168
+ e.stopPropagation();
169
+ e.preventDefault();
170
+ if (copied) return;
171
+ if (typeof text === "function") {
172
+ const val = text();
173
+ if (val instanceof Promise) {
174
+ val.then((res) => {
175
+ copyToClipboard(res);
176
+ }).catch((error) => {
177
+ console.error(error);
178
+ });
179
+ } else {
180
+ copyToClipboard(val);
181
+ }
182
+ } else {
183
+ copyToClipboard(text);
184
+ }
185
+ },
186
+ [copied, text, copyToClipboard]
187
+ );
188
+ const handleEventProxy = useCallback(
189
+ (e) => {
190
+ if (children) {
191
+ onCopy(e);
192
+ }
193
+ },
194
+ [children, onCopy]
195
+ );
196
+ const isPureComponent = !children;
197
+ const iconContainerStyle = {
198
+ minWidth: `${size}px`,
199
+ maxWidth: `${size}px`,
200
+ minHeight: `${size}px`,
201
+ maxHeight: `${size}px`,
202
+ marginLeft: ml !== void 0 ? `${ml}px` : void 0,
203
+ marginRight: mr !== void 0 ? `${mr}px` : void 0,
204
+ visibility: !isPureComponent && hover ? isMobile ? "visible" : isHovered ? "visible" : "hidden" : "visible"
205
+ };
206
+ const containerStyle = {
207
+ display: !isPureComponent ? "inline-block" : "contents"
208
+ };
209
+ const svgStyle = {
210
+ margin: 0
211
+ };
212
+ const iconCopyStyle = {
213
+ transform: copied ? "translateY(-100%)" : "translateY(0)"
214
+ };
215
+ const iconSuccessStyle = {
216
+ transform: copied ? "translateY(-100%)" : "translateY(100%)"
217
+ };
218
+ return /* @__PURE__ */ jsxs3(
219
+ "div",
220
+ {
221
+ className: classNames3(
222
+ "inline-block min-w-fit overflow-hidden whitespace-nowrap",
223
+ "space-x-1",
224
+ className
225
+ ),
226
+ style: containerStyle,
227
+ onClick: handleEventProxy,
228
+ onMouseEnter: () => setIsHovered(true),
229
+ onMouseLeave: () => setIsHovered(false),
230
+ children: [
231
+ placement === "right" && children,
232
+ /* @__PURE__ */ jsxs3(
233
+ "div",
234
+ {
235
+ ref: iconContainerRef,
236
+ className: classNames3(
237
+ "icon-container inline-block overflow-hidden align-sub",
238
+ isPureComponent ? className : "",
239
+ copied ? "copied" : ""
240
+ ),
241
+ style: iconContainerStyle,
242
+ children: [
243
+ /* @__PURE__ */ jsx3(
244
+ CopyIcon,
245
+ {
246
+ className: "icon-copy block cursor-pointer transition-all",
247
+ width: size,
248
+ height: size,
249
+ style: { ...svgStyle, ...iconCopyStyle },
250
+ onClick: onCopy
251
+ }
252
+ ),
253
+ /* @__PURE__ */ jsx3(
254
+ CopySuccessIcon,
255
+ {
256
+ className: "icon-success block transition-all",
257
+ width: size,
258
+ height: size,
259
+ style: { ...svgStyle, ...iconSuccessStyle }
260
+ }
261
+ )
262
+ ]
263
+ }
264
+ ),
265
+ placement === "left" && children
266
+ ]
267
+ }
268
+ );
269
+ };
270
+
271
+ // src/common/NewButton.tsx
272
+ import { cloneElement, forwardRef, useMemo } from "react";
273
+
274
+ // src/common/DivTooltip.tsx
275
+ import React, { useRef as useRef2, useState as useState2, useEffect as useEffect2 } from "react";
276
+ import {
277
+ useFloating,
278
+ useHover,
279
+ useInteractions,
280
+ safePolygon,
281
+ arrow,
282
+ offset,
283
+ shift,
284
+ flip,
285
+ autoUpdate,
286
+ FloatingPortal,
287
+ useDelayGroup
288
+ } from "@floating-ui/react";
289
+ import { cx as classNames4 } from "class-variance-authority";
290
+ import { isString } from "lodash";
291
+ import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
292
+ var PopoverTooltip = ({
293
+ icon,
294
+ text,
295
+ className,
296
+ buttonClassName,
297
+ activeButtonClassName,
298
+ children,
299
+ strategy: propStrategy,
300
+ hideArrow,
301
+ offsetOptions = 8,
302
+ placementOption = "bottom",
303
+ maxWidth = "max-w-[300px]",
304
+ usePortal = false,
305
+ enableFadeAnimation = false,
306
+ animationDuration = 150
307
+ }) => {
308
+ const arrowRef = useRef2(null);
309
+ const [open, setOpen] = useState2(false);
310
+ const [isVisible, setIsVisible] = useState2(false);
311
+ const timeoutRef = useRef2();
312
+ const {
313
+ x,
314
+ y,
315
+ refs,
316
+ strategy,
317
+ middlewareData: { arrow: { x: arrowX, y: arrowY } = {} },
318
+ context,
319
+ placement
320
+ } = useFloating({
321
+ open,
322
+ onOpenChange: (newOpen) => {
323
+ setOpen(newOpen);
324
+ if (enableFadeAnimation) {
325
+ if (newOpen) {
326
+ setIsVisible(true);
327
+ } else {
328
+ if (timeoutRef.current) {
329
+ clearTimeout(timeoutRef.current);
330
+ }
331
+ timeoutRef.current = setTimeout(() => {
332
+ setIsVisible(false);
333
+ }, animationDuration);
334
+ }
335
+ } else {
336
+ setIsVisible(newOpen);
337
+ }
338
+ },
339
+ middleware: [
340
+ offset(offsetOptions),
341
+ flip(),
342
+ shift(),
343
+ arrow({ element: arrowRef, padding: 8 })
344
+ ],
345
+ strategy: propStrategy,
346
+ placement: placementOption,
347
+ whileElementsMounted: autoUpdate
348
+ });
349
+ const {
350
+ delay = {
351
+ open: 500,
352
+ close: 0
353
+ }
354
+ } = useDelayGroup(context);
355
+ const { getReferenceProps, getFloatingProps } = useInteractions([
356
+ useHover(context, {
357
+ handleClose: safePolygon({
358
+ buffer: -Infinity
359
+ }),
360
+ delay
361
+ })
362
+ ]);
363
+ useEffect2(() => {
364
+ return () => {
365
+ if (timeoutRef.current) {
366
+ clearTimeout(timeoutRef.current);
367
+ }
368
+ };
369
+ }, []);
370
+ if (!text)
371
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
372
+ icon,
373
+ children
374
+ ] });
375
+ const Portal = usePortal ? FloatingPortal : React.Fragment;
376
+ return /* @__PURE__ */ jsxs4("div", { className: classNames4("relative flex items-center", className), children: [
377
+ /* @__PURE__ */ jsxs4(
378
+ "div",
379
+ {
380
+ ref: refs.setReference,
381
+ ...getReferenceProps(),
382
+ className: classNames4(buttonClassName, open && activeButtonClassName),
383
+ children: [
384
+ icon,
385
+ children
386
+ ]
387
+ }
388
+ ),
389
+ (enableFadeAnimation ? isVisible : open) && /* @__PURE__ */ jsx4(Portal, { children: /* @__PURE__ */ jsx4("div", { className: "_sentio_", children: /* @__PURE__ */ jsxs4(
390
+ "div",
391
+ {
392
+ className: classNames4(
393
+ "sentio-tooltip dark:bg-sentio-gray-200 z-10 rounded-md bg-white p-2 text-xs shadow-lg ring-1 ring-black ring-opacity-5 dark:ring-gray-100",
394
+ enableFadeAnimation && `transition-opacity duration-[${animationDuration}ms] ease-in-out`,
395
+ enableFadeAnimation ? open ? "opacity-100" : "opacity-0" : ""
396
+ ),
397
+ ref: refs.setFloating,
398
+ style: {
399
+ position: strategy,
400
+ top: y ?? 0,
401
+ left: x ?? 0
402
+ },
403
+ ...getFloatingProps,
404
+ children: [
405
+ !hideArrow && placement === "bottom" && /* @__PURE__ */ jsx4(
406
+ "div",
407
+ {
408
+ className: "arrow -translate-y-[5px] before:absolute before:h-2 before:w-2 before:rotate-45 before:bg-white before:border-l before:border-t before:border-black/5 dark:before:bg-sentio-gray-200 dark:before:border-gray-100",
409
+ ref: arrowRef,
410
+ style: {
411
+ left: arrowX ?? 0,
412
+ top: arrowY ?? 0,
413
+ position: "absolute"
414
+ }
415
+ }
416
+ ),
417
+ isString(text) ? /* @__PURE__ */ jsx4(
418
+ "p",
419
+ {
420
+ className: classNames4("w-max whitespace-pre-wrap", maxWidth),
421
+ children: text
422
+ }
423
+ ) : /* @__PURE__ */ jsx4(
424
+ "div",
425
+ {
426
+ className: classNames4(
427
+ "w-max overflow-auto",
428
+ maxWidth
429
+ ),
430
+ children: text
431
+ }
432
+ )
433
+ ]
434
+ }
435
+ ) }) })
436
+ ] });
437
+ };
438
+
439
+ // src/common/NewButton.tsx
440
+ import { cva, cx } from "class-variance-authority";
441
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
442
+ var buttonClass = cva(["inline-flex", "items-center", "font-medium"], {
443
+ variants: {
444
+ role: {
445
+ primary: ["btn-primary"],
446
+ secondary: ["btn-secondary"],
447
+ dashed: ["btn-dashed"],
448
+ text: ["btn-text"],
449
+ link: ["btn-link"],
450
+ tertiary: [],
451
+ tertiarytext: [],
452
+ custom: []
453
+ // custom button
454
+ },
455
+ status: {
456
+ default: "btn-status-default",
457
+ danger: "btn-status-danger"
458
+ },
459
+ size: {
460
+ sm: ["px-2", "py-1.5", "text-xs", "font-normal", "gap-2"],
461
+ default: ["px-2.5", "text-ilabel", "font-ilabel", "gap-2", "py-1"],
462
+ md: ["px-2.5 text-ilabel font-ilabel gap-2", "py-1.5"],
463
+ lg: ["px-3 text-sm gap-3", "py-2"]
464
+ },
465
+ disabled: {
466
+ false: [""],
467
+ true: ["btn-disabled"]
468
+ },
469
+ position: {
470
+ begin: ["rounded-l-md"],
471
+ end: ["rounded-r-md"],
472
+ middle: [""],
473
+ full: ["rounded-md"]
474
+ }
475
+ },
476
+ compoundVariants: [
477
+ {
478
+ role: "secondary",
479
+ size: "default",
480
+ class: "py-[3px]"
481
+ },
482
+ {
483
+ role: "dashed",
484
+ size: "default",
485
+ class: "py-[3px]"
486
+ },
487
+ {
488
+ role: "secondary",
489
+ size: "md",
490
+ class: "py-[5px]"
491
+ },
492
+ {
493
+ role: "dashed",
494
+ size: "md",
495
+ class: "py-[5px]"
496
+ },
497
+ {
498
+ role: "secondary",
499
+ size: "lg",
500
+ class: "py-[7px]"
501
+ },
502
+ {
503
+ role: "dashed",
504
+ size: "lg",
505
+ class: "py-[7px]"
506
+ },
507
+ {
508
+ role: "tertiary",
509
+ disabled: false,
510
+ class: [
511
+ "bg-primary-100 dark:bg-gray-100",
512
+ "hover:bg-primary-100/90 dark:hover:bg-gray-200/90",
513
+ "active:bg-primary-200 dark:active:bg-gray-300",
514
+ "text-primary-600 dark:text-gray-600",
515
+ "hover:text-primary-500 dark:hover:text-gray-700",
516
+ "active:text-primary-700 dark:active:text-gray-800",
517
+ "focus:ring-primary-700 dark:focus:ring-gray-800"
518
+ ]
519
+ },
520
+ {
521
+ role: "tertiary",
522
+ disabled: true,
523
+ class: "cursor-not-allowed bg-gray-100 text-gray-400"
524
+ },
525
+ {
526
+ role: "tertiarytext",
527
+ disabled: false,
528
+ class: [
529
+ "hover:bg-primary-100/90 dark:hover:bg-gray-200/90",
530
+ "active:bg-primary-200 dark:active:bg-gray-300",
531
+ "text-primary-600 dark:text-gray-600",
532
+ "hover:text-primary-500 dark:hover:text-gray-700",
533
+ "active:text-primary-700 dark:active:text-gray-800",
534
+ "focus:ring-primary-700 dark:focus:ring-gray-800"
535
+ ]
536
+ },
537
+ {
538
+ role: "tertiarytext",
539
+ disabled: true,
540
+ class: "cursor-not-allowed text-gray-400"
541
+ }
542
+ ],
543
+ defaultVariants: {
544
+ role: "secondary",
545
+ status: "default",
546
+ size: "default",
547
+ position: "full",
548
+ disabled: false
549
+ }
550
+ });
551
+ function Proccessing({ className, light }) {
552
+ return /* @__PURE__ */ jsxs5("svg", { className: `h-5 w-5 animate-spin ${className}`, viewBox: "0 0 24 24", children: [
553
+ /* @__PURE__ */ jsx5(
554
+ "circle",
555
+ {
556
+ className: light ? "opacity-5" : "opacity-10",
557
+ cx: "12",
558
+ cy: "12",
559
+ r: "10",
560
+ stroke: "currentColor",
561
+ strokeWidth: "4"
562
+ }
563
+ ),
564
+ /* @__PURE__ */ jsx5(
565
+ "path",
566
+ {
567
+ className: light ? "opacity-50" : "opacity-75",
568
+ fill: "currentColor",
569
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
570
+ }
571
+ )
572
+ ] });
573
+ }
574
+ var iconClass = cva("", {
575
+ variants: {
576
+ size: {
577
+ default: "w-4 h-4",
578
+ md: "w-[18px] h-[18px]",
579
+ lg: "w-5 h-4",
580
+ sm: "w-4 h-4"
581
+ },
582
+ disabled: {
583
+ true: "saturate-0",
584
+ false: ""
585
+ }
586
+ },
587
+ defaultVariants: {
588
+ size: "default",
589
+ disabled: false
590
+ }
591
+ });
592
+ var pIconClass = cva("", {
593
+ variants: {
594
+ size: {
595
+ default: "!w-4 !h-4",
596
+ md: "!w-[18px] !h-[18px]",
597
+ lg: "!w-5 !h-5",
598
+ sm: "!w-4 !h-4"
599
+ }
600
+ },
601
+ defaultVariants: {
602
+ size: "default"
603
+ }
604
+ });
605
+ function Button({
606
+ className,
607
+ size,
608
+ type,
609
+ role,
610
+ status,
611
+ onClick,
612
+ children,
613
+ processing,
614
+ disabled,
615
+ disabledHint,
616
+ disabledHintPortal,
617
+ position,
618
+ icon,
619
+ title,
620
+ value,
621
+ id
622
+ }, ref) {
623
+ const iconClasses = iconClass({ size, disabled });
624
+ const iconEl = useMemo(() => {
625
+ let iconEl2 = null;
626
+ if (processing) {
627
+ iconEl2 = /* @__PURE__ */ jsx5(
628
+ Proccessing,
629
+ {
630
+ className: cx(pIconClass({ size }), role == "primary" ? "text-white" : ""),
631
+ light: role !== "primary"
632
+ }
633
+ );
634
+ } else if (icon) {
635
+ iconEl2 = cloneElement(icon, { className: cx(icon.props.className, iconClasses) });
636
+ }
637
+ return iconEl2;
638
+ }, [icon, iconClasses, processing, role]);
639
+ const cls = cx(
640
+ className,
641
+ buttonClass({
642
+ size,
643
+ status,
644
+ role,
645
+ disabled,
646
+ position
647
+ })
648
+ );
649
+ const btn = /* @__PURE__ */ jsxs5(
650
+ "button",
651
+ {
652
+ title,
653
+ onClick,
654
+ type,
655
+ disabled: disabled || processing,
656
+ className: cls,
657
+ ref,
658
+ value,
659
+ suppressHydrationWarning: true,
660
+ id,
661
+ children: [
662
+ iconEl,
663
+ children
664
+ ]
665
+ }
666
+ );
667
+ if (disabled && disabledHint) {
668
+ return /* @__PURE__ */ jsx5(
669
+ PopoverTooltip,
670
+ {
671
+ usePortal: disabledHintPortal,
672
+ buttonClassName: disabledHintPortal ? "w-full" : "",
673
+ className: "text-gray",
674
+ text: /* @__PURE__ */ jsx5("p", { className: "text-sm text-gray-500", children: disabledHint }),
675
+ hideArrow: true,
676
+ children: btn
677
+ }
678
+ );
679
+ }
680
+ return btn;
681
+ }
682
+ var NewButton = forwardRef(Button);
683
+ var NewButton_default = NewButton;
684
+
685
+ // src/common/dialog/BaseDialog.tsx
686
+ import { Fragment as Fragment2, memo as memo2, createContext } from "react";
687
+ import { Dialog, Transition } from "@headlessui/react";
688
+ import { cx as classNames5 } from "class-variance-authority";
689
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
690
+ var BaseZIndexContext = createContext(10);
691
+ function _BaseDialog({
692
+ title,
693
+ open,
694
+ onClose,
695
+ onCancel,
696
+ cancelText,
697
+ cancelProps = {},
698
+ onOk,
699
+ okText,
700
+ okProps = {},
701
+ children,
702
+ buttonsClassName,
703
+ panelClassName,
704
+ titleBorder = true,
705
+ footerBorder = true,
706
+ initialFocus,
707
+ extraButtons,
708
+ errorMessages,
709
+ footer,
710
+ zIndex = 10,
711
+ mask = "normal"
712
+ }) {
713
+ return /* @__PURE__ */ jsx6(Transition, { appear: true, as: Fragment2, show: open, children: /* @__PURE__ */ jsxs6(
714
+ Dialog,
715
+ {
716
+ className: classNames5("relative", "_sentio_"),
717
+ as: "div",
718
+ onClose,
719
+ initialFocus,
720
+ style: {
721
+ zIndex
722
+ },
723
+ children: [
724
+ /* @__PURE__ */ jsx6(
725
+ Transition.Child,
726
+ {
727
+ as: Fragment2,
728
+ enter: "ease-out duration-300",
729
+ enterFrom: "opacity-0",
730
+ enterTo: "opacity-100",
731
+ leave: "ease-in duration-200",
732
+ leaveFrom: "opacity-100",
733
+ leaveTo: "opacity-0",
734
+ children: /* @__PURE__ */ jsx6(
735
+ "div",
736
+ {
737
+ className: classNames5(
738
+ "fixed inset-0 transition-opacity",
739
+ mask === "light" ? "bg-gray-500/30 dark:bg-gray-200/30" : "bg-gray-500/75 dark:bg-gray-200/50"
740
+ )
741
+ }
742
+ )
743
+ }
744
+ ),
745
+ /* @__PURE__ */ jsx6("div", { className: "fixed inset-0 z-10 overflow-y-auto", children: /* @__PURE__ */ jsx6("div", { className: "flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0", children: /* @__PURE__ */ jsx6(
746
+ Transition.Child,
747
+ {
748
+ as: Fragment2,
749
+ enter: "ease-out duration-300",
750
+ enterFrom: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
751
+ enterTo: "opacity-100 translate-y-0 sm:scale-100",
752
+ leave: "ease-in duration-200",
753
+ leaveFrom: "opacity-100 translate-y-0 sm:scale-100",
754
+ leaveTo: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
755
+ children: /* @__PURE__ */ jsxs6(
756
+ Dialog.Panel,
757
+ {
758
+ "data-testid": "create-dashboard",
759
+ className: classNames5(
760
+ "dark:bg-sidebar relative transform overflow-hidden rounded-lg bg-white pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-3xl",
761
+ panelClassName
762
+ ),
763
+ children: [
764
+ title ? /* @__PURE__ */ jsx6(
765
+ Dialog.Title,
766
+ {
767
+ as: "h3",
768
+ className: classNames5(
769
+ "text-ilabel font-ilabel text-text-foreground pl-4",
770
+ titleBorder && "border-border-color border-b pb-4"
771
+ ),
772
+ children: title
773
+ }
774
+ ) : null,
775
+ children,
776
+ footer ? footer : /* @__PURE__ */ jsxs6(
777
+ "div",
778
+ {
779
+ className: classNames5(
780
+ "flex items-center justify-between pt-4 ",
781
+ footerBorder && "border-border-color border-t"
782
+ ),
783
+ children: [
784
+ /* @__PURE__ */ jsx6(
785
+ "div",
786
+ {
787
+ className: "truncate px-4 text-sm font-semibold text-red-500",
788
+ title: errorMessages || "",
789
+ children: errorMessages || " "
790
+ }
791
+ ),
792
+ /* @__PURE__ */ jsxs6(
793
+ "div",
794
+ {
795
+ className: classNames5(
796
+ `flex flex-row-reverse items-center gap-3 px-4`,
797
+ buttonsClassName ?? ""
798
+ ),
799
+ children: [
800
+ extraButtons,
801
+ onOk && /* @__PURE__ */ jsx6(NewButton_default, { role: "primary", onClick: onOk, ...okProps, children: okText || "OK" }),
802
+ onCancel && /* @__PURE__ */ jsx6(NewButton_default, { onClick: onCancel, ...cancelProps, children: cancelText || "Cancel" })
803
+ ]
804
+ }
805
+ )
806
+ ]
807
+ }
808
+ )
809
+ ]
810
+ }
811
+ )
812
+ }
813
+ ) }) })
814
+ ]
815
+ }
816
+ ) });
817
+ }
818
+ var BaseDialog = memo2(_BaseDialog);
819
+
820
+ // src/common/DisclosurePanel.tsx
821
+ import { cx as classNames6 } from "class-variance-authority";
822
+ import isFunction from "lodash/isFunction";
823
+ import { useState as useState3, useCallback as useCallback2 } from "react";
824
+ import { LuChevronRight } from "react-icons/lu";
825
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
826
+ function DisclosurePanel({
827
+ title,
828
+ children,
829
+ defaultOpen,
830
+ className,
831
+ containerClassName,
832
+ iconClassName = "h-5 w-5",
833
+ titleClassName
834
+ }) {
835
+ const [open, setOpen] = useState3(defaultOpen || false);
836
+ const toggle = useCallback2(() => {
837
+ setOpen((prev) => !prev);
838
+ }, []);
839
+ return /* @__PURE__ */ jsxs7(
840
+ "div",
841
+ {
842
+ className: containerClassName || "dark:bg-sentio-gray-200 w-full rounded bg-[#F6F8FA]",
843
+ children: [
844
+ /* @__PURE__ */ jsxs7(
845
+ "button",
846
+ {
847
+ className: classNames6(
848
+ open ? "rounded-t" : "rounded",
849
+ "focus-visible:ring-primary-500 text-ilabel font-ilabel text-text-foreground hover:bg-sentio-gray-100 dark:hover:bg-sentio-gray-400 flex w-full px-2 py-1.5 text-left focus:outline-none focus-visible:ring focus-visible:ring-opacity-75",
850
+ titleClassName
851
+ ),
852
+ onClick: toggle,
853
+ children: [
854
+ /* @__PURE__ */ jsx7(
855
+ LuChevronRight,
856
+ {
857
+ className: classNames6(
858
+ open ? "rotate-90 transform" : "",
859
+ "mr-1 self-center transition-all",
860
+ iconClassName
861
+ )
862
+ }
863
+ ),
864
+ isFunction(title) ? title(open) : title
865
+ ]
866
+ }
867
+ ),
868
+ open && /* @__PURE__ */ jsx7("div", { className: classNames6("p-2", className), children })
869
+ ]
870
+ }
871
+ );
872
+ }
873
+
874
+ // src/common/Collapse.tsx
875
+ import { ChevronDownIcon } from "@heroicons/react/20/solid";
876
+ import { cx as classNames7 } from "class-variance-authority";
877
+
878
+ // src/utils/use-boolean.ts
879
+ import { useCallback as useCallback3, useState as useState4 } from "react";
880
+ function useBoolean(defaultValue = false) {
881
+ const [value, setValue] = useState4(defaultValue);
882
+ const setTrue = useCallback3(() => setValue(true), []);
883
+ const setFalse = useCallback3(() => setValue(false), []);
884
+ const toggle = useCallback3(() => setValue((v) => !v), []);
885
+ return {
886
+ value,
887
+ setValue,
888
+ setTrue,
889
+ setFalse,
890
+ toggle
891
+ };
892
+ }
893
+
894
+ // src/common/Collapse.tsx
895
+ import { useEffect as useEffect3 } from "react";
896
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
897
+ var Collapse = ({
898
+ title,
899
+ children,
900
+ className,
901
+ titleClassName,
902
+ defaultOpen = false,
903
+ iconClassName = "h-5 w-5"
904
+ }) => {
905
+ const { toggle, value: visible, setTrue, setFalse } = useBoolean(defaultOpen);
906
+ useEffect3(() => {
907
+ if (defaultOpen) {
908
+ setTrue();
909
+ } else {
910
+ setFalse();
911
+ }
912
+ }, [defaultOpen, setTrue, setFalse]);
913
+ return /* @__PURE__ */ jsxs8("div", { className: classNames7("space-y-2", className), children: [
914
+ /* @__PURE__ */ jsxs8(
915
+ "span",
916
+ {
917
+ className: classNames7(
918
+ "text-gray hover:text-primary active:text-primary-700 inline-flex cursor-pointer items-center gap-2",
919
+ titleClassName
920
+ ),
921
+ onClick: toggle,
922
+ children: [
923
+ title,
924
+ /* @__PURE__ */ jsx8(
925
+ ChevronDownIcon,
926
+ {
927
+ className: classNames7(
928
+ "transition",
929
+ iconClassName,
930
+ visible ? "rotate-180" : ""
931
+ )
932
+ }
933
+ )
934
+ ]
935
+ }
936
+ ),
937
+ /* @__PURE__ */ jsx8(
938
+ "div",
939
+ {
940
+ className: classNames7(
941
+ "overflow-hidden transition-all duration-200",
942
+ visible ? "max-h-[2000px] opacity-100" : "max-h-0 opacity-0"
943
+ ),
944
+ children
945
+ }
946
+ )
947
+ ] });
948
+ };
949
+
950
+ // src/common/Input.tsx
951
+ import { cva as cva2, cx as cx2 } from "class-variance-authority";
952
+ import { ExclamationCircleIcon } from "@heroicons/react/20/solid";
953
+ import { forwardRef as forwardRef2 } from "react";
954
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
955
+ var inputContainerStyles = cva2(
956
+ "flex relative rounded-md border focus-within:ring-1 w-full font-normal overflow-hidden",
957
+ {
958
+ variants: {
959
+ size: {
960
+ sm: "text-sm h-6",
961
+ md: "text-base h-8",
962
+ lg: "text-lg h-10"
963
+ },
964
+ error: {
965
+ true: "border-red-300 text-red-900 placeholder:text-red-300 focus-within:ring-red-500",
966
+ false: "border-gray-300 focus-within:ring-primary-500 focus-within:border-primary-500"
967
+ },
968
+ readOnly: {
969
+ true: "bg-gray-50 text-gray-400",
970
+ false: "text-text-foreground"
971
+ }
972
+ },
973
+ defaultVariants: {
974
+ size: "md",
975
+ error: false,
976
+ readOnly: false
977
+ },
978
+ compoundVariants: []
979
+ }
980
+ );
981
+ var inputStyles = cva2(
982
+ [
983
+ "block",
984
+ "w-full",
985
+ "placeholder:text-ilabel placeholder:font-normal",
986
+ "border-none focus:ring-0",
987
+ "focus:outline-none"
988
+ ],
989
+ {
990
+ variants: {
991
+ size: {
992
+ sm: "sm:text-xs placeholder:text-xs placeholder:font-normal pl-2 pr-6",
993
+ md: "sm:text-ilabel placeholder:text-ilabel placeholder:font-normal pl-2 pr-10",
994
+ lg: "sm:text-lg placeholder:text-lg placeholder:font-normal pl-3 pr-10"
995
+ },
996
+ error: {
997
+ true: "border-red-300",
998
+ false: "border-gray-300 "
999
+ }
1000
+ },
1001
+ defaultVariants: {
1002
+ size: "md",
1003
+ error: false
1004
+ }
1005
+ }
1006
+ );
1007
+ var iconStyles = cva2("text-red-500", {
1008
+ variants: {
1009
+ size: {
1010
+ sm: "h-4 w-4",
1011
+ md: "h-5 w-5",
1012
+ lg: "h-6 w-6"
1013
+ }
1014
+ },
1015
+ defaultVariants: {
1016
+ size: "md"
1017
+ }
1018
+ });
1019
+ var Input = forwardRef2(
1020
+ function Input2(props, inputRef) {
1021
+ const { className, error, errorClassName, size, ...rest } = props;
1022
+ const containerClassName = inputContainerStyles({
1023
+ size,
1024
+ error: !!error,
1025
+ readOnly: rest.disabled
1026
+ });
1027
+ const inputClassName = cx2(inputStyles({ size, error: !!error }), className);
1028
+ return /* @__PURE__ */ jsxs9("div", { children: [
1029
+ /* @__PURE__ */ jsxs9("div", { className: containerClassName, children: [
1030
+ /* @__PURE__ */ jsx9("input", { ...rest, ref: inputRef, className: inputClassName }),
1031
+ error && /* @__PURE__ */ jsx9("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3", children: /* @__PURE__ */ jsx9(ExclamationCircleIcon, { className: iconStyles({ size }) }) })
1032
+ ] }),
1033
+ error && /* @__PURE__ */ jsx9("p", { className: "mt-2 text-xs text-red-600", children: typeof error == "string" ? error : error.message })
1034
+ ] });
1035
+ }
1036
+ );
1037
+
1038
+ // src/common/select/Radio.tsx
1039
+ import { RadioGroup } from "@headlessui/react";
1040
+
1041
+ // src/utils/classnames.ts
1042
+ import { cx as cx3 } from "class-variance-authority";
1043
+
1044
+ // src/common/select/Radio.tsx
1045
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1046
+ function RadioSelect({
1047
+ value,
1048
+ onChange,
1049
+ label,
1050
+ labelClassName,
1051
+ options,
1052
+ vertical,
1053
+ containerClassName
1054
+ }) {
1055
+ return /* @__PURE__ */ jsxs10(RadioGroup, { value, onChange, children: [
1056
+ label && /* @__PURE__ */ jsxs10(RadioGroup.Label, { className: "text-ilabel text-text-foreground mr-4 font-medium", children: [
1057
+ label,
1058
+ ":"
1059
+ ] }),
1060
+ /* @__PURE__ */ jsx10(
1061
+ "div",
1062
+ {
1063
+ className: cx3(
1064
+ "item-center",
1065
+ vertical ? "flex flex-col gap-2" : "inline-flex gap-4",
1066
+ containerClassName
1067
+ ),
1068
+ children: options.map(({ name, value: value2 }, index) => /* @__PURE__ */ jsx10(RadioGroup.Option, { value: value2, children: ({ checked }) => /* @__PURE__ */ jsxs10("span", { className: "group/radio", children: [
1069
+ /* @__PURE__ */ jsx10(
1070
+ "input",
1071
+ {
1072
+ readOnly: true,
1073
+ type: "radio",
1074
+ checked,
1075
+ className: "border-sentio-gray-300 group-hover/radio:border-primary-500"
1076
+ }
1077
+ ),
1078
+ /* @__PURE__ */ jsx10(
1079
+ "label",
1080
+ {
1081
+ className: cx3(
1082
+ "text-ilabel group-hover/radio:text-primary-500 group-hover/radio:dark:text-primary-600 ml-2 font-medium ",
1083
+ checked ? "text-primary dark:text-primary-700" : "text-gray",
1084
+ labelClassName
1085
+ ),
1086
+ children: name
1087
+ }
1088
+ )
1089
+ ] }) }, index))
1090
+ }
1091
+ )
1092
+ ] });
1093
+ }
1094
+
1095
+ // src/common/select/Switch.tsx
1096
+ import { useCallback as useCallback4, useEffect as useEffect4, useState as useState5 } from "react";
1097
+ import { Switch as HeadlessSwitch } from "@headlessui/react";
1098
+ import { cva as cva3 } from "class-variance-authority";
1099
+ import { isFunction as isFunction2 } from "lodash";
1100
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1101
+ var switchClass = cva3(
1102
+ [
1103
+ "relative inline-flex shrink-0 rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
1104
+ ],
1105
+ {
1106
+ variants: {
1107
+ size: {
1108
+ lg: "h-8 w-[68px]",
1109
+ default: "h-6 w-[52px]",
1110
+ sm: "h-[16px] w-[30px]"
1111
+ },
1112
+ enabled: {
1113
+ true: "bg-primary group-hover:bg-primary-500",
1114
+ false: "bg-gray-400/50 group-hover:bg-primary-200"
1115
+ },
1116
+ disabled: {
1117
+ true: "cursor-not-allowed opacity-50",
1118
+ false: "cursor-pointer"
1119
+ }
1120
+ },
1121
+ defaultVariants: {
1122
+ size: "default",
1123
+ enabled: false
1124
+ },
1125
+ compoundVariants: [
1126
+ {
1127
+ enabled: false,
1128
+ disabled: true,
1129
+ class: "!bg-gray-400/50"
1130
+ }
1131
+ ]
1132
+ }
1133
+ );
1134
+ var dotClass = cva3(
1135
+ "pointer-events-none inline-block transform rounded-full bg-white dark:bg-sentio-gray-100 shadow-lg ring-0 transition duration-200 ease-in-out",
1136
+ {
1137
+ variants: {
1138
+ size: {
1139
+ lg: "h-7 w-7",
1140
+ default: "h-5 w-5",
1141
+ sm: "h-3 w-3"
1142
+ },
1143
+ enabled: {
1144
+ true: "",
1145
+ false: "translate-x-0"
1146
+ }
1147
+ },
1148
+ defaultVariants: {
1149
+ size: "default"
1150
+ },
1151
+ compoundVariants: [
1152
+ {
1153
+ size: "sm",
1154
+ enabled: true,
1155
+ class: "translate-x-3.5 switch-dot-sm"
1156
+ },
1157
+ {
1158
+ size: "default",
1159
+ enabled: true,
1160
+ class: "translate-x-7"
1161
+ },
1162
+ {
1163
+ size: "lg",
1164
+ enabled: true,
1165
+ class: "translate-x-9"
1166
+ }
1167
+ ]
1168
+ }
1169
+ );
1170
+ var labelClass = cva3(
1171
+ "text-text-foreground ml-2 font-medium align-text-bottom",
1172
+ {
1173
+ variants: {
1174
+ size: {
1175
+ lg: "text-sm leading-8",
1176
+ default: "text-icontent leading-6 ",
1177
+ sm: "text-icontent leading-5"
1178
+ },
1179
+ disabled: {
1180
+ true: "cursor-not-allowed opacity-50",
1181
+ false: "cursor-pointer"
1182
+ }
1183
+ },
1184
+ defaultVariants: {
1185
+ size: "default",
1186
+ disabled: false
1187
+ }
1188
+ }
1189
+ );
1190
+ function Switch({
1191
+ checked,
1192
+ onChange: _onChange,
1193
+ srText,
1194
+ size = "default",
1195
+ disabled,
1196
+ label
1197
+ }) {
1198
+ const [enabled, setState] = useState5(checked);
1199
+ const onChange = useCallback4(() => {
1200
+ setState((enabled2) => {
1201
+ if (isFunction2(_onChange)) {
1202
+ setTimeout(() => {
1203
+ _onChange(!enabled2);
1204
+ });
1205
+ }
1206
+ return !enabled2;
1207
+ });
1208
+ }, [_onChange]);
1209
+ useEffect4(() => {
1210
+ setState(checked);
1211
+ }, [checked]);
1212
+ return /* @__PURE__ */ jsxs11(HeadlessSwitch.Group, { children: [
1213
+ /* @__PURE__ */ jsxs11(
1214
+ HeadlessSwitch,
1215
+ {
1216
+ checked: enabled,
1217
+ onChange: onChange || setState,
1218
+ className: switchClass({
1219
+ enabled,
1220
+ size,
1221
+ disabled
1222
+ }),
1223
+ disabled,
1224
+ children: [
1225
+ srText && /* @__PURE__ */ jsx11("span", { className: "sr-only", children: srText }),
1226
+ /* @__PURE__ */ jsx11(
1227
+ "span",
1228
+ {
1229
+ "aria-hidden": "true",
1230
+ className: dotClass({
1231
+ enabled,
1232
+ size
1233
+ })
1234
+ }
1235
+ )
1236
+ ]
1237
+ }
1238
+ ),
1239
+ label && /* @__PURE__ */ jsx11(
1240
+ HeadlessSwitch.Label,
1241
+ {
1242
+ className: labelClass({
1243
+ size,
1244
+ disabled
1245
+ }),
1246
+ children: label
1247
+ }
1248
+ )
1249
+ ] });
1250
+ }
1251
+
1252
+ // src/common/select/Select.tsx
1253
+ import { Listbox } from "@headlessui/react";
1254
+ import { CheckIcon, ChevronDownIcon as ChevronDownIcon2 } from "@heroicons/react/20/solid";
1255
+ import { isEqual } from "lodash";
1256
+ import { cva as cva4 } from "class-variance-authority";
1257
+ import {
1258
+ useMemo as useMemo2,
1259
+ useRef as useRef3,
1260
+ useState as useState6,
1261
+ useContext
1262
+ } from "react";
1263
+ import isFunction3 from "lodash/isFunction";
1264
+ import { ClipLoader as ClipLoader2 } from "react-spinners";
1265
+ import { useLayer } from "react-laag";
1266
+ import { useResizeDetector } from "react-resize-detector";
1267
+ import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1268
+ var buttonClass2 = cva4(
1269
+ [
1270
+ "focus:ring-primary focus:border-primary",
1271
+ "relative w-full rounded-md border bg-white dark:bg-sentio-gray-100 text-left focus:outline-none focus:ring-1 text-ilabel"
1272
+ ],
1273
+ {
1274
+ variants: {
1275
+ open: {
1276
+ true: "bg-sentio-gray-100 ring-1 ring-primary border-primary",
1277
+ false: ""
1278
+ },
1279
+ size: {
1280
+ sm: "py-1 px-2",
1281
+ md: "py-2 px-3"
1282
+ },
1283
+ error: {
1284
+ true: "border-red-300 text-red-900 placeholder-red-300 focus-within:ring-red-500",
1285
+ false: "border-border-color"
1286
+ },
1287
+ disabled: {
1288
+ true: "cursor-not-allowed",
1289
+ false: "cursor-default"
1290
+ }
1291
+ },
1292
+ defaultVariants: {
1293
+ open: false,
1294
+ size: "sm",
1295
+ error: false,
1296
+ disabled: false
1297
+ },
1298
+ compoundVariants: [
1299
+ {
1300
+ open: true,
1301
+ error: true,
1302
+ class: "!ring-red-300 border-red-300"
1303
+ }
1304
+ ]
1305
+ }
1306
+ );
1307
+ var optionClass = cva4(["relative cursor-default select-none"], {
1308
+ variants: {
1309
+ disabled: {
1310
+ true: "cursor-not-allowed text-gray-400",
1311
+ false: "text-text-foreground"
1312
+ },
1313
+ size: {
1314
+ sm: "py-1 pl-3 pr-5",
1315
+ md: "py-2 pl-3 pr-6"
1316
+ },
1317
+ active: {
1318
+ true: "bg-primary-50 dark:bg-primary-400/50",
1319
+ false: ""
1320
+ },
1321
+ selected: {
1322
+ true: "!bg-primary-100 dark:!bg-primary-400",
1323
+ false: ""
1324
+ }
1325
+ },
1326
+ defaultVariants: {
1327
+ disabled: false,
1328
+ active: false,
1329
+ selected: false,
1330
+ size: "sm"
1331
+ }
1332
+ });
1333
+ var iconClass2 = cva4([], {
1334
+ variants: {
1335
+ size: {
1336
+ sm: "h-3.5 w-3.5",
1337
+ md: "h-4 w-4"
1338
+ },
1339
+ disabled: {
1340
+ true: "opacity-50",
1341
+ false: ""
1342
+ }
1343
+ },
1344
+ defaultVariants: {
1345
+ size: "sm",
1346
+ disabled: false
1347
+ }
1348
+ });
1349
+ function generateLabel(label, props) {
1350
+ if (isFunction3(label)) {
1351
+ return label(props);
1352
+ }
1353
+ return label;
1354
+ }
1355
+ function Select({
1356
+ className,
1357
+ buttonClassName,
1358
+ optionsClassName,
1359
+ options,
1360
+ value,
1361
+ onChange,
1362
+ placeholder,
1363
+ size = "sm",
1364
+ renderOption,
1365
+ noOptionsMessage,
1366
+ error,
1367
+ disabled,
1368
+ fetchMore,
1369
+ isFetchingMore,
1370
+ scrollBottomThreshold = 100,
1371
+ groupedOptions,
1372
+ groupedOrder,
1373
+ unmountOptions = true,
1374
+ direction = "down",
1375
+ asLayer
1376
+ }) {
1377
+ const selectedIndex = options.findIndex((o) => isEqual(o.value, value));
1378
+ const listRef = useRef3(null);
1379
+ const [open, setOpen] = useState6(false);
1380
+ const { width, ref } = useResizeDetector({
1381
+ refreshMode: "debounce",
1382
+ refreshRate: 100,
1383
+ handleHeight: false
1384
+ });
1385
+ const baseZIndex = useContext(BaseZIndexContext);
1386
+ const { renderLayer, triggerProps, layerProps } = useLayer({
1387
+ isOpen: open,
1388
+ auto: true,
1389
+ preferX: "left",
1390
+ preferY: direction === "up" ? "top" : "bottom",
1391
+ placement: direction === "up" ? "top-start" : "bottom-start",
1392
+ triggerOffset: 4,
1393
+ onOutsideClick: () => setOpen(false)
1394
+ });
1395
+ const grouped = useMemo2(() => {
1396
+ if (!groupedOptions || !options || options.length === 0) {
1397
+ return options;
1398
+ }
1399
+ const groupedOptionsList = options.reduce((acc, option) => {
1400
+ ;
1401
+ (acc[option.group] = acc[option.group] || []).push(option);
1402
+ return acc;
1403
+ }, {});
1404
+ return groupedOrder?.reduce((acc, group) => {
1405
+ return [
1406
+ ...acc,
1407
+ {
1408
+ label: group.label,
1409
+ options: groupedOptionsList[group.key] || []
1410
+ }
1411
+ ];
1412
+ }, []);
1413
+ }, [groupedOptions, groupedOrder, options]);
1414
+ const optionsElement = /* @__PURE__ */ jsxs12(
1415
+ Listbox.Options,
1416
+ {
1417
+ ref: listRef,
1418
+ onScroll: () => {
1419
+ if (listRef.current?.scrollHeight) {
1420
+ const bottomHeight = listRef.current?.scrollHeight - listRef.current?.clientHeight - listRef.current?.scrollTop;
1421
+ if (bottomHeight < scrollBottomThreshold) {
1422
+ fetchMore?.();
1423
+ }
1424
+ }
1425
+ },
1426
+ unmount: unmountOptions,
1427
+ className: cx3(
1428
+ "text-ilabel dark:bg-sentio-gray-100 scrollbar-thin max-h-60 w-full overflow-auto rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:ring-gray-100 sm:text-sm",
1429
+ asLayer ? "" : "absolute z-10",
1430
+ optionsClassName
1431
+ ),
1432
+ children: [
1433
+ !options || options.length === 0 ? /* @__PURE__ */ jsx12(
1434
+ Listbox.Option,
1435
+ {
1436
+ value: null,
1437
+ disabled: true,
1438
+ className: optionClass({ disabled: true, size }),
1439
+ children: noOptionsMessage ?? /* @__PURE__ */ jsx12("span", { className: "text-gray-400", children: "No options" })
1440
+ }
1441
+ ) : null,
1442
+ groupedOptions && grouped ? grouped.map(({ label, options: options2 }) => {
1443
+ if (!options2 || options2.length === 0) {
1444
+ return null;
1445
+ }
1446
+ return /* @__PURE__ */ jsxs12("div", { children: [
1447
+ /* @__PURE__ */ jsx12("div", { className: "text-gray px-3.5 py-1 text-xs font-medium", children: label }),
1448
+ /* @__PURE__ */ jsx12("div", { children: options2.map(
1449
+ (option, i) => /* @__PURE__ */ jsx12(
1450
+ Listbox.Option,
1451
+ {
1452
+ value: option.value,
1453
+ disabled: option.disabled,
1454
+ className: ({ active }) => optionClass({
1455
+ disabled: option.disabled,
1456
+ size,
1457
+ active,
1458
+ selected: isEqual(value, option.value)
1459
+ }),
1460
+ title: option.title,
1461
+ children: ({ selected, active }) => {
1462
+ if (renderOption) {
1463
+ return renderOption(option, { selected, active });
1464
+ }
1465
+ return /* @__PURE__ */ jsxs12(Fragment3, { children: [
1466
+ /* @__PURE__ */ jsx12(
1467
+ "span",
1468
+ {
1469
+ className: cx3(
1470
+ selected ? "font-medium" : "font-normal",
1471
+ "text-ilabel block truncate"
1472
+ ),
1473
+ children: generateLabel(option.label, {
1474
+ selected,
1475
+ active
1476
+ })
1477
+ }
1478
+ ),
1479
+ selected ? /* @__PURE__ */ jsx12(
1480
+ "span",
1481
+ {
1482
+ className: cx3(
1483
+ "text-primary-600 absolute inset-y-0 right-0 flex items-center pr-2 dark:text-white"
1484
+ ),
1485
+ children: /* @__PURE__ */ jsx12(
1486
+ CheckIcon,
1487
+ {
1488
+ className: iconClass2({ size }),
1489
+ "aria-hidden": "true"
1490
+ }
1491
+ )
1492
+ }
1493
+ ) : null
1494
+ ] });
1495
+ }
1496
+ },
1497
+ i
1498
+ )
1499
+ ) })
1500
+ ] }, label);
1501
+ }) : options.map((option, i) => /* @__PURE__ */ jsx12(
1502
+ Listbox.Option,
1503
+ {
1504
+ value: option.value,
1505
+ disabled: option.disabled,
1506
+ className: ({ active }) => optionClass({
1507
+ disabled: option.disabled,
1508
+ size,
1509
+ active,
1510
+ selected: selectedIndex === i
1511
+ }),
1512
+ title: option.title,
1513
+ children: ({ selected, active }) => {
1514
+ if (renderOption) {
1515
+ return renderOption(option, { selected, active });
1516
+ }
1517
+ return /* @__PURE__ */ jsxs12(Fragment3, { children: [
1518
+ /* @__PURE__ */ jsx12(
1519
+ "span",
1520
+ {
1521
+ className: cx3(
1522
+ selected ? "font-medium" : "font-normal",
1523
+ "text-ilabel block truncate"
1524
+ ),
1525
+ children: generateLabel(option.label, { selected, active })
1526
+ }
1527
+ ),
1528
+ selected ? /* @__PURE__ */ jsx12(
1529
+ "span",
1530
+ {
1531
+ className: cx3(
1532
+ "text-primary-600 absolute inset-y-0 right-0 flex items-center pr-2 dark:text-white"
1533
+ ),
1534
+ children: /* @__PURE__ */ jsx12(
1535
+ CheckIcon,
1536
+ {
1537
+ className: iconClass2({ size }),
1538
+ "aria-hidden": "true"
1539
+ }
1540
+ )
1541
+ }
1542
+ ) : null
1543
+ ] });
1544
+ }
1545
+ },
1546
+ i
1547
+ )),
1548
+ isFetchingMore && /* @__PURE__ */ jsx12(
1549
+ Listbox.Option,
1550
+ {
1551
+ value: null,
1552
+ disabled: true,
1553
+ className: optionClass({ disabled: true, size }),
1554
+ children: /* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center justify-center gap-2", children: [
1555
+ /* @__PURE__ */ jsx12(ClipLoader2, { size: 16, color: "#A6C2F0" }),
1556
+ /* @__PURE__ */ jsx12("span", { className: "text-gray/50 text-xs", children: "Loading more..." })
1557
+ ] })
1558
+ }
1559
+ )
1560
+ ]
1561
+ }
1562
+ );
1563
+ return /* @__PURE__ */ jsx12(Listbox, { value, onChange, disabled, children: ({ open: headlessOpen }) => {
1564
+ if (headlessOpen !== open && asLayer) {
1565
+ setOpen(headlessOpen);
1566
+ }
1567
+ return /* @__PURE__ */ jsxs12("div", { className: cx3(className, "relative"), ref, children: [
1568
+ /* @__PURE__ */ jsxs12(
1569
+ Listbox.Button,
1570
+ {
1571
+ as: "div",
1572
+ className: cx3(
1573
+ buttonClass2({
1574
+ open: headlessOpen,
1575
+ size,
1576
+ error: !!error,
1577
+ disabled: !!disabled
1578
+ }),
1579
+ buttonClassName
1580
+ ),
1581
+ ...triggerProps,
1582
+ children: [
1583
+ /* @__PURE__ */ jsx12("div", { className: "pr-4", children: selectedIndex > -1 ? generateLabel(options[selectedIndex].label, {}) : placeholder ? /* @__PURE__ */ jsx12(
1584
+ "span",
1585
+ {
1586
+ className: cx3(
1587
+ "font-normal",
1588
+ error ? "text-red-400" : "text-gray-400"
1589
+ ),
1590
+ children: placeholder
1591
+ }
1592
+ ) : "" }),
1593
+ /* @__PURE__ */ jsx12(
1594
+ "button",
1595
+ {
1596
+ type: "button",
1597
+ disabled,
1598
+ className: cx3(
1599
+ "absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none"
1600
+ ),
1601
+ children: /* @__PURE__ */ jsx12(
1602
+ ChevronDownIcon2,
1603
+ {
1604
+ className: iconClass2({ size, disabled: !!disabled })
1605
+ }
1606
+ )
1607
+ }
1608
+ )
1609
+ ]
1610
+ }
1611
+ ),
1612
+ headlessOpen ? asLayer ? renderLayer(
1613
+ /* @__PURE__ */ jsx12(
1614
+ "div",
1615
+ {
1616
+ ...layerProps,
1617
+ style: {
1618
+ ...layerProps.style,
1619
+ zIndex: Math.max(10, baseZIndex + 1),
1620
+ minWidth: width
1621
+ },
1622
+ children: optionsElement
1623
+ }
1624
+ )
1625
+ ) : optionsElement : null,
1626
+ error && /* @__PURE__ */ jsx12("p", { className: "mt-2 text-xs font-medium text-red-600", children: typeof error == "string" ? error : error.message })
1627
+ ] });
1628
+ } });
1629
+ }
1630
+
1631
+ // src/common/tree/FlatTree.tsx
1632
+ import {
1633
+ useState as useState8,
1634
+ useMemo as useMemo4,
1635
+ createContext as createContext2,
1636
+ useContext as useContext2,
1637
+ useCallback as useCallback6,
1638
+ useRef as useRef4,
1639
+ useEffect as useEffect6,
1640
+ memo as memo3,
1641
+ isValidElement,
1642
+ useTransition
1643
+ } from "react";
1644
+
1645
+ // src/common/tree/Tree.tsx
1646
+ import { useCallback as useCallback5, useState as useState7, useMemo as useMemo3, forwardRef as forwardRef3 } from "react";
1647
+
1648
+ // src/common/tree/TreeIcons.tsx
1649
+ import { LuSquarePlus, LuSquareMinus, LuSquareX, LuEye } from "react-icons/lu";
1650
+
1651
+ // src/common/tree/Tree.tsx
1652
+ import { cx as classNames8 } from "class-variance-authority";
1653
+ import { useEffect as useEffect5 } from "react";
1654
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1655
+ var Line = () => {
1656
+ return /* @__PURE__ */ jsx13("div", { className: "-my-1.5 mr-[19px] h-full min-h-[24px] w-[px] translate-x-2 border-l border-dashed border-gray-400" });
1657
+ };
1658
+ var Tree_default = forwardRef3(function Tree({
1659
+ open: defaultOpen,
1660
+ content,
1661
+ children,
1662
+ depth = 0,
1663
+ type,
1664
+ contentClassName,
1665
+ prefix,
1666
+ suffix,
1667
+ onClick,
1668
+ onOpenClick,
1669
+ showToggle,
1670
+ className,
1671
+ expandIcon = /* @__PURE__ */ jsx13(LuSquarePlus, { className: "h-[1em] w-[1em] align-middle" }),
1672
+ collapseIcon = /* @__PURE__ */ jsx13(LuSquareMinus, { className: "h-[1em] w-[1em] align-middle" })
1673
+ }, ref) {
1674
+ const [open, setOpen] = useState7(defaultOpen);
1675
+ useEffect5(() => {
1676
+ setOpen(defaultOpen);
1677
+ }, [defaultOpen]);
1678
+ const toggle = useCallback5(
1679
+ (evt) => {
1680
+ evt.stopPropagation();
1681
+ if (onOpenClick) {
1682
+ onOpenClick(!open);
1683
+ } else {
1684
+ setOpen((val) => {
1685
+ return !val;
1686
+ });
1687
+ }
1688
+ },
1689
+ [open, onOpenClick]
1690
+ );
1691
+ const lineNodes = useMemo3(() => {
1692
+ const lines = [];
1693
+ for (let i = 0; i < depth; i++) {
1694
+ lines.push(/* @__PURE__ */ jsx13(Line, {}, i));
1695
+ }
1696
+ return lines;
1697
+ }, [depth]);
1698
+ return /* @__PURE__ */ jsxs13(
1699
+ "div",
1700
+ {
1701
+ className: classNames8(
1702
+ "text-icontent font-icontent overflow-hidden text-ellipsis whitespace-nowrap align-middle",
1703
+ className
1704
+ ),
1705
+ children: [
1706
+ /* @__PURE__ */ jsxs13(
1707
+ "div",
1708
+ {
1709
+ ref,
1710
+ className: classNames8(
1711
+ "flex items-center px-2 py-1 hover:bg-gray-100",
1712
+ contentClassName
1713
+ ),
1714
+ onClick,
1715
+ children: [
1716
+ /* @__PURE__ */ jsx13("div", { className: "inline-flex shrink-0 items-center self-stretch", children: lineNodes }),
1717
+ /* @__PURE__ */ jsx13("div", { className: "inline-flex shrink-0 items-center", children: children || showToggle ? /* @__PURE__ */ jsx13(
1718
+ "button",
1719
+ {
1720
+ className: "fill-gray color-gray hover:fill-primary-500 hover:color-primary-500 dark:hover:fill-primary-700 mr-1.5 cursor-pointer",
1721
+ onClick: toggle,
1722
+ children: open ? collapseIcon : expandIcon
1723
+ }
1724
+ ) : /* @__PURE__ */ jsx13("span", { className: "mr-[19px] h-1 w-px" }) }),
1725
+ type,
1726
+ /* @__PURE__ */ jsx13("span", { className: "flex-1 align-middle", children: content })
1727
+ ]
1728
+ }
1729
+ ),
1730
+ prefix,
1731
+ open ? children : null,
1732
+ suffix
1733
+ ]
1734
+ }
1735
+ );
1736
+ });
1737
+
1738
+ // src/common/tree/FlatTree.tsx
1739
+ import { useVirtualizer } from "@tanstack/react-virtual";
1740
+ import isNumber from "lodash/isNumber";
1741
+ import { cx as classNames9 } from "class-variance-authority";
1742
+ import { throttle } from "lodash";
1743
+ import { Fragment as Fragment4, jsx as jsx14 } from "react/jsx-runtime";
1744
+ var SUFFIX_NODE_KEY = "selectedKey_after";
1745
+ var ROOT_KEY = "root";
1746
+ var TreeContext = createContext2({
1747
+ expandKeys: [],
1748
+ onExpand: (key) => {
1749
+ console.log(key);
1750
+ }
1751
+ });
1752
+ var ControledTree = ({
1753
+ item,
1754
+ selected,
1755
+ contentClassName,
1756
+ expandIcon,
1757
+ collapseIcon
1758
+ }) => {
1759
+ const { expandKeys, onExpand, onClick } = useContext2(TreeContext);
1760
+ let titleNode;
1761
+ if (typeof item.title === "function") {
1762
+ titleNode = item.title(item);
1763
+ } else {
1764
+ titleNode = item.title;
1765
+ }
1766
+ const onOpenClick = useCallback6(() => {
1767
+ onExpand(item.key);
1768
+ }, [onExpand, item.key]);
1769
+ const onNodeClick = useCallback6(() => {
1770
+ onClick?.(item);
1771
+ }, [item]);
1772
+ const isLeaf = item.children === void 0 || item.children?.length === 0;
1773
+ return /* @__PURE__ */ jsx14(
1774
+ Tree_default,
1775
+ {
1776
+ contentClassName: classNames9(
1777
+ selected ? "bg-sentio-gray-100" : "",
1778
+ item.key === SUFFIX_NODE_KEY ? "!px-0 !py-0" : "",
1779
+ contentClassName
1780
+ ),
1781
+ className: item.key === SUFFIX_NODE_KEY ? "sticky left-0 inline-block !overflow-visible" : "group/tree",
1782
+ showToggle: !isLeaf,
1783
+ open: expandKeys.includes(item.key),
1784
+ depth: item.depth,
1785
+ content: titleNode,
1786
+ onOpenClick,
1787
+ onClick: onNodeClick,
1788
+ expandIcon,
1789
+ collapseIcon
1790
+ },
1791
+ item.key
1792
+ );
1793
+ };
1794
+ var DEFAULT_ROW_HEIGHT = 35;
1795
+ function checkRootKeyDefault(v) {
1796
+ return v === ROOT_KEY;
1797
+ }
1798
+ var FlatTree = (props) => {
1799
+ const {
1800
+ data,
1801
+ defaultExpandAll,
1802
+ virtual,
1803
+ rowHeight = DEFAULT_ROW_HEIGHT,
1804
+ height,
1805
+ onClick,
1806
+ suffixNode,
1807
+ expandDepth,
1808
+ contentClassName,
1809
+ expandIcon,
1810
+ collapseIcon,
1811
+ scrollToKey,
1812
+ scrollIntoView,
1813
+ isRootKey = checkRootKeyDefault
1814
+ } = props;
1815
+ const dataRef = useRef4(null);
1816
+ const selectedKeyRef = useRef4();
1817
+ const [expandKeys, setExpandKeys] = useState8([]);
1818
+ const [selectedKey, setSelectedKey] = useState8();
1819
+ const parentRef = useRef4(null);
1820
+ useEffect6(() => {
1821
+ if (defaultExpandAll) {
1822
+ const flatten = (data2) => {
1823
+ return data2.reduce((acc, cur) => {
1824
+ const { children, key } = cur;
1825
+ acc.push(key);
1826
+ if (children) {
1827
+ acc.push(...flatten(children));
1828
+ }
1829
+ return acc;
1830
+ }, []);
1831
+ };
1832
+ setExpandKeys(flatten(data || []));
1833
+ } else {
1834
+ setExpandKeys([]);
1835
+ }
1836
+ }, [data, defaultExpandAll]);
1837
+ const flattenData = useMemo4(() => {
1838
+ const expandKeysSet = new Set(expandKeys);
1839
+ const flatten = (data2, depth = 0) => {
1840
+ return data2.reduce((acc, cur) => {
1841
+ const { children } = cur;
1842
+ acc.push({ ...cur, depth });
1843
+ if (children && expandKeysSet.has(cur.key)) {
1844
+ acc.push(...flatten(children, depth + 1));
1845
+ }
1846
+ return acc;
1847
+ }, []);
1848
+ };
1849
+ const list = flatten(data || []);
1850
+ if (selectedKey && isValidElement(suffixNode)) {
1851
+ const index = list.findIndex((item) => item.key === selectedKey);
1852
+ if (index > -1) {
1853
+ list.splice(index + 1, 0, {
1854
+ key: SUFFIX_NODE_KEY,
1855
+ title: suffixNode,
1856
+ depth: 0
1857
+ });
1858
+ }
1859
+ }
1860
+ return list;
1861
+ }, [data, expandKeys, selectedKey, suffixNode]);
1862
+ dataRef.current = flattenData;
1863
+ const estimateSize = useCallback6(
1864
+ (index) => {
1865
+ if (isNumber(rowHeight)) {
1866
+ return rowHeight;
1867
+ }
1868
+ return rowHeight(index, dataRef.current?.[index]?.key === SUFFIX_NODE_KEY);
1869
+ },
1870
+ [rowHeight]
1871
+ );
1872
+ const rowVirtualizer = useVirtualizer({
1873
+ count: flattenData.length,
1874
+ getScrollElement: () => parentRef.current,
1875
+ estimateSize,
1876
+ overscan: 10
1877
+ });
1878
+ const contextValue = useMemo4(() => {
1879
+ return {
1880
+ expandKeys,
1881
+ onExpand: (key) => {
1882
+ setExpandKeys((keys) => {
1883
+ if (keys.includes(key)) {
1884
+ return keys.filter((k) => k !== key);
1885
+ } else {
1886
+ return [...keys, key];
1887
+ }
1888
+ });
1889
+ },
1890
+ onClick: (data2) => {
1891
+ if (onClick === void 0) {
1892
+ return;
1893
+ }
1894
+ if (data2.key === SUFFIX_NODE_KEY || isRootKey(data2.key)) {
1895
+ return;
1896
+ }
1897
+ setSelectedKey((key) => {
1898
+ if (key === data2.key) {
1899
+ selectedKeyRef.current = void 0;
1900
+ return void 0;
1901
+ }
1902
+ selectedKeyRef.current = data2.key;
1903
+ return data2.key;
1904
+ });
1905
+ onClick?.(data2);
1906
+ }
1907
+ };
1908
+ }, [expandKeys, onClick]);
1909
+ useEffect6(() => {
1910
+ if (!isNumber(expandDepth)) {
1911
+ return;
1912
+ }
1913
+ const flatten = (data2, currentDepth = 0) => {
1914
+ return data2.reduce((acc, cur) => {
1915
+ const { children, key } = cur;
1916
+ if (currentDepth < expandDepth && children && children.length > 0) {
1917
+ acc.push(key);
1918
+ acc.push(...flatten(children, currentDepth + 1));
1919
+ }
1920
+ return acc;
1921
+ }, []);
1922
+ };
1923
+ setExpandKeys(flatten(data || []));
1924
+ }, [data, expandDepth]);
1925
+ useEffect6(() => {
1926
+ setSelectedKey(void 0);
1927
+ }, [expandDepth]);
1928
+ useEffect6(() => {
1929
+ if (dataRef.current && scrollToKey) {
1930
+ const index = dataRef.current.findIndex(
1931
+ (item) => item.key === scrollToKey
1932
+ );
1933
+ if (index > -1) {
1934
+ rowVirtualizer.scrollToIndex(index, {
1935
+ align: "center",
1936
+ behavior: "auto"
1937
+ });
1938
+ }
1939
+ }
1940
+ }, [scrollToKey]);
1941
+ const visibleItems = rowVirtualizer.getVirtualItems();
1942
+ const [isPending, startTransition] = useTransition();
1943
+ const onScroll = useMemo4(() => {
1944
+ if (!scrollIntoView) {
1945
+ return () => {
1946
+ };
1947
+ }
1948
+ const throttleFn = throttle(
1949
+ () => {
1950
+ startTransition(() => {
1951
+ parentRef.current?.scrollIntoView(true);
1952
+ });
1953
+ },
1954
+ 1e3,
1955
+ { trailing: true }
1956
+ );
1957
+ let lastScrollTop = 0;
1958
+ return (evt) => {
1959
+ const scrollTop = evt.currentTarget.scrollTop;
1960
+ if (scrollTop > lastScrollTop) {
1961
+ throttleFn();
1962
+ }
1963
+ lastScrollTop = scrollTop;
1964
+ };
1965
+ }, [scrollIntoView]);
1966
+ return /* @__PURE__ */ jsx14(TreeContext.Provider, { value: contextValue, children: virtual ? /* @__PURE__ */ jsx14(
1967
+ "div",
1968
+ {
1969
+ className: "overflow-auto",
1970
+ ref: parentRef,
1971
+ style: {
1972
+ height
1973
+ },
1974
+ onScroll,
1975
+ children: /* @__PURE__ */ jsx14(
1976
+ "div",
1977
+ {
1978
+ style: {
1979
+ height: `${rowVirtualizer.getTotalSize()}px`,
1980
+ width: "100%",
1981
+ position: "relative"
1982
+ },
1983
+ children: /* @__PURE__ */ jsx14(
1984
+ "div",
1985
+ {
1986
+ className: "absolute left-0 top-0 w-max min-w-full",
1987
+ style: {
1988
+ transform: visibleItems?.[0]?.start ? `translateY(${visibleItems[0].start}px)` : void 0
1989
+ },
1990
+ children: rowVirtualizer.getVirtualItems().map((virtualItem) => /* @__PURE__ */ jsx14(
1991
+ "div",
1992
+ {
1993
+ className: dataRef.current[virtualItem.index].key === scrollToKey ? "bg-primary-100" : "",
1994
+ children: /* @__PURE__ */ jsx14(
1995
+ ControledTree,
1996
+ {
1997
+ item: dataRef.current[virtualItem.index],
1998
+ selected: selectedKey === dataRef.current[virtualItem.index].key,
1999
+ contentClassName,
2000
+ expandIcon,
2001
+ collapseIcon
2002
+ }
2003
+ )
2004
+ },
2005
+ virtualItem.key
2006
+ ))
2007
+ }
2008
+ )
2009
+ }
2010
+ )
2011
+ }
2012
+ ) : /* @__PURE__ */ jsx14(Fragment4, { children: flattenData.map((item, index) => /* @__PURE__ */ jsx14(
2013
+ "div",
2014
+ {
2015
+ className: item.key === scrollToKey ? "bg-primary-100" : "",
2016
+ children: /* @__PURE__ */ jsx14(
2017
+ ControledTree,
2018
+ {
2019
+ item,
2020
+ selected: selectedKey === item.key,
2021
+ contentClassName,
2022
+ expandIcon,
2023
+ collapseIcon
2024
+ }
2025
+ )
2026
+ },
2027
+ item.key || index
2028
+ )) }) });
2029
+ };
2030
+ var FlatTree_default = memo3(FlatTree);
2031
+
2032
+ // src/common/text/LinkifyText.tsx
2033
+ import { linkifyUrlsToHtml } from "linkify-urls";
2034
+ import DOMPurify from "dompurify";
2035
+ import { memo as memo4 } from "react";
2036
+ import { isString as isString2, isUndefined, isNull } from "lodash";
2037
+ import { jsx as jsx15 } from "react/jsx-runtime";
2038
+ if (DOMPurify?.addHook) {
2039
+ DOMPurify.addHook("afterSanitizeAttributes", function(node) {
2040
+ if ("target" in node) {
2041
+ node.setAttribute("target", "_blank");
2042
+ }
2043
+ if (!node.hasAttribute("target") && (node.hasAttribute("xlink:href") || node.hasAttribute("href"))) {
2044
+ node.setAttribute("xlink:show", "new");
2045
+ }
2046
+ });
2047
+ }
2048
+ var renderTextWithColoredNumbers = (text) => {
2049
+ const numberRegex = /\b(\d+(?:\.\d+)?)\b/g;
2050
+ return text.replace(numberRegex, (match, number, offset2) => {
2051
+ const before = text.charAt(offset2 - 1);
2052
+ const after = text.charAt(offset2 + match.length);
2053
+ if (before === "x" || /[a-fA-F]/.test(before) || /[a-fA-F]/.test(after)) {
2054
+ return match;
2055
+ }
2056
+ return `<span class="font-mono text-primary-500 dark:text-primary-700">${match}</span>`;
2057
+ });
2058
+ };
2059
+ var LinkifyText = memo4(function LinkifyText2({
2060
+ text,
2061
+ className,
2062
+ isHighlightNumbers
2063
+ }) {
2064
+ if (isUndefined(text) || isNull(text)) {
2065
+ return null;
2066
+ }
2067
+ if (!isString2(text)) {
2068
+ if (text.toString) {
2069
+ return /* @__PURE__ */ jsx15("span", { className, children: text.toString() });
2070
+ }
2071
+ return null;
2072
+ }
2073
+ const linkStr = linkifyUrlsToHtml(
2074
+ isHighlightNumbers ? renderTextWithColoredNumbers(text) : text,
2075
+ {
2076
+ attributes: {
2077
+ class: "text-primary hover:underline",
2078
+ target: "_blank",
2079
+ rel: "noopener noreferrer"
2080
+ }
2081
+ }
2082
+ );
2083
+ return /* @__PURE__ */ jsx15(
2084
+ "span",
2085
+ {
2086
+ className,
2087
+ dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(linkStr) }
2088
+ }
2089
+ );
2090
+ });
2091
+
2092
+ // src/common/Empty.tsx
2093
+ import { useContext as useContext4 } from "react";
2094
+
2095
+ // src/utils/extension-context.ts
2096
+ import { createContext as createContext3, useContext as useContext3 } from "react";
2097
+ var SvgFolderContext = createContext3("");
2098
+ var useDetectExtenstion = () => {
2099
+ const folderPath = useContext3(SvgFolderContext);
2100
+ return Boolean(folderPath);
2101
+ };
2102
+ var DarkModeContext = createContext3(false);
2103
+ var useDarkMode = () => {
2104
+ return useContext3(DarkModeContext);
2105
+ };
2106
+
2107
+ // src/common/Empty.tsx
2108
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2109
+ var Empty = (props) => {
2110
+ const parentFolder = useContext4(SvgFolderContext);
2111
+ return /* @__PURE__ */ jsxs14("div", { className: "mx-auto w-fit", children: [
2112
+ /* @__PURE__ */ jsx16(
2113
+ "img",
2114
+ {
2115
+ src: props.src ?? `${parentFolder}/empty.svg`,
2116
+ width: 88,
2117
+ height: 88,
2118
+ alt: "empty icon",
2119
+ className: "mx-auto"
2120
+ }
2121
+ ),
2122
+ /* @__PURE__ */ jsx16("span", { className: "text-ilabel text-gray", children: props.title || "No results found" })
2123
+ ] });
2124
+ };
2125
+
2126
+ // src/common/badge/StatusBadge.tsx
2127
+ import { cx as classNames10 } from "class-variance-authority";
2128
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2129
+ var StatusRole = /* @__PURE__ */ ((StatusRole2) => {
2130
+ StatusRole2["Success"] = "success";
2131
+ StatusRole2["Warning"] = "warning";
2132
+ StatusRole2["Error"] = "error";
2133
+ StatusRole2["Disabled"] = "disabled";
2134
+ StatusRole2["Info"] = "info";
2135
+ return StatusRole2;
2136
+ })(StatusRole || {});
2137
+ var VersionStateColors = {
2138
+ ["success" /* Success */]: "bg-cyan-600/10 text-cyan-600",
2139
+ ["warning" /* Warning */]: "bg-orange-600/10 text-orange-600",
2140
+ ["error" /* Error */]: "bg-red-600/10 text-red-600",
2141
+ ["disabled" /* Disabled */]: "bg-gray-600/10 text-gray-600",
2142
+ ["info" /* Info */]: "bg-gray-300/10 text-gray-300"
2143
+ };
2144
+ function StatusBadge({
2145
+ status,
2146
+ className,
2147
+ colorClasses: _colorClasses,
2148
+ roundClasses,
2149
+ bubble,
2150
+ role
2151
+ }) {
2152
+ const colorClasses = _colorClasses || VersionStateColors[role || "info" /* Info */];
2153
+ return /* @__PURE__ */ jsxs15(
2154
+ "span",
2155
+ {
2156
+ className: classNames10(
2157
+ "text-ilabel inline-flex cursor-default items-center px-2 py-0.5 font-medium",
2158
+ colorClasses,
2159
+ roundClasses ? roundClasses : "rounded-full",
2160
+ className
2161
+ ),
2162
+ "data-test-status": status,
2163
+ children: [
2164
+ bubble && /* @__PURE__ */ jsx17("div", { className: "mr-1.5 h-1.5 w-1.5 rounded-full bg-current" }),
2165
+ status
2166
+ ]
2167
+ }
2168
+ );
2169
+ }
2170
+
2171
+ // src/common/HeaderToolsDropdown.tsx
2172
+ import { LuChevronDown, LuChevronUp } from "react-icons/lu";
2173
+ import { cx as classNames11 } from "class-variance-authority";
2174
+ import { jsx as jsx18 } from "react/jsx-runtime";
2175
+ var HeaderToolsToggleButton = ({
2176
+ isOpen,
2177
+ onClick,
2178
+ className
2179
+ }) => {
2180
+ return /* @__PURE__ */ jsx18(
2181
+ "button",
2182
+ {
2183
+ onClick,
2184
+ className: classNames11(
2185
+ "flex items-center justify-center rounded-md p-1 transition-colors",
2186
+ "dark:hover:bg-sentio-gray-100 hover:bg-gray-200",
2187
+ "text-text-foreground",
2188
+ className
2189
+ ),
2190
+ "aria-label": "Toggle tools",
2191
+ children: isOpen ? /* @__PURE__ */ jsx18(LuChevronUp, { className: "h-4 w-4 transition-transform" }) : /* @__PURE__ */ jsx18(LuChevronDown, { className: "h-4 w-4 transition-transform" })
2192
+ }
2193
+ );
2194
+ };
2195
+ var HeaderToolsContent = ({
2196
+ isOpen,
2197
+ children,
2198
+ className
2199
+ }) => {
2200
+ if (!isOpen) {
2201
+ return null;
2202
+ }
2203
+ return /* @__PURE__ */ jsx18("div", { className: classNames11("w-full overflow-hidden", className), children });
2204
+ };
2205
+
2206
+ // src/common/table/ResizeTable.tsx
2207
+ import {
2208
+ forwardRef as forwardRef4,
2209
+ memo as memo5,
2210
+ useCallback as useCallback7,
2211
+ useEffect as useEffect8,
2212
+ useMemo as useMemo6,
2213
+ useRef as useRef6,
2214
+ useState as useState11
2215
+ } from "react";
2216
+ import {
2217
+ useReactTable,
2218
+ getCoreRowModel,
2219
+ getSortedRowModel,
2220
+ flexRender
2221
+ } from "@tanstack/react-table";
2222
+ import { useVirtualizer as useVirtualizer2 } from "@tanstack/react-virtual";
2223
+ import {
2224
+ HiOutlineSortDescending,
2225
+ HiOutlineSortAscending,
2226
+ HiChevronDown
2227
+ } from "react-icons/hi";
2228
+ import { debounce, isEqual as isEqual2 } from "lodash";
2229
+
2230
+ // src/common/menu/PopupMenuButton.tsx
2231
+ import {
2232
+ Fragment as Fragment5,
2233
+ useState as useState10,
2234
+ useContext as useContext6,
2235
+ useMemo as useMemo5,
2236
+ useEffect as useEffect7,
2237
+ useRef as useRef5
2238
+ } from "react";
2239
+ import { Menu as Menu2, Transition as Transition2 } from "@headlessui/react";
2240
+ import {
2241
+ FloatingPortal as FloatingPortal2,
2242
+ useFloating as useFloating3,
2243
+ shift as shift3,
2244
+ flip as flip3,
2245
+ autoUpdate as autoUpdate3,
2246
+ offset as FloatingOffset
2247
+ } from "@floating-ui/react";
2248
+
2249
+ // src/common/menu/SubMenu.tsx
2250
+ import { useState as useState9, createContext as createContext4, useContext as useContext5 } from "react";
2251
+ import {
2252
+ useFloating as useFloating2,
2253
+ useHover as useHover2,
2254
+ useInteractions as useInteractions2,
2255
+ autoUpdate as autoUpdate2,
2256
+ flip as flip2,
2257
+ shift as shift2,
2258
+ safePolygon as safePolygon2
2259
+ } from "@floating-ui/react";
2260
+ import { Menu } from "@headlessui/react";
2261
+ import { HiCheck } from "react-icons/hi";
2262
+ import { ChevronRightIcon } from "@heroicons/react/20/solid";
2263
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
2264
+ var COLOR_MAP = {
2265
+ default: {
2266
+ active: "bg-gray-100 text-text-foreground dark:bg-primary-600 dark:text-white",
2267
+ default: "text-text-foreground",
2268
+ disabled: "text-gray-400 cursor-not-allowed"
2269
+ },
2270
+ danger: {
2271
+ active: "bg-red-100 text-red-600 dark:bg-red-600 dark:text-white",
2272
+ default: "text-red-600",
2273
+ disabled: "text-red-200 dark:text-red-600/40 cursor-not-allowed"
2274
+ }
2275
+ };
2276
+ var MenuContext = createContext4({});
2277
+ var MenuItem = ({ item, onSelect, labelClassName }) => {
2278
+ const { selectedKey } = useContext5(MenuContext);
2279
+ return /* @__PURE__ */ jsx19(Menu.Item, { disabled: item.disabled, children: ({ active }) => {
2280
+ if (item.items) {
2281
+ return /* @__PURE__ */ jsx19(
2282
+ SubMenuButton,
2283
+ {
2284
+ items: item.items,
2285
+ icon: item.icon,
2286
+ name: item.key,
2287
+ label: item.label,
2288
+ onSelect,
2289
+ active
2290
+ },
2291
+ item.key
2292
+ );
2293
+ }
2294
+ const buttonNode = /* @__PURE__ */ jsxs16(
2295
+ "button",
2296
+ {
2297
+ onClick: (e) => onSelect?.(item.key, e, item),
2298
+ className: cx3(
2299
+ item.disabled ? COLOR_MAP[item.status || "default"].disabled : active ? COLOR_MAP[item.status || "default"].active : COLOR_MAP[item.status || "default"].default,
2300
+ "text-ilabel font-ilabel flex w-full items-center px-4 py-1.5 transition-colors duration-200"
2301
+ ),
2302
+ disabled: item.disabled,
2303
+ children: [
2304
+ item.icon,
2305
+ /* @__PURE__ */ jsx19(
2306
+ "span",
2307
+ {
2308
+ className: cx3(
2309
+ "flex-1 truncate text-left",
2310
+ labelClassName
2311
+ ),
2312
+ children: item.label
2313
+ }
2314
+ ),
2315
+ item.key === selectedKey ? /* @__PURE__ */ jsx19(HiCheck, { className: "icon-lg ml-2" }) : null
2316
+ ]
2317
+ }
2318
+ );
2319
+ if (item.disabled && item.disabledHint) {
2320
+ return /* @__PURE__ */ jsx19(
2321
+ PopoverTooltip,
2322
+ {
2323
+ text: /* @__PURE__ */ jsx19("span", { className: "text-icontent font-icontent text-gray cursor-auto", children: item.disabledHint }),
2324
+ strategy: "fixed",
2325
+ children: buttonNode
2326
+ }
2327
+ );
2328
+ }
2329
+ return buttonNode;
2330
+ } });
2331
+ };
2332
+ var SubMenuButton = (props) => {
2333
+ const {
2334
+ label,
2335
+ status,
2336
+ items,
2337
+ disabled,
2338
+ onSelect,
2339
+ active,
2340
+ placement = "right-start",
2341
+ buttonClass: buttonClass3
2342
+ } = props;
2343
+ const [open, setOpen] = useState9(false);
2344
+ const { refs, floatingStyles, context } = useFloating2({
2345
+ open,
2346
+ onOpenChange: setOpen,
2347
+ placement,
2348
+ whileElementsMounted: autoUpdate2,
2349
+ middleware: [flip2(), shift2()]
2350
+ });
2351
+ const { getReferenceProps, getFloatingProps } = useInteractions2([
2352
+ useHover2(context, {
2353
+ handleClose: safePolygon2()
2354
+ })
2355
+ ]);
2356
+ return /* @__PURE__ */ jsxs16(
2357
+ Menu,
2358
+ {
2359
+ as: "div",
2360
+ className: cx3(
2361
+ "group flex items-center",
2362
+ "text-ilabel rounded-md",
2363
+ disabled ? "pointer-events-none cursor-not-allowed text-gray-400" : "cursor-pointer"
2364
+ ),
2365
+ children: [
2366
+ /* @__PURE__ */ jsxs16(
2367
+ Menu.Button,
2368
+ {
2369
+ className: cx3(
2370
+ active || open ? COLOR_MAP[status || "default"].active : COLOR_MAP[status || "default"].default,
2371
+ "text-ilabel font-ilabel flex w-full items-center px-4 py-1.5",
2372
+ buttonClass3
2373
+ ),
2374
+ ref: refs.setReference,
2375
+ onClick: (e) => {
2376
+ e.preventDefault();
2377
+ onSelect && onSelect(props.name, e);
2378
+ },
2379
+ ...getReferenceProps,
2380
+ children: [
2381
+ props.icon,
2382
+ /* @__PURE__ */ jsx19("span", { className: "flex-shrink flex-grow text-left", children: label }),
2383
+ /* @__PURE__ */ jsx19(
2384
+ ChevronRightIcon,
2385
+ {
2386
+ className: cx3(
2387
+ open ? "text-gray-500" : "text-gray-400",
2388
+ "h-4.5 w-4.5 flex-shrink-0 group-hover:text-gray-500",
2389
+ placement?.startsWith("bottom") ? "rotate-90" : ""
2390
+ ),
2391
+ "aria-label": "expand items"
2392
+ }
2393
+ )
2394
+ ]
2395
+ }
2396
+ ),
2397
+ open && /* @__PURE__ */ jsx19(
2398
+ Menu.Items,
2399
+ {
2400
+ static: true,
2401
+ ref: refs.setFloating,
2402
+ style: floatingStyles,
2403
+ className: "dark:bg-sentio-gray-100 dark:divide-sentio-gray-400/50 w-48 origin-top cursor-pointer divide-y divide-gray-200 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:ring-gray-100",
2404
+ ...getFloatingProps,
2405
+ children: items.map(
2406
+ (items2, i) => items2 && items2.length > 0 ? /* @__PURE__ */ jsx19(
2407
+ "div",
2408
+ {
2409
+ className: "overflow-auto py-1",
2410
+ style: { maxHeight: "60vh" },
2411
+ children: items2.map((item) => /* @__PURE__ */ jsx19(MenuItem, { item, onSelect }, item.key))
2412
+ },
2413
+ i
2414
+ ) : null
2415
+ )
2416
+ }
2417
+ )
2418
+ ]
2419
+ }
2420
+ );
2421
+ };
2422
+
2423
+ // src/utils/nav-size-context.ts
2424
+ import { createContext as createContext5 } from "react";
2425
+ var NavSizeContext = createContext5({
2426
+ small: true,
2427
+ showLabel: true,
2428
+ setSmall: (small) => {
2429
+ },
2430
+ setShowLabel: (showLabel) => {
2431
+ }
2432
+ });
2433
+
2434
+ // src/common/menu/PopupMenuButton.tsx
2435
+ import { Fragment as Fragment6, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
2436
+ function PopupMenuButton({
2437
+ buttonIcon,
2438
+ items,
2439
+ groupLabels,
2440
+ onSelect,
2441
+ ariaLabel,
2442
+ header,
2443
+ footer,
2444
+ buttonClassName,
2445
+ itemsClassName = "",
2446
+ itemLabelClassName,
2447
+ renderItem,
2448
+ placement = "bottom-start",
2449
+ offset: offset2 = 0,
2450
+ portal = true,
2451
+ width,
2452
+ selectedKey,
2453
+ onOpenCallback
2454
+ }) {
2455
+ const [menuOpen, setMenuOpen] = useState10(false);
2456
+ const { small } = useContext6(NavSizeContext);
2457
+ const { refs, floatingStyles, context } = useFloating3({
2458
+ open: menuOpen,
2459
+ onOpenChange: setMenuOpen,
2460
+ middleware: [FloatingOffset(offset2), flip3(), shift3()],
2461
+ placement,
2462
+ whileElementsMounted: autoUpdate3
2463
+ });
2464
+ const itemStyle = useMemo5(() => {
2465
+ return {
2466
+ width
2467
+ };
2468
+ }, [width]);
2469
+ const onOpenCallbackRef = useRef5(onOpenCallback);
2470
+ onOpenCallbackRef.current = onOpenCallback;
2471
+ useEffect7(() => {
2472
+ if (menuOpen) {
2473
+ onOpenCallbackRef.current?.();
2474
+ }
2475
+ }, [menuOpen]);
2476
+ let menuItems = null;
2477
+ if (menuOpen && items.length > 0) {
2478
+ menuItems = /* @__PURE__ */ jsx20(MenuContext.Provider, { value: { selectedKey }, children: /* @__PURE__ */ jsx20("div", { ref: refs.setFloating, style: floatingStyles, children: /* @__PURE__ */ jsx20(
2479
+ Transition2,
2480
+ {
2481
+ as: Fragment5,
2482
+ enter: "transition ease-out duration-100",
2483
+ enterFrom: "transform opacity-0 scale-95",
2484
+ enterTo: "transform opacity-100 scale-100",
2485
+ leave: "transition ease-in duration-75",
2486
+ leaveFrom: "transform opacity-100 scale-100",
2487
+ leaveTo: "transform opacity-0 scale-95",
2488
+ children: /* @__PURE__ */ jsxs17(
2489
+ Menu2.Items,
2490
+ {
2491
+ className: "dark:bg-sentio-gray-200 dark:divide-sentio-gray-400/50 z-10 mt-1 w-[80vw] origin-top cursor-pointer divide-y divide-gray-200 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:ring-gray-100 sm:w-64",
2492
+ style: itemStyle,
2493
+ children: [
2494
+ header,
2495
+ /* @__PURE__ */ jsx20("div", { className: `${itemsClassName} divide-y`, children: items.map((items2, i) => /* @__PURE__ */ jsxs17("div", { className: "py-1", children: [
2496
+ groupLabels?.[i] ? /* @__PURE__ */ jsx20("div", { className: "px-4 py-0.5 text-[10px] font-medium leading-[12px] text-gray-500", children: groupLabels[i] }) : null,
2497
+ items2.map(
2498
+ (item) => renderItem ? renderItem(item) : /* @__PURE__ */ jsx20(
2499
+ MenuItem,
2500
+ {
2501
+ item,
2502
+ onSelect,
2503
+ labelClassName: itemLabelClassName
2504
+ },
2505
+ item.key
2506
+ )
2507
+ )
2508
+ ] }, i)) }),
2509
+ footer
2510
+ ]
2511
+ }
2512
+ )
2513
+ }
2514
+ ) }) });
2515
+ }
2516
+ return /* @__PURE__ */ jsx20(Menu2, { children: ({ open }) => {
2517
+ setTimeout(() => {
2518
+ setMenuOpen(open);
2519
+ }, 0);
2520
+ return /* @__PURE__ */ jsxs17(Fragment6, { children: [
2521
+ /* @__PURE__ */ jsx20(
2522
+ Menu2.Button,
2523
+ {
2524
+ className: cx3(
2525
+ "text-gray w-fit px-1 hover:text-gray-500 active:text-gray-700",
2526
+ buttonClassName
2527
+ ),
2528
+ "aria-label": ariaLabel,
2529
+ ref: refs.setReference,
2530
+ as: buttonIcon ? "div" : void 0,
2531
+ children: typeof buttonIcon === "function" ? buttonIcon(menuOpen) : buttonIcon
2532
+ }
2533
+ ),
2534
+ portal ? /* @__PURE__ */ jsx20(FloatingPortal2, { children: menuItems }) : menuItems
2535
+ ] });
2536
+ } });
2537
+ }
2538
+
2539
+ // src/common/table/Icons.tsx
2540
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
2541
+ var MoveLeftIcon = (props) => /* @__PURE__ */ jsxs18(
2542
+ "svg",
2543
+ {
2544
+ width: "16",
2545
+ height: "16",
2546
+ viewBox: "0 0 16 16",
2547
+ fill: "none",
2548
+ xmlns: "http://www.w3.org/2000/svg",
2549
+ ...props,
2550
+ children: [
2551
+ /* @__PURE__ */ jsxs18("g", { clipPath: "url(#clip0_6869_7300)", children: [
2552
+ /* @__PURE__ */ jsx21(
2553
+ "path",
2554
+ {
2555
+ d: "M2.66666 8H9.33332",
2556
+ stroke: "currentColor",
2557
+ strokeWidth: "1.33333",
2558
+ strokeLinecap: "round",
2559
+ strokeLinejoin: "round"
2560
+ }
2561
+ ),
2562
+ /* @__PURE__ */ jsx21(
2563
+ "path",
2564
+ {
2565
+ d: "M2.66666 8L5.33332 10.6667",
2566
+ stroke: "currentColor",
2567
+ strokeWidth: "1.33333",
2568
+ strokeLinecap: "round",
2569
+ strokeLinejoin: "round"
2570
+ }
2571
+ ),
2572
+ /* @__PURE__ */ jsx21(
2573
+ "path",
2574
+ {
2575
+ d: "M2.66669 7.9987L5.33335 5.33203",
2576
+ stroke: "currentColor",
2577
+ strokeWidth: "1.33333",
2578
+ strokeLinecap: "round",
2579
+ strokeLinejoin: "round"
2580
+ }
2581
+ ),
2582
+ /* @__PURE__ */ jsx21(
2583
+ "path",
2584
+ {
2585
+ d: "M13.3333 2.66797V13.3346",
2586
+ stroke: "currentColor",
2587
+ strokeWidth: "1.33333",
2588
+ strokeLinecap: "round",
2589
+ strokeLinejoin: "round"
2590
+ }
2591
+ )
2592
+ ] }),
2593
+ /* @__PURE__ */ jsx21("defs", { children: /* @__PURE__ */ jsx21("clipPath", { id: "clip0_6869_7300", children: /* @__PURE__ */ jsx21("rect", { width: "16", height: "16", fill: "white" }) }) })
2594
+ ]
2595
+ }
2596
+ );
2597
+ var MoveRightIcon = (props) => /* @__PURE__ */ jsxs18(
2598
+ "svg",
2599
+ {
2600
+ width: "16",
2601
+ height: "16",
2602
+ viewBox: "0 0 16 16",
2603
+ fill: "none",
2604
+ xmlns: "http://www.w3.org/2000/svg",
2605
+ ...props,
2606
+ children: [
2607
+ /* @__PURE__ */ jsxs18("g", { clipPath: "url(#clip0_6869_7309)", children: [
2608
+ /* @__PURE__ */ jsx21(
2609
+ "path",
2610
+ {
2611
+ d: "M13.3333 8H6.66666",
2612
+ stroke: "currentColor",
2613
+ strokeWidth: "1.33333",
2614
+ strokeLinecap: "round",
2615
+ strokeLinejoin: "round"
2616
+ }
2617
+ ),
2618
+ /* @__PURE__ */ jsx21(
2619
+ "path",
2620
+ {
2621
+ d: "M13.3333 8L10.6667 10.6667",
2622
+ stroke: "currentColor",
2623
+ strokeWidth: "1.33333",
2624
+ strokeLinecap: "round",
2625
+ strokeLinejoin: "round"
2626
+ }
2627
+ ),
2628
+ /* @__PURE__ */ jsx21(
2629
+ "path",
2630
+ {
2631
+ d: "M13.3334 7.9987L10.6667 5.33203",
2632
+ stroke: "currentColor",
2633
+ strokeWidth: "1.33333",
2634
+ strokeLinecap: "round",
2635
+ strokeLinejoin: "round"
2636
+ }
2637
+ ),
2638
+ /* @__PURE__ */ jsx21(
2639
+ "path",
2640
+ {
2641
+ d: "M2.66669 2.66797V13.3346",
2642
+ stroke: "currentColor",
2643
+ strokeWidth: "1.33333",
2644
+ strokeLinecap: "round",
2645
+ strokeLinejoin: "round"
2646
+ }
2647
+ )
2648
+ ] }),
2649
+ /* @__PURE__ */ jsx21("defs", { children: /* @__PURE__ */ jsx21("clipPath", { id: "clip0_6869_7309", children: /* @__PURE__ */ jsx21("rect", { width: "16", height: "16", fill: "white" }) }) })
2650
+ ]
2651
+ }
2652
+ );
2653
+ var RenameIcon = (props) => /* @__PURE__ */ jsxs18(
2654
+ "svg",
2655
+ {
2656
+ width: "16",
2657
+ height: "16",
2658
+ viewBox: "0 0 16 16",
2659
+ fill: "none",
2660
+ xmlns: "http://www.w3.org/2000/svg",
2661
+ ...props,
2662
+ children: [
2663
+ /* @__PURE__ */ jsx21(
2664
+ "path",
2665
+ {
2666
+ d: "M8 13.3281H14",
2667
+ stroke: "currentColor",
2668
+ strokeWidth: "1.33333",
2669
+ strokeLinecap: "round",
2670
+ strokeLinejoin: "round"
2671
+ }
2672
+ ),
2673
+ /* @__PURE__ */ jsx21(
2674
+ "path",
2675
+ {
2676
+ d: "M11 2.33609C11.2652 2.07087 11.6249 1.92188 12 1.92188C12.1857 1.92188 12.3696 1.95845 12.5412 2.02953C12.7128 2.1006 12.8687 2.20477 13 2.33609C13.1313 2.46741 13.2355 2.62331 13.3066 2.79489C13.3776 2.96647 13.4142 3.15037 13.4142 3.33609C13.4142 3.52181 13.3776 3.7057 13.3066 3.87728C13.2355 4.04886 13.1313 4.20477 13 4.33609L4.66667 12.6694L2 13.3361L2.66667 10.6694L11 2.33609Z",
2677
+ stroke: "currentColor",
2678
+ strokeWidth: "1.33333",
2679
+ strokeLinecap: "round",
2680
+ strokeLinejoin: "round"
2681
+ }
2682
+ )
2683
+ ]
2684
+ }
2685
+ );
2686
+ var DeleteIcon = (props) => /* @__PURE__ */ jsxs18(
2687
+ "svg",
2688
+ {
2689
+ width: "16",
2690
+ height: "16",
2691
+ viewBox: "0 0 16 16",
2692
+ fill: "none",
2693
+ xmlns: "http://www.w3.org/2000/svg",
2694
+ ...props,
2695
+ children: [
2696
+ /* @__PURE__ */ jsxs18("g", { clipPath: "url(#clip0_6869_7344)", children: [
2697
+ /* @__PURE__ */ jsx21(
2698
+ "path",
2699
+ {
2700
+ d: "M2.66669 4.66797H13.3334",
2701
+ stroke: "currentColor",
2702
+ strokeWidth: "1.02222",
2703
+ strokeLinecap: "round",
2704
+ strokeLinejoin: "round"
2705
+ }
2706
+ ),
2707
+ /* @__PURE__ */ jsx21(
2708
+ "path",
2709
+ {
2710
+ d: "M6.66669 7.33203V11.332",
2711
+ stroke: "currentColor",
2712
+ strokeWidth: "1.02222",
2713
+ strokeLinecap: "round",
2714
+ strokeLinejoin: "round"
2715
+ }
2716
+ ),
2717
+ /* @__PURE__ */ jsx21(
2718
+ "path",
2719
+ {
2720
+ d: "M9.33331 7.33203V11.332",
2721
+ stroke: "currentColor",
2722
+ strokeWidth: "1.02222",
2723
+ strokeLinecap: "round",
2724
+ strokeLinejoin: "round"
2725
+ }
2726
+ ),
2727
+ /* @__PURE__ */ jsx21(
2728
+ "path",
2729
+ {
2730
+ d: "M3.33331 4.66797L3.99998 12.668C3.99998 13.0216 4.14046 13.3607 4.3905 13.6108C4.64055 13.8608 4.97969 14.0013 5.33331 14.0013H10.6666C11.0203 14.0013 11.3594 13.8608 11.6095 13.6108C11.8595 13.3607 12 13.0216 12 12.668L12.6666 4.66797",
2731
+ stroke: "currentColor",
2732
+ strokeWidth: "1.02222",
2733
+ strokeLinecap: "round",
2734
+ strokeLinejoin: "round"
2735
+ }
2736
+ ),
2737
+ /* @__PURE__ */ jsx21(
2738
+ "path",
2739
+ {
2740
+ d: "M6 4.66667V2.66667C6 2.48986 6.07024 2.32029 6.19526 2.19526C6.32029 2.07024 6.48986 2 6.66667 2H9.33333C9.51014 2 9.67971 2.07024 9.80474 2.19526C9.92976 2.32029 10 2.48986 10 2.66667V4.66667",
2741
+ stroke: "currentColor",
2742
+ strokeWidth: "1.02222",
2743
+ strokeLinecap: "round",
2744
+ strokeLinejoin: "round"
2745
+ }
2746
+ )
2747
+ ] }),
2748
+ /* @__PURE__ */ jsx21("defs", { children: /* @__PURE__ */ jsx21("clipPath", { id: "clip0_6869_7344", children: /* @__PURE__ */ jsx21("rect", { width: "16", height: "16", fill: "white" }) }) })
2749
+ ]
2750
+ }
2751
+ );
2752
+
2753
+ // src/common/table/ResizeTable.tsx
2754
+ import { IoReload } from "react-icons/io5";
2755
+ import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
2756
+ var reorder = (list, startIndex, endIndex) => {
2757
+ const result = Array.from(list);
2758
+ const [removed] = result.splice(startIndex, 1);
2759
+ result.splice(endIndex, 0, removed);
2760
+ return result;
2761
+ };
2762
+ function onPreventClick(e) {
2763
+ e.stopPropagation();
2764
+ }
2765
+ var _ResizeTable = forwardRef4(function _ResizeTable2({
2766
+ data,
2767
+ columns,
2768
+ columnResizeMode,
2769
+ onClick,
2770
+ height,
2771
+ onFetchMore,
2772
+ hasMore,
2773
+ isFetching,
2774
+ allowSort,
2775
+ allowEditColumn,
2776
+ allowResizeColumn,
2777
+ state = {},
2778
+ onStateChange,
2779
+ onColumnRemove,
2780
+ onColumnRename,
2781
+ minSize,
2782
+ manualSorting,
2783
+ minWidth,
2784
+ rowClassNameFn,
2785
+ enableVirtualization = false,
2786
+ estimatedRowHeight = 35,
2787
+ overscan = 5
2788
+ }, tableContainerRef) {
2789
+ const adjustedColumns = useMemo6(() => {
2790
+ let totalWidth = 0;
2791
+ const newColumns = columns.map((c) => {
2792
+ const item = Object.assign({ minSize }, c);
2793
+ totalWidth += item.size || item.minSize || 0;
2794
+ return item;
2795
+ });
2796
+ if (minWidth && totalWidth < minWidth) {
2797
+ const ratio = minWidth / totalWidth;
2798
+ newColumns.forEach((c) => {
2799
+ if (c.size) {
2800
+ c.size = Math.floor(c.size * ratio);
2801
+ } else if (c.minSize) {
2802
+ c.size = Math.floor(c.minSize * ratio);
2803
+ }
2804
+ });
2805
+ }
2806
+ return newColumns;
2807
+ }, [columns, minSize, minWidth]);
2808
+ const [tableState, setTableState] = useState11(() => {
2809
+ const initialState = {
2810
+ pagination: {
2811
+ pageIndex: 0,
2812
+ pageSize: 10
2813
+ },
2814
+ ...state
2815
+ };
2816
+ return initialState;
2817
+ });
2818
+ const table = useReactTable({
2819
+ data,
2820
+ columns: adjustedColumns,
2821
+ columnResizeMode,
2822
+ getCoreRowModel: getCoreRowModel(),
2823
+ getSortedRowModel: allowSort ? getSortedRowModel() : void 0,
2824
+ state: tableState,
2825
+ onStateChange: setTableState,
2826
+ manualSorting
2827
+ });
2828
+ useEffect8(() => {
2829
+ if (state && Object.keys(state).length > 0) {
2830
+ setTableState((prev) => {
2831
+ const newState = {
2832
+ ...prev,
2833
+ ...state,
2834
+ pagination: prev.pagination || state.pagination || { pageIndex: 0, pageSize: 10 }
2835
+ };
2836
+ return isEqual2(prev, newState) ? prev : newState;
2837
+ });
2838
+ }
2839
+ }, [state]);
2840
+ const debounceStateChange = useMemo6(() => {
2841
+ if (!onStateChange) return void 0;
2842
+ return debounce(onStateChange, 500, {});
2843
+ }, [onStateChange]);
2844
+ useEffect8(() => {
2845
+ debounceStateChange?.(tableState);
2846
+ }, [debounceStateChange, tableState]);
2847
+ const fetchMoreOnBottomReached = useMemo6(() => {
2848
+ return debounce((containerRefElement) => {
2849
+ if (containerRefElement) {
2850
+ const { scrollHeight, scrollTop, clientHeight } = containerRefElement;
2851
+ if (scrollHeight - scrollTop - clientHeight < 300 && !isFetching && hasMore) {
2852
+ onFetchMore?.();
2853
+ }
2854
+ }
2855
+ }, 500);
2856
+ }, [onFetchMore, isFetching, hasMore]);
2857
+ const tableContainerElementRef = useRef6(null);
2858
+ useEffect8(() => {
2859
+ if (tableContainerRef) {
2860
+ if (typeof tableContainerRef === "function") {
2861
+ tableContainerRef(tableContainerElementRef.current);
2862
+ } else {
2863
+ tableContainerRef.current = tableContainerElementRef.current;
2864
+ }
2865
+ }
2866
+ }, [tableContainerRef]);
2867
+ const rowVirtualizer = useVirtualizer2({
2868
+ count: enableVirtualization ? table.getRowModel().rows.length : 0,
2869
+ getScrollElement: () => tableContainerElementRef.current,
2870
+ estimateSize: useCallback7(() => estimatedRowHeight, [estimatedRowHeight]),
2871
+ overscan,
2872
+ enabled: enableVirtualization
2873
+ });
2874
+ const virtualRows = enableVirtualization ? rowVirtualizer.getVirtualItems() : [];
2875
+ const paddingTop = enableVirtualization && virtualRows.length > 0 ? virtualRows[0].start : 0;
2876
+ const paddingBottom = enableVirtualization && virtualRows.length > 0 ? rowVirtualizer.getTotalSize() - (virtualRows[virtualRows.length - 1].start + virtualRows[virtualRows.length - 1].size) : 0;
2877
+ return /* @__PURE__ */ jsx22(
2878
+ "div",
2879
+ {
2880
+ className: "overflow-auto",
2881
+ style: height ? { height } : void 0,
2882
+ ref: tableContainerElementRef,
2883
+ onScroll: (e) => fetchMoreOnBottomReached(e.target),
2884
+ children: /* @__PURE__ */ jsxs19(
2885
+ "table",
2886
+ {
2887
+ className: "w-fit",
2888
+ ...{
2889
+ style: {
2890
+ width: table.getCenterTotalSize()
2891
+ }
2892
+ },
2893
+ children: [
2894
+ /* @__PURE__ */ jsx22("thead", { className: "dark:bg-sentio-gray-100 sticky top-0 z-[1] bg-white", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx22(
2895
+ "tr",
2896
+ {
2897
+ className: "relative flex w-fit cursor-pointer items-center border-b",
2898
+ children: headerGroup.headers.map((header, i) => /* @__PURE__ */ jsxs19(
2899
+ "th",
2900
+ {
2901
+ colSpan: header.colSpan,
2902
+ style: {
2903
+ width: header.getSize()
2904
+ },
2905
+ className: "text-ilabel group/th blinked dark:hover:!bg-sentio-gray-300 dark:bg-sentio-gray-100 text-text-foreground hover:!bg-primary-50 relative flex items-center whitespace-nowrap bg-white px-2 py-2 text-left font-semibold",
2906
+ onClick: header.column.getToggleSortingHandler(),
2907
+ children: [
2908
+ /* @__PURE__ */ jsxs19("span", { className: "flex w-full flex-1 overflow-hidden", children: [
2909
+ /* @__PURE__ */ jsx22("span", { className: "flex-1 truncate", children: header.isPlaceholder ? null : flexRender(
2910
+ header.column.columnDef.header,
2911
+ header.getContext()
2912
+ ) }),
2913
+ header.column.getCanSort() && allowSort ? /* @__PURE__ */ jsx22(
2914
+ "span",
2915
+ {
2916
+ className: cx3(
2917
+ header.column.getIsSorted() ? "hover:text-text-foreground visible hover:bg-gray-200" : "invisible",
2918
+ "ml-2 flex-none rounded px-1 py-0.5 text-gray-600 group-hover:visible group-focus:visible",
2919
+ "inline-block cursor-pointer",
2920
+ "shrink-0"
2921
+ ),
2922
+ children: header.column.getIsSorted() ? header.column.getIsSorted() == "desc" ? /* @__PURE__ */ jsx22(HiOutlineSortDescending, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx22(HiOutlineSortAscending, { className: "h-4 w-4" }) : ""
2923
+ }
2924
+ ) : null
2925
+ ] }),
2926
+ allowEditColumn !== false && /* @__PURE__ */ jsx22(
2927
+ "span",
2928
+ {
2929
+ className: "invisible inline-block group-hover/th:visible",
2930
+ onClick: onPreventClick,
2931
+ children: /* @__PURE__ */ jsx22(
2932
+ PopupMenuButton,
2933
+ {
2934
+ buttonClassName: "align-text-bottom",
2935
+ onSelect: (commandKey) => {
2936
+ const colOrder = headerGroup.headers.map(
2937
+ (item) => item?.id
2938
+ );
2939
+ switch (commandKey) {
2940
+ case "reorder.left":
2941
+ table.setColumnOrder(
2942
+ reorder(colOrder, i, i - 1)
2943
+ );
2944
+ break;
2945
+ case "reorder.right":
2946
+ table.setColumnOrder(
2947
+ reorder(colOrder, i, i + 1)
2948
+ );
2949
+ break;
2950
+ case "delete":
2951
+ onColumnRemove?.(header.column.columnDef);
2952
+ break;
2953
+ default:
2954
+ console.log(commandKey, "is not applied");
2955
+ }
2956
+ },
2957
+ buttonIcon: /* @__PURE__ */ jsx22(HiChevronDown, { className: "icon mr-2" }),
2958
+ items: [
2959
+ [
2960
+ {
2961
+ key: "reorder.left",
2962
+ label: "Move column left",
2963
+ icon: /* @__PURE__ */ jsx22(MoveLeftIcon, { className: "mr-2" }),
2964
+ disabled: i === 0
2965
+ },
2966
+ {
2967
+ key: "reorder.right",
2968
+ label: "Move column right",
2969
+ icon: /* @__PURE__ */ jsx22(MoveRightIcon, { className: "mr-2" }),
2970
+ disabled: i === headerGroup.headers.length - 1
2971
+ }
2972
+ ],
2973
+ ...onColumnRename ? [
2974
+ [
2975
+ {
2976
+ key: "rename",
2977
+ label: "Rename column",
2978
+ icon: /* @__PURE__ */ jsx22(RenameIcon, { className: "mr-2" })
2979
+ }
2980
+ ]
2981
+ ] : [],
2982
+ ...!onColumnRemove ? [] : [
2983
+ [
2984
+ {
2985
+ key: "delete",
2986
+ label: "Remove column",
2987
+ icon: /* @__PURE__ */ jsx22(DeleteIcon, { className: "mr-2" }),
2988
+ status: "danger"
2989
+ }
2990
+ ]
2991
+ ]
2992
+ ]
2993
+ }
2994
+ )
2995
+ }
2996
+ ),
2997
+ header.column.getCanResize() ? /* @__PURE__ */ jsx22(
2998
+ "div",
2999
+ {
3000
+ onMouseDown: header.getResizeHandler(),
3001
+ onTouchStart: header.getResizeHandler(),
3002
+ className: cx3(
3003
+ `text-md hover:bg-primary-200/50 absolute right-0 top-0 inline-block flex
3004
+ h-full w-2 cursor-col-resize touch-none select-none items-center text-gray-400`
3005
+ ),
3006
+ style: {
3007
+ transform: columnResizeMode === "onEnd" && header.column.getIsResizing() ? `translateX(${table.getState().columnSizingInfo.deltaOffset}px)` : ""
3008
+ },
3009
+ onClick: (e) => e.stopPropagation(),
3010
+ children: "\u22EE"
3011
+ }
3012
+ ) : null
3013
+ ]
3014
+ },
3015
+ header.id
3016
+ ))
3017
+ },
3018
+ headerGroup.id
3019
+ )) }),
3020
+ /* @__PURE__ */ jsxs19("tbody", { children: [
3021
+ enableVirtualization && paddingTop > 0 && /* @__PURE__ */ jsx22("tr", { children: /* @__PURE__ */ jsx22("td", { style: { height: `${paddingTop}px` } }) }),
3022
+ enableVirtualization ? virtualRows.map((virtualRow) => {
3023
+ const row = table.getRowModel().rows[virtualRow.index];
3024
+ return /* @__PURE__ */ jsx22(
3025
+ "tr",
3026
+ {
3027
+ "data-index": virtualRow.index,
3028
+ className: cx3(
3029
+ "hover:!bg-primary-50 dark:hover:!bg-sentio-gray-300 group flex w-fit items-center border-b",
3030
+ onClick ? "cursor-pointer" : "",
3031
+ rowClassNameFn ? rowClassNameFn(row) : ""
3032
+ ),
3033
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx22(
3034
+ "td",
3035
+ {
3036
+ ...{
3037
+ style: {
3038
+ width: cell.column.getSize()
3039
+ }
3040
+ },
3041
+ onClick: () => onClick && onClick(row, cell),
3042
+ className: "text-ilabel dark:text-text-foreground-secondary truncate whitespace-nowrap py-2 pl-2 text-gray-600",
3043
+ children: flexRender(
3044
+ cell.column.columnDef.cell,
3045
+ cell.getContext()
3046
+ )
3047
+ },
3048
+ cell.id
3049
+ ))
3050
+ },
3051
+ row.id
3052
+ );
3053
+ }) : table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx22(
3054
+ "tr",
3055
+ {
3056
+ className: cx3(
3057
+ "hover:!bg-primary-50 dark:hover:!bg-sentio-gray-300 blinked group flex w-fit items-center border-b",
3058
+ onClick ? "cursor-pointer" : "",
3059
+ rowClassNameFn ? rowClassNameFn(row) : ""
3060
+ ),
3061
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx22(
3062
+ "td",
3063
+ {
3064
+ ...{
3065
+ style: {
3066
+ width: cell.column.getSize()
3067
+ }
3068
+ },
3069
+ onClick: () => onClick && onClick(row, cell),
3070
+ className: "text-ilabel dark:text-text-foreground-secondary truncate whitespace-nowrap py-2 pl-2 text-gray-600",
3071
+ children: flexRender(
3072
+ cell.column.columnDef.cell,
3073
+ cell.getContext()
3074
+ )
3075
+ },
3076
+ cell.id
3077
+ ))
3078
+ },
3079
+ row.id
3080
+ )),
3081
+ enableVirtualization && paddingBottom > 0 && /* @__PURE__ */ jsx22("tr", { children: /* @__PURE__ */ jsx22("td", { style: { height: `${paddingBottom}px` } }) }),
3082
+ onFetchMore && /* @__PURE__ */ jsx22("tr", { children: /* @__PURE__ */ jsx22(
3083
+ "td",
3084
+ {
3085
+ colSpan: table.getHeaderGroups()[0].headers.length,
3086
+ className: "text-ilabel hover:bg-primary-50 cursor-pointer py-2 text-center text-gray-600",
3087
+ onClick: () => {
3088
+ if (isFetching) return;
3089
+ onFetchMore?.();
3090
+ },
3091
+ children: isFetching || hasMore ? /* @__PURE__ */ jsxs19("span", { className: "inline-flex items-center gap-2", children: [
3092
+ /* @__PURE__ */ jsx22(
3093
+ IoReload,
3094
+ {
3095
+ className: cx3(
3096
+ "h-4 w-4",
3097
+ isFetching ? "animate-spin" : ""
3098
+ )
3099
+ }
3100
+ ),
3101
+ /* @__PURE__ */ jsx22("span", { children: "Loading..." })
3102
+ ] }) : "No more data"
3103
+ }
3104
+ ) })
3105
+ ] })
3106
+ ]
3107
+ }
3108
+ )
3109
+ }
3110
+ );
3111
+ });
3112
+ var ResizeTable = memo5(_ResizeTable);
3113
+
3114
+ // src/utils/number-format.ts
3115
+ import BigDecimal from "@sentio/bigdecimal";
3116
+ var BD = BigDecimal.clone({
3117
+ EXPONENTIAL_AT: 1e9
3118
+ });
3119
+ function parseHex(hex = "0") {
3120
+ try {
3121
+ return BigInt(BD(hex).toString());
3122
+ } catch {
3123
+ return BigInt(0);
3124
+ }
3125
+ }
3126
+ function getNumberWithDecimal(hex, decimal, asNumber) {
3127
+ if (hex === void 0 || decimal === void 0) {
3128
+ return null;
3129
+ }
3130
+ const bigInt = typeof hex === "bigint" ? hex : parseHex(hex);
3131
+ const n = BD(bigInt.toString()).div(decimal > 0 ? BD(10).pow(decimal) : 1);
3132
+ if (asNumber) {
3133
+ return n.toNumber();
3134
+ }
3135
+ return n.toString();
3136
+ }
3137
+
3138
+ // src/utils/use-mobile.ts
3139
+ import { useState as useState12, useEffect as useEffect9 } from "react";
3140
+ function useMobile(breakpoint = 768, defaultValue = false) {
3141
+ const [isMobile, setIsMobile] = useState12(defaultValue);
3142
+ useEffect9(() => {
3143
+ const checkUserAgent = () => {
3144
+ if (typeof window === "undefined") return false;
3145
+ const userAgent = window.navigator.userAgent.toLowerCase();
3146
+ const mobileKeywords = [
3147
+ "android",
3148
+ "iphone",
3149
+ "ipad",
3150
+ "ipod",
3151
+ "blackberry",
3152
+ "windows phone",
3153
+ "mobile",
3154
+ "webos",
3155
+ "opera mini"
3156
+ ];
3157
+ return mobileKeywords.some((keyword) => userAgent.includes(keyword));
3158
+ };
3159
+ const checkScreenWidth = () => {
3160
+ if (typeof window === "undefined") return false;
3161
+ return window.innerWidth < breakpoint;
3162
+ };
3163
+ const checkTouchSupport = () => {
3164
+ if (typeof window === "undefined") return false;
3165
+ return "ontouchstart" in window || navigator.maxTouchPoints > 0;
3166
+ };
3167
+ const detectMobile = () => {
3168
+ const isUserAgentMobile = checkUserAgent();
3169
+ const isScreenSmall = checkScreenWidth();
3170
+ const hasTouchSupport = checkTouchSupport();
3171
+ if (isUserAgentMobile) return true;
3172
+ if (isScreenSmall && hasTouchSupport) return true;
3173
+ return isScreenSmall;
3174
+ };
3175
+ setIsMobile(detectMobile());
3176
+ const handleResize = () => {
3177
+ setIsMobile(detectMobile());
3178
+ };
3179
+ window.addEventListener("resize", handleResize);
3180
+ return () => {
3181
+ window.removeEventListener("resize", handleResize);
3182
+ };
3183
+ }, [breakpoint]);
3184
+ return isMobile;
3185
+ }
3186
+ export {
3187
+ BD,
3188
+ BarLoading,
3189
+ BaseDialog,
3190
+ NewButton as Button,
3191
+ COLOR_MAP,
3192
+ LuSquareX as CloseSquareO,
3193
+ Collapse,
3194
+ CopyButton,
3195
+ CopyIcon,
3196
+ CopySuccessIcon,
3197
+ DarkModeContext,
3198
+ DeleteIcon,
3199
+ DisclosurePanel,
3200
+ Empty,
3201
+ LuEye as EyeO,
3202
+ FlatTree,
3203
+ HeaderToolsContent,
3204
+ HeaderToolsToggleButton,
3205
+ Input,
3206
+ LinkifyText,
3207
+ MenuContext,
3208
+ MenuItem,
3209
+ LuSquareMinus as MinusSquareO,
3210
+ MoveLeftIcon,
3211
+ MoveRightIcon,
3212
+ NavSizeContext,
3213
+ LuSquarePlus as PlusSquareO,
3214
+ PopoverTooltip,
3215
+ PopupMenuButton,
3216
+ ROOT_KEY,
3217
+ RadioSelect,
3218
+ RenameIcon,
3219
+ ResizeTable,
3220
+ SUFFIX_NODE_KEY,
3221
+ Select,
3222
+ SpinLoading,
3223
+ StatusBadge,
3224
+ StatusRole,
3225
+ SubMenuButton,
3226
+ SvgFolderContext,
3227
+ Switch,
3228
+ cx3 as classNames,
3229
+ getNumberWithDecimal,
3230
+ parseHex,
3231
+ useBoolean,
3232
+ useDarkMode,
3233
+ useDetectExtenstion,
3234
+ useMobile
3235
+ };
3236
+ //# sourceMappingURL=index.mjs.map