warqadui 0.0.18 → 0.0.20
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 +76 -7
- package/dist/index.d.ts +76 -7
- package/dist/index.js +728 -425
- package/dist/index.mjs +740 -432
- package/dist/styles.js +1 -1
- package/dist/styles.mjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -57,7 +57,14 @@ __export(index_exports, {
|
|
|
57
57
|
PhoneInput: () => PhoneInput,
|
|
58
58
|
PostTable: () => PostTable,
|
|
59
59
|
SearchApi: () => SearchApi,
|
|
60
|
+
SearchApiContent: () => SearchApiContent,
|
|
61
|
+
SearchApiInput: () => SearchApiInput,
|
|
62
|
+
SearchApiItem: () => SearchApiItem,
|
|
63
|
+
SearchApiTrigger: () => SearchApiTrigger,
|
|
60
64
|
Select: () => Select,
|
|
65
|
+
SelectContent: () => SelectContent,
|
|
66
|
+
SelectItem: () => SelectItem,
|
|
67
|
+
SelectTrigger: () => SelectTrigger,
|
|
61
68
|
SimpleTable: () => SimpleTable,
|
|
62
69
|
Textarea: () => Textarea,
|
|
63
70
|
ThemeProvider: () => ThemeProvider,
|
|
@@ -67,6 +74,8 @@ __export(index_exports, {
|
|
|
67
74
|
useA4StatementView: () => useA4DataView_default,
|
|
68
75
|
useApi: () => useApis_default,
|
|
69
76
|
useModal: () => useModal,
|
|
77
|
+
useSearchApiContext: () => useSearchApiContext,
|
|
78
|
+
useSelectContext: () => useSelectContext,
|
|
70
79
|
useTheme: () => useTheme,
|
|
71
80
|
useTransaction: () => useTransaction_default,
|
|
72
81
|
useWarqadConfig: () => useWarqadConfig
|
|
@@ -1372,65 +1381,113 @@ var PhoneInput = (0, import_react9.forwardRef)(
|
|
|
1372
1381
|
PhoneInput.displayName = "PhoneInput";
|
|
1373
1382
|
|
|
1374
1383
|
// src/components/Fields/select.tsx
|
|
1375
|
-
var import_react10 = require("react");
|
|
1384
|
+
var import_react10 = __toESM(require("react"));
|
|
1376
1385
|
var import_react_dom = require("react-dom");
|
|
1377
1386
|
var import_lucide_react7 = require("lucide-react");
|
|
1378
1387
|
var import_react_hook_form3 = require("react-hook-form");
|
|
1379
1388
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1380
|
-
var
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1389
|
+
var SelectContext = (0, import_react10.createContext)(void 0);
|
|
1390
|
+
var useSelectContext = () => {
|
|
1391
|
+
const context = (0, import_react10.useContext)(SelectContext);
|
|
1392
|
+
if (!context)
|
|
1393
|
+
throw new Error("Select components must be used within a SelectProvider");
|
|
1394
|
+
return context;
|
|
1395
|
+
};
|
|
1396
|
+
var Select = (0, import_react10.forwardRef)((props, ref) => {
|
|
1397
|
+
const { form, name, onChange, value, children, options = [] } = props;
|
|
1398
|
+
if (form && name) {
|
|
1399
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1400
|
+
import_react_hook_form3.Controller,
|
|
1401
|
+
{
|
|
1402
|
+
name,
|
|
1403
|
+
control: form.control,
|
|
1404
|
+
render: ({
|
|
1405
|
+
field: {
|
|
1406
|
+
onChange: formOnChange,
|
|
1407
|
+
value: formValue,
|
|
1408
|
+
ref: fieldRef,
|
|
1409
|
+
onBlur
|
|
1410
|
+
}
|
|
1411
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1412
|
+
SelectRoot,
|
|
1413
|
+
{
|
|
1414
|
+
...props,
|
|
1415
|
+
options,
|
|
1416
|
+
currentValue: formValue,
|
|
1417
|
+
onChangeHandler: (val) => {
|
|
1418
|
+
formOnChange(val);
|
|
1419
|
+
onChange?.(val);
|
|
1420
|
+
},
|
|
1421
|
+
fieldInternalProps: { ref: fieldRef, onBlur },
|
|
1422
|
+
children
|
|
1423
|
+
}
|
|
1424
|
+
)
|
|
1425
|
+
}
|
|
1426
|
+
);
|
|
1427
|
+
}
|
|
1428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1429
|
+
SelectRoot,
|
|
1430
|
+
{
|
|
1431
|
+
...props,
|
|
1432
|
+
options,
|
|
1433
|
+
currentValue: value,
|
|
1434
|
+
onChangeHandler: onChange || (() => {
|
|
1435
|
+
}),
|
|
1436
|
+
children
|
|
1437
|
+
}
|
|
1438
|
+
);
|
|
1439
|
+
});
|
|
1440
|
+
Select.displayName = "Select";
|
|
1441
|
+
var SelectRoot = ({
|
|
1442
|
+
children,
|
|
1443
|
+
currentValue,
|
|
1444
|
+
onChangeHandler,
|
|
1445
|
+
form,
|
|
1446
|
+
name,
|
|
1384
1447
|
error,
|
|
1448
|
+
options: initialOptions,
|
|
1449
|
+
fieldInternalProps,
|
|
1450
|
+
label,
|
|
1385
1451
|
containerClassName = "",
|
|
1386
|
-
name,
|
|
1387
|
-
form,
|
|
1388
|
-
onChangeHandler,
|
|
1389
|
-
currentValue,
|
|
1390
|
-
onFocus,
|
|
1391
|
-
onBlur,
|
|
1392
|
-
className = "",
|
|
1393
1452
|
variant = "default",
|
|
1394
|
-
|
|
1453
|
+
icon,
|
|
1454
|
+
placeholder = "Select...",
|
|
1455
|
+
required,
|
|
1456
|
+
disabled,
|
|
1457
|
+
id,
|
|
1458
|
+
className = "",
|
|
1395
1459
|
...props
|
|
1396
1460
|
}) => {
|
|
1397
1461
|
const [isOpen, setIsOpen] = (0, import_react10.useState)(false);
|
|
1398
1462
|
const [isFocused, setIsFocused] = (0, import_react10.useState)(false);
|
|
1399
|
-
const [
|
|
1463
|
+
const [activeIndex, setActiveIndex] = (0, import_react10.useState)(-1);
|
|
1464
|
+
const [registeredOptions, setRegisteredOptions] = (0, import_react10.useState)([]);
|
|
1400
1465
|
const { theme } = useWarqadConfig();
|
|
1401
1466
|
const primaryColor = theme?.primaryColor;
|
|
1402
1467
|
const containerRef = (0, import_react10.useRef)(null);
|
|
1403
1468
|
const dropdownAnchorRef = (0, import_react10.useRef)(null);
|
|
1404
1469
|
const dropdownContentRef = (0, import_react10.useRef)(null);
|
|
1405
|
-
const
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
};
|
|
1416
|
-
if (rect.bottom + 240 > window.innerHeight) {
|
|
1417
|
-
style.top = "auto";
|
|
1418
|
-
style.bottom = `${window.innerHeight - rect.top + 4}px`;
|
|
1470
|
+
const registerOption = (opt) => {
|
|
1471
|
+
setRegisteredOptions((prev) => {
|
|
1472
|
+
const index = prev.findIndex((p) => p.value === opt.value);
|
|
1473
|
+
if (index >= 0) {
|
|
1474
|
+
if (prev[index].label !== opt.label || prev[index].disabled !== opt.disabled) {
|
|
1475
|
+
const newOpts = [...prev];
|
|
1476
|
+
newOpts[index] = opt;
|
|
1477
|
+
return newOpts;
|
|
1478
|
+
}
|
|
1479
|
+
return prev;
|
|
1419
1480
|
}
|
|
1420
|
-
|
|
1421
|
-
}
|
|
1481
|
+
return [...prev, opt];
|
|
1482
|
+
});
|
|
1422
1483
|
};
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
return () => {
|
|
1429
|
-
window.removeEventListener("scroll", updateDropdownPosition, true);
|
|
1430
|
-
window.removeEventListener("resize", updateDropdownPosition);
|
|
1431
|
-
};
|
|
1484
|
+
const setSelectedValue = (val) => {
|
|
1485
|
+
onChangeHandler(val);
|
|
1486
|
+
if (form && name) {
|
|
1487
|
+
form.setValue(name, val, { shouldValidate: true, shouldDirty: true });
|
|
1488
|
+
form.clearErrors(name);
|
|
1432
1489
|
}
|
|
1433
|
-
}
|
|
1490
|
+
};
|
|
1434
1491
|
(0, import_react10.useEffect)(() => {
|
|
1435
1492
|
const handleClickOutside = (event) => {
|
|
1436
1493
|
const target = event.target;
|
|
@@ -1443,20 +1500,6 @@ var SelectContent = ({
|
|
|
1443
1500
|
document.addEventListener("mousedown", handleClickOutside);
|
|
1444
1501
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1445
1502
|
}, [fieldInternalProps]);
|
|
1446
|
-
const handleSelect = (option) => {
|
|
1447
|
-
if (option.disabled) return;
|
|
1448
|
-
onChangeHandler(option.value);
|
|
1449
|
-
if (form && name) {
|
|
1450
|
-
form.setValue(name, option.value, {
|
|
1451
|
-
shouldValidate: true,
|
|
1452
|
-
shouldDirty: true
|
|
1453
|
-
});
|
|
1454
|
-
form.clearErrors(name);
|
|
1455
|
-
}
|
|
1456
|
-
setIsOpen(false);
|
|
1457
|
-
fieldInternalProps?.onBlur?.();
|
|
1458
|
-
};
|
|
1459
|
-
const displayValue = options.find((o) => o.value === currentValue)?.label || "Select...";
|
|
1460
1503
|
let message = error;
|
|
1461
1504
|
if (form && name) {
|
|
1462
1505
|
const {
|
|
@@ -1469,7 +1512,27 @@ var SelectContent = ({
|
|
|
1469
1512
|
}
|
|
1470
1513
|
message = currentError?.message || message;
|
|
1471
1514
|
}
|
|
1472
|
-
|
|
1515
|
+
const allOptions = initialOptions?.length ? initialOptions : registeredOptions;
|
|
1516
|
+
const valueCtx = {
|
|
1517
|
+
isOpen,
|
|
1518
|
+
setIsOpen,
|
|
1519
|
+
selectedValue: currentValue,
|
|
1520
|
+
setSelectedValue,
|
|
1521
|
+
activeIndex,
|
|
1522
|
+
setActiveIndex,
|
|
1523
|
+
isFocused,
|
|
1524
|
+
setIsFocused,
|
|
1525
|
+
dropdownAnchorRef,
|
|
1526
|
+
dropdownContentRef,
|
|
1527
|
+
containerRef,
|
|
1528
|
+
primaryColor,
|
|
1529
|
+
options: allOptions,
|
|
1530
|
+
registerOption,
|
|
1531
|
+
fieldInternalProps,
|
|
1532
|
+
disabled
|
|
1533
|
+
};
|
|
1534
|
+
const hasChildren = import_react10.default.Children.count(children) > 0;
|
|
1535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectContext.Provider, { value: valueCtx, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1473
1536
|
"div",
|
|
1474
1537
|
{
|
|
1475
1538
|
ref: containerRef,
|
|
@@ -1482,172 +1545,246 @@ var SelectContent = ({
|
|
|
1482
1545
|
style: { color: isFocused || isOpen ? primaryColor : void 0 },
|
|
1483
1546
|
children: [
|
|
1484
1547
|
label,
|
|
1485
|
-
|
|
1548
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
|
|
1486
1549
|
]
|
|
1487
1550
|
}
|
|
1488
1551
|
),
|
|
1489
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1490
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.
|
|
1491
|
-
|
|
1552
|
+
hasChildren ? children : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
1553
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1554
|
+
SelectTrigger,
|
|
1492
1555
|
{
|
|
1493
|
-
id
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
} : void 0,
|
|
1500
|
-
onClick: () => {
|
|
1501
|
-
if (props.disabled) return;
|
|
1502
|
-
if (Date.now() - lastFocusTime.current < 150) {
|
|
1503
|
-
return;
|
|
1504
|
-
}
|
|
1505
|
-
setIsOpen(!isOpen);
|
|
1506
|
-
setIsFocused(true);
|
|
1507
|
-
onFocus?.(null);
|
|
1508
|
-
},
|
|
1509
|
-
onKeyDown: (e) => {
|
|
1510
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
1511
|
-
e.preventDefault();
|
|
1512
|
-
if (props.disabled) return;
|
|
1513
|
-
setIsOpen(!isOpen);
|
|
1514
|
-
setIsFocused(true);
|
|
1515
|
-
} else if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
1516
|
-
e.preventDefault();
|
|
1517
|
-
setIsOpen(true);
|
|
1518
|
-
}
|
|
1519
|
-
},
|
|
1520
|
-
onFocus: () => {
|
|
1521
|
-
setIsFocused(true);
|
|
1522
|
-
setIsOpen(true);
|
|
1523
|
-
lastFocusTime.current = Date.now();
|
|
1524
|
-
},
|
|
1525
|
-
tabIndex: props.disabled ? -1 : 0,
|
|
1526
|
-
onBlur: (e) => {
|
|
1527
|
-
if (!dropdownContentRef.current?.contains(e.relatedTarget) && !containerRef.current?.contains(e.relatedTarget)) {
|
|
1528
|
-
setIsOpen(false);
|
|
1529
|
-
setIsFocused(false);
|
|
1530
|
-
fieldInternalProps?.onBlur?.();
|
|
1531
|
-
onBlur?.(null);
|
|
1532
|
-
}
|
|
1533
|
-
},
|
|
1534
|
-
children: [
|
|
1535
|
-
icon && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1536
|
-
"div",
|
|
1537
|
-
{
|
|
1538
|
-
className: `pl-2.5 pr-2 flex items-center transition-colors duration-200`,
|
|
1539
|
-
style: { color: isFocused || isOpen ? primaryColor : "#9ca3af" },
|
|
1540
|
-
children: icon
|
|
1541
|
-
}
|
|
1542
|
-
),
|
|
1543
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1544
|
-
"div",
|
|
1545
|
-
{
|
|
1546
|
-
className: `flex-1 truncate text-sm ${icon ? "" : "pl-2.5"} ${!currentValue && currentValue !== 0 && currentValue !== false ? "text-gray-400 dark:text-zinc-500" : ""}`,
|
|
1547
|
-
children: displayValue
|
|
1548
|
-
}
|
|
1549
|
-
),
|
|
1550
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "pr-2.5 flex items-center gap-1 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1551
|
-
import_lucide_react7.ChevronDown,
|
|
1552
|
-
{
|
|
1553
|
-
className: `h-4 w-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
1554
|
-
}
|
|
1555
|
-
) })
|
|
1556
|
-
]
|
|
1556
|
+
id,
|
|
1557
|
+
icon,
|
|
1558
|
+
placeholder,
|
|
1559
|
+
variant,
|
|
1560
|
+
className,
|
|
1561
|
+
...props
|
|
1557
1562
|
}
|
|
1558
1563
|
),
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
const isSelected = currentValue === option.value;
|
|
1569
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1570
|
-
"button",
|
|
1571
|
-
{
|
|
1572
|
-
type: "button",
|
|
1573
|
-
disabled: option.disabled,
|
|
1574
|
-
className: `w-full text-left px-3 py-2 rounded-md text-sm flex items-center justify-between transition-colors ${option.disabled ? "opacity-50 cursor-not-allowed text-gray-400" : isSelected ? "bg-gray-100 dark:bg-zinc-800 text-gray-900 dark:text-gray-100" : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-zinc-800"}`,
|
|
1575
|
-
style: isSelected && !option.disabled && primaryColor ? {
|
|
1576
|
-
color: primaryColor
|
|
1577
|
-
} : void 0,
|
|
1578
|
-
onClick: (e) => {
|
|
1579
|
-
e.stopPropagation();
|
|
1580
|
-
handleSelect(option);
|
|
1581
|
-
},
|
|
1582
|
-
children: [
|
|
1583
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "whitespace-nowrap truncate flex-1", children: option.label }),
|
|
1584
|
-
isSelected && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1585
|
-
import_lucide_react7.Check,
|
|
1586
|
-
{
|
|
1587
|
-
className: "h-4 w-4 shrink-0 ml-2",
|
|
1588
|
-
style: { color: primaryColor }
|
|
1589
|
-
}
|
|
1590
|
-
)
|
|
1591
|
-
]
|
|
1592
|
-
},
|
|
1593
|
-
String(option.value) || index
|
|
1594
|
-
);
|
|
1595
|
-
}),
|
|
1596
|
-
options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "p-3 text-center text-sm text-gray-500", children: "No options available" })
|
|
1597
|
-
] })
|
|
1598
|
-
}
|
|
1599
|
-
),
|
|
1600
|
-
document.body
|
|
1601
|
-
)
|
|
1564
|
+
allOptions && allOptions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SelectContent, { children: allOptions.map((opt, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1565
|
+
SelectItem,
|
|
1566
|
+
{
|
|
1567
|
+
value: opt.value,
|
|
1568
|
+
label: opt.label,
|
|
1569
|
+
disabled: opt.disabled
|
|
1570
|
+
},
|
|
1571
|
+
String(opt.value) || index
|
|
1572
|
+
)) })
|
|
1602
1573
|
] }),
|
|
1603
1574
|
message && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
|
|
1604
1575
|
]
|
|
1605
1576
|
}
|
|
1606
|
-
);
|
|
1577
|
+
) });
|
|
1607
1578
|
};
|
|
1608
|
-
var
|
|
1609
|
-
(
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1579
|
+
var SelectTrigger = (0, import_react10.forwardRef)(
|
|
1580
|
+
({
|
|
1581
|
+
className = "",
|
|
1582
|
+
variant = "default",
|
|
1583
|
+
icon,
|
|
1584
|
+
placeholder = "Select...",
|
|
1585
|
+
id,
|
|
1586
|
+
children,
|
|
1587
|
+
...props
|
|
1588
|
+
}, ref) => {
|
|
1589
|
+
const {
|
|
1590
|
+
isOpen,
|
|
1591
|
+
setIsOpen,
|
|
1592
|
+
isFocused,
|
|
1593
|
+
setIsFocused,
|
|
1594
|
+
primaryColor,
|
|
1595
|
+
dropdownAnchorRef,
|
|
1596
|
+
dropdownContentRef,
|
|
1597
|
+
containerRef,
|
|
1598
|
+
selectedValue,
|
|
1599
|
+
options,
|
|
1600
|
+
fieldInternalProps,
|
|
1601
|
+
disabled
|
|
1602
|
+
} = useSelectContext();
|
|
1603
|
+
const lastFocusTime = (0, import_react10.useRef)(0);
|
|
1604
|
+
const displayOption = options.find((o) => o.value === selectedValue);
|
|
1605
|
+
const displayValue = displayOption ? displayOption.label : selectedValue != null && selectedValue !== "" ? String(selectedValue) : placeholder;
|
|
1606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "relative", ref: dropdownAnchorRef, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1607
|
+
"div",
|
|
1608
|
+
{
|
|
1609
|
+
id,
|
|
1610
|
+
className: `flex items-center w-full select-none text-gray-900 dark:text-white transition-all duration-200 outline-none focus:outline-none focus:ring-0 py-1 ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"} ${variant === "ghost" ? "bg-transparent border-transparent shadow-none px-0 h-full border-none ring-0 focus:border-none focus:ring-0" : isFocused || isOpen ? "ring-0 border rounded-xl h-9" : "border-gray-200 dark:border-zinc-800 border rounded-xl bg-white dark:bg-zinc-900/50 h-9"} ${className}`,
|
|
1611
|
+
style: variant === "default" ? {
|
|
1612
|
+
borderColor: isFocused || isOpen ? primaryColor : void 0,
|
|
1613
|
+
boxShadow: isFocused || isOpen ? `${primaryColor}33 0px 0px 0px 2px` : void 0,
|
|
1614
|
+
backgroundColor: isFocused || isOpen ? "var(--tw-colors-white, white)" : void 0
|
|
1615
|
+
} : void 0,
|
|
1616
|
+
onMouseDown: (e) => {
|
|
1617
|
+
if (disabled) return;
|
|
1618
|
+
e.preventDefault();
|
|
1619
|
+
},
|
|
1620
|
+
onClick: (e) => {
|
|
1621
|
+
if (disabled) return;
|
|
1622
|
+
if (Date.now() - lastFocusTime.current < 150) return;
|
|
1623
|
+
e.stopPropagation();
|
|
1624
|
+
setIsOpen(!isOpen);
|
|
1625
|
+
setIsFocused(true);
|
|
1626
|
+
},
|
|
1627
|
+
onKeyDown: (e) => {
|
|
1628
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1629
|
+
e.preventDefault();
|
|
1630
|
+
e.stopPropagation();
|
|
1631
|
+
if (disabled) return;
|
|
1632
|
+
setIsOpen(!isOpen);
|
|
1633
|
+
setIsFocused(true);
|
|
1634
|
+
} else if (e.key === "ArrowDown" || e.key === "ArrowUp") {
|
|
1635
|
+
e.preventDefault();
|
|
1636
|
+
e.stopPropagation();
|
|
1637
|
+
setIsOpen(true);
|
|
1638
|
+
} else if (e.key === "Escape") {
|
|
1639
|
+
setIsOpen(false);
|
|
1640
|
+
}
|
|
1641
|
+
},
|
|
1642
|
+
onFocus: () => {
|
|
1643
|
+
setIsFocused(true);
|
|
1644
|
+
lastFocusTime.current = Date.now();
|
|
1645
|
+
},
|
|
1646
|
+
tabIndex: disabled ? -1 : 0,
|
|
1647
|
+
onBlur: (e) => {
|
|
1648
|
+
if (!dropdownContentRef.current?.contains(e.relatedTarget) && !containerRef.current?.contains(e.relatedTarget)) {
|
|
1649
|
+
setIsFocused(false);
|
|
1650
|
+
setIsOpen(false);
|
|
1651
|
+
fieldInternalProps?.onBlur?.();
|
|
1652
|
+
}
|
|
1653
|
+
},
|
|
1654
|
+
...props,
|
|
1655
|
+
children: children ? children : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
1656
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1657
|
+
"div",
|
|
1626
1658
|
{
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
formOnChange(val);
|
|
1631
|
-
onChange?.(val);
|
|
1659
|
+
className: `pl-2.5 pr-2 flex items-center transition-colors duration-200`,
|
|
1660
|
+
style: {
|
|
1661
|
+
color: isFocused || isOpen ? primaryColor : "#9ca3af"
|
|
1632
1662
|
},
|
|
1633
|
-
|
|
1663
|
+
children: icon
|
|
1634
1664
|
}
|
|
1635
|
-
)
|
|
1665
|
+
),
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1667
|
+
"div",
|
|
1668
|
+
{
|
|
1669
|
+
className: `flex-1 truncate text-sm ${icon ? "" : "pl-2.5"} ${!selectedValue && selectedValue !== 0 && selectedValue !== false ? "text-gray-400 dark:text-zinc-500" : ""}`,
|
|
1670
|
+
children: displayValue
|
|
1671
|
+
}
|
|
1672
|
+
),
|
|
1673
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "pr-2.5 flex items-center gap-1 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1674
|
+
import_lucide_react7.ChevronDown,
|
|
1675
|
+
{
|
|
1676
|
+
className: `h-4 w-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
1677
|
+
}
|
|
1678
|
+
) })
|
|
1679
|
+
] })
|
|
1680
|
+
}
|
|
1681
|
+
) });
|
|
1682
|
+
}
|
|
1683
|
+
);
|
|
1684
|
+
SelectTrigger.displayName = "SelectTrigger";
|
|
1685
|
+
var SelectContent = (0, import_react10.forwardRef)(
|
|
1686
|
+
({ children, className = "", style, ...props }, ref) => {
|
|
1687
|
+
const { isOpen, setIsOpen, dropdownAnchorRef, dropdownContentRef } = useSelectContext();
|
|
1688
|
+
const [dropdownStyle, setDropdownStyle] = (0, import_react10.useState)({});
|
|
1689
|
+
const updateDropdownPosition = () => {
|
|
1690
|
+
if (dropdownAnchorRef.current) {
|
|
1691
|
+
const rect = dropdownAnchorRef.current.getBoundingClientRect();
|
|
1692
|
+
const newStyle = {
|
|
1693
|
+
position: "fixed",
|
|
1694
|
+
top: `${rect.bottom + 4}px`,
|
|
1695
|
+
left: `${rect.left}px`,
|
|
1696
|
+
width: `${rect.width}px`,
|
|
1697
|
+
zIndex: 999999
|
|
1698
|
+
};
|
|
1699
|
+
if (rect.bottom + 240 > window.innerHeight) {
|
|
1700
|
+
newStyle.top = "auto";
|
|
1701
|
+
newStyle.bottom = `${window.innerHeight - rect.top + 4}px`;
|
|
1636
1702
|
}
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1703
|
+
setDropdownStyle(newStyle);
|
|
1704
|
+
}
|
|
1705
|
+
};
|
|
1706
|
+
(0, import_react10.useEffect)(() => {
|
|
1707
|
+
if (isOpen) {
|
|
1708
|
+
updateDropdownPosition();
|
|
1709
|
+
window.addEventListener("scroll", updateDropdownPosition, true);
|
|
1710
|
+
window.addEventListener("resize", updateDropdownPosition);
|
|
1711
|
+
return () => {
|
|
1712
|
+
window.removeEventListener("scroll", updateDropdownPosition, true);
|
|
1713
|
+
window.removeEventListener("resize", updateDropdownPosition);
|
|
1714
|
+
};
|
|
1715
|
+
}
|
|
1716
|
+
}, [isOpen]);
|
|
1717
|
+
if (!isOpen || typeof document === "undefined") return null;
|
|
1718
|
+
return (0, import_react_dom.createPortal)(
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1720
|
+
"div",
|
|
1721
|
+
{
|
|
1722
|
+
ref: dropdownContentRef,
|
|
1723
|
+
className: `bg-white dark:bg-zinc-950 rounded-xl border border-gray-200 dark:border-zinc-800 shadow-xl max-h-60 overflow-y-auto overflow-x-hidden p-1.5 ${className}`,
|
|
1724
|
+
style: { ...dropdownStyle, ...style },
|
|
1725
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
1726
|
+
...props,
|
|
1727
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex flex-col gap-0.5", children: import_react10.default.Children.count(children) === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "p-3 text-center text-sm text-gray-500", children: "No options available" }) : children })
|
|
1728
|
+
}
|
|
1729
|
+
),
|
|
1730
|
+
document.body
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
);
|
|
1734
|
+
SelectContent.displayName = "SelectContent";
|
|
1735
|
+
var SelectItem = (0, import_react10.forwardRef)(
|
|
1736
|
+
({ value, label, disabled, children, className = "", ...props }, ref) => {
|
|
1737
|
+
const {
|
|
1738
|
+
selectedValue,
|
|
1739
|
+
setSelectedValue,
|
|
1740
|
+
setIsOpen,
|
|
1741
|
+
primaryColor,
|
|
1742
|
+
fieldInternalProps,
|
|
1743
|
+
registerOption
|
|
1744
|
+
} = useSelectContext();
|
|
1745
|
+
const isSelected = selectedValue === value;
|
|
1746
|
+
const displayLabel = label || children || value;
|
|
1747
|
+
(0, import_react10.useEffect)(() => {
|
|
1748
|
+
if (value !== void 0) {
|
|
1749
|
+
registerOption({ value, label: String(displayLabel), disabled });
|
|
1750
|
+
}
|
|
1751
|
+
}, [value, displayLabel, disabled]);
|
|
1752
|
+
const handleSelect = () => {
|
|
1753
|
+
if (disabled) return;
|
|
1754
|
+
setSelectedValue(value);
|
|
1755
|
+
setIsOpen(false);
|
|
1756
|
+
fieldInternalProps?.onBlur?.();
|
|
1757
|
+
};
|
|
1758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1759
|
+
"button",
|
|
1641
1760
|
{
|
|
1761
|
+
ref,
|
|
1762
|
+
type: "button",
|
|
1763
|
+
disabled,
|
|
1764
|
+
className: `w-full text-left px-3 py-2 rounded-md text-sm flex items-center justify-between transition-colors ${disabled ? "opacity-50 cursor-not-allowed text-gray-400" : isSelected ? "bg-gray-100 dark:bg-zinc-800 text-gray-900 dark:text-gray-100" : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-zinc-800"} ${className}`,
|
|
1765
|
+
style: isSelected && !disabled && primaryColor ? { color: primaryColor } : void 0,
|
|
1766
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
1767
|
+
onClick: (e) => {
|
|
1768
|
+
e.stopPropagation();
|
|
1769
|
+
e.preventDefault();
|
|
1770
|
+
handleSelect();
|
|
1771
|
+
},
|
|
1642
1772
|
...props,
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1773
|
+
children: [
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "whitespace-nowrap truncate flex-1", children: children || label }),
|
|
1775
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1776
|
+
import_lucide_react7.Check,
|
|
1777
|
+
{
|
|
1778
|
+
className: "h-4 w-4 shrink-0 ml-2",
|
|
1779
|
+
style: { color: primaryColor }
|
|
1780
|
+
}
|
|
1781
|
+
)
|
|
1782
|
+
]
|
|
1646
1783
|
}
|
|
1647
1784
|
);
|
|
1648
1785
|
}
|
|
1649
1786
|
);
|
|
1650
|
-
|
|
1787
|
+
SelectItem.displayName = "SelectItem";
|
|
1651
1788
|
|
|
1652
1789
|
// src/components/Fields/textArea.tsx
|
|
1653
1790
|
var import_react11 = require("react");
|
|
@@ -1740,7 +1877,7 @@ var Textarea = (0, import_react11.forwardRef)(
|
|
|
1740
1877
|
);
|
|
1741
1878
|
|
|
1742
1879
|
// src/components/Fields/searchApi.tsx
|
|
1743
|
-
var import_react13 = require("react");
|
|
1880
|
+
var import_react13 = __toESM(require("react"));
|
|
1744
1881
|
var import_react_dom2 = require("react-dom");
|
|
1745
1882
|
var import_lucide_react8 = require("lucide-react");
|
|
1746
1883
|
|
|
@@ -1913,27 +2050,77 @@ var useApis_default = useApi;
|
|
|
1913
2050
|
// src/components/Fields/searchApi.tsx
|
|
1914
2051
|
var import_react_hook_form5 = require("react-hook-form");
|
|
1915
2052
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1916
|
-
var
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
2053
|
+
var SearchApiContext = (0, import_react13.createContext)(
|
|
2054
|
+
void 0
|
|
2055
|
+
);
|
|
2056
|
+
var useSearchApiContext = () => {
|
|
2057
|
+
const context = (0, import_react13.useContext)(SearchApiContext);
|
|
2058
|
+
if (!context)
|
|
2059
|
+
throw new Error(
|
|
2060
|
+
"SearchApi components must be used within a SearchApiProvider"
|
|
2061
|
+
);
|
|
2062
|
+
return context;
|
|
2063
|
+
};
|
|
2064
|
+
var SearchApi = (0, import_react13.forwardRef)(
|
|
2065
|
+
(props, _) => {
|
|
2066
|
+
const { form, name, onChange, value, children } = props;
|
|
2067
|
+
if (form && name) {
|
|
2068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2069
|
+
import_react_hook_form5.Controller,
|
|
2070
|
+
{
|
|
2071
|
+
name,
|
|
2072
|
+
control: form.control,
|
|
2073
|
+
render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2074
|
+
SearchApiRoot,
|
|
2075
|
+
{
|
|
2076
|
+
...props,
|
|
2077
|
+
currentValue: field.value !== void 0 && field.value !== "" ? field.value : value,
|
|
2078
|
+
onChangeHandler: (val) => {
|
|
2079
|
+
field.onChange(val);
|
|
2080
|
+
if (onChange) onChange(val);
|
|
2081
|
+
},
|
|
2082
|
+
fieldInternalProps: { ref: field.ref, onBlur: field.onBlur },
|
|
2083
|
+
children
|
|
2084
|
+
}
|
|
2085
|
+
)
|
|
2086
|
+
}
|
|
2087
|
+
);
|
|
2088
|
+
}
|
|
2089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2090
|
+
SearchApiRoot,
|
|
2091
|
+
{
|
|
2092
|
+
...props,
|
|
2093
|
+
currentValue: value,
|
|
2094
|
+
onChangeHandler: onChange || (() => {
|
|
2095
|
+
}),
|
|
2096
|
+
children
|
|
2097
|
+
}
|
|
2098
|
+
);
|
|
2099
|
+
}
|
|
2100
|
+
);
|
|
2101
|
+
SearchApi.displayName = "SearchApi";
|
|
2102
|
+
var SearchApiRoot = ({
|
|
2103
|
+
children,
|
|
1920
2104
|
currentValue,
|
|
1921
2105
|
onChangeHandler,
|
|
2106
|
+
form,
|
|
2107
|
+
name,
|
|
2108
|
+
obj,
|
|
2109
|
+
error,
|
|
2110
|
+
api = "",
|
|
1922
2111
|
queryKey = "search",
|
|
1923
2112
|
labelKey = "name",
|
|
1924
2113
|
valueKey = "_id",
|
|
1925
|
-
error,
|
|
1926
|
-
containerClassName = "",
|
|
1927
|
-
className = "",
|
|
1928
|
-
disabled,
|
|
1929
|
-
name,
|
|
1930
|
-
obj,
|
|
1931
|
-
form,
|
|
1932
2114
|
filter = [],
|
|
1933
2115
|
required,
|
|
1934
2116
|
v = 2,
|
|
1935
2117
|
variant = "default",
|
|
1936
2118
|
fieldInternalProps,
|
|
2119
|
+
label,
|
|
2120
|
+
containerClassName = "",
|
|
2121
|
+
placeholder = "Search...",
|
|
2122
|
+
disabled,
|
|
2123
|
+
className = "",
|
|
1937
2124
|
...props
|
|
1938
2125
|
}) => {
|
|
1939
2126
|
const [searchTerm, setSearchTerm] = (0, import_react13.useState)("");
|
|
@@ -1947,51 +2134,13 @@ var SearchApiContent = ({
|
|
|
1947
2134
|
const [hasAttemptedHydration, setHasAttemptedHydration] = (0, import_react13.useState)(false);
|
|
1948
2135
|
const containerRef = (0, import_react13.useRef)(null);
|
|
1949
2136
|
const dropdownAnchorRef = (0, import_react13.useRef)(null);
|
|
1950
|
-
const
|
|
2137
|
+
const dropdownContentRef = (0, import_react13.useRef)(null);
|
|
1951
2138
|
const inputRef = (0, import_react13.useRef)(null);
|
|
1952
2139
|
const prevApiRef = (0, import_react13.useRef)(api);
|
|
1953
|
-
const [dropdownStyle, setDropdownStyle] = (0, import_react13.useState)({});
|
|
1954
|
-
const updateDropdownPosition = () => {
|
|
1955
|
-
if (dropdownAnchorRef.current) {
|
|
1956
|
-
const rect = dropdownAnchorRef.current.getBoundingClientRect();
|
|
1957
|
-
const style = {
|
|
1958
|
-
position: "fixed",
|
|
1959
|
-
top: `${rect.bottom + 4}px`,
|
|
1960
|
-
left: `${rect.left}px`,
|
|
1961
|
-
width: `${rect.width}px`,
|
|
1962
|
-
zIndex: 999999
|
|
1963
|
-
};
|
|
1964
|
-
if (rect.bottom + 240 > window.innerHeight) {
|
|
1965
|
-
style.top = "auto";
|
|
1966
|
-
style.bottom = `${window.innerHeight - rect.top + 4}px`;
|
|
1967
|
-
}
|
|
1968
|
-
setDropdownStyle(style);
|
|
1969
|
-
}
|
|
1970
|
-
};
|
|
1971
|
-
(0, import_react13.useEffect)(() => {
|
|
1972
|
-
if (isOpen) {
|
|
1973
|
-
updateDropdownPosition();
|
|
1974
|
-
window.addEventListener("scroll", updateDropdownPosition, true);
|
|
1975
|
-
window.addEventListener("resize", updateDropdownPosition);
|
|
1976
|
-
return () => {
|
|
1977
|
-
window.removeEventListener("scroll", updateDropdownPosition, true);
|
|
1978
|
-
window.removeEventListener("resize", updateDropdownPosition);
|
|
1979
|
-
};
|
|
1980
|
-
}
|
|
1981
|
-
}, [isOpen]);
|
|
1982
|
-
const setInputRef = (element) => {
|
|
1983
|
-
inputRef.current = element;
|
|
1984
|
-
if (fieldInternalProps?.ref) {
|
|
1985
|
-
if (typeof fieldInternalProps.ref === "function") {
|
|
1986
|
-
fieldInternalProps.ref(element);
|
|
1987
|
-
} else {
|
|
1988
|
-
fieldInternalProps.ref.current = element;
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
|
-
};
|
|
1992
2140
|
const { get, isLoading, error: errorMessage } = useApis_default();
|
|
1993
2141
|
const fetchOptions = async (query) => {
|
|
1994
2142
|
try {
|
|
2143
|
+
if (!api) return;
|
|
1995
2144
|
const params = {};
|
|
1996
2145
|
if (query) params[queryKey] = query;
|
|
1997
2146
|
const response = await get({
|
|
@@ -2042,7 +2191,7 @@ var SearchApiContent = ({
|
|
|
2042
2191
|
setHasAttemptedHydration(true);
|
|
2043
2192
|
if (selectedObject) setSelectedObject(void 0);
|
|
2044
2193
|
}
|
|
2045
|
-
}, [currentValue
|
|
2194
|
+
}, [currentValue]);
|
|
2046
2195
|
const getOptionValue = (option) => {
|
|
2047
2196
|
if (valueKey === "_id" && option._id === void 0 && option.id !== void 0) {
|
|
2048
2197
|
return option.id;
|
|
@@ -2055,11 +2204,14 @@ var SearchApiContent = ({
|
|
|
2055
2204
|
if (found) {
|
|
2056
2205
|
setSelectedObject(found);
|
|
2057
2206
|
if (form && obj) {
|
|
2058
|
-
form.setValue(obj, found
|
|
2207
|
+
form.setValue(obj, found, {
|
|
2208
|
+
shouldValidate: true,
|
|
2209
|
+
shouldDirty: true
|
|
2210
|
+
});
|
|
2059
2211
|
}
|
|
2060
2212
|
}
|
|
2061
2213
|
}
|
|
2062
|
-
}, [currentValue, options,
|
|
2214
|
+
}, [currentValue, options, obj]);
|
|
2063
2215
|
(0, import_react13.useEffect)(() => {
|
|
2064
2216
|
if (prevApiRef.current !== api) {
|
|
2065
2217
|
prevApiRef.current = api;
|
|
@@ -2084,11 +2236,11 @@ var SearchApiContent = ({
|
|
|
2084
2236
|
}
|
|
2085
2237
|
fetchOptions("");
|
|
2086
2238
|
}
|
|
2087
|
-
}, [api,
|
|
2239
|
+
}, [api, name, obj]);
|
|
2088
2240
|
(0, import_react13.useEffect)(() => {
|
|
2089
2241
|
const handleClickOutside = (event) => {
|
|
2090
2242
|
const target = event.target;
|
|
2091
|
-
if (containerRef.current && !containerRef.current.contains(target) && !(
|
|
2243
|
+
if (containerRef.current && !containerRef.current.contains(target) && !(dropdownContentRef.current && dropdownContentRef.current.contains(target))) {
|
|
2092
2244
|
setIsOpen(false);
|
|
2093
2245
|
setIsFocused(false);
|
|
2094
2246
|
setSearchTerm("");
|
|
@@ -2109,42 +2261,21 @@ var SearchApiContent = ({
|
|
|
2109
2261
|
return currentValue || "";
|
|
2110
2262
|
};
|
|
2111
2263
|
const handleSelect = (option) => {
|
|
2112
|
-
const
|
|
2264
|
+
const val = getOptionValue(option);
|
|
2265
|
+
setIsOpen(false);
|
|
2266
|
+
inputRef.current?.blur();
|
|
2113
2267
|
setSelectedObject(option);
|
|
2114
|
-
|
|
2268
|
+
setTimeout(() => {
|
|
2269
|
+
onChangeHandler(val);
|
|
2270
|
+
}, 0);
|
|
2115
2271
|
if (form) {
|
|
2116
2272
|
if (obj) form.setValue(obj, option);
|
|
2117
2273
|
if (name) form.clearErrors(name);
|
|
2118
2274
|
}
|
|
2119
|
-
setIsOpen(false);
|
|
2120
2275
|
setSearchTerm("");
|
|
2121
2276
|
setActiveIndex(-1);
|
|
2122
2277
|
fieldInternalProps?.onBlur?.();
|
|
2123
2278
|
};
|
|
2124
|
-
const handleKeyDown = (e) => {
|
|
2125
|
-
if (!isOpen) {
|
|
2126
|
-
if (e.key === "ArrowDown" || e.key === "Enter") setIsOpen(true);
|
|
2127
|
-
return;
|
|
2128
|
-
}
|
|
2129
|
-
switch (e.key) {
|
|
2130
|
-
case "ArrowDown":
|
|
2131
|
-
e.preventDefault();
|
|
2132
|
-
setActiveIndex((prev) => prev < options.length - 1 ? prev + 1 : prev);
|
|
2133
|
-
break;
|
|
2134
|
-
case "ArrowUp":
|
|
2135
|
-
e.preventDefault();
|
|
2136
|
-
setActiveIndex((prev) => prev > 0 ? prev - 1 : prev);
|
|
2137
|
-
break;
|
|
2138
|
-
case "Enter":
|
|
2139
|
-
e.preventDefault();
|
|
2140
|
-
if (activeIndex >= 0 && activeIndex < options.length)
|
|
2141
|
-
handleSelect(options[activeIndex]);
|
|
2142
|
-
break;
|
|
2143
|
-
case "Escape":
|
|
2144
|
-
setIsOpen(false);
|
|
2145
|
-
break;
|
|
2146
|
-
}
|
|
2147
|
-
};
|
|
2148
2279
|
const clearSelection = (e) => {
|
|
2149
2280
|
e.stopPropagation();
|
|
2150
2281
|
if (form) {
|
|
@@ -2166,13 +2297,7 @@ var SearchApiContent = ({
|
|
|
2166
2297
|
const filteredOptions = options.filter(
|
|
2167
2298
|
(option) => !filter.includes(getOptionValue(option))
|
|
2168
2299
|
);
|
|
2169
|
-
|
|
2170
|
-
if (form && name && !form.watch(name)) {
|
|
2171
|
-
form.setValue(name, void 0);
|
|
2172
|
-
if (obj) form.setValue(obj, void 0);
|
|
2173
|
-
}
|
|
2174
|
-
}, [form, name, obj]);
|
|
2175
|
-
let message = error;
|
|
2300
|
+
let message = error || errorMessage;
|
|
2176
2301
|
if (form && name) {
|
|
2177
2302
|
const {
|
|
2178
2303
|
formState: { errors }
|
|
@@ -2184,7 +2309,42 @@ var SearchApiContent = ({
|
|
|
2184
2309
|
}
|
|
2185
2310
|
message = currentError?.message || message;
|
|
2186
2311
|
}
|
|
2187
|
-
|
|
2312
|
+
const valueCtx = {
|
|
2313
|
+
isOpen,
|
|
2314
|
+
setIsOpen,
|
|
2315
|
+
searchTerm,
|
|
2316
|
+
setSearchTerm,
|
|
2317
|
+
selectedValue: currentValue,
|
|
2318
|
+
setSelectedValue: onChangeHandler,
|
|
2319
|
+
// alias
|
|
2320
|
+
activeIndex,
|
|
2321
|
+
setActiveIndex,
|
|
2322
|
+
isFocused,
|
|
2323
|
+
setIsFocused,
|
|
2324
|
+
dropdownAnchorRef,
|
|
2325
|
+
dropdownContentRef,
|
|
2326
|
+
containerRef,
|
|
2327
|
+
inputRef,
|
|
2328
|
+
primaryColor,
|
|
2329
|
+
options: filteredOptions,
|
|
2330
|
+
setOptions,
|
|
2331
|
+
fieldInternalProps,
|
|
2332
|
+
disabled,
|
|
2333
|
+
isLoading,
|
|
2334
|
+
clearSelection,
|
|
2335
|
+
handleSelect,
|
|
2336
|
+
getDisplayValue,
|
|
2337
|
+
placeholder,
|
|
2338
|
+
variant,
|
|
2339
|
+
labelKey,
|
|
2340
|
+
valueKey,
|
|
2341
|
+
form,
|
|
2342
|
+
name,
|
|
2343
|
+
obj,
|
|
2344
|
+
error: message
|
|
2345
|
+
};
|
|
2346
|
+
const hasChildren = import_react13.default.Children.count(children) > 0;
|
|
2347
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SearchApiContext.Provider, { value: valueCtx, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2188
2348
|
"div",
|
|
2189
2349
|
{
|
|
2190
2350
|
ref: containerRef,
|
|
@@ -2201,153 +2361,280 @@ var SearchApiContent = ({
|
|
|
2201
2361
|
]
|
|
2202
2362
|
}
|
|
2203
2363
|
),
|
|
2204
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2205
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.
|
|
2206
|
-
|
|
2364
|
+
hasChildren ? children : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
2365
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SearchApiTrigger, { className, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SearchApiInput, { ...props }) }),
|
|
2366
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SearchApiContent, { children: filteredOptions.map((opt, index) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2367
|
+
SearchApiItem,
|
|
2207
2368
|
{
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
onClick: () => {
|
|
2214
|
-
if (disabled) return;
|
|
2215
|
-
inputRef.current?.focus();
|
|
2216
|
-
setIsOpen(true);
|
|
2217
|
-
},
|
|
2218
|
-
children: [
|
|
2219
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2220
|
-
"div",
|
|
2221
|
-
{
|
|
2222
|
-
className: `${variant === "ghost" ? "pl-0" : "pl-2.5"} text-gray-400`,
|
|
2223
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Search, { className: "h-4 w-4" })
|
|
2224
|
-
}
|
|
2225
|
-
),
|
|
2226
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 relative ms-2", children: [
|
|
2227
|
-
!isOpen && currentValue && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "absolute inset-0 flex items-center ms-1 truncate select-none", children: getDisplayValue() }),
|
|
2228
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2229
|
-
"input",
|
|
2230
|
-
{
|
|
2231
|
-
ref: setInputRef,
|
|
2232
|
-
type: "text",
|
|
2233
|
-
className: `block w-full bg-transparent border-none focus:ring-0 py-1 focus:outline-none text-sm placeholder-gray-400 dark:placeholder-zinc-500 ${!isOpen && currentValue ? "opacity-0" : "opacity-100"} ${variant === "ghost" ? "h-full" : "h-9"}`,
|
|
2234
|
-
placeholder: !currentValue ? placeholder : "",
|
|
2235
|
-
value: searchTerm,
|
|
2236
|
-
onChange: (e) => setSearchTerm(e.target.value),
|
|
2237
|
-
onFocus: () => {
|
|
2238
|
-
setIsFocused(true);
|
|
2239
|
-
setIsOpen(true);
|
|
2240
|
-
},
|
|
2241
|
-
onKeyDown: handleKeyDown,
|
|
2242
|
-
disabled,
|
|
2243
|
-
...props
|
|
2244
|
-
}
|
|
2245
|
-
)
|
|
2246
|
-
] }),
|
|
2247
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "pr-2.5 w-16! flex items-center gap-1 shrink-0 min-w-10 justify-end", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Loader2, { className: "h-4 w-4 animate-spin text-blue-500 shrink-0" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
2248
|
-
currentValue && !disabled && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2249
|
-
"button",
|
|
2250
|
-
{
|
|
2251
|
-
onClick: clearSelection,
|
|
2252
|
-
type: "button",
|
|
2253
|
-
className: "p-0.5 hover:bg-gray-200 dark:hover:bg-zinc-700 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-300",
|
|
2254
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { className: "h-3 w-3" })
|
|
2255
|
-
}
|
|
2256
|
-
),
|
|
2257
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2258
|
-
import_lucide_react8.ChevronDown,
|
|
2259
|
-
{
|
|
2260
|
-
className: `h-4 w-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
2261
|
-
}
|
|
2262
|
-
)
|
|
2263
|
-
] }) })
|
|
2264
|
-
]
|
|
2265
|
-
}
|
|
2266
|
-
),
|
|
2267
|
-
isOpen && typeof document !== "undefined" && (0, import_react_dom2.createPortal)(
|
|
2268
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2269
|
-
"div",
|
|
2270
|
-
{
|
|
2271
|
-
ref: dropdownRef,
|
|
2272
|
-
className: "bg-white dark:bg-zinc-900 rounded-xl border border-gray-200 dark:border-zinc-800 shadow-lg max-h-60 overflow-y-auto overflow-x-hidden",
|
|
2273
|
-
style: dropdownStyle,
|
|
2274
|
-
children: isLoading && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "p-4 text-center text-sm text-gray-500", children: [
|
|
2275
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Loader2, { className: "h-5 w-5 animate-spin mx-auto mb-2" }),
|
|
2276
|
-
"Loading options..."
|
|
2277
|
-
] }) : filteredOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "py-1", children: filteredOptions.map((option, index) => {
|
|
2278
|
-
const optValue = getOptionValue(option);
|
|
2279
|
-
const isSelected = currentValue === optValue;
|
|
2280
|
-
const isHighlighted = index === activeIndex;
|
|
2281
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2282
|
-
"button",
|
|
2283
|
-
{
|
|
2284
|
-
type: "button",
|
|
2285
|
-
className: `w-full text-left px-3 py-2 text-sm flex items-center justify-between transition-colors ${isSelected ? "font-medium" : isHighlighted ? "bg-gray-100 dark:bg-zinc-800 text-gray-900 dark:text-gray-100" : "text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-zinc-800"}`,
|
|
2286
|
-
style: {
|
|
2287
|
-
backgroundColor: isSelected ? `${primaryColor}1A` : void 0,
|
|
2288
|
-
color: isSelected ? primaryColor : void 0
|
|
2289
|
-
},
|
|
2290
|
-
onClick: () => handleSelect(option),
|
|
2291
|
-
onMouseEnter: () => setActiveIndex(index),
|
|
2292
|
-
children: [
|
|
2293
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate", children: option[labelKey] }),
|
|
2294
|
-
isSelected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2295
|
-
import_lucide_react8.Check,
|
|
2296
|
-
{
|
|
2297
|
-
className: "h-4 w-4",
|
|
2298
|
-
style: { color: primaryColor }
|
|
2299
|
-
}
|
|
2300
|
-
)
|
|
2301
|
-
]
|
|
2302
|
-
},
|
|
2303
|
-
optValue || index
|
|
2304
|
-
);
|
|
2305
|
-
}) }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "p-4 text-center text-sm text-gray-500", children: errorMessage || (searchTerm ? `No results for "${searchTerm}"` : "No options available") })
|
|
2306
|
-
}
|
|
2307
|
-
),
|
|
2308
|
-
document.body
|
|
2309
|
-
)
|
|
2369
|
+
option: opt,
|
|
2370
|
+
index
|
|
2371
|
+
},
|
|
2372
|
+
String(getOptionValue(opt)) || index
|
|
2373
|
+
)) })
|
|
2310
2374
|
] }),
|
|
2311
2375
|
message && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: message })
|
|
2312
2376
|
]
|
|
2313
2377
|
}
|
|
2314
|
-
);
|
|
2378
|
+
) });
|
|
2315
2379
|
};
|
|
2316
|
-
var
|
|
2317
|
-
(props,
|
|
2318
|
-
const {
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2380
|
+
var SearchApiTrigger = (0, import_react13.forwardRef)(
|
|
2381
|
+
({ className = "", children, ...props }, ref) => {
|
|
2382
|
+
const {
|
|
2383
|
+
isOpen,
|
|
2384
|
+
setIsOpen,
|
|
2385
|
+
isFocused,
|
|
2386
|
+
setIsFocused,
|
|
2387
|
+
primaryColor,
|
|
2388
|
+
dropdownAnchorRef,
|
|
2389
|
+
disabled,
|
|
2390
|
+
isLoading,
|
|
2391
|
+
clearSelection,
|
|
2392
|
+
selectedValue,
|
|
2393
|
+
variant,
|
|
2394
|
+
inputRef
|
|
2395
|
+
} = useSearchApiContext();
|
|
2396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "relative", ref: dropdownAnchorRef, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2397
|
+
"div",
|
|
2398
|
+
{
|
|
2399
|
+
className: `flex items-center w-full px-0 text-gray-900 dark:text-white transition-all duration-200 cursor-text py-1 ${variant === "ghost" ? "bg-transparent border-transparent shadow-none px-0 h-full" : isFocused || isOpen ? "ring-2 bg-white dark:bg-zinc-900 border rounded-xl h-9" : "border-gray-200 dark:border-zinc-800 border rounded-xl bg-white dark:bg-zinc-900/50 h-9"} ${className}`,
|
|
2400
|
+
style: variant === "default" ? {
|
|
2401
|
+
borderColor: isFocused || isOpen ? primaryColor : void 0,
|
|
2402
|
+
boxShadow: isFocused || isOpen ? `${primaryColor}33 0px 0px 0px 2px` : void 0
|
|
2403
|
+
} : void 0,
|
|
2404
|
+
onClick: () => {
|
|
2405
|
+
if (disabled) return;
|
|
2406
|
+
inputRef.current?.focus();
|
|
2407
|
+
setIsOpen(true);
|
|
2408
|
+
},
|
|
2409
|
+
...props,
|
|
2410
|
+
children: [
|
|
2411
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2412
|
+
"div",
|
|
2329
2413
|
{
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
onChangeHandler: formOnChange,
|
|
2333
|
-
fieldInternalProps: { ref, onBlur }
|
|
2414
|
+
className: `${variant === "ghost" ? "pl-0" : "pl-2.5"} text-gray-400`,
|
|
2415
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Search, { className: "h-4 w-4" })
|
|
2334
2416
|
}
|
|
2335
|
-
)
|
|
2417
|
+
),
|
|
2418
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 relative ms-2", children }),
|
|
2419
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "pr-2.5 w-16! flex items-center gap-1 shrink-0 min-w-10 justify-end", children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Loader2, { className: "h-4 w-4 animate-spin text-blue-500 shrink-0" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
2420
|
+
selectedValue && !disabled && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2421
|
+
"button",
|
|
2422
|
+
{
|
|
2423
|
+
onClick: clearSelection,
|
|
2424
|
+
type: "button",
|
|
2425
|
+
className: "p-0.5 hover:bg-gray-200 dark:hover:bg-zinc-700 rounded-full text-gray-400 hover:text-gray-600 dark:hover:text-gray-300",
|
|
2426
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { className: "h-3 w-3" })
|
|
2427
|
+
}
|
|
2428
|
+
),
|
|
2429
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2430
|
+
import_lucide_react8.ChevronDown,
|
|
2431
|
+
{
|
|
2432
|
+
className: `h-4 w-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
2433
|
+
}
|
|
2434
|
+
)
|
|
2435
|
+
] }) })
|
|
2436
|
+
]
|
|
2437
|
+
}
|
|
2438
|
+
) });
|
|
2439
|
+
}
|
|
2440
|
+
);
|
|
2441
|
+
SearchApiTrigger.displayName = "SearchApiTrigger";
|
|
2442
|
+
var SearchApiInput = (0, import_react13.forwardRef)(
|
|
2443
|
+
({ className = "", ...props }, ref) => {
|
|
2444
|
+
const {
|
|
2445
|
+
isOpen,
|
|
2446
|
+
setIsOpen,
|
|
2447
|
+
isFocused,
|
|
2448
|
+
setIsFocused,
|
|
2449
|
+
searchTerm,
|
|
2450
|
+
setSearchTerm,
|
|
2451
|
+
disabled,
|
|
2452
|
+
selectedValue,
|
|
2453
|
+
getDisplayValue,
|
|
2454
|
+
placeholder,
|
|
2455
|
+
variant,
|
|
2456
|
+
activeIndex,
|
|
2457
|
+
setActiveIndex,
|
|
2458
|
+
options,
|
|
2459
|
+
handleSelect,
|
|
2460
|
+
inputRef,
|
|
2461
|
+
fieldInternalProps
|
|
2462
|
+
} = useSearchApiContext();
|
|
2463
|
+
const setInternalInputRef = (element) => {
|
|
2464
|
+
inputRef.current = element;
|
|
2465
|
+
if (fieldInternalProps?.ref) {
|
|
2466
|
+
if (typeof fieldInternalProps.ref === "function") {
|
|
2467
|
+
fieldInternalProps.ref(element);
|
|
2468
|
+
} else {
|
|
2469
|
+
fieldInternalProps.ref.current = element;
|
|
2336
2470
|
}
|
|
2337
|
-
|
|
2338
|
-
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2471
|
+
}
|
|
2472
|
+
};
|
|
2473
|
+
const handleKeyDown = (e) => {
|
|
2474
|
+
if (!isOpen) {
|
|
2475
|
+
if (e.key === "ArrowDown" || e.key === "Enter") setIsOpen(true);
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
switch (e.key) {
|
|
2479
|
+
case "ArrowDown":
|
|
2480
|
+
e.preventDefault();
|
|
2481
|
+
e.stopPropagation();
|
|
2482
|
+
setActiveIndex(
|
|
2483
|
+
activeIndex < options.length - 1 ? activeIndex + 1 : activeIndex
|
|
2484
|
+
);
|
|
2485
|
+
break;
|
|
2486
|
+
case "ArrowUp":
|
|
2487
|
+
e.preventDefault();
|
|
2488
|
+
e.stopPropagation();
|
|
2489
|
+
setActiveIndex(activeIndex > 0 ? activeIndex - 1 : activeIndex);
|
|
2490
|
+
break;
|
|
2491
|
+
case "Enter":
|
|
2492
|
+
e.preventDefault();
|
|
2493
|
+
e.stopPropagation();
|
|
2494
|
+
if (activeIndex >= 0 && activeIndex < options.length)
|
|
2495
|
+
handleSelect(options[activeIndex]);
|
|
2496
|
+
break;
|
|
2497
|
+
case "Escape":
|
|
2498
|
+
e.preventDefault();
|
|
2499
|
+
e.stopPropagation();
|
|
2500
|
+
setIsOpen(false);
|
|
2501
|
+
break;
|
|
2502
|
+
}
|
|
2503
|
+
};
|
|
2504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
2505
|
+
!isOpen && selectedValue && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "absolute inset-0 flex items-center ms-1 truncate select-none", children: getDisplayValue() }),
|
|
2506
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2507
|
+
"input",
|
|
2508
|
+
{
|
|
2509
|
+
ref: setInternalInputRef,
|
|
2510
|
+
type: "text",
|
|
2511
|
+
className: `block w-full bg-transparent border-none focus:ring-0 py-1 focus:outline-none text-sm placeholder-gray-400 dark:placeholder-zinc-500 ${!isOpen && selectedValue ? "opacity-0" : "opacity-100"} ${variant === "ghost" ? "h-full" : "h-9"} ${className}`,
|
|
2512
|
+
placeholder: !selectedValue ? placeholder : "",
|
|
2513
|
+
value: searchTerm,
|
|
2514
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
2515
|
+
onFocus: () => {
|
|
2516
|
+
setIsFocused(true);
|
|
2517
|
+
setIsOpen(true);
|
|
2518
|
+
},
|
|
2519
|
+
onKeyDown: handleKeyDown,
|
|
2520
|
+
disabled,
|
|
2521
|
+
...props
|
|
2522
|
+
}
|
|
2523
|
+
)
|
|
2524
|
+
] });
|
|
2525
|
+
}
|
|
2526
|
+
);
|
|
2527
|
+
SearchApiInput.displayName = "SearchApiInput";
|
|
2528
|
+
var SearchApiContent = (0, import_react13.forwardRef)(
|
|
2529
|
+
({ children, className = "", style, ...props }, ref) => {
|
|
2530
|
+
const {
|
|
2531
|
+
isOpen,
|
|
2532
|
+
setIsOpen,
|
|
2533
|
+
dropdownAnchorRef,
|
|
2534
|
+
dropdownContentRef,
|
|
2535
|
+
isLoading,
|
|
2536
|
+
searchTerm,
|
|
2537
|
+
options,
|
|
2538
|
+
error
|
|
2539
|
+
} = useSearchApiContext();
|
|
2540
|
+
const [dropdownStyle, setDropdownStyle] = (0, import_react13.useState)({});
|
|
2541
|
+
const updateDropdownPosition = () => {
|
|
2542
|
+
if (dropdownAnchorRef.current) {
|
|
2543
|
+
const rect = dropdownAnchorRef.current.getBoundingClientRect();
|
|
2544
|
+
const newStyle = {
|
|
2545
|
+
position: "fixed",
|
|
2546
|
+
top: `${rect.bottom + 4}px`,
|
|
2547
|
+
left: `${rect.left}px`,
|
|
2548
|
+
width: `${rect.width}px`,
|
|
2549
|
+
zIndex: 999999
|
|
2550
|
+
};
|
|
2551
|
+
if (rect.bottom + 240 > window.innerHeight) {
|
|
2552
|
+
newStyle.top = "auto";
|
|
2553
|
+
newStyle.bottom = `${window.innerHeight - rect.top + 4}px`;
|
|
2554
|
+
}
|
|
2555
|
+
setDropdownStyle(newStyle);
|
|
2556
|
+
}
|
|
2557
|
+
};
|
|
2558
|
+
(0, import_react13.useEffect)(() => {
|
|
2559
|
+
if (isOpen) {
|
|
2560
|
+
updateDropdownPosition();
|
|
2561
|
+
window.addEventListener("scroll", updateDropdownPosition, true);
|
|
2562
|
+
window.addEventListener("resize", updateDropdownPosition);
|
|
2563
|
+
return () => {
|
|
2564
|
+
window.removeEventListener("scroll", updateDropdownPosition, true);
|
|
2565
|
+
window.removeEventListener("resize", updateDropdownPosition);
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2568
|
+
}, [isOpen]);
|
|
2569
|
+
if (!isOpen || typeof document === "undefined") return null;
|
|
2570
|
+
return (0, import_react_dom2.createPortal)(
|
|
2571
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2572
|
+
"div",
|
|
2573
|
+
{
|
|
2574
|
+
ref: dropdownContentRef,
|
|
2575
|
+
className: `bg-white dark:bg-zinc-900 rounded-xl border border-gray-200 dark:border-zinc-800 shadow-lg max-h-60 overflow-y-auto overflow-x-hidden ${className}`,
|
|
2576
|
+
style: { ...dropdownStyle, ...style },
|
|
2577
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
2578
|
+
...props,
|
|
2579
|
+
children: isLoading && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "p-4 text-center text-sm text-gray-500", children: [
|
|
2580
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Loader2, { className: "h-5 w-5 animate-spin mx-auto mb-2" }),
|
|
2581
|
+
"Loading options..."
|
|
2582
|
+
] }) : import_react13.default.Children.count(children) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "py-1", children }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "p-4 text-center text-sm text-gray-500", children: error && options.length === 0 ? error : searchTerm ? `No results for "${searchTerm}"` : "No options available" })
|
|
2583
|
+
}
|
|
2584
|
+
),
|
|
2585
|
+
document.body
|
|
2586
|
+
);
|
|
2587
|
+
}
|
|
2588
|
+
);
|
|
2589
|
+
SearchApiContent.displayName = "SearchApiContent";
|
|
2590
|
+
var SearchApiItem = (0, import_react13.forwardRef)(
|
|
2591
|
+
({ option, index, className = "", ...props }, ref) => {
|
|
2592
|
+
const {
|
|
2593
|
+
selectedValue,
|
|
2594
|
+
activeIndex,
|
|
2595
|
+
setActiveIndex,
|
|
2596
|
+
handleSelect,
|
|
2597
|
+
primaryColor,
|
|
2598
|
+
labelKey,
|
|
2599
|
+
valueKey
|
|
2600
|
+
} = useSearchApiContext();
|
|
2601
|
+
const getOptionValue = (opt) => {
|
|
2602
|
+
if (valueKey === "_id" && opt._id === void 0 && opt.id !== void 0) {
|
|
2603
|
+
return opt.id;
|
|
2604
|
+
}
|
|
2605
|
+
return opt[valueKey];
|
|
2606
|
+
};
|
|
2607
|
+
const optValue = getOptionValue(option);
|
|
2608
|
+
const isSelected = selectedValue === optValue;
|
|
2609
|
+
const isHighlighted = index === activeIndex;
|
|
2610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2611
|
+
"button",
|
|
2341
2612
|
{
|
|
2613
|
+
ref,
|
|
2614
|
+
type: "button",
|
|
2615
|
+
className: `w-full text-left px-3 py-2 text-sm flex items-center justify-between transition-colors ${isSelected ? "font-medium" : isHighlighted ? "bg-gray-100 dark:bg-zinc-800 text-gray-900 dark:text-gray-100" : "text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-zinc-800"} ${className}`,
|
|
2616
|
+
style: isSelected && primaryColor ? {
|
|
2617
|
+
backgroundColor: `${primaryColor}1A`,
|
|
2618
|
+
color: primaryColor
|
|
2619
|
+
} : void 0,
|
|
2620
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
2621
|
+
onClick: (e) => {
|
|
2622
|
+
e.stopPropagation();
|
|
2623
|
+
e.preventDefault();
|
|
2624
|
+
handleSelect(option);
|
|
2625
|
+
},
|
|
2626
|
+
onMouseEnter: () => setActiveIndex(index),
|
|
2342
2627
|
...props,
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2628
|
+
children: [
|
|
2629
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate", children: option[labelKey] }),
|
|
2630
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Check, { className: "h-4 w-4", style: { color: primaryColor } })
|
|
2631
|
+
]
|
|
2632
|
+
},
|
|
2633
|
+
optValue || index
|
|
2347
2634
|
);
|
|
2348
2635
|
}
|
|
2349
2636
|
);
|
|
2350
|
-
|
|
2637
|
+
SearchApiItem.displayName = "SearchApiItem";
|
|
2351
2638
|
|
|
2352
2639
|
// src/components/Fields/date.tsx
|
|
2353
2640
|
var import_react14 = require("react");
|
|
@@ -2466,8 +2753,15 @@ var Fields = {
|
|
|
2466
2753
|
Input,
|
|
2467
2754
|
PhoneInput,
|
|
2468
2755
|
Select,
|
|
2756
|
+
SelectTrigger,
|
|
2757
|
+
SelectContent,
|
|
2758
|
+
SelectItem,
|
|
2469
2759
|
Textarea,
|
|
2470
2760
|
SearchApi,
|
|
2761
|
+
SearchApiTrigger,
|
|
2762
|
+
SearchApiInput,
|
|
2763
|
+
SearchApiContent,
|
|
2764
|
+
SearchApiItem,
|
|
2471
2765
|
DateInput
|
|
2472
2766
|
};
|
|
2473
2767
|
var Fields_default = Fields;
|
|
@@ -4069,7 +4363,14 @@ var generatePdf = async (elementId, options = {}) => {
|
|
|
4069
4363
|
PhoneInput,
|
|
4070
4364
|
PostTable,
|
|
4071
4365
|
SearchApi,
|
|
4366
|
+
SearchApiContent,
|
|
4367
|
+
SearchApiInput,
|
|
4368
|
+
SearchApiItem,
|
|
4369
|
+
SearchApiTrigger,
|
|
4072
4370
|
Select,
|
|
4371
|
+
SelectContent,
|
|
4372
|
+
SelectItem,
|
|
4373
|
+
SelectTrigger,
|
|
4073
4374
|
SimpleTable,
|
|
4074
4375
|
Textarea,
|
|
4075
4376
|
ThemeProvider,
|
|
@@ -4079,6 +4380,8 @@ var generatePdf = async (elementId, options = {}) => {
|
|
|
4079
4380
|
useA4StatementView,
|
|
4080
4381
|
useApi,
|
|
4081
4382
|
useModal,
|
|
4383
|
+
useSearchApiContext,
|
|
4384
|
+
useSelectContext,
|
|
4082
4385
|
useTheme,
|
|
4083
4386
|
useTransaction,
|
|
4084
4387
|
useWarqadConfig
|