@youngonesworks/ui 0.1.103 → 0.1.105

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.cjs CHANGED
@@ -29,13 +29,12 @@ const __tabler_icons_react = __toESM(require("@tabler/icons-react"));
29
29
  const clsx = __toESM(require("clsx"));
30
30
  const tailwind_merge = __toESM(require("tailwind-merge"));
31
31
  const react_jsx_runtime = __toESM(require("react/jsx-runtime"));
32
- const react_tooltip = __toESM(require("react-tooltip"));
32
+ const __floating_ui_react = __toESM(require("@floating-ui/react"));
33
33
  const react_day_picker = __toESM(require("react-day-picker"));
34
34
  const date_fns = __toESM(require("date-fns"));
35
35
  const date_fns_locale = __toESM(require("date-fns/locale"));
36
- const __floating_ui_react = __toESM(require("@floating-ui/react"));
37
36
  const react_dom = __toESM(require("react-dom"));
38
- const react_select = __toESM(require("react-select"));
37
+ const react_tooltip = __toESM(require("react-tooltip"));
39
38
  const __tiptap_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"));
40
39
  const __tiptap_extension_underline = __toESM(require("@tiptap/extension-underline"));
41
40
  const __tiptap_react = __toESM(require("@tiptap/react"));
@@ -115,6 +114,113 @@ const AccordionWrapper = ({ children, className }) => /* @__PURE__ */ (0, react_
115
114
  children
116
115
  });
117
116
 
117
+ //#endregion
118
+ //#region src/hooks/useMergeRefs.ts
119
+ function useMergeRefs(...refs) {
120
+ return (0, react.useCallback)((value) => {
121
+ refs.forEach((ref) => {
122
+ if (typeof ref === "function") {
123
+ ref(value);
124
+ } else if (ref) {
125
+ ref.current = value;
126
+ }
127
+ });
128
+ }, [refs]);
129
+ }
130
+
131
+ //#endregion
132
+ //#region src/components/tooltip/index.tsx
133
+ const sizeClasses = {
134
+ xs: "max-w-xs",
135
+ sm: "max-w-sm",
136
+ md: "max-w-md",
137
+ lg: "max-w-lg"
138
+ };
139
+ const Tooltip = ({ content, children, passedOpen = false, size = "md", variant = "default" }) => {
140
+ const [isOpen, setIsOpen] = (0, react.useState)(passedOpen);
141
+ const arrowRef = (0, react.useRef)(null);
142
+ const { refs, floatingStyles, context } = (0, __floating_ui_react.useFloating)({
143
+ open: isOpen,
144
+ onOpenChange: setIsOpen,
145
+ placement: "top",
146
+ middleware: [
147
+ variant === "default" ? (0, __floating_ui_react.offset)(20) : (0, __floating_ui_react.offset)(25),
148
+ (0, __floating_ui_react.flip)(),
149
+ (0, __floating_ui_react.shift)(),
150
+ (0, __floating_ui_react.arrow)({ element: arrowRef })
151
+ ],
152
+ whileElementsMounted: __floating_ui_react.autoUpdate
153
+ });
154
+ const hover = (0, __floating_ui_react.useHover)(context, { move: false });
155
+ const focus = (0, __floating_ui_react.useFocus)(context);
156
+ const dismiss = (0, __floating_ui_react.useDismiss)(context);
157
+ const role = (0, __floating_ui_react.useRole)(context, { role: "tooltip" });
158
+ const { getReferenceProps, getFloatingProps } = (0, __floating_ui_react.useInteractions)([
159
+ hover,
160
+ focus,
161
+ dismiss,
162
+ role
163
+ ]);
164
+ const childRef = children.ref;
165
+ const mergedRef = useMergeRefs(refs.setReference, childRef);
166
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react.isValidElement)(children) && (0, react.cloneElement)(children, getReferenceProps({
167
+ ...children.props,
168
+ ...getReferenceProps(),
169
+ ref: mergedRef
170
+ })), isOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
171
+ ref: refs.setFloating,
172
+ style: floatingStyles,
173
+ ...getFloatingProps(),
174
+ className: "z-70 drop-shadow-xl",
175
+ "data-testid": "tooltip",
176
+ "data-component": "tooltip",
177
+ children: variant === "default" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
178
+ "data-testid": "tooltip-container",
179
+ className: "w-full rounded bg-gray-800 pt-[3px] text-white",
180
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
181
+ "data-testid": "tooltip-content",
182
+ className: `${sizeClasses[size]} px-2 py-1 text-sm font-normal`,
183
+ children: content
184
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingArrow, {
185
+ ref: arrowRef,
186
+ context,
187
+ width: 10,
188
+ height: 6,
189
+ tipRadius: 1,
190
+ "data-testid": "tooltip-arrow",
191
+ className: "fill-gray-800 drop-shadow-xl"
192
+ })]
193
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
194
+ "data-testid": "tooltip-container",
195
+ className: "bg-linear-gradient-x pt-[3px]",
196
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
197
+ "data-testid": "tooltip-content",
198
+ className: `${sizeClasses[size]} overflow-hidden bg-white p-5 px-2 py-1 text-start text-sm font-normal`,
199
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: content })
200
+ }), size === "md" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingArrow, {
201
+ ref: arrowRef,
202
+ context,
203
+ width: 25,
204
+ height: 17,
205
+ tipRadius: 1,
206
+ fill: "white",
207
+ className: "drop-shadow-xl",
208
+ "data-testid": "tooltip-arrow"
209
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingArrow, {
210
+ ref: arrowRef,
211
+ context,
212
+ width: 10,
213
+ height: 6,
214
+ tipRadius: 1,
215
+ fill: "white",
216
+ className: "drop-shadow-xl",
217
+ "data-testid": "tooltip-arrow"
218
+ })]
219
+ })
220
+ })] });
221
+ };
222
+ Tooltip.displayName = "Tooltip";
223
+
118
224
  //#endregion
