@seekho/ui 0.1.15 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -22,6 +22,21 @@ interface AutoCompleteProps<T> {
22
22
  }
23
23
  declare function AutoComplete<T>({ label, value, options, disabled, error, className, getOptionLabel, isOptionEqualToValue, isLoading, renderOption, onChange, onInputChange, }: AutoCompleteProps<T>): react_jsx_runtime.JSX.Element;
24
24
 
25
+ interface BreadcrumbProps {
26
+ /** Current URL pathname — pass location.pathname (React Router) or router.pathname (Next.js) */
27
+ pathname: string;
28
+ /** Called when a breadcrumb is clicked — pass navigate() (React Router) or router.push (Next.js) */
29
+ onNavigate: (path: string) => void;
30
+ /** Paths that depend on slug/id — clicking these will go back instead of navigating directly */
31
+ dependentPaths?: string[];
32
+ /** Show browser-style back/forward nav arrows before the breadcrumbs */
33
+ showNavArrows?: boolean;
34
+ className?: string;
35
+ linkClassName?: string;
36
+ activeClassName?: string;
37
+ }
38
+ declare const Breadcrumb: ({ pathname, onNavigate, dependentPaths, showNavArrows, className, linkClassName, activeClassName, }: BreadcrumbProps) => react_jsx_runtime.JSX.Element;
39
+
25
40
  interface ButtonLoaderProps {
26
41
  className?: string;
27
42
  }
@@ -43,6 +58,43 @@ interface CustomAnchorProps {
43
58
  }
44
59
  declare const CustomAnchor: ({ displayText, href, className, openInNewTab, }: CustomAnchorProps) => react_jsx_runtime.JSX.Element;
45
60
 
