@seekho/ui 0.1.9 → 0.1.10
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 +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +340 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +332 -4
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
+
interface RenderOptionProps {
|
|
5
|
+
onClick: (e: React.MouseEvent<HTMLLIElement>) => void;
|
|
6
|
+
onMouseEnter: () => void;
|
|
7
|
+
className: string;
|
|
8
|
+
}
|
|
9
|
+
interface AutoCompleteProps<T> {
|
|
10
|
+
label?: string;
|
|
11
|
+
value: T | null;
|
|
12
|
+
options: T[];
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
error?: boolean;
|
|
15
|
+
className?: string;
|
|
16
|
+
getOptionLabel: (option: T) => string;
|
|
17
|
+
isOptionEqualToValue?: (option: T, value: T) => boolean;
|
|
18
|
+
isLoading?: boolean;
|
|
19
|
+
renderOption?: (props: RenderOptionProps, option: T) => React.ReactNode;
|
|
20
|
+
onChange: (value: T | null) => void;
|
|
21
|
+
onInputChange?: (value: string) => void;
|
|
22
|
+
}
|
|
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
|
+
|
|
4
25
|
interface ModalProps {
|
|
5
26
|
show: boolean;
|
|
6
27
|
title?: string;
|
|
@@ -28,6 +49,19 @@ interface ReadMoreProps {
|
|
|
28
49
|
}
|
|
29
50
|
declare function ReadMore({ readMore, index, displayText, className, numberOfCharactersToShow, handleCopyDisplayText, handleToggleReadMore, }: ReadMoreProps): react_jsx_runtime.JSX.Element;
|
|
30
51
|
|
|
52
|
+
interface SearchBarProps {
|
|
53
|
+
value: string;
|
|
54
|
+
placeHolder?: string;
|
|
55
|
+
wrapperClass?: string;
|
|
56
|
+
className?: string;
|
|
57
|
+
/** Pass the current URL search param value (e.g. from useLocation) to control clear button visibility */
|
|
58
|
+
searchParamQuery?: string;
|
|
59
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
60
|
+
handleInputKey?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
61
|
+
handleClearInput?: () => void;
|
|
62
|
+
}
|
|
63
|
+
declare function SearchBar({ value, placeHolder, wrapperClass, className, searchParamQuery, onChange, handleInputKey, handleClearInput, }: SearchBarProps): react_jsx_runtime.JSX.Element;
|
|
64
|
+
|
|
31
65
|
/**
|
|
32
66
|
* useState backed by localStorage — syncs value on mount and persists on change.
|
|
33
67
|
*/
|
|
@@ -39,4 +73,4 @@ declare function useLocalStorage<T>(key: string, initialValue: T): readonly [T,
|
|
|
39
73
|
*/
|
|
40
74
|
declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
41
75
|
|
|
42
|
-
export { Modal, type ModalProps, ReadMore, type ReadMoreProps, cn, useLocalStorage };
|
|
76
|
+
export { AutoComplete, type AutoCompleteProps, Modal, type ModalProps, ReadMore, type ReadMoreProps, SearchBar, type SearchBarProps, cn, useLocalStorage };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
+
interface RenderOptionProps {
|
|
5
|
+
onClick: (e: React.MouseEvent<HTMLLIElement>) => void;
|
|
6
|
+
onMouseEnter: () => void;
|
|
7
|
+
className: string;
|
|
8
|
+
}
|
|
9
|
+
interface AutoCompleteProps<T> {
|
|
10
|
+
label?: string;
|
|
11
|
+
value: T | null;
|
|
12
|
+
options: T[];
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
error?: boolean;
|
|
15
|
+
className?: string;
|
|
16
|
+
getOptionLabel: (option: T) => string;
|
|
17
|
+
isOptionEqualToValue?: (option: T, value: T) => boolean;
|
|
18
|
+
isLoading?: boolean;
|
|
19
|
+
renderOption?: (props: RenderOptionProps, option: T) => React.ReactNode;
|
|
20
|
+
onChange: (value: T | null) => void;
|
|
21
|
+
onInputChange?: (value: string) => void;
|
|
22
|
+
}
|
|
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
|
+
|
|
4
25
|
interface ModalProps {
|
|
5
26
|
show: boolean;
|
|
6
27
|
title?: string;
|
|
@@ -28,6 +49,19 @@ interface ReadMoreProps {
|
|
|
28
49
|
}
|
|
29
50
|
declare function ReadMore({ readMore, index, displayText, className, numberOfCharactersToShow, handleCopyDisplayText, handleToggleReadMore, }: ReadMoreProps): react_jsx_runtime.JSX.Element;
|
|
30
51
|
|
|
52
|
+
interface SearchBarProps {
|
|
53
|
+
value: string;
|
|
54
|
+
placeHolder?: string;
|
|
55
|
+
wrapperClass?: string;
|
|
56
|
+
className?: string;
|
|
57
|
+
/** Pass the current URL search param value (e.g. from useLocation) to control clear button visibility */
|
|
58
|
+
searchParamQuery?: string;
|
|
59
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
60
|
+
handleInputKey?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
61
|
+
handleClearInput?: () => void;
|
|
62
|
+
}
|
|
63
|
+
declare function SearchBar({ value, placeHolder, wrapperClass, className, searchParamQuery, onChange, handleInputKey, handleClearInput, }: SearchBarProps): react_jsx_runtime.JSX.Element;
|
|
64
|
+
|
|
31
65
|
/**
|
|
32
66
|
* useState backed by localStorage — syncs value on mount and persists on change.
|
|
33
67
|
*/
|
|
@@ -39,4 +73,4 @@ declare function useLocalStorage<T>(key: string, initialValue: T): readonly [T,
|
|
|
39
73
|
*/
|
|
40
74
|
declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
41
75
|
|
|
42
|
-
export { Modal, type ModalProps, ReadMore, type ReadMoreProps, cn, useLocalStorage };
|
|
76
|
+
export { AutoComplete, type AutoCompleteProps, Modal, type ModalProps, ReadMore, type ReadMoreProps, SearchBar, type SearchBarProps, cn, useLocalStorage };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,271 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var reactHotkeysHook = require('react-hotkeys-hook');
|
|
3
|
+
var React = require('react');
|
|
5
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var reactHotkeysHook = require('react-hotkeys-hook');
|
|
6
|
+
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
10
|
+
|
|
11
|
+
// src/components/AutoComplete/AutoComplete.tsx
|
|
12
|
+
function AutoComplete({
|
|
13
|
+
label,
|
|
14
|
+
value,
|
|
15
|
+
options,
|
|
16
|
+
disabled = false,
|
|
17
|
+
error = false,
|
|
18
|
+
className,
|
|
19
|
+
getOptionLabel,
|
|
20
|
+
isOptionEqualToValue,
|
|
21
|
+
isLoading = false,
|
|
22
|
+
renderOption,
|
|
23
|
+
onChange,
|
|
24
|
+
onInputChange
|
|
25
|
+
}) {
|
|
26
|
+
const inputId = React.useId();
|
|
27
|
+
const containerRef = React.useRef(null);
|
|
28
|
+
const listRef = React.useRef(null);
|
|
29
|
+
const [open, setOpen] = React.useState(false);
|
|
30
|
+
const [inputValue, setInputValue] = React.useState(
|
|
31
|
+
value ? getOptionLabel(value) : ""
|
|
32
|
+
);
|
|
33
|
+
const [highlightedIndex, setHighlightedIndex] = React.useState(-1);
|
|
34
|
+
const filteredOptions = options.filter(
|
|
35
|
+
(option) => getOptionLabel(option).toLowerCase().includes(inputValue.toLowerCase())
|
|
36
|
+
);
|
|
37
|
+
const handleInputChange = (e) => {
|
|
38
|
+
const val = e.target.value;
|
|
39
|
+
setInputValue(val);
|
|
40
|
+
setOpen(true);
|
|
41
|
+
setHighlightedIndex(-1);
|
|
42
|
+
onInputChange == null ? void 0 : onInputChange(val);
|
|
43
|
+
};
|
|
44
|
+
const handleSelect = ({ option }) => {
|
|
45
|
+
onChange(option);
|
|
46
|
+
setInputValue(getOptionLabel(option));
|
|
47
|
+
setOpen(false);
|
|
48
|
+
setHighlightedIndex(-1);
|
|
49
|
+
};
|
|
50
|
+
const handleKeyDown = (e) => {
|
|
51
|
+
if (!open && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
|
|
52
|
+
setOpen(true);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (e.key === "ArrowDown") {
|
|
56
|
+
setHighlightedIndex(
|
|
57
|
+
(prev) => Math.min(prev + 1, filteredOptions.length - 1)
|
|
58
|
+
);
|
|
59
|
+
} else if (e.key === "ArrowUp") {
|
|
60
|
+
setHighlightedIndex((prev) => Math.max(prev - 1, 0));
|
|
61
|
+
} else if (e.key === "Enter" && highlightedIndex >= 0) {
|
|
62
|
+
handleSelect({ option: filteredOptions[highlightedIndex] });
|
|
63
|
+
} else if (e.key === "Escape") {
|
|
64
|
+
setOpen(false);
|
|
65
|
+
setInputValue(value ? getOptionLabel(value) : "");
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const isSelected = ({ option }) => {
|
|
69
|
+
if (!value) return false;
|
|
70
|
+
return isOptionEqualToValue ? isOptionEqualToValue(option, value) : getOptionLabel(option) === getOptionLabel(value);
|
|
71
|
+
};
|
|
72
|
+
React.useEffect(() => {
|
|
73
|
+
setInputValue(value ? getOptionLabel(value) : "");
|
|
74
|
+
}, [value]);
|
|
75
|
+
React.useEffect(() => {
|
|
76
|
+
const handleClickOutside = (e) => {
|
|
77
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
78
|
+
setOpen(false);
|
|
79
|
+
setInputValue(value ? getOptionLabel(value) : "");
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
83
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
84
|
+
}, [value]);
|
|
85
|
+
const isFloated = !!(inputValue || open);
|
|
86
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
87
|
+
"div",
|
|
88
|
+
{
|
|
89
|
+
ref: containerRef,
|
|
90
|
+
className: ["relative w-full", className || ""].join(" "),
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
className: [
|
|
96
|
+
"relative flex items-center rounded-md bg-white px-3 py-2 gap-2 transition-colors",
|
|
97
|
+
disabled ? "bg-gray-50 opacity-60 cursor-not-allowed" : ""
|
|
98
|
+
].join(" "),
|
|
99
|
+
children: [
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
101
|
+
"fieldset",
|
|
102
|
+
{
|
|
103
|
+
className: [
|
|
104
|
+
"absolute inset-0 rounded-md border pointer-events-none transition-colors",
|
|
105
|
+
error ? "border-red-400" : open ? "border-basePurple border-2" : "border-gray-300"
|
|
106
|
+
].join(" "),
|
|
107
|
+
style: { paddingLeft: "8px" },
|
|
108
|
+
children: label && /* @__PURE__ */ jsxRuntime.jsx(
|
|
109
|
+
"legend",
|
|
110
|
+
{
|
|
111
|
+
className: "text-[11px] transition-all duration-150 h-0 overflow-visible",
|
|
112
|
+
style: {
|
|
113
|
+
maxWidth: isFloated ? "100%" : "0.01px",
|
|
114
|
+
visibility: "hidden",
|
|
115
|
+
whiteSpace: "nowrap"
|
|
116
|
+
},
|
|
117
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1 text-[11px]", children: label })
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
label && /* @__PURE__ */ jsxRuntime.jsx(
|
|
123
|
+
"label",
|
|
124
|
+
{
|
|
125
|
+
htmlFor: inputId,
|
|
126
|
+
className: [
|
|
127
|
+
"absolute left-3 transition-all duration-150 pointer-events-none",
|
|
128
|
+
isFloated ? "-top-[9px] text-[11px] bg-white px-1" : "top-1/2 -translate-y-1/2 text-[13px]",
|
|
129
|
+
error ? "text-red-500" : isFloated || open ? "text-basePurple" : "text-gray-500"
|
|
130
|
+
].join(" "),
|
|
131
|
+
children: label
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
135
|
+
"input",
|
|
136
|
+
{
|
|
137
|
+
id: inputId,
|
|
138
|
+
value: inputValue,
|
|
139
|
+
disabled,
|
|
140
|
+
autoComplete: "off",
|
|
141
|
+
className: "w-full text-[13px] focus:outline-none bg-transparent text-gray-800 disabled:cursor-not-allowed",
|
|
142
|
+
onChange: handleInputChange,
|
|
143
|
+
onFocus: () => setOpen(true),
|
|
144
|
+
onKeyDown: handleKeyDown
|
|
145
|
+
}
|
|
146
|
+
) }),
|
|
147
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
148
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
149
|
+
"svg",
|
|
150
|
+
{
|
|
151
|
+
className: "animate-spin w-4 h-4 text-gray-400",
|
|
152
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
153
|
+
fill: "none",
|
|
154
|
+
viewBox: "0 0 24 24",
|
|
155
|
+
children: [
|
|
156
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
157
|
+
"circle",
|
|
158
|
+
{
|
|
159
|
+
className: "opacity-25",
|
|
160
|
+
cx: "12",
|
|
161
|
+
cy: "12",
|
|
162
|
+
r: "10",
|
|
163
|
+
stroke: "currentColor",
|
|
164
|
+
strokeWidth: "4"
|
|
165
|
+
}
|
|
166
|
+
),
|
|
167
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
168
|
+
"path",
|
|
169
|
+
{
|
|
170
|
+
className: "opacity-75",
|
|
171
|
+
fill: "currentColor",
|
|
172
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
value && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
179
|
+
"button",
|
|
180
|
+
{
|
|
181
|
+
type: "button",
|
|
182
|
+
onClick: () => {
|
|
183
|
+
onChange(null);
|
|
184
|
+
setInputValue("");
|
|
185
|
+
onInputChange == null ? void 0 : onInputChange("");
|
|
186
|
+
},
|
|
187
|
+
className: "text-gray-400 hover:text-gray-600 transition-colors",
|
|
188
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
189
|
+
"svg",
|
|
190
|
+
{
|
|
191
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
192
|
+
className: "w-3.5 h-3.5",
|
|
193
|
+
viewBox: "0 0 24 24",
|
|
194
|
+
fill: "none",
|
|
195
|
+
stroke: "currentColor",
|
|
196
|
+
strokeWidth: "2.5",
|
|
197
|
+
strokeLinecap: "round",
|
|
198
|
+
strokeLinejoin: "round",
|
|
199
|
+
children: [
|
|
200
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
201
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
),
|
|
207
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
208
|
+
"button",
|
|
209
|
+
{
|
|
210
|
+
type: "button",
|
|
211
|
+
disabled,
|
|
212
|
+
onClick: () => !disabled && setOpen((prev) => !prev),
|
|
213
|
+
className: "text-gray-400 hover:text-gray-600 transition-colors disabled:cursor-not-allowed",
|
|
214
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
215
|
+
"svg",
|
|
216
|
+
{
|
|
217
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
218
|
+
className: [
|
|
219
|
+
"w-4 h-4 transition-transform",
|
|
220
|
+
open ? "rotate-180" : ""
|
|
221
|
+
].join(" "),
|
|
222
|
+
viewBox: "0 0 24 24",
|
|
223
|
+
fill: "none",
|
|
224
|
+
stroke: "currentColor",
|
|
225
|
+
strokeWidth: "2",
|
|
226
|
+
strokeLinecap: "round",
|
|
227
|
+
strokeLinejoin: "round",
|
|
228
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" })
|
|
229
|
+
}
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
)
|
|
233
|
+
] })
|
|
234
|
+
]
|
|
235
|
+
}
|
|
236
|
+
),
|
|
237
|
+
open && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
238
|
+
"ul",
|
|
239
|
+
{
|
|
240
|
+
ref: listRef,
|
|
241
|
+
className: "absolute z-50 mt-1 w-full bg-white border border-gray-200 rounded-md shadow-lg max-h-56 overflow-y-auto",
|
|
242
|
+
children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("li", { className: "px-3 py-2 text-[13px] text-gray-400", children: "Loading..." }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("li", { className: "px-3 py-2 text-[13px] text-gray-400", children: "No options" }) : filteredOptions.map((option, idx) => {
|
|
243
|
+
const optionProps = {
|
|
244
|
+
onClick: () => handleSelect({ option }),
|
|
245
|
+
onMouseEnter: () => setHighlightedIndex(idx),
|
|
246
|
+
className: [
|
|
247
|
+
"px-3 py-2 text-[13px] cursor-pointer select-none",
|
|
248
|
+
highlightedIndex === idx ? "bg-basePurple/10 text-basePurple" : "text-gray-700",
|
|
249
|
+
isSelected({ option }) ? "font-semibold" : ""
|
|
250
|
+
].join(" ")
|
|
251
|
+
};
|
|
252
|
+
return renderOption ? /* @__PURE__ */ jsxRuntime.jsx(React__default.default.Fragment, { children: renderOption(optionProps, option) }, idx) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
253
|
+
"li",
|
|
254
|
+
{
|
|
255
|
+
onMouseDown: () => handleSelect({ option }),
|
|
256
|
+
onMouseEnter: () => setHighlightedIndex(idx),
|
|
257
|
+
className: optionProps.className,
|
|
258
|
+
children: getOptionLabel(option)
|
|
259
|
+
},
|
|
260
|
+
idx
|
|
261
|
+
);
|
|
262
|
+
})
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
}
|
|
8
269
|
|
|
9
270
|
// src/utils/modalStack.ts
|
|
10
271
|
var stack = [];
|
|
@@ -32,8 +293,8 @@ function Modal({
|
|
|
32
293
|
handleConfirmation,
|
|
33
294
|
handleConfirmationBtnText = "Confirm"
|
|
34
295
|
}) {
|
|
35
|
-
const modalId =
|
|
36
|
-
|
|
296
|
+
const modalId = React.useId();
|
|
297
|
+
React.useEffect(() => {
|
|
37
298
|
if (show) handlePushModal({ id: modalId });
|
|
38
299
|
return () => handlePopModal({ id: modalId });
|
|
39
300
|
}, [show, modalId]);
|
|
@@ -216,8 +477,79 @@ function ReadMore({
|
|
|
216
477
|
}
|
|
217
478
|
) });
|
|
218
479
|
}
|
|
480
|
+
function SearchBar({
|
|
481
|
+
value,
|
|
482
|
+
placeHolder,
|
|
483
|
+
wrapperClass,
|
|
484
|
+
className,
|
|
485
|
+
searchParamQuery = "",
|
|
486
|
+
onChange,
|
|
487
|
+
handleInputKey,
|
|
488
|
+
handleClearInput
|
|
489
|
+
}) {
|
|
490
|
+
const showClear = searchParamQuery || value;
|
|
491
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
492
|
+
"div",
|
|
493
|
+
{
|
|
494
|
+
className: [
|
|
495
|
+
"flex items-center rounded-full justify-between border px-2 bg-white",
|
|
496
|
+
wrapperClass || ""
|
|
497
|
+
].join(" "),
|
|
498
|
+
children: [
|
|
499
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
500
|
+
"svg",
|
|
501
|
+
{
|
|
502
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
503
|
+
className: "text-gray-400 w-[14px] h-[14px] ml-2 shrink-0",
|
|
504
|
+
viewBox: "0 0 24 24",
|
|
505
|
+
fill: "none",
|
|
506
|
+
stroke: "currentColor",
|
|
507
|
+
strokeWidth: "2",
|
|
508
|
+
strokeLinecap: "round",
|
|
509
|
+
strokeLinejoin: "round",
|
|
510
|
+
children: [
|
|
511
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }),
|
|
512
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
|
|
513
|
+
]
|
|
514
|
+
}
|
|
515
|
+
),
|
|
516
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
517
|
+
"input",
|
|
518
|
+
{
|
|
519
|
+
value,
|
|
520
|
+
placeholder: placeHolder,
|
|
521
|
+
className: [
|
|
522
|
+
"w-[95%] focus:outline-none rounded-r-full",
|
|
523
|
+
"placeholder:text-[13px] text-[13px] py-[8px] px-2",
|
|
524
|
+
className || ""
|
|
525
|
+
].join(" "),
|
|
526
|
+
onKeyPress: handleInputKey,
|
|
527
|
+
onChange
|
|
528
|
+
}
|
|
529
|
+
),
|
|
530
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[20px] shrink-0", children: showClear && handleClearInput && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleClearInput, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
531
|
+
"svg",
|
|
532
|
+
{
|
|
533
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
534
|
+
className: "w-[16px] h-[16px]",
|
|
535
|
+
viewBox: "0 0 24 24",
|
|
536
|
+
fill: "none",
|
|
537
|
+
stroke: "currentColor",
|
|
538
|
+
strokeWidth: "2.5",
|
|
539
|
+
strokeLinecap: "round",
|
|
540
|
+
strokeLinejoin: "round",
|
|
541
|
+
children: [
|
|
542
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
543
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
544
|
+
]
|
|
545
|
+
}
|
|
546
|
+
) }) })
|
|
547
|
+
]
|
|
548
|
+
}
|
|
549
|
+
);
|
|
550
|
+
}
|
|
219
551
|
function useLocalStorage(key, initialValue) {
|
|
220
|
-
const [storedValue, setStoredValue] =
|
|
552
|
+
const [storedValue, setStoredValue] = React.useState(() => {
|
|
221
553
|
if (typeof window === "undefined") return initialValue;
|
|
222
554
|
try {
|
|
223
555
|
const item = window.localStorage.getItem(key);
|
|
@@ -255,8 +587,10 @@ function cn(...classes) {
|
|
|
255
587
|
return classes.filter(Boolean).join(" ");
|
|
256
588
|
}
|
|
257
589
|
|
|
590
|
+
exports.AutoComplete = AutoComplete;
|
|
258
591
|
exports.Modal = Modal;
|
|
259
592
|
exports.ReadMore = ReadMore;
|
|
593
|
+
exports.SearchBar = SearchBar;
|
|
260
594
|
exports.cn = cn;
|
|
261
595
|
exports.useLocalStorage = useLocalStorage;
|
|
262
596
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/modalStack.ts","../src/components/Modal/Modal.tsx","../src/components/ReadMore/ReadMore.tsx","../src/hooks/useLocalStorage.ts","../src/utils/cn.ts"],"names":["useId","useEffect","useHotkeys","jsx","jsxs","useState"],"mappings":";;;;;;;;;AAEA,IAAM,QAAsB,EAAC;AAEtB,SAAS,eAAA,CAAgB,EAAE,EAAA,EAAG,EAAe;AAClD,EAAA,IAAI,CAAC,MAAM,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAA,EAAG;AACnC,IAAA,KAAA,CAAM,IAAA,CAAK,EAAE,EAAA,EAAI,CAAA;AAAA,EACnB;AACF;AAEO,SAAS,cAAA,CAAe,EAAE,EAAA,EAAG,EAAe;AACjD,EAAA,MAAM,MAAM,KAAA,CAAM,SAAA,CAAU,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAC9C,EAAA,IAAI,GAAA,KAAQ,EAAA,EAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACrC;AAEO,SAAS,gBAAA,CAAiB,EAAE,EAAA,EAAG,EAAwB;AAC5D,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,IAAK,KAAA,CAAM,MAAM,MAAA,GAAS,CAAC,EAAE,EAAA,KAAO,EAAA;AAC5D;ACIO,SAAS,KAAA,CAAM;AAAA,EACpB,IAAA;AAAA,EACA,KAAA,GAAQ,EAAA;AAAA,EACR,SAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,MAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,iBAAA,GAAoB,IAAA;AAAA,EACpB,kBAAA;AAAA,EACA,yBAAA,GAA4B;AAC9B,CAAA,EAAe;AACb,EAAA,MAAM,UAAUA,WAAA,EAAM;AAEtB,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAA,EAAM,eAAA,CAAgB,EAAE,EAAA,EAAI,SAAS,CAAA;AACzC,IAAA,OAAO,MAAM,cAAA,CAAe,EAAE,EAAA,EAAI,SAAS,CAAA;AAAA,EAC7C,CAAA,EAAG,CAAC,IAAA,EAAM,OAAO,CAAC,CAAA;AAElB,EAAAC,2BAAA;AAAA,IACE,OAAA;AAAA,IACA,CAAC,CAAA,KAAM;AACL,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,IAAI,QAAQ,gBAAA,CAAiB,EAAE,EAAA,EAAI,OAAA,EAAS,CAAA,IAAK,kBAAA;AAC/C,QAAA,kBAAA,EAAmB;AAAA,IACvB,CAAA;AAAA,IACA,EAAE,OAAA,EAAS,IAAA,IAAQ,CAAC,SAAA;AAAU,GAChC;AAEA,EAAAA,2BAAA;AAAA,IACE,KAAA;AAAA,IACA,CAAC,CAAA,KAAM;AACL,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,IAAI,IAAA,IAAQ,iBAAiB,EAAE,EAAA,EAAI,SAAS,CAAA,IAAK,QAAQ,MAAA,EAAO;AAAA,IAClE,CAAA;AAAA,IACA,EAAE,OAAA,EAAS,IAAA,IAAQ,CAAC,SAAA;AAAU,GAChC;AAEA,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAElB,EAAA,uBACEC,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uEAAA,EACb,QAAA,kBAAAC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW;AAAA,QACT,qDAAA;AAAA,QACA,oCAAA;AAAA,QACA,SAAA,IAAa;AAAA,OACf,CAAE,KAAK,GAAG,CAAA;AAAA,MAGT,QAAA,EAAA;AAAA,QAAA,KAAA,oBACCA,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+EAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,eAAA,CAAC,IAAA,EAAA,EAAG,WAAU,6EAAA,EACX,QAAA,EAAA;AAAA,YAAA,SAAA,oBACCD,cAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAU,+BAAA;AAAA,gBACV,OAAA,EAAQ,WAAA;AAAA,gBACR,IAAA,EAAK,cAAA;AAAA,gBAEL,QAAA,kBAAAA,cAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,QAAA,EAAS,SAAA;AAAA,oBACT,CAAA,EAAE,iIAAA;AAAA,oBACF,QAAA,EAAS;AAAA;AAAA;AACX;AAAA,aACF;AAAA,YAED;AAAA,WAAA,EACH,CAAA;AAAA,UACC,MAAA,oBACCA,cAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,MAAA;AAAA,cACT,SAAA,EAAU,8DAAA;AAAA,cACV,YAAA,EAAW,OAAA;AAAA,cACZ,QAAA,EAAA;AAAA;AAAA;AAED,SAAA,EAEJ,CAAA;AAAA,wBAIFA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EAAsC,QAAA,EAAS,CAAA;AAAA,QAG7D,iBAAA,oBACCC,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+DAAA,EACZ,QAAA,EAAA;AAAA,UAAA,MAAA,oBACCD,cAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,MAAA;AAAA,cACT,SAAA,EAAU,4FAAA;AAAA,cACX,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BAEFA,cAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,kBAAA;AAAA,cACT,QAAA,EAAU,SAAA;AAAA,cACV,SAAA,EAAW;AAAA,gBACT,2DAAA;AAAA,gBACA,mEAAA;AAAA,gBACA,YACI,6BAAA,GACA;AAAA,eACN,CAAE,KAAK,GAAG,CAAA;AAAA,cAET,QAAA,EAAA,SAAA,mBACCC,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EACd,QAAA,EAAA;AAAA,gCAAAA,eAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,sBAAA;AAAA,oBACV,KAAA,EAAM,4BAAA;AAAA,oBACN,IAAA,EAAK,MAAA;AAAA,oBACL,OAAA,EAAQ,WAAA;AAAA,oBAER,QAAA,EAAA;AAAA,sCAAAD,cAAA;AAAA,wBAAC,QAAA;AAAA,wBAAA;AAAA,0BACC,SAAA,EAAU,YAAA;AAAA,0BACV,EAAA,EAAG,IAAA;AAAA,0BACH,EAAA,EAAG,IAAA;AAAA,0BACH,CAAA,EAAE,IAAA;AAAA,0BACF,MAAA,EAAO,cAAA;AAAA,0BACP,WAAA,EAAY;AAAA;AAAA,uBACd;AAAA,sCACAA,cAAA;AAAA,wBAAC,MAAA;AAAA,wBAAA;AAAA,0BACC,SAAA,EAAU,YAAA;AAAA,0BACV,IAAA,EAAK,cAAA;AAAA,0BACL,CAAA,EAAE;AAAA;AAAA;AACJ;AAAA;AAAA,iBACF;AAAA,gBACC;AAAA,eAAA,EACH,CAAA,GAEA;AAAA;AAAA;AAEJ,SAAA,EACF;AAAA;AAAA;AAAA,GAEJ,EACF,CAAA;AAEJ;ACnJO,SAAS,QAAA,CAAS;AAAA,EACvB,QAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,wBAAA,GAA2B,GAAA;AAAA,EAC3B,qBAAA;AAAA,EACA;AACF,CAAA,EAAkB;AAChB,EAAA,MAAM,aAAa,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAW,KAAA,CAAA;AAC9B,EAAA,MAAM,MAAA,GAAA,CAAS,2CAAa,MAAA,IAAS,wBAAA;AAErC,EAAA,uBACEA,cAAAA,CAAC,KAAA,EAAA,EACC,QAAA,kBAAAC,eAAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW;AAAA,QACT,mGAAA;AAAA,QACA,SAAA,IAAa;AAAA,OACf,CAAE,KAAK,GAAG,CAAA;AAAA,MAET,QAAA,EAAA;AAAA,QAAA,UAAA,GAAa,WAAA,GAAc,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAa,KAAA,CAAM,CAAA,EAAG,wBAAA,CAAA;AAAA,QAA2B,GAAA;AAAA,QAC5E,0BACCD,cAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,oBAAA;AAAA,YACT,SAAA,EAAU,0DAAA;AAAA,YAET,QAAA,EAAA,UAAA,mBACCC,eAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,gCAAA,EACb,QAAA,EAAA;AAAA,cAAA,qBAAA,oBACCD,cAAAA;AAAA,gBAAC,MAAA;AAAA,gBAAA;AAAA,kBACC,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,oBAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,oBAAA,qBAAA,CAAsB,EAAE,aAAa,CAAA;AAAA,kBACvC,CAAA;AAAA,kBAEA,QAAA,kBAAAC,eAAAA;AAAA,oBAAC,KAAA;AAAA,oBAAA;AAAA,sBACC,KAAA,EAAM,4BAAA;AAAA,sBACN,SAAA,EAAU,iCAAA;AAAA,sBACV,OAAA,EAAQ,WAAA;AAAA,sBACR,IAAA,EAAK,MAAA;AAAA,sBACL,MAAA,EAAO,cAAA;AAAA,sBACP,WAAA,EAAY,GAAA;AAAA,sBACZ,aAAA,EAAc,OAAA;AAAA,sBACd,cAAA,EAAe,OAAA;AAAA,sBAEf,QAAA,EAAA;AAAA,wCAAAD,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAI,CAAA;AAAA,wCACvDA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,yDAAA,EAA0D;AAAA;AAAA;AAAA;AACpE;AAAA,eACF;AAAA,cACC,GAAA;AAAA,cAAI;AAAA,aAAA,EAET,CAAA,mBAEAA,cAAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAA,cAAA,EAAY;AAAA;AAAA;AAEtB;AAAA;AAAA,GAEJ,EACF,CAAA;AAEJ;ACnEO,SAAS,eAAA,CAAmB,KAAa,YAAA,EAAiB;AAC/D,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIE,eAAY,MAAM;AACtD,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,YAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AAC5C,MAAA,OAAO,IAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,GAAU,YAAA;AAAA,IAC1C,CAAA,CAAA,OAAQ,CAAA,EAAA;AACN,MAAA,OAAO,YAAA;AAAA,IACT;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAAgC;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,YAAA,GAAe,KAAA,YAAiB,QAAA,GAAW,KAAA,CAAM,WAAW,CAAA,GAAI,KAAA;AACtE,MAAA,cAAA,CAAe,YAAY,CAAA;AAC3B,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,QAAA,MAAA,CAAO,aAAa,OAAA,CAAQ,GAAA,EAAK,IAAA,CAAK,SAAA,CAAU,YAAY,CAAC,CAAA;AAAA,MAC/D;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,gCAAA,EAAmC,GAAG,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,IAC/D;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,SAAS,MAAM;AACnB,IAAA,IAAI;AACF,MAAA,cAAA,CAAe,YAAY,CAAA;AAC3B,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,QAAA,MAAA,CAAO,YAAA,CAAa,WAAW,GAAG,CAAA;AAAA,MACpC;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,mCAAA,EAAsC,GAAG,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,IAClE;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,CAAC,WAAA,EAAa,QAAA,EAAU,MAAM,CAAA;AACvC;;;ACpCO,SAAS,MAAM,OAAA,EAAwD;AAC5E,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,GAAG,CAAA;AACzC","file":"index.js","sourcesContent":["type ModalEntry = { id: string };\n\nconst stack: ModalEntry[] = [];\n\nexport function handlePushModal({ id }: ModalEntry) {\n if (!stack.find((m) => m.id === id)) {\n stack.push({ id });\n }\n}\n\nexport function handlePopModal({ id }: ModalEntry) {\n const idx = stack.findIndex((m) => m.id === id);\n if (idx !== -1) stack.splice(idx, 1);\n}\n\nexport function handleIsTopModal({ id }: ModalEntry): boolean {\n return stack.length > 0 && stack[stack.length - 1].id === id;\n}\n","import React, { useEffect, useId } from \"react\";\nimport { useHotkeys } from \"react-hotkeys-hook\";\nimport {\n handleIsTopModal,\n handlePopModal,\n handlePushModal,\n} from \"../../utils/modalStack\";\n\nexport interface ModalProps {\n show: boolean;\n title?: string;\n className?: string;\n children?: React.ReactNode;\n isLoading?: boolean;\n onHide?: () => void;\n isWarning?: boolean;\n isButtonsRequired?: boolean;\n handleConfirmation?: () => void;\n handleConfirmationBtnText?: string;\n}\n\nexport function Modal({\n show,\n title = \"\",\n className,\n children,\n isLoading = false,\n onHide,\n isWarning = false,\n isButtonsRequired = true,\n handleConfirmation,\n handleConfirmationBtnText = \"Confirm\",\n}: ModalProps) {\n const modalId = useId();\n\n useEffect(() => {\n if (show) handlePushModal({ id: modalId });\n return () => handlePopModal({ id: modalId });\n }, [show, modalId]);\n\n useHotkeys(\n \"enter\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && handleConfirmation)\n handleConfirmation();\n },\n { enabled: show && !isLoading }\n );\n\n useHotkeys(\n \"esc\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && onHide) onHide();\n },\n { enabled: show && !isLoading }\n );\n\n if (!show) return null;\n\n return (\n <div className=\"fixed inset-0 z-[999] bg-gray-800/50 flex items-center justify-center\">\n <div\n className={[\n \"w-[95%] bg-white rounded-lg shadow-lg flex flex-col\",\n \"md:w-[60%] lg:w-[30%] max-h-[95vh]\",\n className || \"\",\n ].join(\" \")}\n >\n {/* Header */}\n {title && (\n <div className=\"px-3.5 py-3 border-b border-gray-200 flex justify-between items-start gap-x-3\">\n <h2 className=\"text-[17px] font-semibold line-clamp-2 capitalize flex gap-x-2 items-center\">\n {isWarning && (\n <svg\n className=\"text-red-500 w-6 h-6 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12 2a10 10 0 100 20A10 10 0 0012 2zm0 5a1 1 0 011 1v4a1 1 0 11-2 0V8a1 1 0 011-1zm0 8a1.25 1.25 0 110 2.5A1.25 1.25 0 0112 15z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )}\n {title}\n </h2>\n {onHide && (\n <button\n onClick={onHide}\n className=\"text-gray-400 hover:text-gray-600 transition-colors shrink-0\"\n aria-label=\"Close\"\n >\n ✕\n </button>\n )}\n </div>\n )}\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-3.5 py-3\">{children}</div>\n\n {/* Footer */}\n {isButtonsRequired && (\n <div className=\"px-6 py-3 bg-gray-100 flex justify-end space-x-3 rounded-b-md\">\n {onHide && (\n <button\n onClick={onHide}\n className=\"px-4 py-2 bg-white rounded-md font-semibold text-[14px] hover:bg-gray-50 transition-colors\"\n >\n Cancel\n </button>\n )}\n <button\n onClick={handleConfirmation}\n disabled={isLoading}\n className={[\n \"px-4 py-2 text-white rounded-md text-[14px] font-semibold\",\n \"disabled:opacity-50 disabled:cursor-not-allowed transition-colors\",\n isWarning\n ? \"bg-red-600 hover:bg-red-700\"\n : \"bg-basePurple hover:bg-basePurple/80\",\n ].join(\" \")}\n >\n {isLoading ? (\n <span className=\"inline-flex items-center gap-2\">\n <svg\n className=\"animate-spin h-4 w-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n {handleConfirmationBtnText}\n </span>\n ) : (\n handleConfirmationBtnText\n )}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import React from \"react\";\n\nexport interface ReadMoreProps {\n readMore: Record<string | number, boolean>;\n index: string | number;\n displayText: string;\n className?: string;\n numberOfCharactersToShow?: number;\n handleCopyDisplayText?: (args: { displayText: string }) => void;\n handleToggleReadMore: () => void;\n}\n\nexport function ReadMore({\n readMore,\n index,\n displayText,\n className,\n numberOfCharactersToShow = 300,\n handleCopyDisplayText,\n handleToggleReadMore,\n}: ReadMoreProps) {\n const isExpanded = readMore?.[index];\n const isLong = displayText?.length > numberOfCharactersToShow;\n\n return (\n <div>\n <p\n className={[\n \"text-[14px] mt-1 break-all text-[#333333] leading-[20px] tracking-wide overflow-hidden max-h-full\",\n className || \"\",\n ].join(\" \")}\n >\n {isExpanded ? displayText : displayText?.slice(0, numberOfCharactersToShow)}{\" \"}\n {isLong && (\n <button\n onClick={handleToggleReadMore}\n className=\"text-basePurple cursor-pointer font-semibold text-[11px]\"\n >\n {isExpanded ? (\n <span className=\"inline-flex items-center gap-1\">\n {handleCopyDisplayText && (\n <span\n onClick={(e) => {\n e.stopPropagation();\n handleCopyDisplayText({ displayText });\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-gray-500 w-[14px] h-[14px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n </span>\n )}{\" \"}\n ...Read Less\n </span>\n ) : (\n <span>...Read More</span>\n )}\n </button>\n )}\n </p>\n </div>\n );\n}\n","import { useState } from \"react\";\n\n/**\n * useState backed by localStorage — syncs value on mount and persists on change.\n */\nexport function useLocalStorage<T>(key: string, initialValue: T) {\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") return initialValue;\n try {\n const item = window.localStorage.getItem(key);\n return item ? (JSON.parse(item) as T) : initialValue;\n } catch {\n return initialValue;\n }\n });\n\n const setValue = (value: T | ((prev: T) => T)) => {\n try {\n const valueToStore = value instanceof Function ? value(storedValue) : value;\n setStoredValue(valueToStore);\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to set \"${key}\"`, error);\n }\n };\n\n const remove = () => {\n try {\n setStoredValue(initialValue);\n if (typeof window !== \"undefined\") {\n window.localStorage.removeItem(key);\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to remove \"${key}\"`, error);\n }\n };\n\n return [storedValue, setValue, remove] as const;\n}\n","/**\n * Merges class names, filtering out falsy values.\n * Lightweight alternative to clsx for simple use cases.\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/AutoComplete/AutoComplete.tsx","../src/utils/modalStack.ts","../src/components/Modal/Modal.tsx","../src/components/ReadMore/ReadMore.tsx","../src/components/SearchBar/SearchBar.tsx","../src/hooks/useLocalStorage.ts","../src/utils/cn.ts"],"names":["useId","useRef","useState","useEffect","jsxs","jsx","React","useHotkeys"],"mappings":"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","file":"index.js","sourcesContent":["import React, { useEffect, useId, useRef, useState } from \"react\";\n\nexport interface RenderOptionProps {\n onClick: (e: React.MouseEvent<HTMLLIElement>) => void;\n onMouseEnter: () => void;\n className: string;\n}\n\nexport interface AutoCompleteProps<T> {\n label?: string;\n value: T | null;\n options: T[];\n disabled?: boolean;\n error?: boolean;\n className?: string;\n getOptionLabel: (option: T) => string;\n isOptionEqualToValue?: (option: T, value: T) => boolean;\n isLoading?: boolean;\n renderOption?: (props: RenderOptionProps, option: T) => React.ReactNode;\n onChange: (value: T | null) => void;\n onInputChange?: (value: string) => void;\n}\n\nexport function AutoComplete<T>({\n label,\n value,\n options,\n disabled = false,\n error = false,\n className,\n getOptionLabel,\n isOptionEqualToValue,\n isLoading = false,\n renderOption,\n onChange,\n onInputChange,\n}: AutoCompleteProps<T>) {\n const inputId = useId();\n const containerRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const [open, setOpen] = useState(false);\n const [inputValue, setInputValue] = useState(\n value ? getOptionLabel(value) : \"\"\n );\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n\n const filteredOptions = options.filter((option) =>\n getOptionLabel(option).toLowerCase().includes(inputValue.toLowerCase())\n );\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const val = e.target.value;\n setInputValue(val);\n setOpen(true);\n setHighlightedIndex(-1);\n onInputChange?.(val);\n };\n\n const handleSelect = ({ option }: { option: T }) => {\n onChange(option);\n setInputValue(getOptionLabel(option));\n setOpen(false);\n setHighlightedIndex(-1);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!open && (e.key === \"ArrowDown\" || e.key === \"ArrowUp\")) {\n setOpen(true);\n return;\n }\n if (e.key === \"ArrowDown\") {\n setHighlightedIndex((prev) =>\n Math.min(prev + 1, filteredOptions.length - 1)\n );\n } else if (e.key === \"ArrowUp\") {\n setHighlightedIndex((prev) => Math.max(prev - 1, 0));\n } else if (e.key === \"Enter\" && highlightedIndex >= 0) {\n handleSelect({ option: filteredOptions[highlightedIndex] });\n } else if (e.key === \"Escape\") {\n setOpen(false);\n setInputValue(value ? getOptionLabel(value) : \"\");\n }\n };\n\n const isSelected = ({ option }: { option: T }): boolean => {\n if (!value) return false;\n return isOptionEqualToValue\n ? isOptionEqualToValue(option, value)\n : getOptionLabel(option) === getOptionLabel(value);\n };\n\n // Sync input when value changes externally\n useEffect(() => {\n setInputValue(value ? getOptionLabel(value) : \"\");\n }, [value]);\n\n // Close on outside click\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n setOpen(false);\n setInputValue(value ? getOptionLabel(value) : \"\");\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [value]);\n\n const isFloated = !!(inputValue || open);\n\n return (\n <div\n ref={containerRef}\n className={[\"relative w-full\", className || \"\"].join(\" \")}\n >\n {/* Notched outline container */}\n <div\n className={[\n \"relative flex items-center rounded-md bg-white px-3 py-2 gap-2 transition-colors\",\n disabled ? \"bg-gray-50 opacity-60 cursor-not-allowed\" : \"\",\n ].join(\" \")}\n >\n {/* Notched fieldset border */}\n <fieldset\n className={[\n \"absolute inset-0 rounded-md border pointer-events-none transition-colors\",\n error\n ? \"border-red-400\"\n : open\n ? \"border-basePurple border-2\"\n : \"border-gray-300\",\n ].join(\" \")}\n style={{ paddingLeft: \"8px\" }}\n >\n {label && (\n <legend\n className=\"text-[11px] transition-all duration-150 h-0 overflow-visible\"\n style={{\n maxWidth: isFloated ? \"100%\" : \"0.01px\",\n visibility: \"hidden\",\n whiteSpace: \"nowrap\",\n }}\n >\n {/* Invisible spacer to cut the notch */}\n <span className=\"px-1 text-[11px]\">{label}</span>\n </legend>\n )}\n </fieldset>\n\n {/* Floating label */}\n {label && (\n <label\n htmlFor={inputId}\n className={[\n \"absolute left-3 transition-all duration-150 pointer-events-none\",\n isFloated\n ? \"-top-[9px] text-[11px] bg-white px-1\"\n : \"top-1/2 -translate-y-1/2 text-[13px]\",\n error\n ? \"text-red-500\"\n : isFloated || open\n ? \"text-basePurple\"\n : \"text-gray-500\",\n ].join(\" \")}\n >\n {label}\n </label>\n )}\n\n <div className=\"relative flex-1\">\n <input\n id={inputId}\n value={inputValue}\n disabled={disabled}\n autoComplete=\"off\"\n className=\"w-full text-[13px] focus:outline-none bg-transparent text-gray-800 disabled:cursor-not-allowed\"\n onChange={handleInputChange}\n onFocus={() => setOpen(true)}\n onKeyDown={handleKeyDown}\n />\n </div>\n\n {/* Right icons */}\n <div className=\"flex items-center gap-1 shrink-0\">\n {/* Loading spinner */}\n {isLoading && (\n <svg\n className=\"animate-spin w-4 h-4 text-gray-400\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n )}\n\n {/* Clear button */}\n {value && !disabled && (\n <button\n type=\"button\"\n onClick={() => {\n onChange(null);\n setInputValue(\"\");\n onInputChange?.(\"\");\n }}\n className=\"text-gray-400 hover:text-gray-600 transition-colors\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"w-3.5 h-3.5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n )}\n\n {/* Chevron */}\n <button\n type=\"button\"\n disabled={disabled}\n onClick={() => !disabled && setOpen((prev) => !prev)}\n className=\"text-gray-400 hover:text-gray-600 transition-colors disabled:cursor-not-allowed\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className={[\n \"w-4 h-4 transition-transform\",\n open ? \"rotate-180\" : \"\",\n ].join(\" \")}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Dropdown */}\n {open && !disabled && (\n <ul\n ref={listRef}\n className=\"absolute z-50 mt-1 w-full bg-white border border-gray-200 rounded-md shadow-lg max-h-56 overflow-y-auto\"\n >\n {isLoading ? (\n <li className=\"px-3 py-2 text-[13px] text-gray-400\">Loading...</li>\n ) : filteredOptions.length === 0 ? (\n <li className=\"px-3 py-2 text-[13px] text-gray-400\">No options</li>\n ) : (\n filteredOptions.map((option, idx) => {\n const optionProps: RenderOptionProps = {\n onClick: () => handleSelect({ option }),\n onMouseEnter: () => setHighlightedIndex(idx),\n className: [\n \"px-3 py-2 text-[13px] cursor-pointer select-none\",\n highlightedIndex === idx\n ? \"bg-basePurple/10 text-basePurple\"\n : \"text-gray-700\",\n isSelected({ option }) ? \"font-semibold\" : \"\",\n ].join(\" \"),\n };\n\n return renderOption ? (\n <React.Fragment key={idx}>\n {renderOption(optionProps, option)}\n </React.Fragment>\n ) : (\n <li\n key={idx}\n onMouseDown={() => handleSelect({ option })}\n onMouseEnter={() => setHighlightedIndex(idx)}\n className={optionProps.className}\n >\n {getOptionLabel(option)}\n </li>\n );\n })\n )}\n </ul>\n )}\n </div>\n );\n}\n","type ModalEntry = { id: string };\n\nconst stack: ModalEntry[] = [];\n\nexport function handlePushModal({ id }: ModalEntry) {\n if (!stack.find((m) => m.id === id)) {\n stack.push({ id });\n }\n}\n\nexport function handlePopModal({ id }: ModalEntry) {\n const idx = stack.findIndex((m) => m.id === id);\n if (idx !== -1) stack.splice(idx, 1);\n}\n\nexport function handleIsTopModal({ id }: ModalEntry): boolean {\n return stack.length > 0 && stack[stack.length - 1].id === id;\n}\n","import React, { useEffect, useId } from \"react\";\nimport { useHotkeys } from \"react-hotkeys-hook\";\nimport {\n handleIsTopModal,\n handlePopModal,\n handlePushModal,\n} from \"../../utils/modalStack\";\n\nexport interface ModalProps {\n show: boolean;\n title?: string;\n className?: string;\n children?: React.ReactNode;\n isLoading?: boolean;\n onHide?: () => void;\n isWarning?: boolean;\n isButtonsRequired?: boolean;\n handleConfirmation?: () => void;\n handleConfirmationBtnText?: string;\n}\n\nexport function Modal({\n show,\n title = \"\",\n className,\n children,\n isLoading = false,\n onHide,\n isWarning = false,\n isButtonsRequired = true,\n handleConfirmation,\n handleConfirmationBtnText = \"Confirm\",\n}: ModalProps) {\n const modalId = useId();\n\n useEffect(() => {\n if (show) handlePushModal({ id: modalId });\n return () => handlePopModal({ id: modalId });\n }, [show, modalId]);\n\n useHotkeys(\n \"enter\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && handleConfirmation)\n handleConfirmation();\n },\n { enabled: show && !isLoading }\n );\n\n useHotkeys(\n \"esc\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && onHide) onHide();\n },\n { enabled: show && !isLoading }\n );\n\n if (!show) return null;\n\n return (\n <div className=\"fixed inset-0 z-[999] bg-gray-800/50 flex items-center justify-center\">\n <div\n className={[\n \"w-[95%] bg-white rounded-lg shadow-lg flex flex-col\",\n \"md:w-[60%] lg:w-[30%] max-h-[95vh]\",\n className || \"\",\n ].join(\" \")}\n >\n {/* Header */}\n {title && (\n <div className=\"px-3.5 py-3 border-b border-gray-200 flex justify-between items-start gap-x-3\">\n <h2 className=\"text-[17px] font-semibold line-clamp-2 capitalize flex gap-x-2 items-center\">\n {isWarning && (\n <svg\n className=\"text-red-500 w-6 h-6 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12 2a10 10 0 100 20A10 10 0 0012 2zm0 5a1 1 0 011 1v4a1 1 0 11-2 0V8a1 1 0 011-1zm0 8a1.25 1.25 0 110 2.5A1.25 1.25 0 0112 15z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )}\n {title}\n </h2>\n {onHide && (\n <button\n onClick={onHide}\n className=\"text-gray-400 hover:text-gray-600 transition-colors shrink-0\"\n aria-label=\"Close\"\n >\n ✕\n </button>\n )}\n </div>\n )}\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-3.5 py-3\">{children}</div>\n\n {/* Footer */}\n {isButtonsRequired && (\n <div className=\"px-6 py-3 bg-gray-100 flex justify-end space-x-3 rounded-b-md\">\n {onHide && (\n <button\n onClick={onHide}\n className=\"px-4 py-2 bg-white rounded-md font-semibold text-[14px] hover:bg-gray-50 transition-colors\"\n >\n Cancel\n </button>\n )}\n <button\n onClick={handleConfirmation}\n disabled={isLoading}\n className={[\n \"px-4 py-2 text-white rounded-md text-[14px] font-semibold\",\n \"disabled:opacity-50 disabled:cursor-not-allowed transition-colors\",\n isWarning\n ? \"bg-red-600 hover:bg-red-700\"\n : \"bg-basePurple hover:bg-basePurple/80\",\n ].join(\" \")}\n >\n {isLoading ? (\n <span className=\"inline-flex items-center gap-2\">\n <svg\n className=\"animate-spin h-4 w-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n {handleConfirmationBtnText}\n </span>\n ) : (\n handleConfirmationBtnText\n )}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import React from \"react\";\n\nexport interface ReadMoreProps {\n readMore: Record<string | number, boolean>;\n index: string | number;\n displayText: string;\n className?: string;\n numberOfCharactersToShow?: number;\n handleCopyDisplayText?: (args: { displayText: string }) => void;\n handleToggleReadMore: () => void;\n}\n\nexport function ReadMore({\n readMore,\n index,\n displayText,\n className,\n numberOfCharactersToShow = 300,\n handleCopyDisplayText,\n handleToggleReadMore,\n}: ReadMoreProps) {\n const isExpanded = readMore?.[index];\n const isLong = displayText?.length > numberOfCharactersToShow;\n\n return (\n <div>\n <p\n className={[\n \"text-[14px] mt-1 break-all text-[#333333] leading-[20px] tracking-wide overflow-hidden max-h-full\",\n className || \"\",\n ].join(\" \")}\n >\n {isExpanded ? displayText : displayText?.slice(0, numberOfCharactersToShow)}{\" \"}\n {isLong && (\n <button\n onClick={handleToggleReadMore}\n className=\"text-basePurple cursor-pointer font-semibold text-[11px]\"\n >\n {isExpanded ? (\n <span className=\"inline-flex items-center gap-1\">\n {handleCopyDisplayText && (\n <span\n onClick={(e) => {\n e.stopPropagation();\n handleCopyDisplayText({ displayText });\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-gray-500 w-[14px] h-[14px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n </span>\n )}{\" \"}\n ...Read Less\n </span>\n ) : (\n <span>...Read More</span>\n )}\n </button>\n )}\n </p>\n </div>\n );\n}\n","import React from \"react\";\n\nexport interface SearchBarProps {\n value: string;\n placeHolder?: string;\n wrapperClass?: string;\n className?: string;\n /** Pass the current URL search param value (e.g. from useLocation) to control clear button visibility */\n searchParamQuery?: string;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n handleInputKey?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n handleClearInput?: () => void;\n}\n\nexport function SearchBar({\n value,\n placeHolder,\n wrapperClass,\n className,\n searchParamQuery = \"\",\n onChange,\n handleInputKey,\n handleClearInput,\n}: SearchBarProps) {\n const showClear = searchParamQuery || value;\n\n return (\n <div\n className={[\n \"flex items-center rounded-full justify-between border px-2 bg-white\",\n wrapperClass || \"\",\n ].join(\" \")}\n >\n {/* Search icon */}\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-gray-400 w-[14px] h-[14px] ml-2 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n\n <input\n value={value}\n placeholder={placeHolder}\n className={[\n \"w-[95%] focus:outline-none rounded-r-full\",\n \"placeholder:text-[13px] text-[13px] py-[8px] px-2\",\n className || \"\",\n ].join(\" \")}\n onKeyPress={handleInputKey}\n onChange={onChange}\n />\n\n {/* Clear button */}\n <div className=\"w-[20px] shrink-0\">\n {showClear && handleClearInput && (\n <button onClick={handleClearInput}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"w-[16px] h-[16px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\n\n/**\n * useState backed by localStorage — syncs value on mount and persists on change.\n */\nexport function useLocalStorage<T>(key: string, initialValue: T) {\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") return initialValue;\n try {\n const item = window.localStorage.getItem(key);\n return item ? (JSON.parse(item) as T) : initialValue;\n } catch {\n return initialValue;\n }\n });\n\n const setValue = (value: T | ((prev: T) => T)) => {\n try {\n const valueToStore = value instanceof Function ? value(storedValue) : value;\n setStoredValue(valueToStore);\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to set \"${key}\"`, error);\n }\n };\n\n const remove = () => {\n try {\n setStoredValue(initialValue);\n if (typeof window !== \"undefined\") {\n window.localStorage.removeItem(key);\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to remove \"${key}\"`, error);\n }\n };\n\n return [storedValue, setValue, remove] as const;\n}\n","/**\n * Merges class names, filtering out falsy values.\n * Lightweight alternative to clsx for simple use cases.\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,265 @@
|
|
|
1
|
-
import { useId,
|
|
1
|
+
import React, { useId, useRef, useState, useEffect } from 'react';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
3
|
import { useHotkeys } from 'react-hotkeys-hook';
|
|
3
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
|
-
// src/components/
|
|
5
|
+
// src/components/AutoComplete/AutoComplete.tsx
|
|
6
|
+
function AutoComplete({
|
|
7
|
+
label,
|
|
8
|
+
value,
|
|
9
|
+
options,
|
|
10
|
+
disabled = false,
|
|
11
|
+
error = false,
|
|
12
|
+
className,
|
|
13
|
+
getOptionLabel,
|
|
14
|
+
isOptionEqualToValue,
|
|
15
|
+
isLoading = false,
|
|
16
|
+
renderOption,
|
|
17
|
+
onChange,
|
|
18
|
+
onInputChange
|
|
19
|
+
}) {
|
|
20
|
+
const inputId = useId();
|
|
21
|
+
const containerRef = useRef(null);
|
|
22
|
+
const listRef = useRef(null);
|
|
23
|
+
const [open, setOpen] = useState(false);
|
|
24
|
+
const [inputValue, setInputValue] = useState(
|
|
25
|
+
value ? getOptionLabel(value) : ""
|
|
26
|
+
);
|
|
27
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
28
|
+
const filteredOptions = options.filter(
|
|
29
|
+
(option) => getOptionLabel(option).toLowerCase().includes(inputValue.toLowerCase())
|
|
30
|
+
);
|
|
31
|
+
const handleInputChange = (e) => {
|
|
32
|
+
const val = e.target.value;
|
|
33
|
+
setInputValue(val);
|
|
34
|
+
setOpen(true);
|
|
35
|
+
setHighlightedIndex(-1);
|
|
36
|
+
onInputChange == null ? void 0 : onInputChange(val);
|
|
37
|
+
};
|
|
38
|
+
const handleSelect = ({ option }) => {
|
|
39
|
+
onChange(option);
|
|
40
|
+
setInputValue(getOptionLabel(option));
|
|
41
|
+
setOpen(false);
|
|
42
|
+
setHighlightedIndex(-1);
|
|
43
|
+
};
|
|
44
|
+
const handleKeyDown = (e) => {
|
|
45
|
+
if (!open && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
|
|
46
|
+
setOpen(true);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (e.key === "ArrowDown") {
|
|
50
|
+
setHighlightedIndex(
|
|
51
|
+
(prev) => Math.min(prev + 1, filteredOptions.length - 1)
|
|
52
|
+
);
|
|
53
|
+
} else if (e.key === "ArrowUp") {
|
|
54
|
+
setHighlightedIndex((prev) => Math.max(prev - 1, 0));
|
|
55
|
+
} else if (e.key === "Enter" && highlightedIndex >= 0) {
|
|
56
|
+
handleSelect({ option: filteredOptions[highlightedIndex] });
|
|
57
|
+
} else if (e.key === "Escape") {
|
|
58
|
+
setOpen(false);
|
|
59
|
+
setInputValue(value ? getOptionLabel(value) : "");
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const isSelected = ({ option }) => {
|
|
63
|
+
if (!value) return false;
|
|
64
|
+
return isOptionEqualToValue ? isOptionEqualToValue(option, value) : getOptionLabel(option) === getOptionLabel(value);
|
|
65
|
+
};
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
setInputValue(value ? getOptionLabel(value) : "");
|
|
68
|
+
}, [value]);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const handleClickOutside = (e) => {
|
|
71
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
72
|
+
setOpen(false);
|
|
73
|
+
setInputValue(value ? getOptionLabel(value) : "");
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
77
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
78
|
+
}, [value]);
|
|
79
|
+
const isFloated = !!(inputValue || open);
|
|
80
|
+
return /* @__PURE__ */ jsxs(
|
|
81
|
+
"div",
|
|
82
|
+
{
|
|
83
|
+
ref: containerRef,
|
|
84
|
+
className: ["relative w-full", className || ""].join(" "),
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ jsxs(
|
|
87
|
+
"div",
|
|
88
|
+
{
|
|
89
|
+
className: [
|
|
90
|
+
"relative flex items-center rounded-md bg-white px-3 py-2 gap-2 transition-colors",
|
|
91
|
+
disabled ? "bg-gray-50 opacity-60 cursor-not-allowed" : ""
|
|
92
|
+
].join(" "),
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsx(
|
|
95
|
+
"fieldset",
|
|
96
|
+
{
|
|
97
|
+
className: [
|
|
98
|
+
"absolute inset-0 rounded-md border pointer-events-none transition-colors",
|
|
99
|
+
error ? "border-red-400" : open ? "border-basePurple border-2" : "border-gray-300"
|
|
100
|
+
].join(" "),
|
|
101
|
+
style: { paddingLeft: "8px" },
|
|
102
|
+
children: label && /* @__PURE__ */ jsx(
|
|
103
|
+
"legend",
|
|
104
|
+
{
|
|
105
|
+
className: "text-[11px] transition-all duration-150 h-0 overflow-visible",
|
|
106
|
+
style: {
|
|
107
|
+
maxWidth: isFloated ? "100%" : "0.01px",
|
|
108
|
+
visibility: "hidden",
|
|
109
|
+
whiteSpace: "nowrap"
|
|
110
|
+
},
|
|
111
|
+
children: /* @__PURE__ */ jsx("span", { className: "px-1 text-[11px]", children: label })
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
),
|
|
116
|
+
label && /* @__PURE__ */ jsx(
|
|
117
|
+
"label",
|
|
118
|
+
{
|
|
119
|
+
htmlFor: inputId,
|
|
120
|
+
className: [
|
|
121
|
+
"absolute left-3 transition-all duration-150 pointer-events-none",
|
|
122
|
+
isFloated ? "-top-[9px] text-[11px] bg-white px-1" : "top-1/2 -translate-y-1/2 text-[13px]",
|
|
123
|
+
error ? "text-red-500" : isFloated || open ? "text-basePurple" : "text-gray-500"
|
|
124
|
+
].join(" "),
|
|
125
|
+
children: label
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex-1", children: /* @__PURE__ */ jsx(
|
|
129
|
+
"input",
|
|
130
|
+
{
|
|
131
|
+
id: inputId,
|
|
132
|
+
value: inputValue,
|
|
133
|
+
disabled,
|
|
134
|
+
autoComplete: "off",
|
|
135
|
+
className: "w-full text-[13px] focus:outline-none bg-transparent text-gray-800 disabled:cursor-not-allowed",
|
|
136
|
+
onChange: handleInputChange,
|
|
137
|
+
onFocus: () => setOpen(true),
|
|
138
|
+
onKeyDown: handleKeyDown
|
|
139
|
+
}
|
|
140
|
+
) }),
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
142
|
+
isLoading && /* @__PURE__ */ jsxs(
|
|
143
|
+
"svg",
|
|
144
|
+
{
|
|
145
|
+
className: "animate-spin w-4 h-4 text-gray-400",
|
|
146
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
147
|
+
fill: "none",
|
|
148
|
+
viewBox: "0 0 24 24",
|
|
149
|
+
children: [
|
|
150
|
+
/* @__PURE__ */ jsx(
|
|
151
|
+
"circle",
|
|
152
|
+
{
|
|
153
|
+
className: "opacity-25",
|
|
154
|
+
cx: "12",
|
|
155
|
+
cy: "12",
|
|
156
|
+
r: "10",
|
|
157
|
+
stroke: "currentColor",
|
|
158
|
+
strokeWidth: "4"
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
/* @__PURE__ */ jsx(
|
|
162
|
+
"path",
|
|
163
|
+
{
|
|
164
|
+
className: "opacity-75",
|
|
165
|
+
fill: "currentColor",
|
|
166
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
167
|
+
}
|
|
168
|
+
)
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
),
|
|
172
|
+
value && !disabled && /* @__PURE__ */ jsx(
|
|
173
|
+
"button",
|
|
174
|
+
{
|
|
175
|
+
type: "button",
|
|
176
|
+
onClick: () => {
|
|
177
|
+
onChange(null);
|
|
178
|
+
setInputValue("");
|
|
179
|
+
onInputChange == null ? void 0 : onInputChange("");
|
|
180
|
+
},
|
|
181
|
+
className: "text-gray-400 hover:text-gray-600 transition-colors",
|
|
182
|
+
children: /* @__PURE__ */ jsxs(
|
|
183
|
+
"svg",
|
|
184
|
+
{
|
|
185
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
186
|
+
className: "w-3.5 h-3.5",
|
|
187
|
+
viewBox: "0 0 24 24",
|
|
188
|
+
fill: "none",
|
|
189
|
+
stroke: "currentColor",
|
|
190
|
+
strokeWidth: "2.5",
|
|
191
|
+
strokeLinecap: "round",
|
|
192
|
+
strokeLinejoin: "round",
|
|
193
|
+
children: [
|
|
194
|
+
/* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
195
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
),
|
|
201
|
+
/* @__PURE__ */ jsx(
|
|
202
|
+
"button",
|
|
203
|
+
{
|
|
204
|
+
type: "button",
|
|
205
|
+
disabled,
|
|
206
|
+
onClick: () => !disabled && setOpen((prev) => !prev),
|
|
207
|
+
className: "text-gray-400 hover:text-gray-600 transition-colors disabled:cursor-not-allowed",
|
|
208
|
+
children: /* @__PURE__ */ jsx(
|
|
209
|
+
"svg",
|
|
210
|
+
{
|
|
211
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
212
|
+
className: [
|
|
213
|
+
"w-4 h-4 transition-transform",
|
|
214
|
+
open ? "rotate-180" : ""
|
|
215
|
+
].join(" "),
|
|
216
|
+
viewBox: "0 0 24 24",
|
|
217
|
+
fill: "none",
|
|
218
|
+
stroke: "currentColor",
|
|
219
|
+
strokeWidth: "2",
|
|
220
|
+
strokeLinecap: "round",
|
|
221
|
+
strokeLinejoin: "round",
|
|
222
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" })
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
] })
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
),
|
|
231
|
+
open && !disabled && /* @__PURE__ */ jsx(
|
|
232
|
+
"ul",
|
|
233
|
+
{
|
|
234
|
+
ref: listRef,
|
|
235
|
+
className: "absolute z-50 mt-1 w-full bg-white border border-gray-200 rounded-md shadow-lg max-h-56 overflow-y-auto",
|
|
236
|
+
children: isLoading ? /* @__PURE__ */ jsx("li", { className: "px-3 py-2 text-[13px] text-gray-400", children: "Loading..." }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsx("li", { className: "px-3 py-2 text-[13px] text-gray-400", children: "No options" }) : filteredOptions.map((option, idx) => {
|
|
237
|
+
const optionProps = {
|
|
238
|
+
onClick: () => handleSelect({ option }),
|
|
239
|
+
onMouseEnter: () => setHighlightedIndex(idx),
|
|
240
|
+
className: [
|
|
241
|
+
"px-3 py-2 text-[13px] cursor-pointer select-none",
|
|
242
|
+
highlightedIndex === idx ? "bg-basePurple/10 text-basePurple" : "text-gray-700",
|
|
243
|
+
isSelected({ option }) ? "font-semibold" : ""
|
|
244
|
+
].join(" ")
|
|
245
|
+
};
|
|
246
|
+
return renderOption ? /* @__PURE__ */ jsx(React.Fragment, { children: renderOption(optionProps, option) }, idx) : /* @__PURE__ */ jsx(
|
|
247
|
+
"li",
|
|
248
|
+
{
|
|
249
|
+
onMouseDown: () => handleSelect({ option }),
|
|
250
|
+
onMouseEnter: () => setHighlightedIndex(idx),
|
|
251
|
+
className: optionProps.className,
|
|
252
|
+
children: getOptionLabel(option)
|
|
253
|
+
},
|
|
254
|
+
idx
|
|
255
|
+
);
|
|
256
|
+
})
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
);
|
|
262
|
+
}
|
|
6
263
|
|
|
7
264
|
// src/utils/modalStack.ts
|
|
8
265
|
var stack = [];
|
|
@@ -214,6 +471,77 @@ function ReadMore({
|
|
|
214
471
|
}
|
|
215
472
|
) });
|
|
216
473
|
}
|
|
474
|
+
function SearchBar({
|
|
475
|
+
value,
|
|
476
|
+
placeHolder,
|
|
477
|
+
wrapperClass,
|
|
478
|
+
className,
|
|
479
|
+
searchParamQuery = "",
|
|
480
|
+
onChange,
|
|
481
|
+
handleInputKey,
|
|
482
|
+
handleClearInput
|
|
483
|
+
}) {
|
|
484
|
+
const showClear = searchParamQuery || value;
|
|
485
|
+
return /* @__PURE__ */ jsxs(
|
|
486
|
+
"div",
|
|
487
|
+
{
|
|
488
|
+
className: [
|
|
489
|
+
"flex items-center rounded-full justify-between border px-2 bg-white",
|
|
490
|
+
wrapperClass || ""
|
|
491
|
+
].join(" "),
|
|
492
|
+
children: [
|
|
493
|
+
/* @__PURE__ */ jsxs(
|
|
494
|
+
"svg",
|
|
495
|
+
{
|
|
496
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
497
|
+
className: "text-gray-400 w-[14px] h-[14px] ml-2 shrink-0",
|
|
498
|
+
viewBox: "0 0 24 24",
|
|
499
|
+
fill: "none",
|
|
500
|
+
stroke: "currentColor",
|
|
501
|
+
strokeWidth: "2",
|
|
502
|
+
strokeLinecap: "round",
|
|
503
|
+
strokeLinejoin: "round",
|
|
504
|
+
children: [
|
|
505
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
|
|
506
|
+
/* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
|
|
507
|
+
]
|
|
508
|
+
}
|
|
509
|
+
),
|
|
510
|
+
/* @__PURE__ */ jsx(
|
|
511
|
+
"input",
|
|
512
|
+
{
|
|
513
|
+
value,
|
|
514
|
+
placeholder: placeHolder,
|
|
515
|
+
className: [
|
|
516
|
+
"w-[95%] focus:outline-none rounded-r-full",
|
|
517
|
+
"placeholder:text-[13px] text-[13px] py-[8px] px-2",
|
|
518
|
+
className || ""
|
|
519
|
+
].join(" "),
|
|
520
|
+
onKeyPress: handleInputKey,
|
|
521
|
+
onChange
|
|
522
|
+
}
|
|
523
|
+
),
|
|
524
|
+
/* @__PURE__ */ jsx("div", { className: "w-[20px] shrink-0", children: showClear && handleClearInput && /* @__PURE__ */ jsx("button", { onClick: handleClearInput, children: /* @__PURE__ */ jsxs(
|
|
525
|
+
"svg",
|
|
526
|
+
{
|
|
527
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
528
|
+
className: "w-[16px] h-[16px]",
|
|
529
|
+
viewBox: "0 0 24 24",
|
|
530
|
+
fill: "none",
|
|
531
|
+
stroke: "currentColor",
|
|
532
|
+
strokeWidth: "2.5",
|
|
533
|
+
strokeLinecap: "round",
|
|
534
|
+
strokeLinejoin: "round",
|
|
535
|
+
children: [
|
|
536
|
+
/* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
537
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
538
|
+
]
|
|
539
|
+
}
|
|
540
|
+
) }) })
|
|
541
|
+
]
|
|
542
|
+
}
|
|
543
|
+
);
|
|
544
|
+
}
|
|
217
545
|
function useLocalStorage(key, initialValue) {
|
|
218
546
|
const [storedValue, setStoredValue] = useState(() => {
|
|
219
547
|
if (typeof window === "undefined") return initialValue;
|
|
@@ -253,6 +581,6 @@ function cn(...classes) {
|
|
|
253
581
|
return classes.filter(Boolean).join(" ");
|
|
254
582
|
}
|
|
255
583
|
|
|
256
|
-
export { Modal, ReadMore, cn, useLocalStorage };
|
|
584
|
+
export { AutoComplete, Modal, ReadMore, SearchBar, cn, useLocalStorage };
|
|
257
585
|
//# sourceMappingURL=index.mjs.map
|
|
258
586
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/modalStack.ts","../src/components/Modal/Modal.tsx","../src/components/ReadMore/ReadMore.tsx","../src/hooks/useLocalStorage.ts","../src/utils/cn.ts"],"names":["jsx","jsxs"],"mappings":"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","file":"index.mjs","sourcesContent":["type ModalEntry = { id: string };\n\nconst stack: ModalEntry[] = [];\n\nexport function handlePushModal({ id }: ModalEntry) {\n if (!stack.find((m) => m.id === id)) {\n stack.push({ id });\n }\n}\n\nexport function handlePopModal({ id }: ModalEntry) {\n const idx = stack.findIndex((m) => m.id === id);\n if (idx !== -1) stack.splice(idx, 1);\n}\n\nexport function handleIsTopModal({ id }: ModalEntry): boolean {\n return stack.length > 0 && stack[stack.length - 1].id === id;\n}\n","import React, { useEffect, useId } from \"react\";\nimport { useHotkeys } from \"react-hotkeys-hook\";\nimport {\n handleIsTopModal,\n handlePopModal,\n handlePushModal,\n} from \"../../utils/modalStack\";\n\nexport interface ModalProps {\n show: boolean;\n title?: string;\n className?: string;\n children?: React.ReactNode;\n isLoading?: boolean;\n onHide?: () => void;\n isWarning?: boolean;\n isButtonsRequired?: boolean;\n handleConfirmation?: () => void;\n handleConfirmationBtnText?: string;\n}\n\nexport function Modal({\n show,\n title = \"\",\n className,\n children,\n isLoading = false,\n onHide,\n isWarning = false,\n isButtonsRequired = true,\n handleConfirmation,\n handleConfirmationBtnText = \"Confirm\",\n}: ModalProps) {\n const modalId = useId();\n\n useEffect(() => {\n if (show) handlePushModal({ id: modalId });\n return () => handlePopModal({ id: modalId });\n }, [show, modalId]);\n\n useHotkeys(\n \"enter\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && handleConfirmation)\n handleConfirmation();\n },\n { enabled: show && !isLoading }\n );\n\n useHotkeys(\n \"esc\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && onHide) onHide();\n },\n { enabled: show && !isLoading }\n );\n\n if (!show) return null;\n\n return (\n <div className=\"fixed inset-0 z-[999] bg-gray-800/50 flex items-center justify-center\">\n <div\n className={[\n \"w-[95%] bg-white rounded-lg shadow-lg flex flex-col\",\n \"md:w-[60%] lg:w-[30%] max-h-[95vh]\",\n className || \"\",\n ].join(\" \")}\n >\n {/* Header */}\n {title && (\n <div className=\"px-3.5 py-3 border-b border-gray-200 flex justify-between items-start gap-x-3\">\n <h2 className=\"text-[17px] font-semibold line-clamp-2 capitalize flex gap-x-2 items-center\">\n {isWarning && (\n <svg\n className=\"text-red-500 w-6 h-6 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12 2a10 10 0 100 20A10 10 0 0012 2zm0 5a1 1 0 011 1v4a1 1 0 11-2 0V8a1 1 0 011-1zm0 8a1.25 1.25 0 110 2.5A1.25 1.25 0 0112 15z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )}\n {title}\n </h2>\n {onHide && (\n <button\n onClick={onHide}\n className=\"text-gray-400 hover:text-gray-600 transition-colors shrink-0\"\n aria-label=\"Close\"\n >\n ✕\n </button>\n )}\n </div>\n )}\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-3.5 py-3\">{children}</div>\n\n {/* Footer */}\n {isButtonsRequired && (\n <div className=\"px-6 py-3 bg-gray-100 flex justify-end space-x-3 rounded-b-md\">\n {onHide && (\n <button\n onClick={onHide}\n className=\"px-4 py-2 bg-white rounded-md font-semibold text-[14px] hover:bg-gray-50 transition-colors\"\n >\n Cancel\n </button>\n )}\n <button\n onClick={handleConfirmation}\n disabled={isLoading}\n className={[\n \"px-4 py-2 text-white rounded-md text-[14px] font-semibold\",\n \"disabled:opacity-50 disabled:cursor-not-allowed transition-colors\",\n isWarning\n ? \"bg-red-600 hover:bg-red-700\"\n : \"bg-basePurple hover:bg-basePurple/80\",\n ].join(\" \")}\n >\n {isLoading ? (\n <span className=\"inline-flex items-center gap-2\">\n <svg\n className=\"animate-spin h-4 w-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n {handleConfirmationBtnText}\n </span>\n ) : (\n handleConfirmationBtnText\n )}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import React from \"react\";\n\nexport interface ReadMoreProps {\n readMore: Record<string | number, boolean>;\n index: string | number;\n displayText: string;\n className?: string;\n numberOfCharactersToShow?: number;\n handleCopyDisplayText?: (args: { displayText: string }) => void;\n handleToggleReadMore: () => void;\n}\n\nexport function ReadMore({\n readMore,\n index,\n displayText,\n className,\n numberOfCharactersToShow = 300,\n handleCopyDisplayText,\n handleToggleReadMore,\n}: ReadMoreProps) {\n const isExpanded = readMore?.[index];\n const isLong = displayText?.length > numberOfCharactersToShow;\n\n return (\n <div>\n <p\n className={[\n \"text-[14px] mt-1 break-all text-[#333333] leading-[20px] tracking-wide overflow-hidden max-h-full\",\n className || \"\",\n ].join(\" \")}\n >\n {isExpanded ? displayText : displayText?.slice(0, numberOfCharactersToShow)}{\" \"}\n {isLong && (\n <button\n onClick={handleToggleReadMore}\n className=\"text-basePurple cursor-pointer font-semibold text-[11px]\"\n >\n {isExpanded ? (\n <span className=\"inline-flex items-center gap-1\">\n {handleCopyDisplayText && (\n <span\n onClick={(e) => {\n e.stopPropagation();\n handleCopyDisplayText({ displayText });\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-gray-500 w-[14px] h-[14px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n </span>\n )}{\" \"}\n ...Read Less\n </span>\n ) : (\n <span>...Read More</span>\n )}\n </button>\n )}\n </p>\n </div>\n );\n}\n","import { useState } from \"react\";\n\n/**\n * useState backed by localStorage — syncs value on mount and persists on change.\n */\nexport function useLocalStorage<T>(key: string, initialValue: T) {\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") return initialValue;\n try {\n const item = window.localStorage.getItem(key);\n return item ? (JSON.parse(item) as T) : initialValue;\n } catch {\n return initialValue;\n }\n });\n\n const setValue = (value: T | ((prev: T) => T)) => {\n try {\n const valueToStore = value instanceof Function ? value(storedValue) : value;\n setStoredValue(valueToStore);\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to set \"${key}\"`, error);\n }\n };\n\n const remove = () => {\n try {\n setStoredValue(initialValue);\n if (typeof window !== \"undefined\") {\n window.localStorage.removeItem(key);\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to remove \"${key}\"`, error);\n }\n };\n\n return [storedValue, setValue, remove] as const;\n}\n","/**\n * Merges class names, filtering out falsy values.\n * Lightweight alternative to clsx for simple use cases.\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/AutoComplete/AutoComplete.tsx","../src/utils/modalStack.ts","../src/components/Modal/Modal.tsx","../src/components/ReadMore/ReadMore.tsx","../src/components/SearchBar/SearchBar.tsx","../src/hooks/useLocalStorage.ts","../src/utils/cn.ts"],"names":["useId","useEffect","jsx","jsxs","useState"],"mappings":"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","file":"index.mjs","sourcesContent":["import React, { useEffect, useId, useRef, useState } from \"react\";\n\nexport interface RenderOptionProps {\n onClick: (e: React.MouseEvent<HTMLLIElement>) => void;\n onMouseEnter: () => void;\n className: string;\n}\n\nexport interface AutoCompleteProps<T> {\n label?: string;\n value: T | null;\n options: T[];\n disabled?: boolean;\n error?: boolean;\n className?: string;\n getOptionLabel: (option: T) => string;\n isOptionEqualToValue?: (option: T, value: T) => boolean;\n isLoading?: boolean;\n renderOption?: (props: RenderOptionProps, option: T) => React.ReactNode;\n onChange: (value: T | null) => void;\n onInputChange?: (value: string) => void;\n}\n\nexport function AutoComplete<T>({\n label,\n value,\n options,\n disabled = false,\n error = false,\n className,\n getOptionLabel,\n isOptionEqualToValue,\n isLoading = false,\n renderOption,\n onChange,\n onInputChange,\n}: AutoCompleteProps<T>) {\n const inputId = useId();\n const containerRef = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n\n const [open, setOpen] = useState(false);\n const [inputValue, setInputValue] = useState(\n value ? getOptionLabel(value) : \"\"\n );\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n\n const filteredOptions = options.filter((option) =>\n getOptionLabel(option).toLowerCase().includes(inputValue.toLowerCase())\n );\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const val = e.target.value;\n setInputValue(val);\n setOpen(true);\n setHighlightedIndex(-1);\n onInputChange?.(val);\n };\n\n const handleSelect = ({ option }: { option: T }) => {\n onChange(option);\n setInputValue(getOptionLabel(option));\n setOpen(false);\n setHighlightedIndex(-1);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (!open && (e.key === \"ArrowDown\" || e.key === \"ArrowUp\")) {\n setOpen(true);\n return;\n }\n if (e.key === \"ArrowDown\") {\n setHighlightedIndex((prev) =>\n Math.min(prev + 1, filteredOptions.length - 1)\n );\n } else if (e.key === \"ArrowUp\") {\n setHighlightedIndex((prev) => Math.max(prev - 1, 0));\n } else if (e.key === \"Enter\" && highlightedIndex >= 0) {\n handleSelect({ option: filteredOptions[highlightedIndex] });\n } else if (e.key === \"Escape\") {\n setOpen(false);\n setInputValue(value ? getOptionLabel(value) : \"\");\n }\n };\n\n const isSelected = ({ option }: { option: T }): boolean => {\n if (!value) return false;\n return isOptionEqualToValue\n ? isOptionEqualToValue(option, value)\n : getOptionLabel(option) === getOptionLabel(value);\n };\n\n // Sync input when value changes externally\n useEffect(() => {\n setInputValue(value ? getOptionLabel(value) : \"\");\n }, [value]);\n\n // Close on outside click\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(e.target as Node)\n ) {\n setOpen(false);\n setInputValue(value ? getOptionLabel(value) : \"\");\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [value]);\n\n const isFloated = !!(inputValue || open);\n\n return (\n <div\n ref={containerRef}\n className={[\"relative w-full\", className || \"\"].join(\" \")}\n >\n {/* Notched outline container */}\n <div\n className={[\n \"relative flex items-center rounded-md bg-white px-3 py-2 gap-2 transition-colors\",\n disabled ? \"bg-gray-50 opacity-60 cursor-not-allowed\" : \"\",\n ].join(\" \")}\n >\n {/* Notched fieldset border */}\n <fieldset\n className={[\n \"absolute inset-0 rounded-md border pointer-events-none transition-colors\",\n error\n ? \"border-red-400\"\n : open\n ? \"border-basePurple border-2\"\n : \"border-gray-300\",\n ].join(\" \")}\n style={{ paddingLeft: \"8px\" }}\n >\n {label && (\n <legend\n className=\"text-[11px] transition-all duration-150 h-0 overflow-visible\"\n style={{\n maxWidth: isFloated ? \"100%\" : \"0.01px\",\n visibility: \"hidden\",\n whiteSpace: \"nowrap\",\n }}\n >\n {/* Invisible spacer to cut the notch */}\n <span className=\"px-1 text-[11px]\">{label}</span>\n </legend>\n )}\n </fieldset>\n\n {/* Floating label */}\n {label && (\n <label\n htmlFor={inputId}\n className={[\n \"absolute left-3 transition-all duration-150 pointer-events-none\",\n isFloated\n ? \"-top-[9px] text-[11px] bg-white px-1\"\n : \"top-1/2 -translate-y-1/2 text-[13px]\",\n error\n ? \"text-red-500\"\n : isFloated || open\n ? \"text-basePurple\"\n : \"text-gray-500\",\n ].join(\" \")}\n >\n {label}\n </label>\n )}\n\n <div className=\"relative flex-1\">\n <input\n id={inputId}\n value={inputValue}\n disabled={disabled}\n autoComplete=\"off\"\n className=\"w-full text-[13px] focus:outline-none bg-transparent text-gray-800 disabled:cursor-not-allowed\"\n onChange={handleInputChange}\n onFocus={() => setOpen(true)}\n onKeyDown={handleKeyDown}\n />\n </div>\n\n {/* Right icons */}\n <div className=\"flex items-center gap-1 shrink-0\">\n {/* Loading spinner */}\n {isLoading && (\n <svg\n className=\"animate-spin w-4 h-4 text-gray-400\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n )}\n\n {/* Clear button */}\n {value && !disabled && (\n <button\n type=\"button\"\n onClick={() => {\n onChange(null);\n setInputValue(\"\");\n onInputChange?.(\"\");\n }}\n className=\"text-gray-400 hover:text-gray-600 transition-colors\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"w-3.5 h-3.5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n )}\n\n {/* Chevron */}\n <button\n type=\"button\"\n disabled={disabled}\n onClick={() => !disabled && setOpen((prev) => !prev)}\n className=\"text-gray-400 hover:text-gray-600 transition-colors disabled:cursor-not-allowed\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className={[\n \"w-4 h-4 transition-transform\",\n open ? \"rotate-180\" : \"\",\n ].join(\" \")}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Dropdown */}\n {open && !disabled && (\n <ul\n ref={listRef}\n className=\"absolute z-50 mt-1 w-full bg-white border border-gray-200 rounded-md shadow-lg max-h-56 overflow-y-auto\"\n >\n {isLoading ? (\n <li className=\"px-3 py-2 text-[13px] text-gray-400\">Loading...</li>\n ) : filteredOptions.length === 0 ? (\n <li className=\"px-3 py-2 text-[13px] text-gray-400\">No options</li>\n ) : (\n filteredOptions.map((option, idx) => {\n const optionProps: RenderOptionProps = {\n onClick: () => handleSelect({ option }),\n onMouseEnter: () => setHighlightedIndex(idx),\n className: [\n \"px-3 py-2 text-[13px] cursor-pointer select-none\",\n highlightedIndex === idx\n ? \"bg-basePurple/10 text-basePurple\"\n : \"text-gray-700\",\n isSelected({ option }) ? \"font-semibold\" : \"\",\n ].join(\" \"),\n };\n\n return renderOption ? (\n <React.Fragment key={idx}>\n {renderOption(optionProps, option)}\n </React.Fragment>\n ) : (\n <li\n key={idx}\n onMouseDown={() => handleSelect({ option })}\n onMouseEnter={() => setHighlightedIndex(idx)}\n className={optionProps.className}\n >\n {getOptionLabel(option)}\n </li>\n );\n })\n )}\n </ul>\n )}\n </div>\n );\n}\n","type ModalEntry = { id: string };\n\nconst stack: ModalEntry[] = [];\n\nexport function handlePushModal({ id }: ModalEntry) {\n if (!stack.find((m) => m.id === id)) {\n stack.push({ id });\n }\n}\n\nexport function handlePopModal({ id }: ModalEntry) {\n const idx = stack.findIndex((m) => m.id === id);\n if (idx !== -1) stack.splice(idx, 1);\n}\n\nexport function handleIsTopModal({ id }: ModalEntry): boolean {\n return stack.length > 0 && stack[stack.length - 1].id === id;\n}\n","import React, { useEffect, useId } from \"react\";\nimport { useHotkeys } from \"react-hotkeys-hook\";\nimport {\n handleIsTopModal,\n handlePopModal,\n handlePushModal,\n} from \"../../utils/modalStack\";\n\nexport interface ModalProps {\n show: boolean;\n title?: string;\n className?: string;\n children?: React.ReactNode;\n isLoading?: boolean;\n onHide?: () => void;\n isWarning?: boolean;\n isButtonsRequired?: boolean;\n handleConfirmation?: () => void;\n handleConfirmationBtnText?: string;\n}\n\nexport function Modal({\n show,\n title = \"\",\n className,\n children,\n isLoading = false,\n onHide,\n isWarning = false,\n isButtonsRequired = true,\n handleConfirmation,\n handleConfirmationBtnText = \"Confirm\",\n}: ModalProps) {\n const modalId = useId();\n\n useEffect(() => {\n if (show) handlePushModal({ id: modalId });\n return () => handlePopModal({ id: modalId });\n }, [show, modalId]);\n\n useHotkeys(\n \"enter\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && handleConfirmation)\n handleConfirmation();\n },\n { enabled: show && !isLoading }\n );\n\n useHotkeys(\n \"esc\",\n (e) => {\n e.preventDefault();\n if (show && handleIsTopModal({ id: modalId }) && onHide) onHide();\n },\n { enabled: show && !isLoading }\n );\n\n if (!show) return null;\n\n return (\n <div className=\"fixed inset-0 z-[999] bg-gray-800/50 flex items-center justify-center\">\n <div\n className={[\n \"w-[95%] bg-white rounded-lg shadow-lg flex flex-col\",\n \"md:w-[60%] lg:w-[30%] max-h-[95vh]\",\n className || \"\",\n ].join(\" \")}\n >\n {/* Header */}\n {title && (\n <div className=\"px-3.5 py-3 border-b border-gray-200 flex justify-between items-start gap-x-3\">\n <h2 className=\"text-[17px] font-semibold line-clamp-2 capitalize flex gap-x-2 items-center\">\n {isWarning && (\n <svg\n className=\"text-red-500 w-6 h-6 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M12 2a10 10 0 100 20A10 10 0 0012 2zm0 5a1 1 0 011 1v4a1 1 0 11-2 0V8a1 1 0 011-1zm0 8a1.25 1.25 0 110 2.5A1.25 1.25 0 0112 15z\"\n clipRule=\"evenodd\"\n />\n </svg>\n )}\n {title}\n </h2>\n {onHide && (\n <button\n onClick={onHide}\n className=\"text-gray-400 hover:text-gray-600 transition-colors shrink-0\"\n aria-label=\"Close\"\n >\n ✕\n </button>\n )}\n </div>\n )}\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-3.5 py-3\">{children}</div>\n\n {/* Footer */}\n {isButtonsRequired && (\n <div className=\"px-6 py-3 bg-gray-100 flex justify-end space-x-3 rounded-b-md\">\n {onHide && (\n <button\n onClick={onHide}\n className=\"px-4 py-2 bg-white rounded-md font-semibold text-[14px] hover:bg-gray-50 transition-colors\"\n >\n Cancel\n </button>\n )}\n <button\n onClick={handleConfirmation}\n disabled={isLoading}\n className={[\n \"px-4 py-2 text-white rounded-md text-[14px] font-semibold\",\n \"disabled:opacity-50 disabled:cursor-not-allowed transition-colors\",\n isWarning\n ? \"bg-red-600 hover:bg-red-700\"\n : \"bg-basePurple hover:bg-basePurple/80\",\n ].join(\" \")}\n >\n {isLoading ? (\n <span className=\"inline-flex items-center gap-2\">\n <svg\n className=\"animate-spin h-4 w-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n {handleConfirmationBtnText}\n </span>\n ) : (\n handleConfirmationBtnText\n )}\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import React from \"react\";\n\nexport interface ReadMoreProps {\n readMore: Record<string | number, boolean>;\n index: string | number;\n displayText: string;\n className?: string;\n numberOfCharactersToShow?: number;\n handleCopyDisplayText?: (args: { displayText: string }) => void;\n handleToggleReadMore: () => void;\n}\n\nexport function ReadMore({\n readMore,\n index,\n displayText,\n className,\n numberOfCharactersToShow = 300,\n handleCopyDisplayText,\n handleToggleReadMore,\n}: ReadMoreProps) {\n const isExpanded = readMore?.[index];\n const isLong = displayText?.length > numberOfCharactersToShow;\n\n return (\n <div>\n <p\n className={[\n \"text-[14px] mt-1 break-all text-[#333333] leading-[20px] tracking-wide overflow-hidden max-h-full\",\n className || \"\",\n ].join(\" \")}\n >\n {isExpanded ? displayText : displayText?.slice(0, numberOfCharactersToShow)}{\" \"}\n {isLong && (\n <button\n onClick={handleToggleReadMore}\n className=\"text-basePurple cursor-pointer font-semibold text-[11px]\"\n >\n {isExpanded ? (\n <span className=\"inline-flex items-center gap-1\">\n {handleCopyDisplayText && (\n <span\n onClick={(e) => {\n e.stopPropagation();\n handleCopyDisplayText({ displayText });\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-gray-500 w-[14px] h-[14px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n </span>\n )}{\" \"}\n ...Read Less\n </span>\n ) : (\n <span>...Read More</span>\n )}\n </button>\n )}\n </p>\n </div>\n );\n}\n","import React from \"react\";\n\nexport interface SearchBarProps {\n value: string;\n placeHolder?: string;\n wrapperClass?: string;\n className?: string;\n /** Pass the current URL search param value (e.g. from useLocation) to control clear button visibility */\n searchParamQuery?: string;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n handleInputKey?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n handleClearInput?: () => void;\n}\n\nexport function SearchBar({\n value,\n placeHolder,\n wrapperClass,\n className,\n searchParamQuery = \"\",\n onChange,\n handleInputKey,\n handleClearInput,\n}: SearchBarProps) {\n const showClear = searchParamQuery || value;\n\n return (\n <div\n className={[\n \"flex items-center rounded-full justify-between border px-2 bg-white\",\n wrapperClass || \"\",\n ].join(\" \")}\n >\n {/* Search icon */}\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"text-gray-400 w-[14px] h-[14px] ml-2 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n\n <input\n value={value}\n placeholder={placeHolder}\n className={[\n \"w-[95%] focus:outline-none rounded-r-full\",\n \"placeholder:text-[13px] text-[13px] py-[8px] px-2\",\n className || \"\",\n ].join(\" \")}\n onKeyPress={handleInputKey}\n onChange={onChange}\n />\n\n {/* Clear button */}\n <div className=\"w-[20px] shrink-0\">\n {showClear && handleClearInput && (\n <button onClick={handleClearInput}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"w-[16px] h-[16px]\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\n\n/**\n * useState backed by localStorage — syncs value on mount and persists on change.\n */\nexport function useLocalStorage<T>(key: string, initialValue: T) {\n const [storedValue, setStoredValue] = useState<T>(() => {\n if (typeof window === \"undefined\") return initialValue;\n try {\n const item = window.localStorage.getItem(key);\n return item ? (JSON.parse(item) as T) : initialValue;\n } catch {\n return initialValue;\n }\n });\n\n const setValue = (value: T | ((prev: T) => T)) => {\n try {\n const valueToStore = value instanceof Function ? value(storedValue) : value;\n setStoredValue(valueToStore);\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(key, JSON.stringify(valueToStore));\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to set \"${key}\"`, error);\n }\n };\n\n const remove = () => {\n try {\n setStoredValue(initialValue);\n if (typeof window !== \"undefined\") {\n window.localStorage.removeItem(key);\n }\n } catch (error) {\n console.warn(`useLocalStorage: failed to remove \"${key}\"`, error);\n }\n };\n\n return [storedValue, setValue, remove] as const;\n}\n","/**\n * Merges class names, filtering out falsy values.\n * Lightweight alternative to clsx for simple use cases.\n */\nexport function cn(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(\" \");\n}\n"]}
|
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}.fixed{position:fixed}.inset-0{inset:0}.z-\[999\]{z-index:999}.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}.h-4{height:1rem}.h-6{height:1.5rem}.h-\[14px\]{height:14px}.max-h-\[95vh\]{max-height:95vh}.max-h-full{max-height:100%}.w-4{width:1rem}.w-6{width:1.5rem}.w-80{width:20rem}.w-\[14px\]{width:14px}.w-\[95\%\]{width:95%}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.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-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-y-auto{overflow-y:auto}.break-all{word-break:break-all}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.border-b{border-bottom-width:1px}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.bg-basePurple{--tw-bg-opacity:1;background-color:rgb(83 79 143/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-800\/50{background-color:rgba(31,41,55,.5)}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.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}.text-\[11px\]{font-size:11px}.text-\[14px\]{font-size:14px}.text-\[17px\]{font-size:17px}.text-sm{font-size:.875rem;line-height:1.25rem}.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-basePurple{--tw-text-opacity:1;color:rgb(83 79 143/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-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-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)}.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-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}.hover\:bg-basePurple\/80:hover{background-color:rgba(83,79,143,.8)}.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-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.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}.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-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-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-basePurple{--tw-border-opacity:1;border-color:rgb(83 79 143/var(--tw-border-opacity,1))}.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-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity,1))}.bg-basePurple{--tw-bg-opacity:1;background-color:rgb(83 79 143/var(--tw-bg-opacity,1))}.bg-basePurple\/10{background-color:rgba(83,79,143,.1)}.bg-basePurple\/20{background-color:rgba(83,79,143,.2)}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/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-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))}.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-\[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-basePurple{--tw-text-opacity:1;color:rgb(83 79 143/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-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-basePurple\/80:hover{background-color:rgba(83,79,143,.8)}.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-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.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%}}
|