119
225
  //#region src/utils/enums.ts
120
226
  let ACTION_ICON_STYLE_VARIANT = /* @__PURE__ */ function(ACTION_ICON_STYLE_VARIANT$1) {
@@ -192,34 +298,35 @@ function formatIcon(icon, defaultFormatAttributes) {
192
298
 
193
299
  //#endregion
194
300
  //#region src/components/actionIcon/index.tsx
195
- const ActionIcon = (0, react.forwardRef)(({ title, disabled = false, styleVariant = "default", icon, type = "button", "data-testid": testId, iconSize = 20, strokeWidth = 1, onClick, className,...props }, ref) => {
301
+ const ActionIcon = ({ ref, title, disabled = false, styleVariant = "default", icon, type = "button", "data-testid": testId, iconSize = 20, strokeWidth = 1, onClick, className,...props }) => {
196
302
  const variantClassNames = (0, clsx.default)({
197
303
  "active:translate-y-[1px] content-center flex items-center justify-center rounded-[4px] border border-gray-200 hover:border-black text-black child:p-10 w-[36px] h-[36px] disabled:text-gray-500": styleVariant === ACTION_ICON_STYLE_VARIANT.DEFAULT,
198
304
  "active:translate-y-[1px] border-none content-center flex items-center justify-center rounded-[4px] border text-black child:p-10 w-[36px] h-[36px] disabled:text-gray-500": styleVariant === ACTION_ICON_STYLE_VARIANT.TRANSPARENT,
199
305
  "active:translate-y-[1px] content-center flex items-center justify-center rounded-[4px] child:p-10 w-[37px] h-[37px] text-black rounded-full bg-primary hover:bg-turquoise-700 disabled:turquoise-50 disabled:text-gray-800": styleVariant === ACTION_ICON_STYLE_VARIANT.ROUND,
200
306
  "w-7 h-7 active:translate-y-[1px] content-center flex items-center justify-center rounded-[4px] border border-gray-200 hover:border-black text-black hover:bg-gray-50 disabled:text-gray-500": styleVariant === ACTION_ICON_STYLE_VARIANT.SMALL
201
307
  });
202
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
203
- title,
204
- type,
205
- disabled,
206
- "data-testid": testId,
207
- "data-component": "ActionIcon",
208
- className: cn(variantClassNames, { "hover:bg-transparant cursor-not-allowed hover:border-gray-200": disabled }, className),
209
- onClick,
210
- ref,
211
- "data-tooltip-id": title,
212
- "data-tooltip-content": title,
213
- ...props,
214
- children: icon ? formatIcon(icon, {
215
- stroke: strokeWidth,
216
- size: iconSize
217
- }) : props.children
218
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_tooltip.Tooltip, {
219
- id: title,
220
- className: "z-[99]"
221
- })] });
222
- });
308
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
309
+ size: "sm",
310
+ content: title,
311
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
312
+ title,
313
+ type,
314
+ disabled,
315
+ "data-testid": testId,
316
+ "data-component": "ActionIcon",
317
+ className: cn(variantClassNames, { "hover:bg-transparant cursor-not-allowed hover:border-gray-200": disabled }, className),
318
+ onClick,
319
+ ref,
320
+ "data-tooltip-id": title,
321
+ "data-tooltip-content": title,
322
+ ...props,
323
+ children: icon ? formatIcon(icon, {
324
+ stroke: strokeWidth,
325
+ size: iconSize
326
+ }) : props.children
327
+ })
328
+ }) });
329
+ };
223
330
  ActionIcon.displayName = "ActionIcon";