61
+ interface CustomInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
62
+ label?: string;
63
+ error?: boolean;
64
+ }
65
+ declare const CustomInput: React.ForwardRefExoticComponent<CustomInputProps & React.RefAttributes<HTMLInputElement>>;
66
+
67
+ type DrawerAnchor = "left" | "right" | "top" | "bottom";
68
+ interface DrawerProps {
69
+ open: boolean;
70
+ anchor?: DrawerAnchor;
71
+ children: React.ReactNode;
72
+ className?: string;
73
+ onClose: () => void;
74
+ }
75
+ declare const Drawer: ({ open, anchor, children, className, onClose, }: DrawerProps) => react_jsx_runtime.JSX.Element;
76
+
77
+ interface InputTitleWithRequiredProps {
78
+ title: string;
79
+ isRequired?: boolean;
80
+ className?: string;
81
+ }
82
+ declare const InputTitleWithRequired: ({ title, isRequired, className, }: InputTitleWithRequiredProps) => react_jsx_runtime.JSX.Element;
83
+
84
+ interface FilterDrawerProps {
85
+ open: boolean;
86
+ title?: string;
87
+ anchor?: DrawerAnchor;
88
+ children?: React.ReactNode;
89
+ childrenClassName?: string;
90
+ applyBtnText?: string;
91
+ clearBtnText?: string;
92
+ handleClose: () => void;
93
+ handleApplyFilters: () => void;
94
+ handleClearFilters: () => void;
95
+ }
96
+ declare const FilterDrawer: ({ open, title, anchor, children, childrenClassName, applyBtnText, clearBtnText, handleClose, handleApplyFilters, handleClearFilters, }: FilterDrawerProps) => react_jsx_runtime.JSX.Element;
97
+
46
98
  interface ModalProps {
47
99
  show: boolean;
48
100
  title?: string;
@@ -82,6 +134,12 @@ interface SearchBarProps {
82
134
  }
83
135
  declare function SearchBar({ value, placeHolder, wrapperClass, className, searchParamQuery, onChange, handleInputKey, handleClearInput, }: SearchBarProps): react_jsx_runtime.JSX.Element;
84
136
 
137
+ interface StagingAlertProps {
138
+ liveUrl: string;
139
+ liveLinkText?: string;
140
+ }
141
+ declare const StagingAlert: ({ liveUrl, liveLinkText, }: StagingAlertProps) => react_jsx_runtime.JSX.Element;
142
+
85
143
  /**
86
144
  * useState backed by localStorage — syncs value on mount and persists on change.
87
145
  */
@@ -92,4 +150,4 @@ declare const handleCopyTextToClipboard: ({ clipboardText, }: {
92
150
  clipboardText: string | number | null | undefined;
93
151
  }) => Promise<boolean>;
94
152
 
95
- export { AutoComplete, type AutoCompleteProps, ButtonLoader, type ButtonLoaderProps, CopyId, type CopyIdProps, CustomAnchor, type CustomAnchorProps, Modal, type ModalProps, ReadMore, type ReadMoreProps, SearchBar, type SearchBarProps, cn, handleCopyTextToClipboard, useLocalStorage };
153
+ export { AutoComplete, type AutoCompleteProps, Breadcrumb, type BreadcrumbProps, ButtonLoader, type ButtonLoaderProps, CopyId, type CopyIdProps, CustomAnchor, type CustomAnchorProps, CustomInput, type CustomInputProps, Drawer, type DrawerAnchor, type DrawerProps, FilterDrawer, type FilterDrawerProps, InputTitleWithRequired, type InputTitleWithRequiredProps, Modal, type ModalProps, ReadMore, type ReadMoreProps, SearchBar, type SearchBarProps, StagingAlert, type StagingAlertProps, cn, handleCopyTextToClipboard, useLocalStorage };
package/dist/index.d.ts CHANGED
@@ -22,6 +22,21 @@ interface AutoCompleteProps<T> {
22
22
  }
23
23
  declare function AutoComplete<T>({ label, value, options, disabled, error, className, getOptionLabel, isOptionEqualToValue, isLoading, renderOption, onChange, onInputChange, }: AutoCompleteProps<T>): react_jsx_runtime.JSX.Element;
24
24
 
25
+ interface BreadcrumbProps {
26
+ /** Current URL pathname — pass location.pathname (React Router) or router.pathname (Next.js) */
27
+ pathname: string;
28
+ /** Called when a breadcrumb is clicked — pass navigate() (React Router) or router.push (Next.js) */
29
+ onNavigate: (path: string) => void;
30
+ /** Paths that depend on slug/id — clicking these will go back instead of navigating directly */
31
+ dependentPaths?: string[];
32
+ /** Show browser-style back/forward nav arrows before the breadcrumbs */
33
+ showNavArrows?: boolean;
34
+ className?: string;
35
+ linkClassName?: string;
36
+ activeClassName?: string;
37
+ }
38
+ declare const Breadcrumb: ({ pathname, onNavigate, dependentPaths, showNavArrows, className, linkClassName, activeClassName, }: BreadcrumbProps) => react_jsx_runtime.JSX.Element;
39
+
25
40
  interface ButtonLoaderProps {
26
41
  className?: string;
27
42
  }
@@ -43,6 +58,43 @@ interface CustomAnchorProps {
43
58
  }
44
59
  declare const CustomAnchor: ({ displayText, href, className, openInNewTab, }: CustomAnchorProps) => react_jsx_runtime.JSX.Element;
45
60
 
61
+ interface CustomInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
62
+ label?: string;
63
+ error?: boolean;
64
+ }
65
+ declare const CustomInput: React.ForwardRefExoticComponent<CustomInputProps & React.RefAttributes<HTMLInputElement>>;
66
+
67
+ type DrawerAnchor = "left" | "right" | "top" | "bottom";
68
+ interface DrawerProps {
69
+ open: boolean;
70
+ anchor?: DrawerAnchor;
71
+ children: React.ReactNode;
72
+ className?: string;
73
+ onClose: () => void;
74
+ }
75
+ declare const Drawer: ({ open, anchor, children, className, onClose, }: DrawerProps) => react_jsx_runtime.JSX.Element;
76
+
77
+ interface InputTitleWithRequiredProps {
78
+ title: string;
79
+ isRequired?: boolean;
80
+ className?: string;
81
+ }
82
+ declare const InputTitleWithRequired: ({ title, isRequired, className, }: InputTitleWithRequiredProps) => react_jsx_runtime.JSX.Element;
83
+
84
+ interface FilterDrawerProps {
85
+ open: boolean;
86
+ title?: string;
87
+ anchor?: DrawerAnchor;
88
+ children?: React.ReactNode;
89
+ childrenClassName?: string;
90
+ applyBtnText?: string;
91
+ clearBtnText?: string;
92
+ handleClose: () => void;
93
+ handleApplyFilters: () => void;
94
+ handleClearFilters: () => void;
95
+ }
96
+ declare const FilterDrawer: ({ open, title, anchor, children, childrenClassName, applyBtnText, clearBtnText, handleClose, handleApplyFilters, handleClearFilters, }: FilterDrawerProps) => react_jsx_runtime.JSX.Element;
97
+
46
98
  interface ModalProps {
47
99
  show: boolean;
48
100
  title?: string;
@@ -82,6 +134,12 @@ interface SearchBarProps {
82
134
  }
83
135
  declare function SearchBar({ value, placeHolder, wrapperClass, className, searchParamQuery, onChange, handleInputKey, handleClearInput, }: SearchBarProps): react_jsx_runtime.JSX.Element;
84
136
 
137
+ interface StagingAlertProps {
138
+ liveUrl: string;
139
+ liveLinkText?: string;
140
+ }
141
+ declare const StagingAlert: ({ liveUrl, liveLinkText, }: StagingAlertProps) => react_jsx_runtime.JSX.Element;
142
+
85
143
  /**
86
144
  * useState backed by localStorage — syncs value on mount and persists on change.
87
145
  */
@@ -92,4 +150,4 @@ declare const handleCopyTextToClipboard: ({ clipboardText, }: {
92
150
  clipboardText: string | number | null | undefined;
93
151
  }) => Promise<boolean>;
94
152
 
95
- export { AutoComplete, type AutoCompleteProps, ButtonLoader, type ButtonLoaderProps, CopyId, type CopyIdProps, CustomAnchor, type CustomAnchorProps, Modal, type ModalProps, ReadMore, type ReadMoreProps, SearchBar, type SearchBarProps, cn, handleCopyTextToClipboard, useLocalStorage };
153
+ export { AutoComplete, type AutoCompleteProps, Breadcrumb, type BreadcrumbProps, ButtonLoader, type ButtonLoaderProps, CopyId, type CopyIdProps, CustomAnchor, type CustomAnchorProps, CustomInput, type CustomInputProps, Drawer, type DrawerAnchor, type DrawerProps, FilterDrawer, type FilterDrawerProps, InputTitleWithRequired, type InputTitleWithRequiredProps, Modal, type ModalProps, ReadMore, type ReadMoreProps, SearchBar, type SearchBarProps, StagingAlert, type StagingAlertProps, cn, handleCopyTextToClipboard, useLocalStorage };
package/dist/index.js CHANGED
@@ -8,7 +8,34 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
8
 
9
9
  var React__default = /*#__PURE__*/_interopDefault(React);
10
10
 
11
- // src/components/AutoComplete/AutoComplete.tsx
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
15
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
16
+ var __spreadValues = (a, b) => {
17
+ for (var prop in b || (b = {}))
18
+ if (__hasOwnProp.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ if (__getOwnPropSymbols)
21
+ for (var prop of __getOwnPropSymbols(b)) {
22
+ if (__propIsEnum.call(b, prop))
23
+ __defNormalProp(a, prop, b[prop]);
24
+ }
25
+ return a;
26
+ };
27
+ var __objRest = (source, exclude) => {
28
+ var target = {};
29
+ for (var prop in source)
30
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
31
+ target[prop] = source[prop];
32
+ if (source != null && __getOwnPropSymbols)
33
+ for (var prop of __getOwnPropSymbols(source)) {
34
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
35
+ target[prop] = source[prop];
36
+ }
37
+ return target;
38
+ };
12
39
  function AutoComplete({
13
40
  label,
14
41
  value,
@@ -266,6 +293,112 @@ function AutoComplete({
266
293
  }
267
294
  );
268
295
  }
296
+ var generateBreadcrumbs = (pathname) => {
297
+ const pathnames = pathname.split("/").filter((x) => x);
298
+ const breadcrumbs = [{ label: "Home", href: "/" }];
299
+ pathnames.forEach((segment, index) => {
300
+ const href = `/${pathnames.slice(0, index + 1).join("/")}`;
301
+ breadcrumbs.push({
302
+ label: segment.replace(/-/g, " "),
303
+ href
304
+ });
305
+ });
306
+ return breadcrumbs;
307
+ };
308
+ var Breadcrumb = ({
309
+ pathname,
310
+ onNavigate,
311
+ dependentPaths = [],
312
+ showNavArrows = false,
313
+ className,
314
+ linkClassName,
315
+ activeClassName
316
+ }) => {
317
+ const breadcrumbs = generateBreadcrumbs(pathname);
318
+ const handleClick = ({ e, href }) => {
319
+ e.preventDefault();
320
+ const isDependent = dependentPaths.some((route) => href.includes(route));
321
+ if (isDependent) {
322
+ history.go(-1);
323
+ return;
324
+ }
325
+ onNavigate(href);
326
+ };
327
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { role: "presentation", "aria-label": "breadcrumb", children: /* @__PURE__ */ jsxRuntime.jsxs(
328
+ "ol",
329
+ {
330
+ className: [
331
+ "flex flex-wrap items-center gap-1 text-sm",
332
+ className || ""
333
+ ].join(" "),
334
+ children: [
335
+ showNavArrows && /* @__PURE__ */ jsxRuntime.jsx("li", { className: "flex items-center mr-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center rounded-md overflow-hidden gap-1 px-2 py-1", children: [
336
+ /* @__PURE__ */ jsxRuntime.jsx(
337
+ "button",
338
+ {
339
+ type: "button",
340
+ onClick: () => history.go(-1),
341
+ title: "Go back",
342
+ className: " text-base leading-none hover:opacity-70 transition-opacity",
343
+ children: "\u2190"
344
+ }
345
+ ),
346
+ /* @__PURE__ */ jsxRuntime.jsx(
347
+ "button",
348
+ {
349
+ type: "button",
350
+ onClick: () => history.go(1),
351
+ title: "Go forward",
352
+ className: "text-base leading-none hover:opacity-70 transition-opacity",
353
+ children: "\u2192"
354
+ }
355
+ )
356
+ ] }) }),
357
+ breadcrumbs.map((breadcrumb, index) => {
358
+ const isLast = index === breadcrumbs.length - 1;
359
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center gap-1", children: [
360
+ isLast ? /* @__PURE__ */ jsxRuntime.jsx(
361
+ "span",
362
+ {
363
+ className: [
364
+ "capitalize text-[13px] cursor-default",
365
+ activeClassName || "font-medium"
366
+ ].join(" "),
367
+ children: breadcrumb.label
368
+ }
369
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
370
+ "a",
371
+ {
372
+ href: breadcrumb.href,
373
+ "data-path": breadcrumb.href,
374
+ onClick: (e) => handleClick({ e, href: breadcrumb.href }),
375
+ className: [
376
+ "capitalize text-[13px] cursor-pointer hover:underline transition-colors opacity-85",
377
+ linkClassName || "hover:text-primary"
378
+ ].join(" "),
379
+ children: breadcrumb.label
380
+ }
381
+ ),
382
+ !isLast && /* @__PURE__ */ jsxRuntime.jsx(
383
+ "svg",
384
+ {
385
+ xmlns: "http://www.w3.org/2000/svg",
386
+ className: "w-3.5 h-3.5 shrink-0 opacity-60",
387
+ viewBox: "0 0 24 24",
388
+ fill: "none",
389
+ stroke: "currentColor",
390
+ strokeWidth: "2",
391
+ strokeLinecap: "round",
392
+ strokeLinejoin: "round",
393
+ children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" })
394
+ }
395
+ )
396
+ ] }, index);
397
+ })
398
+ ]
399
+ }
400
+ ) });
401
+ };
269
402
  var ButtonLoader = ({ className }) => {
270
403
  return /* @__PURE__ */ jsxRuntime.jsxs(
271
404
  "svg",
@@ -386,6 +519,175 @@ var CustomAnchor = ({
386
519
  }
387
520
  );
388
521
  };
522
+ var CustomInput = React__default.default.forwardRef(
523
+ (_a, ref) => {
524
+ var _b = _a, { label: _label, error, className, type } = _b, props = __objRest(_b, ["label", "error", "className", "type"]);
525
+ return /* @__PURE__ */ jsxRuntime.jsx(
526
+ "input",
527
+ __spreadValues({
528
+ ref,
529
+ type,
530
+ className: type === "checkbox" ? className || "" : [
531
+ "w-full h-[45px] text-[14.5px] px-2 border rounded-md",
532
+ "focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary",
533
+ "placeholder:text-gray-500 text-gray-800",
534
+ "disabled:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-60",
535
+ "transition-colors",
536
+ error ? "border-red-500 focus:ring-red-400" : "border-gray-300",
537
+ className || ""
538
+ ].join(" ")
539
+ }, props)
540
+ );
541
+ }
542
+ );
543
+ CustomInput.displayName = "CustomInput";
544
+ var translateClass = {
545
+ right: { hidden: "translate-x-full", visible: "translate-x-0" },
546
+ left: { hidden: "-translate-x-full", visible: "translate-x-0" },
547
+ top: { hidden: "-translate-y-full", visible: "translate-y-0" },
548
+ bottom: { hidden: "translate-y-full", visible: "translate-y-0" }
549
+ };
550
+ var positionClass = {
551
+ right: "right-0 top-0 h-full",
552
+ left: "left-0 top-0 h-full",
553
+ top: "top-0 left-0 w-full",
554
+ bottom: "bottom-0 left-0 w-full"
555
+ };
556
+ var Drawer = ({
557
+ open,
558
+ anchor = "right",
559
+ children,
560
+ className,
561
+ onClose
562
+ }) => {
563
+ React.useEffect(() => {
564
+ document.body.style.overflow = open ? "hidden" : "";
565
+ return () => {
566
+ document.body.style.overflow = "";
567
+ };
568
+ }, [open]);
569
+ React.useEffect(() => {
570
+ const handleKeyDown = (e) => {
571
+ if (e.key === "Escape" && open) onClose();
572
+ };
573
+ document.addEventListener("keydown", handleKeyDown);
574
+ return () => document.removeEventListener("keydown", handleKeyDown);
575
+ }, [open, onClose]);
576
+ return /* @__PURE__ */ jsxRuntime.jsxs(
577
+ "div",
578
+ {
579
+ className: [
580
+ "fixed inset-0 z-[1200]",
581
+ open ? "pointer-events-auto" : "pointer-events-none"
582
+ ].join(" "),
583
+ children: [
584
+ /* @__PURE__ */ jsxRuntime.jsx(
585
+ "div",
586
+ {
587
+ onClick: onClose,
588
+ className: [
589
+ "absolute inset-0 bg-black transition-opacity duration-300",
590
+ open ? "opacity-50" : "opacity-0"
591
+ ].join(" ")
592
+ }
593
+ ),
594
+ /* @__PURE__ */ jsxRuntime.jsx(
595
+ "div",
596
+ {
597
+ className: [
598
+ "absolute bg-white shadow-xl transition-transform duration-300",
599
+ positionClass[anchor],
600
+ open ? translateClass[anchor].visible : translateClass[anchor].hidden,
601
+ className || ""
602
+ ].join(" "),
603
+ children
604
+ }
605
+ )
606
+ ]
607
+ }
608
+ );
609
+ };
610
+ var InputTitleWithRequired = ({
611
+ title,
612
+ isRequired = true,
613
+ className
614
+ }) => {
615
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `text-sm font-medium ${className || ""}`, children: [
616
+ title,
617
+ " ",
618
+ isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
619
+ ] });
620
+ };
621
+ var FilterDrawer = ({
622
+ open,
623
+ title,
624
+ anchor = "right",
625
+ children,
626
+ childrenClassName,
627
+ applyBtnText = "Apply",
628
+ clearBtnText = "Clear",
629
+ handleClose,
630
+ handleApplyFilters,
631
+ handleClearFilters
632
+ }) => {
633
+ return /* @__PURE__ */ jsxRuntime.jsx(Drawer, { open, anchor, onClose: handleClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full w-[300px] bg-white flex flex-col justify-between lg:w-[450px]", children: [
634
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2.5 bg-gray-100 flex justify-between items-center z-10", children: [
635
+ /* @__PURE__ */ jsxRuntime.jsx("h6", { className: "text-lg font-bold flex items-center gap-1", children: title }),
636
+ /* @__PURE__ */ jsxRuntime.jsx(
637
+ "button",
638
+ {
639
+ onClick: handleClose,
640
+ className: "cursor-pointer text-gray-600 hover:text-gray-900 transition-colors",
641
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
642
+ "svg",
643
+ {
644
+ xmlns: "http://www.w3.org/2000/svg",
645
+ className: "w-[24px] h-[24px]",
646
+ viewBox: "0 0 24 24",
647
+ fill: "none",
648
+ stroke: "currentColor",
649
+ strokeWidth: "2",
650
+ strokeLinecap: "round",
651
+ strokeLinejoin: "round",
652
+ children: [
653
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
654
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
655
+ ]
656
+ }
657
+ )
658
+ }
659
+ )
660
+ ] }),
661
+ /* @__PURE__ */ jsxRuntime.jsx(
662
+ "div",
663
+ {
664
+ className: [
665
+ "flex-1 overflow-auto px-2 pb-3",
666
+ childrenClassName || ""
667
+ ].join(" "),
668
+ children
669
+ }
670
+ ),
671
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-x-2 py-3 px-4 justify-end bg-gray-100 border-gray-300", children: [
672
+ /* @__PURE__ */ jsxRuntime.jsx(
673
+ "button",
674
+ {
675
+ onClick: handleClearFilters,
676
+ className: "!px-10 py-2 bg-white !text-[15px] text-black rounded-lg",
677
+ children: clearBtnText
678
+ }
679
+ ),
680
+ /* @__PURE__ */ jsxRuntime.jsx(
681
+ "button",
682
+ {
683
+ onClick: handleApplyFilters,
684
+ className: "!px-10 py-2 bg-primary !text-[15px] text-white rounded-lg",
685
+ children: applyBtnText
686
+ }
687
+ )
688
+ ] })
689
+ ] }) });
690
+ };
389
691
 
