@eztrak/shared 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -39,6 +39,8 @@ __export(src_exports, {
39
39
  ResetFiltersButton: () => ResetFiltersButton,
40
40
  SearchInput: () => SearchInput,
41
41
  TableLayoutToolbarControls: () => TableLayoutToolbarControls,
42
+ ToolTip: () => ToolTip,
43
+ TooltipText: () => TooltipText,
42
44
  capitalizeText: () => capitalizeText,
43
45
  checkIfExistsInArray: () => checkIfExistsInArray,
44
46
  cn: () => cn,
@@ -1316,23 +1318,117 @@ function Modal({
1316
1318
  return (0, import_react_dom.createPortal)(modalContent, modalRoot);
1317
1319
  }
1318
1320
 
1319
- // src/components/cell-editor/CustomCellEditor.tsx
1321
+ // src/components/tooltip/ToolTip.tsx
1320
1322
  var import_react6 = require("react");
1321
- var import_react_hot_toast2 = __toESM(require("react-hot-toast"));
1322
- var import_fa2 = require("react-icons/fa");
1323
+ var import_react_tooltip = require("react-tooltip");
1323
1324
  var import_jsx_runtime7 = require("react/jsx-runtime");
1325
+ var defaultTooltipStyle = {
1326
+ color: "#fff",
1327
+ borderRadius: "5px",
1328
+ zIndex: 999,
1329
+ textAlign: "justify",
1330
+ maxWidth: "300px",
1331
+ whiteSpace: "pre-wrap",
1332
+ wordWrap: "break-word",
1333
+ overflowWrap: "break-word"
1334
+ };
1335
+ function ToolTip({
1336
+ text = "tool tip",
1337
+ placement = "top",
1338
+ delayShow,
1339
+ delayHide,
1340
+ className,
1341
+ tooltipClassName,
1342
+ tooltipStyle,
1343
+ wrapperTabIndex,
1344
+ disabled = false,
1345
+ children
1346
+ }) {
1347
+ const generatedId = (0, import_react6.useId)();
1348
+ const tooltipId = `eztrak-tooltip-${generatedId.replace(/:/g, "")}`;
1349
+ const tooltipText = String(text ?? "");
1350
+ if (disabled || !tooltipText) {
1351
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className, children });
1352
+ }
1353
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1354
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1355
+ "span",
1356
+ {
1357
+ className,
1358
+ "data-tooltip-id": tooltipId,
1359
+ "data-tooltip-content": tooltipText,
1360
+ tabIndex: wrapperTabIndex,
1361
+ children
1362
+ }
1363
+ ),
1364
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1365
+ import_react_tooltip.Tooltip,
1366
+ {
1367
+ id: tooltipId,
1368
+ place: placement,
1369
+ delayShow,
1370
+ delayHide,
1371
+ className: tooltipClassName,
1372
+ style: { ...defaultTooltipStyle, ...tooltipStyle }
1373
+ }
1374
+ )
1375
+ ] });
1376
+ }
1377
+
1378
+ // src/components/tooltip/TooltipText.tsx
1379
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1380
+ function TooltipText({
1381
+ text = "",
1382
+ maxLength = 20,
1383
+ fallback = "-",
1384
+ placement = "top",
1385
+ delayShow,
1386
+ delayHide,
1387
+ className,
1388
+ textClassName,
1389
+ tooltipClassName,
1390
+ tooltipStyle,
1391
+ showTooltip = true,
1392
+ tooltipWhenTruncatedOnly = false
1393
+ }) {
1394
+ const hasValue = text !== null && text !== void 0 && text !== "";
1395
+ const fullText = hasValue ? String(text) : fallback;
1396
+ const displayText = truncateText(fullText, maxLength);
1397
+ const isTruncated = displayText !== fullText;
1398
+ const tooltipDisabled = !showTooltip || !hasValue || tooltipWhenTruncatedOnly && !isTruncated;
1399
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1400
+ ToolTip,
1401
+ {
1402
+ text: fullText,
1403
+ placement,
1404
+ delayShow,
1405
+ delayHide,
1406
+ className: cn("inline-block max-w-full", className),
1407
+ tooltipClassName,
1408
+ tooltipStyle,
1409
+ wrapperTabIndex: tooltipDisabled ? void 0 : 0,
1410
+ disabled: tooltipDisabled,
1411
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: cn("inline-block max-w-full align-bottom", textClassName), children: displayText })
1412
+ }
1413
+ );
1414
+ }
1415
+
1416
+ // src/components/cell-editor/CustomCellEditor.tsx
1417
+ var import_react7 = require("react");
1418
+ var import_react_hot_toast2 = __toESM(require("react-hot-toast"));
1419
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1324
1420
  function ButtonSpinner() {
1325
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1421
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1326
1422
  "svg",
1327
1423
  {
1328
1424
  className: "animate-spin",
1329
- width: 8,
1330
- height: 8,
1425
+ width: 12,
1426
+ height: 12,
1331
1427
  viewBox: "0 0 24 24",
1332
1428
  fill: "none",
1333
1429
  "aria-hidden": true,
1334
1430
  children: [
1335
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1431
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1336
1432
  "circle",
1337
1433
  {
1338
1434
  cx: "12",
@@ -1343,7 +1439,7 @@ function ButtonSpinner() {
1343
1439
  strokeOpacity: "0.25"
1344
1440
  }
1345
1441
  ),
1346
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1442
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1347
1443
  "path",
1348
1444
  {
1349
1445
  d: "M12 2a10 10 0 0 1 10 10",
@@ -1365,7 +1461,7 @@ function normalizeInitialValue(initialValue, inputType) {
1365
1461
  }
1366
1462
  return initialValue;
1367
1463
  }
1368
- var CustomCellEditor = (0, import_react6.forwardRef)(
1464
+ var CustomCellEditor = (0, import_react7.forwardRef)(
1369
1465
  ({
1370
1466
  value: initialValue,
1371
1467
  name,
@@ -1375,47 +1471,59 @@ var CustomCellEditor = (0, import_react6.forwardRef)(
1375
1471
  entityName = "Record",
1376
1472
  onSave,
1377
1473
  dropdownOptions = [],
1378
- className
1474
+ customOptions,
1475
+ valueKey = "value",
1476
+ labelKey = "label",
1477
+ containerStyle,
1478
+ className,
1479
+ inputClassName,
1480
+ loadingIndicator,
1481
+ saveButtonContent,
1482
+ cancelButtonContent,
1483
+ saveButtonStyle,
1484
+ cancelButtonStyle,
1485
+ saveButtonClassName,
1486
+ cancelButtonClassName
1379
1487
  }, ref) => {
1380
1488
  const normalizedInitial = normalizeInitialValue(initialValue, inputType);
1381
- const [value, setValue] = (0, import_react6.useState)(normalizedInitial);
1382
- const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
1383
- const inputRef = (0, import_react6.useRef)(null);
1384
- const selectRef = (0, import_react6.useRef)(null);
1385
- (0, import_react6.useImperativeHandle)(ref, () => ({
1489
+ const [value, setValue] = (0, import_react7.useState)(normalizedInitial);
1490
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
1491
+ const inputRef = (0, import_react7.useRef)(null);
1492
+ const selectRef = (0, import_react7.useRef)(null);
1493
+ const normalizedOptions = (0, import_react7.useMemo)(() => {
1494
+ if (customOptions && customOptions.length > 0) {
1495
+ return customOptions.map((opt) => ({
1496
+ value: String(opt[valueKey] ?? ""),
1497
+ label: String(opt[labelKey] ?? "")
1498
+ }));
1499
+ }
1500
+ return dropdownOptions;
1501
+ }, [customOptions, dropdownOptions, valueKey, labelKey]);
1502
+ const isDropdown = inputType === "dropdown" || normalizedOptions.length > 0;
1503
+ (0, import_react7.useImperativeHandle)(ref, () => ({
1386
1504
  getValue: () => value,
1387
1505
  isCancelBeforeStart: () => false,
1388
- isCancelAfterEnd: () => false
1506
+ isCancelAfterEnd: () => false,
1507
+ isPopup: () => true
1389
1508
  }));
1390
- (0, import_react6.useEffect)(() => {
1391
- if (inputType === "dropdown") {
1392
- const el2 = selectRef.current;
1393
- if (el2) {
1394
- el2.focus();
1395
- }
1509
+ (0, import_react7.useEffect)(() => {
1510
+ if (isDropdown) {
1511
+ selectRef.current?.focus();
1396
1512
  return;
1397
1513
  }
1398
1514
  const el = inputRef.current;
1399
- if (!el) {
1400
- return;
1401
- }
1515
+ if (!el) return;
1402
1516
  el.focus();
1403
1517
  if (inputType !== "date") {
1404
1518
  el.select();
1405
1519
  }
1406
- }, [inputType]);
1520
+ }, [isDropdown, inputType]);
1407
1521
  const handleSave = async () => {
1408
- if (isLoading) {
1409
- return;
1410
- }
1522
+ if (isLoading) return;
1411
1523
  if (String(value) === String(normalizedInitial)) {
1412
1524
  stopEditing();
1413
1525
  return;
1414
1526
  }
1415
- if (!entityId) {
1416
- import_react_hot_toast2.default.error("Entity ID is required");
1417
- return;
1418
- }
1419
1527
  if (!name) {
1420
1528
  import_react_hot_toast2.default.error("Property name is required");
1421
1529
  return;
@@ -1464,29 +1572,33 @@ var CustomCellEditor = (0, import_react6.forwardRef)(
1464
1572
  setValue(event.target.value);
1465
1573
  };
1466
1574
  const isSaveDisabled = isLoading || String(value) === String(normalizedInitial);
1467
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1575
+ const defaultInputClass = "w-48 px-2 py-1 text-sm border border-gray-200 rounded-md bg-white focus:outline-none focus:ring-1 focus:ring-blue-400";
1576
+ const defaultSaveBtnClass = "px-3 py-1 text-sm font-medium text-white bg-green-500 rounded-md hover:bg-green-600 disabled:opacity-50 whitespace-nowrap shrink-0";
1577
+ const defaultCancelBtnClass = "px-3 py-1 text-sm font-medium text-white bg-red-500 rounded-md hover:bg-red-600 disabled:opacity-50 whitespace-nowrap shrink-0";
1578
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1468
1579
  "div",
1469
1580
  {
1470
1581
  className: cn(
1471
- "flex items-center w-full h-full min-h-0 overflow-hidden gap-0.5 min-w-[80px]",
1582
+ "flex items-center gap-2 px-2 py-1 min-w-[320px] bg-white border border-gray-200 rounded-md shadow-md",
1472
1583
  className
1473
1584
  ),
1585
+ style: containerStyle,
1474
1586
  children: [
1475
- inputType === "dropdown" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1587
+ isDropdown ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1476
1588
  "select",
1477
1589
  {
1478
1590
  ref: selectRef,
1479
1591
  value: String(value),
1480
1592
  onChange: handleDropdownChange,
1481
1593
  onKeyDown: handleKeyDown,
1482
- className: "flex-1 h-full p-0 text-[10px] border border-gray-300 rounded-sm focus:outline-none focus:ring-1 focus:ring-blue-400 min-w-0 truncate",
1594
+ className: inputClassName ?? defaultInputClass,
1483
1595
  disabled: isLoading,
1484
1596
  children: [
1485
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", disabled: true, children: "Select option..." }),
1486
- dropdownOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1597
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: true, children: "Select option..." }),
1598
+ normalizedOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1487
1599
  ]
1488
1600
  }
1489
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1601
+ ) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1490
1602
  "input",
1491
1603
  {
1492
1604
  ref: inputRef,
@@ -1494,35 +1606,35 @@ var CustomCellEditor = (0, import_react6.forwardRef)(
1494
1606
  value: String(value),
1495
1607
  onChange: handleInputChange,
1496
1608
  onKeyDown: handleKeyDown,
1497
- className: "flex-1 h-full p-0 text-[10px] border border-gray-300 rounded-sm focus:outline-none focus:ring-1 focus:ring-blue-400 min-w-0 truncate",
1609
+ className: inputClassName ?? defaultInputClass,
1498
1610
  placeholder: "...",
1499
1611
  disabled: isLoading
1500
1612
  }
1501
1613
  ),
1502
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center shrink-0 gap-0.5", children: [
1503
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1504
- "button",
1505
- {
1506
- type: "button",
1507
- onClick: handleSave,
1508
- disabled: isSaveDisabled,
1509
- className: "flex items-center justify-center w-4 h-4 text-white bg-green-500 rounded-sm hover:bg-green-600 disabled:opacity-50",
1510
- title: "Save (Enter)",
1511
- children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ButtonSpinner, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_fa2.FaCheck, { size: 7, "aria-hidden": true })
1512
- }
1513
- ),
1514
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1515
- "button",
1516
- {
1517
- type: "button",
1518
- onClick: handleCancel,
1519
- disabled: isLoading,
1520
- className: "flex items-center justify-center w-4 h-4 text-white bg-red-500 rounded-sm hover:bg-red-600 disabled:opacity-50",
1521
- title: "Cancel (Escape)",
1522
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_fa2.FaTimes, { size: 7, "aria-hidden": true })
1523
- }
1524
- )
1525
- ] })
1614
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1615
+ "button",
1616
+ {
1617
+ type: "button",
1618
+ onClick: handleSave,
1619
+ disabled: isSaveDisabled,
1620
+ className: saveButtonClassName ?? (saveButtonStyle ? void 0 : defaultSaveBtnClass),
1621
+ style: saveButtonStyle,
1622
+ title: "Save (Enter)",
1623
+ children: isLoading ? loadingIndicator ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ButtonSpinner, {}) : saveButtonContent ?? "Save"
1624
+ }
1625
+ ),
1626
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1627
+ "button",
1628
+ {
1629
+ type: "button",
1630
+ onClick: handleCancel,
1631
+ disabled: isLoading,
1632
+ className: cancelButtonClassName ?? (cancelButtonStyle ? void 0 : defaultCancelBtnClass),
1633
+ style: cancelButtonStyle,
1634
+ title: "Cancel (Escape)",
1635
+ children: cancelButtonContent ?? "Cancel"
1636
+ }
1637
+ )
1526
1638
  ]
1527
1639
  }
1528
1640
  );
@@ -1540,6 +1652,8 @@ CustomCellEditor.displayName = "CustomCellEditor";
1540
1652
  ResetFiltersButton,
1541
1653
  SearchInput,
1542
1654
  TableLayoutToolbarControls,
1655
+ ToolTip,
1656
+ TooltipText,
1543
1657
  capitalizeText,
1544
1658
  checkIfExistsInArray,
1545
1659
  cn,