224
331
 
225
332
  //#endregion
@@ -1513,6 +1620,86 @@ const Island = ({ children, className, noShadow = false, noPadding = false,...pr
1513
1620
  });
1514
1621
  Island.displayName = "Island";
1515
1622
 
1623
+ //#endregion
1624
+ //#region src/components/kebabMenu/index.tsx
1625
+ const KebabMenu = ({ title, tooltip, content, disabled = false, styleVariant = "default" }) => {
1626
+ const [isOpen, setIsOpen] = (0, react.useState)(false);
1627
+ const menuRef = (0, react.useRef)(null);
1628
+ const defaultStyling = "text-black flex items-center justify-self-end gap-1 bg-transparent font-medium py-1 h-9 min-w-9 cursor-pointer px-0";
1629
+ const handleToggle = () => {
1630
+ if (!disabled) setIsOpen((prev) => !prev);
1631
+ };
1632
+ const handleItemClick = (onClick) => {
1633
+ if (!disabled) {
1634
+ onClick();
1635
+ setIsOpen(false);
1636
+ }
1637
+ };
1638
+ const handleClickOutside = (event) => {
1639
+ if (menuRef.current && !menuRef.current.contains(event.target)) setIsOpen(false);
1640
+ };
1641
+ (0, react.useEffect)(() => {
1642
+ document.addEventListener("mousedown", handleClickOutside);
1643
+ return () => {
1644
+ document.removeEventListener("mousedown", handleClickOutside);
1645
+ };
1646
+ }, []);
1647
+ const button = (0, react.useMemo)(() => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(UnstyledButton, {
1648
+ "aria-label": "Options Menu",
1649
+ className: cn(buttonVariants["secondary"], defaultStyling, {
1650
+ "md:pr-3.5 md:pl-5": title,
1651
+ "h-7 min-w-7": styleVariant === "small"
1652
+ }),
1653
+ disabled,
1654
+ onClick: handleToggle,
1655
+ children: [title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1656
+ className: "hidden md:block",
1657
+ children: title
1658
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tabler_icons_react.IconDotsVertical, {
1659
+ size: 20,
1660
+ stroke: 1,
1661
+ fill: "black"
1662
+ })]
1663
+ }), [
1664
+ title,
1665
+ styleVariant,
1666
+ disabled,
1667
+ handleToggle
1668
+ ]);
1669
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1670
+ className: "relative",
1671
+ "data-component": "kebabMenu",
1672
+ "data-testid": "kebab-menu",
1673
+ ref: menuRef,
1674
+ "data-tooltip-id": title,
1675
+ "data-tooltip-content": title,
1676
+ children: [tooltip ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
1677
+ passedOpen: false,
1678
+ size: "sm",
1679
+ content: tooltip,
1680
+ children: button
1681
+ }) : button, isOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1682
+ className: "absolute right-0 z-10 mt-2 w-auto min-w-[200px] rounded-md border-[0.0625rem] border-gray-200 bg-white p-1 shadow-md",
1683
+ children: content.map((c, index) => {
1684
+ const button$1 = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnstyledButton, {
1685
+ onClick: () => handleItemClick(c.onClick),
1686
+ className: "w-full rounded-md px-4 py-2 text-left text-sm font-normal whitespace-nowrap hover:bg-gray-50",
1687
+ "aria-label": "Options Menu Item",
1688
+ disabled: c.disabled,
1689
+ children: c.title
1690
+ });
1691
+ return c.tooltip ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
1692
+ passedOpen: false,
1693
+ size: "sm",
1694
+ content: c.tooltip,
1695
+ children: button$1
1696
+ }, index) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: button$1 }, index);
1697
+ })
1698
+ })]
1699
+ }) });
1700
+ };
1701
+ KebabMenu.displayName = "KebabMenu";
1702
+
1516
1703
  //#endregion
1517
1704
  //#region src/components/label/index.tsx