390
692
  // src/utils/modalStack.ts
391
693
  var stack = [];
@@ -475,7 +777,7 @@ function Modal({
475
777
  }
476
778
  )
477
779
  ] }),
478
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto px-3.5 py-3", children }),
780
+ /* @__PURE__ */ jsxRuntime.jsx("div", { id: "HideScroll", className: "flex-1 overflow-y-auto px-3.5 py-3", children }),
479
781
  isButtonsRequired && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-3 bg-gray-100 flex justify-end space-x-3 rounded-b-md", children: [
480
782
  onHide && /* @__PURE__ */ jsxRuntime.jsx(
481
783
  "button",
@@ -667,6 +969,42 @@ function SearchBar({
667
969
  }
668
970
  );
669
971
  }
972
+ var StagingAlert = ({
973
+ liveUrl,
974
+ liveLinkText = "Live App"
975
+ }) => {
976
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-fit mt-1 bg-[#ec6c03] px-1 py-1 text-[8px] lg:text-[12px] lg:px-4 lg:py-2 rounded-lg text-white", children: [
977
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: /* @__PURE__ */ jsxRuntime.jsx(
978
+ "svg",
979
+ {
980
+ xmlns: "http://www.w3.org/2000/svg",
981
+ className: "inline-block w-[14px] h-[14px]",
982
+ viewBox: "0 0 24 24",
983
+ fill: "currentColor",
984
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" })
985
+ }
986
+ ) }),
987
+ " ",
988
+ "You are currently viewing the",
989
+ " ",
990
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold", children: "staging environment." }),
991
+ " ",
992
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
993
+ "If you are looking for the live app, please visit:",
994
+ " ",
995
+ /* @__PURE__ */ jsxRuntime.jsx(
996
+ "a",
997
+ {
998
+ href: liveUrl,
999
+ target: "_blank",
1000
+ rel: "noopener noreferrer",
1001
+ className: "underline font-bold",
1002
+ children: liveLinkText
1003
+ }
1004
+ )
1005
+ ] })
1006
+ ] });
1007
+ };
670
1008
  function useLocalStorage(key, initialValue) {
671
1009
  const [storedValue, setStoredValue] = React.useState(() => {
672
1010
  if (typeof window === "undefined") return initialValue;
@@ -702,12 +1040,18 @@ function useLocalStorage(key, initialValue) {
702
1040
  }
703
1041
 
704
1042
  exports.AutoComplete = AutoComplete;
1043
+ exports.Breadcrumb = Breadcrumb;
705
1044
  exports.ButtonLoader = ButtonLoader;
706
1045
  exports.CopyId = CopyId;
707
1046
  exports.CustomAnchor = CustomAnchor;
1047
+ exports.CustomInput = CustomInput;
1048
+ exports.Drawer = Drawer;
1049
+ exports.FilterDrawer = FilterDrawer;
1050
+ exports.InputTitleWithRequired = InputTitleWithRequired;
708
1051
  exports.Modal = Modal;
709
1052
  exports.ReadMore = ReadMore;
710
1053
  exports.SearchBar = SearchBar;
1054
+ exports.StagingAlert = StagingAlert;
711
1055
  exports.cn = cn;
712
1056
  exports.handleCopyTextToClipboard = handleCopyTextToClipboard;
713
1057
  exports.useLocalStorage = useLocalStorage;
package/dist/index.mjs CHANGED
@@ -1,8 +1,35 @@
1
1
  import React, { useId, useRef, useState, useEffect } from 'react';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { useHotkeys } from 'react-hotkeys-hook';
4
4
 
5
- // src/components/AutoComplete/AutoComplete.tsx
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __spreadValues = (a, b) => {
11
+ for (var prop in b || (b = {}))
12
+ if (__hasOwnProp.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ if (__getOwnPropSymbols)
15
+ for (var prop of __getOwnPropSymbols(b)) {
16
+ if (__propIsEnum.call(b, prop))
17
+ __defNormalProp(a, prop, b[prop]);
18
+ }
19
+ return a;
20
+ };
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
6
33
  function AutoComplete({
7
34
  label,
8
35
  value,
@@ -260,6 +287,112 @@ function AutoComplete({
260
287
  }
261
288
  );
262
289
  }
290
+ var generateBreadcrumbs = (pathname) => {
291
+ const pathnames = pathname.split("/").filter((x) => x);
292
+ const breadcrumbs = [{ label: "Home", href: "/" }];
293
+ pathnames.forEach((segment, index) => {
294
+ const href = `/${pathnames.slice(0, index + 1).join("/")}`;
295
+ breadcrumbs.push({
296
+ label: segment.replace(/-/g, " "),
297
+ href
298
+ });
299
+ });
300
+ return breadcrumbs;
301
+ };
302
+ var Breadcrumb = ({
303
+ pathname,
304
+ onNavigate,
305
+ dependentPaths = [],
306
+ showNavArrows = false,
307
+ className,
308
+ linkClassName,
309
+ activeClassName
310
+ }) => {
311
+ const breadcrumbs = generateBreadcrumbs(pathname);
312
+ const handleClick = ({ e, href }) => {
313
+ e.preventDefault();
314
+ const isDependent = dependentPaths.some((route) => href.includes(route));
315
+ if (isDependent) {
316
+ history.go(-1);
317
+ return;
318
+ }
319
+ onNavigate(href);
320
+ };
321
+ return /* @__PURE__ */ jsx("nav", { role: "presentation", "aria-label": "breadcrumb", children: /* @__PURE__ */ jsxs(
322
+ "ol",
323
+ {
324
+ className: [
325
+ "flex flex-wrap items-center gap-1 text-sm",
326
+ className || ""
327
+ ].join(" "),
328
+ children: [
329
+ showNavArrows && /* @__PURE__ */ jsx("li", { className: "flex items-center mr-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center rounded-md overflow-hidden gap-1 px-2 py-1", children: [
330
+ /* @__PURE__ */ jsx(
331
+ "button",
332
+ {
333
+ type: "button",
334
+ onClick: () => history.go(-1),
335
+ title: "Go back",
336
+ className: " text-base leading-none hover:opacity-70 transition-opacity",
337
+ children: "\u2190"
338
+ }
339
+ ),
340
+ /* @__PURE__ */ jsx(
341
+ "button",
342
+ {
343
+ type: "button",
344
+ onClick: () => history.go(1),
345
+ title: "Go forward",
346
+ className: "text-base leading-none hover:opacity-70 transition-opacity",
347
+ children: "\u2192"
348
+ }
349
+ )
350
+ ] }) }),
351
+ breadcrumbs.map((breadcrumb, index) => {
352
+ const isLast = index === breadcrumbs.length - 1;
353
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-1", children: [
354
+ isLast ? /* @__PURE__ */ jsx(
355
+ "span",
356
+ {
357
+ className: [
358
+ "capitalize text-[13px] cursor-default",
359
+ activeClassName || "font-medium"
360
+ ].join(" "),
361
+ children: breadcrumb.label
362
+ }
363
+ ) : /* @__PURE__ */ jsx(
364
+ "a",
365
+ {
366
+ href: breadcrumb.href,
367
+ "data-path": breadcrumb.href,
368
+ onClick: (e) => handleClick({ e, href: breadcrumb.href }),
369
+ className: [
370
+ "capitalize text-[13px] cursor-pointer hover:underline transition-colors opacity-85",
371
+ linkClassName || "hover:text-primary"
372
+ ].join(" "),
373
+ children: breadcrumb.label
374
+ }
375
+ ),
376
+ !isLast && /* @__PURE__ */ jsx(
377
+ "svg",
378
+ {
379
+ xmlns: "http://www.w3.org/2000/svg",
380
+ className: "w-3.5 h-3.5 shrink-0 opacity-60",
381
+ viewBox: "0 0 24 24",
382
+ fill: "none",
383
+ stroke: "currentColor",
384
+ strokeWidth: "2",
385
+ strokeLinecap: "round",
386
+ strokeLinejoin: "round",
387
+ children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" })
388
+ }
389
+ )
390
+ ] }, index);
391
+ })
392
+ ]
393
+ }
394
+ ) });
395
+ };
263
396
  var ButtonLoader = ({ className }) => {
264
397
  return /* @__PURE__ */ jsxs(
265
398
  "svg",
@@ -380,6 +513,175 @@ var CustomAnchor = ({
380
513
  }
381
514
  );
382
515
  };
516
+ var CustomInput = React.forwardRef(
517
+ (_a, ref) => {
518
+ var _b = _a, { label: _label, error, className, type } = _b, props = __objRest(_b, ["label", "error", "className", "type"]);
519
+ return /* @__PURE__ */ jsx(
520
+ "input",
521
+ __spreadValues({
522
+ ref,
523
+ type,
524
+ className: type === "checkbox" ? className || "" : [
525
+ "w-full h-[45px] text-[14.5px] px-2 border rounded-md",
526
+ "focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary",
527
+ "placeholder:text-gray-500 text-gray-800",
528
+ "disabled:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-60",
529
+ "transition-colors",
530
+ error ? "border-red-500 focus:ring-red-400" : "border-gray-300",
531
+ className || ""
532
+ ].join(" ")
533
+ }, props)
534
+ );
535
+ }
536
+ );
537
+ CustomInput.displayName = "CustomInput";
538
+ var translateClass = {
539
+ right: { hidden: "translate-x-full", visible: "translate-x-0" },
540
+ left: { hidden: "-translate-x-full", visible: "translate-x-0" },
541
+ top: { hidden: "-translate-y-full", visible: "translate-y-0" },
542
+ bottom: { hidden: "translate-y-full", visible: "translate-y-0" }
543
+ };
544
+ var positionClass = {
545
+ right: "right-0 top-0 h-full",
546
+ left: "left-0 top-0 h-full",
547
+ top: "top-0 left-0 w-full",
548
+ bottom: "bottom-0 left-0 w-full"
549
+ };
550
+ var Drawer = ({
551
+ open,
552
+ anchor = "right",
553
+ children,
554
+ className,
555
+ onClose
556
+ }) => {
557
+ useEffect(() => {
558
+ document.body.style.overflow = open ? "hidden" : "";
559
+ return () => {
560
+ document.body.style.overflow = "";
561
+ };
562
+ }, [open]);
563
+ useEffect(() => {
564
+ const handleKeyDown = (e) => {
565
+ if (e.key === "Escape" && open) onClose();
566
+ };
567
+ document.addEventListener("keydown", handleKeyDown);
568
+ return () => document.removeEventListener("keydown", handleKeyDown);
569
+ }, [open, onClose]);
570
+ return /* @__PURE__ */ jsxs(
571
+ "div",
572
+ {
573
+ className: [
574
+ "fixed inset-0 z-[1200]",
575
+ open ? "pointer-events-auto" : "pointer-events-none"
576
+ ].join(" "),
577
+ children: [
578
+ /* @__PURE__ */ jsx(
579
+ "div",
580
+ {
581
+ onClick: onClose,
582
+ className: [
583
+ "absolute inset-0 bg-black transition-opacity duration-300",
584
+ open ? "opacity-50" : "opacity-0"
585
+ ].join(" ")
586
+ }
587
+ ),
588
+ /* @__PURE__ */ jsx(
589
+ "div",
590
+ {
591
+ className: [
592
+ "absolute bg-white shadow-xl transition-transform duration-300",
593
+ positionClass[anchor],
594
+ open ? translateClass[anchor].visible : translateClass[anchor].hidden,
595
+ className || ""
596
+ ].join(" "),
597
+ children
598
+ }
599
+ )
600
+ ]
601
+ }
602
+ );
603
+ };
604
+ var InputTitleWithRequired = ({
605
+ title,
606
+ isRequired = true,
607
+ className
608
+ }) => {
609
+ return /* @__PURE__ */ jsxs("div", { className: `text-sm font-medium ${className || ""}`, children: [
610
+ title,
611
+ " ",
612
+ isRequired && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
613
+ ] });
614
+ };
615
+ var FilterDrawer = ({
616
+ open,
617
+ title,
618
+ anchor = "right",
619
+ children,
620
+ childrenClassName,
621
+ applyBtnText = "Apply",
622
+ clearBtnText = "Clear",
623
+ handleClose,
624
+ handleApplyFilters,
625
+ handleClearFilters
626
+ }) => {
627
+ return /* @__PURE__ */ jsx(Drawer, { open, anchor, onClose: handleClose, children: /* @__PURE__ */ jsxs("div", { className: "relative h-full w-[300px] bg-white flex flex-col justify-between lg:w-[450px]", children: [
628
+ /* @__PURE__ */ jsxs("div", { className: "px-3 py-2.5 bg-gray-100 flex justify-between items-center z-10", children: [
629
+ /* @__PURE__ */ jsx("h6", { className: "text-lg font-bold flex items-center gap-1", children: title }),
630
+ /* @__PURE__ */ jsx(
631
+ "button",
632
+ {
633
+ onClick: handleClose,
634
+ className: "cursor-pointer text-gray-600 hover:text-gray-900 transition-colors",
635
+ children: /* @__PURE__ */ jsxs(
636
+ "svg",
637
+ {
638
+ xmlns: "http://www.w3.org/2000/svg",
639
+ className: "w-[24px] h-[24px]",
640
+ viewBox: "0 0 24 24",
641
+ fill: "none",
642
+ stroke: "currentColor",
643
+ strokeWidth: "2",
644
+ strokeLinecap: "round",
645
+ strokeLinejoin: "round",
646
+ children: [
647
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
648
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
649
+ ]
650
+ }
651
+ )
652
+ }
653
+ )
654
+ ] }),
655
+ /* @__PURE__ */ jsx(
656
+ "div",
657
+ {
658
+ className: [
659
+ "flex-1 overflow-auto px-2 pb-3",
660
+ childrenClassName || ""
661
+ ].join(" "),
662
+ children
663
+ }
664
+ ),
665
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-x-2 py-3 px-4 justify-end bg-gray-100 border-gray-300", children: [
666
+ /* @__PURE__ */ jsx(
667
+ "button",
668
+ {
669
+ onClick: handleClearFilters,
670
+ className: "!px-10 py-2 bg-white !text-[15px] text-black rounded-lg",
671
+ children: clearBtnText
672
+ }
673
+ ),
674
+ /* @__PURE__ */ jsx(
675
+ "button",
676
+ {
677
+ onClick: handleApplyFilters,
678
+ className: "!px-10 py-2 bg-primary !text-[15px] text-white rounded-lg",
679
+ children: applyBtnText
680
+ }
681
+ )
682
+ ] })
683
+ ] }) });
684
+ };
383
685
 