1518
1705
  const Label = ({ children, className,...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
@@ -2153,183 +2340,289 @@ const SearchInput = ({ placeholder, value, onChange, className, rightSection,...
2153
2340
  ...props
2154
2341
  });
2155
2342
 
2343
+ //#endregion
2344
+ //#region src/hooks/useDebouncedValue.ts
2345
+ function useDebouncedValue(value, delay = 200) {
2346
+ const [debouncedValue, setDebouncedValue] = (0, react.useState)(value);
2347
+ (0, react.useEffect)(() => {
2348
+ const handler = setTimeout(() => setDebouncedValue(value), delay);
2349
+ return () => clearTimeout(handler);
2350
+ }, [value, delay]);
2351
+ return debouncedValue;
2352
+ }
2353
+
2156
2354
  //#endregion
2157
2355
  //#region src/components/select/index.tsx
2158
- const LANGUAGE_FLAGS = [
2159
- {
2160
- value: "nl-NL",
2161
- altValue: "nl_NL",
2162
- label: "nl"
2163
- },
2164
- {
2165
- value: "nl-BE",
2166
- altValue: "nl_BE",
2167
- label: "be"
2168
- },
2169
- {
2170
- value: "en-GB",
2171
- altValue: "en_GB",
2172
- label: "gb"
2173
- },
2174
- {
2175
- value: "fr-FR",
2176
- altValue: "fr_FR",
2177
- label: "fr"
2178
- }
2179
- ];
2180
- const selectStyles = {
2181
- singleValue: (provided) => ({
2182
- ...provided,
2183
- fontSize: "14px"
2184
- }),
2185
- placeholder: (provided) => ({
2186
- ...provided,
2187
- color: "#838383",
2188
- fontSize: "14px",
2189
- textWrap: "nowrap"
2190
- }),
2191
- dropdownIndicator: (provided) => ({
2192
- ...provided,
2193
- color: "black"
2194
- }),
2195
- option: (base, { isFocused, isSelected }) => ({
2196
- ...base,
2197
- color: "black",
2198
- marginLeft: "4px",
2199
- marginRight: "4px",
2200
- backgroundColor: isSelected ? "#f8f8f8" : isFocused ? "#f8f8f8" : "transparent",
2201
- width: "calc(100% - 8px)",
2202
- cursor: "pointer"
2203
- }),
2204
- menuList: (provided) => ({
2205
- ...provided,
2206
- fontSize: "14px"
2207
- })
2208
- };
2209
- const selectTheme = (theme) => ({
2210
- ...theme,
2211
- borderRadius: 4,
2212
- colors: {
2213
- ...theme.colors,
2214
- primary25: "#f8f8f8",
2215
- primary: "#f8f8f8"
2216
- }
2217
- });
2218
- const Select = (0, react.forwardRef)(({ options, placeholder, defaultValue, label, id, icon, error, className, labelClassNames, showLangFlags = false, hideErrorText = false, isClearable = true, fullWidth = true, width, isDisabled,...props }, ref) => {
2219
- const DropdownIndicator = (props$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_select.components.DropdownIndicator, {
2220
- ...props$1,
2221
- children: props$1.hasValue && isClearable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tabler_icons_react.IconX, {
2222
- "data-testid": "icon-x",
2223
- className: "cursor-pointer",
2224
- size: 16,
2225
- color: "black",
2226
- onClick: () => props$1.clearValue()
2227
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tabler_icons_react.IconSelector, {
2228
- size: 16,
2229
- color: "black"
2230
- })
2231
- });
2232
- const GroupHeading = ({ children }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2233
- className: "flex items-stretch px-4 py-2 font-normal text-[#838383] capitalize",
2234
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2235
- className: "flex-nowrap whitespace-nowrap",
2236
- children
2237
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2238
- className: "ml-2 flex w-full flex-1 items-center justify-center",
2239
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "h-px w-full bg-[#838383]" })
2240
- })]
2241
- });
2242
- const LanguageControl = ({ children,...props$1 }) => {
2243
- const getSelectedFlag = () => {
2244
- const selectValue = props$1.selectProps.value;
2245
- const findFlag = (value) => LANGUAGE_FLAGS.find((e) => e.value === value || e.altValue === value)?.label || "";
2246
- if (typeof selectValue === "string") return findFlag(selectValue);
2247
- if (typeof selectValue === "object" && selectValue !== null && "value" in selectValue) return findFlag(selectValue.value);
2248
- return null;
2249
- };
2250
- const selectedFlag = getSelectedFlag();
2251
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_select.components.Control, {
2252
- ...props$1,
2253
- children: [selectedFlag && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2254
- className: "flex h-[39px] items-center border-r border-gray-200 p-3",
2255
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
2256
- src: `/images/countries/${selectedFlag.toUpperCase()}_flag.svg`,
2257
- alt: "",
2258
- width: 24,
2259
- height: 24
2260
- })
2261
- }), children]
2262
- });
2263
- };
2264
- const NoOptionsMessage = (props$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_select.components.NoOptionsMessage, {
2265
- ...props$1,
2266
- children: "noOptionsMessage"
2267
- });
2268
- const SingleValue = ({ children,...props$1 }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_select.components.SingleValue, {
2269
- ...props$1,
2270
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2271
- className: "flex items-center",
2272
- children: [icon && icon, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2273
- className: "mx-2",
2274
- children
2275
- })]
2276
- })
2356
+ function Select({ id, options, placeholder, label, errorText, hideError = false, isClearable = false, disabled = false, multiSelect = false, searchable = false, value, defaultValue, onValueChange, className, searchPlaceholder, noResultsText,...props }) {
2357
+ const innerRef = (0, react.useRef)(null);
2358
+ const buttonRef = (0, react.useRef)(null);
2359
+ const optionRefs = (0, react.useRef)([]);
2360
+ const mergedRef = useMergeRefs(innerRef, props.ref);
2361
+ const [internalValue, setInternalValue] = (0, react.useState)(defaultValue);
2362
+ const [open, setOpen] = (0, react.useState)(false);
2363
+ const [searchTerm, setSearchTerm] = (0, react.useState)("");
2364
+ const [focusedIndex, setFocusedIndex] = (0, react.useState)(-1);
2365
+ const debouncedSearch = useDebouncedValue(searchTerm);
2366
+ const isControlled = value !== undefined;
2367
+ const currentValue = isControlled ? value : internalValue;
2368
+ const selectedLabels = (0, react.useMemo)(() => {
2369
+ if (Array.isArray(currentValue)) {
2370
+ return options.filter((o) => currentValue.includes(o.value)).map((o) => o.label).join(", ");
2371
+ }
2372
+ return options.find((o) => o.value === currentValue)?.label;
2373
+ }, [currentValue, options]);
2374
+ const { refs, floatingStyles, context } = (0, __floating_ui_react.useFloating)({
2375
+ open,
2376
+ onOpenChange: setOpen,
2377
+ middleware: [
2378
+ (0, __floating_ui_react.offset)(4),
2379
+ (0, __floating_ui_react.flip)(),
2380
+ (0, __floating_ui_react.shift)()
2381
+ ],
2382
+ whileElementsMounted: __floating_ui_react.autoUpdate,
2383
+ placement: "bottom-start"
2277
2384
  });
2385
+ const click = (0, __floating_ui_react.useClick)(context);
2386
+ const dismiss = (0, __floating_ui_react.useDismiss)(context);
2387
+ const role = (0, __floating_ui_react.useRole)(context, { role: "combobox" });
2388
+ const { getReferenceProps, getFloatingProps } = (0, __floating_ui_react.useInteractions)([
2389
+ click,
2390
+ dismiss,
2391
+ role
2392
+ ]);
2393
+ const handleSelect = (0, react.useCallback)((val) => {
2394
+ if (multiSelect) {
2395
+ const current = Array.isArray(currentValue) ? currentValue : [];
2396
+ const newValues = current.includes(val) ? current.filter((v) => v !== val) : [...current, val];
2397
+ if (!isControlled) setInternalValue(newValues);
2398
+ onValueChange?.(newValues);
2399
+ } else {
2400
+ if (!isControlled) setInternalValue(val);
2401
+ onValueChange?.(val);
2402
+ setOpen(false);
2403
+ buttonRef.current?.focus();
2404
+ }
2405
+ }, [
2406
+ multiSelect,
2407
+ currentValue,
2408
+ isControlled,
2409
+ onValueChange
2410
+ ]);
2411
+ const handleClear = (0, react.useCallback)((e) => {
2412
+ e.preventDefault();
2413
+ e.stopPropagation();
2414
+ if (!isControlled) setInternalValue(undefined);
2415
+ onValueChange?.(undefined);
2416
+ setSearchTerm("");
2417
+ }, [isControlled, onValueChange]);
2418
+ const showPlaceholder = !currentValue || Array.isArray(currentValue) && currentValue.length === 0;
2419
+ const filteredOptions = (0, react.useMemo)(() => {
2420
+ if (!debouncedSearch.trim()) return options;
2421
+ return options.filter((opt) => opt.label.toLowerCase().includes(debouncedSearch.toLowerCase()));
2422
+ }, [options, debouncedSearch]);
2423
+ const handleKeyDown = (0, react.useCallback)((event) => {
2424
+ if (disabled) return;
2425
+ if (!open) {
2426
+ if (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ") {
2427
+ event.preventDefault();
2428
+ setOpen(true);
2429
+ setTimeout(() => {
2430
+ setFocusedIndex(0);
2431
+ optionRefs.current[0]?.focus();
2432
+ }, 0);
2433
+ }
2434
+ return;
2435
+ }
2436
+ switch (event.key) {
2437
+ case "Escape":
2438
+ event.preventDefault();
2439
+ setOpen(false);
2440
+ setFocusedIndex(-1);
2441
+ buttonRef.current?.focus();
2442
+ break;
2443
+ case "ArrowDown":
2444
+ event.preventDefault();
2445
+ setFocusedIndex((prev) => {
2446
+ const next = prev < filteredOptions.length - 1 ? prev + 1 : 0;
2447
+ optionRefs.current[next]?.focus();
2448
+ return next;
2449
+ });
2450
+ break;
2451
+ case "ArrowUp":
2452
+ event.preventDefault();
2453
+ setFocusedIndex((prev) => {
2454
+ const next = prev > 0 ? prev - 1 : filteredOptions.length - 1;
2455
+ optionRefs.current[next]?.focus();
2456
+ return next;
2457
+ });
2458
+ break;
2459
+ case "Home":
2460
+ event.preventDefault();
2461
+ setFocusedIndex(0);
2462
+ optionRefs.current[0]?.focus();
2463
+ break;
2464
+ case "End":
2465
+ event.preventDefault();
2466
+ setFocusedIndex(filteredOptions.length - 1);
2467
+ optionRefs.current[filteredOptions.length - 1]?.focus();
2468
+ break;
2469
+ case "Enter":
2470
+ case " ":
2471
+ event.preventDefault();
2472
+ if (focusedIndex >= 0 && filteredOptions[focusedIndex]) {
2473
+ handleSelect(filteredOptions[focusedIndex].value);
2474
+ }
2475
+ break;
2476
+ }
2477
+ }, [
2478
+ open,
2479
+ filteredOptions,
2480
+ focusedIndex,
2481
+ handleSelect,
2482
+ disabled
2483
+ ]);
2484
+ (0, react.useEffect)(() => {
2485
+ if (!open) return;
2486
+ const listener = (e) => handleKeyDown(e);
2487
+ document.addEventListener("keydown", listener);
2488
+ return () => document.removeEventListener("keydown", listener);
2489
+ }, [open, handleKeyDown]);
2490
+ (0, react.useEffect)(() => {
2491
+ if (!open) setSearchTerm("");
2492
+ }, [open]);
2278
2493
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2494
+ ref: mergedRef,
2495
+ ...props,
2279
2496
  "data-component": "Select",
2280
- "data-testid": "select-container",
2281
- ref,
2282
- className: (0, clsx.default)("m-0 grid gap-2 p-0", width ? width : fullWidth && "w-full", className),
2497
+ className: cn("grid gap-2 w-full", className),
2498
+ role: "group",
2499
+ "aria-labelledby": `${id}-label`,
2283
2500
  children: [
2284
- label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
2285
- className: cn("leading-4", labelClassNames),
2286
- children: label
2501
+ label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2502
+ className: "leading-4",
2503
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Label, {
2504
+ htmlFor: id,
2505
+ children: label
2506
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2507
+ id: `${id}-label`,
2508
+ className: "sr-only",
2509
+ children: label
2510
+ })]
2287
2511
  }),