384
686
  // src/utils/modalStack.ts
385
687
  var stack = [];
@@ -469,7 +771,7 @@ function Modal({
469
771
  }
470
772
  )
471
773
  ] }),
472
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-3.5 py-3", children }),
774
+ /* @__PURE__ */ jsx("div", { id: "HideScroll", className: "flex-1 overflow-y-auto px-3.5 py-3", children }),
473
775
  isButtonsRequired && /* @__PURE__ */ jsxs("div", { className: "px-6 py-3 bg-gray-100 flex justify-end space-x-3 rounded-b-md", children: [
474
776
  onHide && /* @__PURE__ */ jsx(
475
777
  "button",
@@ -661,6 +963,42 @@ function SearchBar({
661
963
  }
662
964
  );
663
965
  }
966
+ var StagingAlert = ({
967
+ liveUrl,
968
+ liveLinkText = "Live App"
969
+ }) => {
970
+ return /* @__PURE__ */ jsxs("div", { className: "w-fit mt-1 bg-[#ec6c03] px-1 py-1 text-[8px] lg:text-[12px] lg:px-4 lg:py-2 rounded-lg text-white", children: [
971
+ /* @__PURE__ */ jsx("strong", { children: /* @__PURE__ */ jsx(
972
+ "svg",
973
+ {
974
+ xmlns: "http://www.w3.org/2000/svg",
975
+ className: "inline-block w-[14px] h-[14px]",
976
+ viewBox: "0 0 24 24",
977
+ fill: "currentColor",
978
+ children: /* @__PURE__ */ jsx("path", { d: "M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" })
979
+ }
980
+ ) }),
981
+ " ",
982
+ "You are currently viewing the",
983
+ " ",
984
+ /* @__PURE__ */ jsx("span", { className: "font-bold", children: "staging environment." }),
985
+ " ",
986
+ /* @__PURE__ */ jsxs("span", { children: [
987
+ "If you are looking for the live app, please visit:",
988
+ " ",
989
+ /* @__PURE__ */ jsx(
990
+ "a",
991
+ {
992
+ href: liveUrl,
993
+ target: "_blank",
994
+ rel: "noopener noreferrer",
995
+ className: "underline font-bold",
996
+ children: liveLinkText
997
+ }
998
+ )
999
+ ] })
1000
+ ] });
1001
+ };
664
1002
  function useLocalStorage(key, initialValue) {
665
1003
  const [storedValue, setStoredValue] = useState(() => {
666
1004
  if (typeof window === "undefined") return initialValue;
@@ -695,4 +1033,4 @@ function useLocalStorage(key, initialValue) {
695
1033
  return [storedValue, setValue, remove];
696
1034
  }
697
1035
 
698
- export { AutoComplete, ButtonLoader, CopyId, CustomAnchor, Modal, ReadMore, SearchBar, cn, handleCopyTextToClipboard, useLocalStorage };
1036
+ export { AutoComplete, Breadcrumb, ButtonLoader, CopyId, CustomAnchor, CustomInput, Drawer, FilterDrawer, InputTitleWithRequired, Modal, ReadMore, SearchBar, StagingAlert, cn, handleCopyTextToClipboard, useLocalStorage };
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.-top-\[9px\]{top:-9px}.left-3{left:.75rem}.top-1\/2{top:50%}.z-50{z-index:50}.z-\[999\]{z-index:999}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.h-0{height:0}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-\[14px\]{height:14px}.h-\[16px\]{height:16px}.max-h-56{max-height:14rem}.max-h-\[95vh\]{max-height:95vh}.max-h-full{max-height:100%}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-72{width:18rem}.w-80{width:20rem}.w-\[14px\]{width:14px}.w-\[16px\]{width:16px}.w-\[20px\]{width:20px}.w-\[95\%\]{width:95%}.w-full{width:100%}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y:-50%}.-translate-y-1\/2,.rotate-180{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.75rem*var(--tw-space-x-reverse));margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)))}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.break-all{word-break:break-all}.rounded-\[24px\]{border-radius:24px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-primary{border-color:var(--color-primary,#534f8f)}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity,1))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-gray-800\/50{background-color:rgba(31,41,55,.5)}.bg-primary{background-color:var(--color-primary,#534f8f)}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-\[1px\]{padding-top:1px;padding-bottom:1px}.py-\[8px\]{padding-top:8px;padding-bottom:8px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[17px\]{font-size:17px}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.capitalize{text-transform:capitalize}.leading-\[20px\]{line-height:20px}.tracking-wide{letter-spacing:.025em}.text-\[\#333333\]{--tw-text-opacity:1;color:rgb(51 51 51/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.text-primary{color:var(--color-primary,#534f8f)}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.opacity-25{opacity:.25}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150,.transition-transform{transition-duration:.15s}.placeholder\:text-\[13px\]::-moz-placeholder{font-size:13px}.placeholder\:text-\[13px\]::placeholder{font-size:13px}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:bg-red-700:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity,1))}.hover\:text-black:hover{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.hover\:text-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.hover\:no-underline:hover{text-decoration-line:none}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:768px){.md\:w-\[60\%\]{width:60%}}@media (min-width:1024px){.lg\:w-\[30\%\]{width:30%}}
1
+ *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.-top-\[9px\]{top:-9px}.bottom-0{bottom:0}.left-0{left:0}.left-3{left:.75rem}.right-0{right:0}.top-0{top:0}.top-1\/2{top:50%}.z-10{z-index:10}.z-50{z-index:50}.z-\[1200\]{z-index:1200}.z-\[999\]{z-index:999}.ml-2{margin-left:.5rem}.mr-1{margin-right:.25rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.h-0{height:0}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-\[14px\]{height:14px}.h-\[16px\]{height:16px}.h-\[24px\]{height:24px}.h-\[45px\]{height:45px}.h-full{height:100%}.max-h-56{max-height:14rem}.max-h-\[95vh\]{max-height:95vh}.max-h-full{max-height:100%}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-72{width:18rem}.w-80{width:20rem}.w-\[14px\]{width:14px}.w-\[16px\]{width:16px}.w-\[20px\]{width:20px}.w-\[24px\]{width:24px}.w-\[300px\]{width:300px}.w-\[95\%\]{width:95%}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%}.-translate-x-full,.-translate-y-1\/2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y:-50%}.-translate-y-full{--tw-translate-y:-100%}.-translate-y-full,.translate-x-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x:0px}.translate-x-full{--tw-translate-x:100%}.translate-x-full,.translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px}.translate-y-full{--tw-translate-y:100%}.rotate-180,.translate-y-full{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.75rem*var(--tw-space-x-reverse));margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.break-all{word-break:break-all}.rounded-\[24px\]{border-radius:24px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-primary{border-color:var(--color-primary,#534f8f)}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity,1))}.border-red-500{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1))}.bg-\[\#ec6c03\]{--tw-bg-opacity:1;background-color:rgb(236 108 3/var(--tw-bg-opacity,1))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-gray-800\/50{background-color:rgba(31,41,55,.5)}.bg-primary{background-color:var(--color-primary,#534f8f)}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.p-4{padding:1rem}.p-6{padding:1.5rem}.\!px-10{padding-left:2.5rem!important;padding-right:2.5rem!important}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-\[1px\]{padding-top:1px;padding-bottom:1px}.py-\[8px\]{padding-top:8px;padding-bottom:8px}.pb-3{padding-bottom:.75rem}.\!text-\[15px\]{font-size:15px!important}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[14\.5px\]{font-size:14.5px}.text-\[14px\]{font-size:14px}.text-\[17px\]{font-size:17px}.text-\[8px\]{font-size:8px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.capitalize{text-transform:capitalize}.leading-\[20px\]{line-height:20px}.leading-none{line-height:1}.tracking-wide{letter-spacing:.025em}.text-\[\#333333\]{--tw-text-opacity:1;color:rgb(51 51 51/var(--tw-text-opacity,1))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.text-primary{color:var(--color-primary,#534f8f)}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.opacity-85{opacity:.85}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150,.transition-transform{transition-duration:.15s}.duration-300{transition-duration:.3s}#HideScroll::-webkit-scrollbar{width:0;height:0}#HideScroll::-ms-scrollbar{display:none}#HideScroll{overflow:-moz-scrollbars-none;-ms-overflow-style:none;scrollbar-width:none}.placeholder\:text-\[13px\]::-moz-placeholder{font-size:13px}.placeholder\:text-\[13px\]::placeholder{font-size:13px}.placeholder\:text-gray-500::-moz-placeholder{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.placeholder\:text-gray-500::placeholder{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:bg-red-700:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity,1))}.hover\:text-black:hover{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.hover\:text-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.hover\:text-gray-900:hover{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.hover\:text-primary:hover{color:var(--color-primary,#534f8f)}.hover\:underline:hover{text-decoration-line:underline}.hover\:no-underline:hover{text-decoration-line:none}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-70:hover{opacity:.7}.focus\:border-primary:focus{border-color:var(--color-primary,#534f8f)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-primary:focus{--tw-ring-color:var(--color-primary,#534f8f)}.focus\:ring-red-400:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(248 113 113/var(--tw-ring-opacity,1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-50:disabled{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media (min-width:768px){.md\:w-\[60\%\]{width:60%}}@media (min-width:1024px){.lg\:w-\[30\%\]{width:30%}.lg\:w-\[450px\]{width:450px}.lg\:px-4{padding-left:1rem;padding-right:1rem}.lg\:py-2{padding-top:.5rem;padding-bottom:.5rem}.lg\:text-\[12px\]{font-size:12px}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seekho/ui",
3
- "version": "0.1.15",
3
+ "version": "0.1.18",
4
4
  "description": "Seekho internal UI component library",
5
5
  "keywords": [
6
6
  "seekho",
package/readme.md CHANGED
@@ -1,103 +1,89 @@
1
1
  # seekho-ui
2
2
 
3
- Seekho internal UI component library — shared components, hooks, and utilities for internal tools built on React + Tailwind.
3
+ A React component library built with TypeScript and Tailwind CSS — pre-built CSS included, works with any Tailwind version or no Tailwind at all.
4
4
 
5
- ## What's included
5
+ ## Components
6
6
 
7
7
  | Export | Description |
8
8
  | ------ | ----------- |
9
- | `<Modal>` | Confirmation/dialog modal with hotkey support (Enter to confirm, Esc to close), loading state, warning variant, and stacked modal management |
9
+ | `<Modal>` | Confirmation/dialog modal with hotkey support (Enter to confirm, Esc to close), loading state, and warning variant |
10
+ | `<AutoComplete>` | Fully custom autocomplete with keyboard navigation, filtering, loading state, and custom render support |
11
+ | `<SearchBar>` | Search input with clear button and URL param support |
12
+ | `<ReadMore>` | Truncated text with expand/collapse and optional copy |
13
+ | `<CopyId>` | Pill button that copies an ID to clipboard |
14
+ | `<ButtonLoader>` | Animated spinner for button loading states |
15
+ | `<CustomAnchor>` | Anchor tag with new tab support |
10
16
  | `useLocalStorage` | useState backed by localStorage |
11
17
  | `cn()` | Utility to merge Tailwind class names |
18
+ | `handleCopyTextToClipboard()` | Cross-browser clipboard copy (Chrome + Safari) |
12
19
 
13
- ## Development
14
-
15
- ```bash
16
- npm install
17
- npm run storybook # component playground at http://localhost:6006
18
- npm run build # build dist/
19
- npm run lint # type check
20
- ```
21
-
22
- ## Using in a consumer project
23
-
24
- ### 1. Install
20
+ ## Installation
25
21
 
26
22
  ```bash
27
23
  npm install @seekho/ui
28
24
  ```
29
25
 
30
- ### 2. Install peer dependencies
26
+ ### Peer dependencies
31
27
 
32
28
  ```bash
33
29
  npm install react-hotkeys-hook
34
30
  ```
35
31
 
36
- ### 3. Import styles once
32
+ ### Import styles
37
33
 
38
- In your app's entry file (`src/index.tsx`, `src/main.tsx`, `app/layout.tsx`, or `pages/_app.tsx`):
34
+ Add once to your app's entry file:
39
35
 
40
36
  ```tsx
41
37
  import "@seekho/ui/styles.css";
42
38
  ```
43
39
 
44
- > The CSS is pre-built and works with any Tailwind version (v3, v4, or no Tailwind at all) — no PostCSS configuration needed.
40
+ ### Theming
45
41
 
46
- ### 4. Use components
42
+ Override the primary color via a CSS variable:
47
43
 
48
- ```tsx
49
- import { Modal } from "@seekho/ui";
44
+ ```css
45
+ :root {
46
+ --color-primary: #534f8f; /* defaults to #534f8f if not set */
47
+ }
50
48
  ```
51
49
 
52
- Refer to Storybook for usage examples of each component.
53
-
54
- ## Modal props
50
+ ### Usage
55
51
 
56
- | Prop | Type | Default | Description |
57
- | ---- | ---- | ------- | ----------- |
58
- | `show` | `boolean` | required | Controls visibility |
59
- | `title` | `string` | `""` | Modal header title |
60
- | `onHide` | `() => void` | — | Called on Cancel / Esc key |
61
- | `handleConfirmation` | `() => void` | — | Called on Confirm / Enter key |
62
- | `handleConfirmationBtnText` | `string` | `"Confirm"` | Confirm button label |
63
- | `isLoading` | `boolean` | `false` | Shows spinner, disables buttons |
64
- | `isWarning` | `boolean` | `false` | Red confirm button + warning icon |
65
- | `isButtonsRequired` | `boolean` | `true` | Hide footer buttons if false |
66
- | `className` | `string` | — | Extra classes on the modal panel |
67
- | `children` | `ReactNode` | — | Modal body content |
52
+ ```tsx
53
+ import { Modal, AutoComplete, SearchBar } from "@seekho/ui";
54
+ ```
68
55
 
69
- ## Publishing
56
+ ## Development
70
57
 
71
58
  ```bash
72
- git add .
73
- git commit -m "your message"
74
- npm version patch # or minor / major
75
- npm publish
59
+ npm install
60
+ npm run storybook # component playground at http://localhost:6006
61
+ npm run build # build dist/
62
+ npm run lint # type check
76
63
  ```
77
64
 
78
- ## Adding a new component
65
+ ## Contributing
79
66
 
80
67
  ```text
81
68
  src/components/
82
69
  └── MyComponent/
83
- ├── MyComponent.tsx # component + types
70
+ ├── MyComponent.tsx
84
71
  ├── MyComponent.stories.tsx
85
- └── index.ts # re-export
72
+ └── index.ts
86
73
  ```
87
74
 
88
- Then add `export * from "./MyComponent"` to [src/components/index.ts](src/components/index.ts).
75
+ Add `export * from "./MyComponent"` to [src/components/index.ts](src/components/index.ts).
89
76
 
90
77
  ## Project structure
91
78
 
92
79
  ```text
93
80
  seekho-ui/
94
81
  ├── src/
95
- │ ├── components/ # React components
96
- │ ├── hooks/ # Shared React hooks
97
- │ ├── utils/ # Pure utility functions
98
- │ └── index.ts # Single entry point
99
- ├── .storybook/ # Storybook config
100
- ├── postcss.config.js # PostCSS (Tailwind v3 for Storybook)
101
- ├── tailwind.config.js # Tailwind config + brand colors
102
- └── tsup.config.ts # Build config
82
+ │ ├── components/
83
+ │ ├── hooks/
84
+ │ ├── utils/
85
+ │ └── index.ts
86
+ ├── .storybook/
87
+ ├── tailwind.config.js
88
+ └── tsup.config.ts
103
89
  ```