2288
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_select.default, {
2289
- "data-component": "select",
2290
- "data-testid": "select-input",
2291
- options,
2292
- menuPlacement: "auto",
2293
- isDisabled,
2294
- defaultValue,
2295
- placeholder,
2296
- isClearable: false,
2297
- menuPortalTarget: document?.body,
2298
- styles: {
2299
- ...selectStyles,
2300
- control: (base, state) => ({
2301
- ...base,
2302
- "&:hover": { borderColor: "#A8A8A8" },
2303
- height: "40px",
2304
- width: "100%",
2305
- backgroundColor: "#fbfbfb",
2306
- borderColor: error ? "red" : state.isFocused ? "#10d1bb" : "#cccccc",
2307
- cursor: "pointer"
2308
- }),
2309
- menuPortal: (base) => ({
2310
- ...base,
2311
- zIndex: 99999
2312
- })
2512
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2513
+ id,
2514
+ type: "button",
2515
+ ref: (node) => {
2516
+ refs.setReference(node);
2517
+ buttonRef.current = node;
2313
2518
  },
2314
- theme: selectTheme,
2315
- components: {
2316
- IndicatorSeparator: () => null,
2317
- DropdownIndicator,
2318
- GroupHeading,
2319
- Control: showLangFlags ? LanguageControl : react_select.components.Control,
2320
- SingleValue,
2321
- NoOptionsMessage
2322
- },
2323
- ...props
2324
- }, id),
2325
- !hideErrorText && error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", {
2326
- className: "text-xs font-normal text-red-500",
2519
+ ...getReferenceProps(),
2520
+ disabled,
2521
+ className: cn("flex h-10 w-full items-center justify-between rounded-md border px-3 text-sm transition-colors bg-gray-20", "border-gray-200 hover:border-gray-300 focus:border-gray-300 outline-none", !hideError && errorText && "border-red-500 hover:border-red-500 focus:border-red-500", disabled && "opacity-50 cursor-not-allowed"),
2522
+ "aria-haspopup": "listbox",
2523
+ "aria-expanded": open,
2524
+ "aria-disabled": disabled,
2525
+ "aria-labelledby": `${id}-label`,
2526
+ "aria-controls": `${id}-listbox`,
2527
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2528
+ className: "flex items-center gap-2 truncate text-black",
2529
+ children: showPlaceholder ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2530
+ className: "text-gray-200",
2531
+ "aria-hidden": "true",
2532
+ children: placeholder
2533
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2534
+ className: "truncate",
2535
+ children: selectedLabels
2536
+ })
2537
+ }), isClearable && !showPlaceholder ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tabler_icons_react.IconX, {
2538
+ size: 16,
2539
+ color: "black",
2540
+ className: "cursor-pointer",
2541
+ "data-testid": "clear-button",
2542
+ onPointerDown: handleClear,
2543
+ role: "button",
2544
+ "aria-label": "Clear selection"
2545
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tabler_icons_react.IconSelector, {
2546
+ size: 16,
2547
+ color: "black",
2548
+ "aria-hidden": "true"
2549
+ })]
2550
+ }),
2551
+ open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingPortal, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingFocusManager, {
2552
+ context,
2553
+ modal: false,
2554
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2555
+ ref: refs.setFloating,
2556
+ style: {
2557
+ ...floatingStyles,
2558
+ width: refs.reference.current?.offsetWidth ?? "auto"
2559
+ },
2560
+ ...getFloatingProps(),
2561
+ id: `${id}-listbox`,
2562
+ role: "listbox",
2563
+ "aria-labelledby": `${id}-label`,
2564
+ className: cn("z-[99999] mt-2 rounded-md border border-gray-200 bg-white shadow-md", "overflow-hidden animate-in fade-in"),
2565
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2566
+ className: "p-1 text-sm max-h-[250px] overflow-auto",
2567
+ children: [searchable && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2568
+ className: "flex items-center gap-2 px-2 py-1 border-b border-gray-100 sticky top-0 bg-white",
2569
+ role: "search",
2570
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tabler_icons_react.IconSearch, {
2571
+ size: 14,
2572
+ className: "text-gray-400",
2573
+ "aria-hidden": "true"
2574
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2575
+ type: "text",
2576
+ autoFocus: true,
2577
+ value: searchTerm,
2578
+ onChange: (e) => setSearchTerm(e.target.value),
2579
+ placeholder: searchPlaceholder,
2580
+ className: "w-full text-sm outline-none bg-transparent placeholder-gray-300",
2581
+ "aria-label": "Search options"
2582
+ })]
2583
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2584
+ className: "mt-1 pr-2",
2585
+ children: filteredOptions.length ? filteredOptions.map((opt, index) => {
2586
+ const isSelected = Array.isArray(currentValue) ? currentValue.includes(opt.value) : currentValue === opt.value;
2587
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2588
+ ref: (el) => optionRefs.current[index] = el,
2589
+ type: "button",
2590
+ onClick: () => handleSelect(opt.value),
2591
+ role: "option",
2592
+ "aria-selected": isSelected,
2593
+ tabIndex: -1,
2594
+ className: cn("relative flex w-full items-center gap-2 rounded px-3 py-2 text-sm text-black select-none", "hover:bg-gray-50 mx-1 my-[2px]", isSelected && "bg-gray-50", focusedIndex === index && "bg-gray-50 ring-1 ring-primary"),
2595
+ children: [multiSelect && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2596
+ className: cn("flex h-4 w-4 items-center justify-center rounded-sm border", isSelected ? "border-light-blue bg-light-blue" : "border-gray-400 bg-white"),
2597
+ "aria-hidden": "true",
2598
+ children: isSelected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__tabler_icons_react.IconCheck, {
2599
+ size: 12,
2600
+ color: "white",
2601
+ stroke: 2,
2602
+ className: "pointer-events-none"
2603
+ })
2604
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2605
+ className: "flex-1 text-left",
2606
+ children: opt.label
2607
+ })]
2608
+ }, opt.value);
2609
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2610
+ className: "px-3 py-2 text-gray-400",
2611
+ role: "status",
2612
+ children: noResultsText
2613
+ })
2614
+ })]
2615
+ })
2616
+ })
2617
+ }) }),
2618
+ !hideError && errorText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2619
+ className: "text-xs text-red-500",
2327
2620
  role: "alert",
2328
- children: error
2621
+ children: errorText
2329
2622
  })
2330
2623
  ]
2331
2624
  });
2332
- });
2625
+ }
2333
2626
  Select.displayName = "Select";
2334
2627
 
2335
2628
  //#endregion
@@ -2734,97 +3027,6 @@ const Toggle = ({ onClick, value, disabled = false }) => {
2734
3027
  });
2735
3028
  };
2736
3029
 
2737
- //#endregion
2738
- //#region src/components/tooltip/index.tsx
2739
- const sizeClasses = {
2740
- xs: "max-w-xs",
2741
- sm: "max-w-sm",
2742
- md: "max-w-md",
2743
- lg: "max-w-lg"
2744
- };
2745
- const Tooltip = ({ content, children, passedOpen = false, size = "md", variant = "default" }) => {
2746
- const [isOpen, setIsOpen] = (0, react.useState)(passedOpen);
2747
- const arrowRef = (0, react.useRef)(null);
2748
- const { refs, floatingStyles, context } = (0, __floating_ui_react.useFloating)({
2749
- open: isOpen,
2750
- onOpenChange: setIsOpen,
2751
- placement: "top",
2752
- middleware: [
2753
- variant === "default" ? (0, __floating_ui_react.offset)(20) : (0, __floating_ui_react.offset)(25),
2754
- (0, __floating_ui_react.flip)(),
2755
- (0, __floating_ui_react.shift)(),
2756
- (0, __floating_ui_react.arrow)({ element: arrowRef })
2757
- ],
2758
- whileElementsMounted: __floating_ui_react.autoUpdate
2759
- });
2760
- const hover = (0, __floating_ui_react.useHover)(context, { move: false });
2761
- const focus = (0, __floating_ui_react.useFocus)(context);
2762
- const dismiss = (0, __floating_ui_react.useDismiss)(context);
2763
- const role = (0, __floating_ui_react.useRole)(context, { role: "tooltip" });
2764
- const { getReferenceProps, getFloatingProps } = (0, __floating_ui_react.useInteractions)([
2765
- hover,
2766
- focus,
2767
- dismiss,
2768
- role
2769
- ]);
2770
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react.isValidElement)(children) && (0, react.cloneElement)(children, getReferenceProps({
2771
- ref: refs.setReference,
2772
- ...children.props,
2773
- ...getReferenceProps()
2774
- })), isOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2775
- ref: refs.setFloating,
2776
- style: floatingStyles,
2777
- ...getFloatingProps(),
2778
- className: "z-70 drop-shadow-xl",
2779
- "data-testid": "tooltip",
2780
- "data-component": "tooltip",
2781
- children: variant === "default" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2782
- "data-testid": "tooltip-container",
2783
- className: "w-full rounded bg-gray-800 pt-[3px] text-white",
2784
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2785
- "data-testid": "tooltip-content",
2786
- className: `${sizeClasses[size]} px-2 py-1 text-sm font-normal`,
2787
- children: content
2788
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingArrow, {
2789
- ref: arrowRef,
2790
- context,
2791
- width: 10,
2792
- height: 6,
2793
- tipRadius: 1,
2794
- "data-testid": "tooltip-arrow",
2795
- className: "fill-gray-800 drop-shadow-xl"
2796
- })]
2797
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2798
- "data-testid": "tooltip-container",
2799
- className: "bg-linear-gradient-x pt-[3px]",
2800
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2801
- "data-testid": "tooltip-content",
2802
- className: `${sizeClasses[size]} overflow-hidden bg-white p-5 px-2 py-1 text-start text-sm font-normal`,
2803
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: content })
2804
- }), size === "md" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingArrow, {
2805
- ref: arrowRef,
2806
- context,
2807
- width: 25,
2808
- height: 17,
2809
- tipRadius: 1,
2810
- fill: "white",
2811
- className: "drop-shadow-xl",
2812
- "data-testid": "tooltip-arrow"
2813
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__floating_ui_react.FloatingArrow, {
2814
- ref: arrowRef,
2815
- context,
2816
- width: 10,
2817
- height: 6,
2818
- tipRadius: 1,
2819
- fill: "white",
2820
- className: "drop-shadow-xl",
2821
- "data-testid": "tooltip-arrow"
2822
- })]
2823
- })
2824
- })] });
2825
- };
2826
- Tooltip.displayName = "Tooltip";
2827
-
2828
3030
  //#endregion
2829
3031
  //#region src/components/truncatedText/index.tsx
2830
3032
  const TruncatedText = ({ text, limit = 20 }) => {
@@ -3195,6 +3397,7 @@ exports.GoogleAppButtonIcon = GoogleAppButtonIcon;
3195
3397
  exports.HR = HR;
3196
3398
  exports.HamburgerMenuButton = HamburgerMenuButton;
3197
3399
  exports.Island = Island;
3400
+ exports.KebabMenu = KebabMenu;
3198
3401
  exports.Label = Label;
3199
3402
  exports.Loader = Loader;
3200
3403
  exports.LogoBlack = LogoBlack;