@expcat/tigercat-react 0.4.0 → 0.4.2

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.
Files changed (34) hide show
  1. package/dist/{chunk-ZTVATZB6.js → chunk-6OVVMHZJ.js} +137 -70
  2. package/dist/{chunk-ZGQOYCQT.mjs → chunk-FX2IBA4W.mjs} +1 -1
  3. package/dist/{chunk-PWZB45Z7.js → chunk-JQK354YN.js} +11 -9
  4. package/dist/chunk-PEGJ2KHC.js +273 -0
  5. package/dist/{chunk-3577FW3I.mjs → chunk-PJ7NS7NX.mjs} +139 -72
  6. package/dist/{chunk-IRH2ZVD3.js → chunk-Q7GUWWG5.js} +2 -2
  7. package/dist/chunk-RCNTRSUA.mjs +271 -0
  8. package/dist/chunk-SHT4TU3T.mjs +26 -0
  9. package/dist/{chunk-OUAZM7NY.mjs → chunk-SMC2RV3V.mjs} +12 -10
  10. package/dist/{chunk-OESNOOOT.js → chunk-YWTZALG5.js} +8 -4
  11. package/dist/components/ActivityFeed.js +4 -4
  12. package/dist/components/ActivityFeed.mjs +2 -2
  13. package/dist/components/DataTableWithToolbar.js +4 -4
  14. package/dist/components/DataTableWithToolbar.mjs +2 -2
  15. package/dist/components/InputNumber.d.mts +24 -0
  16. package/dist/components/InputNumber.d.ts +24 -0
  17. package/dist/components/InputNumber.js +10 -0
  18. package/dist/components/InputNumber.mjs +1 -0
  19. package/dist/components/Sidebar.js +2 -2
  20. package/dist/components/Sidebar.mjs +1 -1
  21. package/dist/components/SubMenu.js +2 -2
  22. package/dist/components/SubMenu.mjs +1 -1
  23. package/dist/components/Table.d.mts +5 -1
  24. package/dist/components/Table.d.ts +5 -1
  25. package/dist/components/Table.js +2 -2
  26. package/dist/components/Table.mjs +1 -1
  27. package/dist/index.d.mts +1 -0
  28. package/dist/index.d.ts +1 -0
  29. package/dist/index.js +45 -40
  30. package/dist/index.mjs +12 -11
  31. package/package.json +2 -2
  32. package/dist/chunk-RITTIFCJ.mjs +0 -22
  33. package/dist/{chunk-IOM7DWWQ.js → chunk-J3HKED4B.js} +1 -1
  34. package/dist/{chunk-FTY2W4L2.mjs → chunk-MTL2QUM3.mjs} +1 -1
@@ -66,12 +66,14 @@ function Table({
66
66
  stickyHeader = false,
67
67
  maxHeight,
68
68
  tableLayout = "auto",
69
+ expandable,
69
70
  onChange,
70
71
  onRowClick,
71
72
  onSelectionChange,
72
73
  onSortChange,
73
74
  onFilterChange,
74
75
  onPageChange,
76
+ onExpandedRowsChange,
75
77
  className,
76
78
  ...props
77
79
  }) {
@@ -124,6 +126,24 @@ function Table({
124
126
  setUncontrolledSelectedRowKeys(rowSelection?.selectedRowKeys ?? []);
125
127
  }
126
128
  }, [isSelectionControlled, rowSelection?.selectedRowKeys]);
129
+ const isExpandControlled = expandable?.expandedRowKeys !== void 0;
130
+ const [uncontrolledExpandedRowKeys, setUncontrolledExpandedRowKeys] = react.useState(expandable?.defaultExpandedRowKeys ?? expandable?.expandedRowKeys ?? []);
131
+ const expandedRowKeys = isExpandControlled ? expandable.expandedRowKeys : uncontrolledExpandedRowKeys;
132
+ const expandedRowKeySet = react.useMemo(
133
+ () => new Set(expandedRowKeys),
134
+ [expandedRowKeys]
135
+ );
136
+ const handleToggleExpand = react.useCallback(
137
+ (key) => {
138
+ const isExp = expandedRowKeySet.has(key);
139
+ const next = isExp ? expandedRowKeys.filter((k) => k !== key) : [...expandedRowKeys, key];
140
+ if (!isExpandControlled) {
141
+ setUncontrolledExpandedRowKeys(next);
142
+ }
143
+ onExpandedRowsChange?.(next);
144
+ },
145
+ [expandedRowKeys, expandedRowKeySet, isExpandControlled, onExpandedRowsChange]
146
+ );
127
147
  const [fixedOverrides, setFixedOverrides] = react.useState({});
128
148
  const displayColumns = react.useMemo(() => {
129
149
  return columns.map((column) => {
@@ -134,6 +154,12 @@ function Table({
134
154
  };
135
155
  });
136
156
  }, [columns, fixedOverrides]);
157
+ const totalColumnCount = react.useMemo(() => {
158
+ let count = displayColumns.length;
159
+ if (rowSelection && rowSelection.showCheckbox !== false) count++;
160
+ if (expandable) count++;
161
+ return count;
162
+ }, [displayColumns.length, rowSelection, expandable]);
137
163
  const columnByKey = react.useMemo(() => {
138
164
  const map = {};
139
165
  for (const column of displayColumns) {
@@ -345,6 +371,7 @@ function Table({
345
371
  }, [selectedRowKeys.length, allSelected]);
346
372
  const renderTableHeader = react.useCallback(() => {
347
373
  return /* @__PURE__ */ jsxRuntime.jsx("thead", { className: tigercatCore.getTableHeaderClasses(stickyHeader), children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
374
+ expandable && expandable.expandIconPosition !== "end" && /* @__PURE__ */ jsxRuntime.jsx("th", { className: tigercatCore.getExpandCellClasses(size) }),
348
375
  rowSelection && rowSelection.showCheckbox !== false && rowSelection.type !== "radio" && /* @__PURE__ */ jsxRuntime.jsx("th", { className: tigercatCore.getCheckboxCellClasses(size), children: /* @__PURE__ */ jsxRuntime.jsx(
349
376
  "input",
350
377
  {
@@ -437,7 +464,8 @@ function Table({
437
464
  },
438
465
  column.key
439
466
  );
440
- })
467
+ }),
468
+ expandable && expandable.expandIconPosition === "end" && /* @__PURE__ */ jsxRuntime.jsx("th", { className: tigercatCore.getExpandCellClasses(size) })
441
469
  ] }) });
442
470
  }, [
443
471
  displayColumns,
@@ -452,86 +480,121 @@ function Table({
452
480
  handleSelectAll,
453
481
  columnLockable,
454
482
  toggleColumnLock,
455
- fixedColumnsInfo
483
+ fixedColumnsInfo,
484
+ expandable
456
485
  ]);
457
486
  const renderTableBody = react.useCallback(() => {
458
487
  if (loading) {
459
488
  return null;
460
489
  }
461
490
  if (paginatedData.length === 0) {
462
- return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
463
- "td",
464
- {
465
- colSpan: displayColumns.length + (rowSelection ? 1 : 0),
466
- className: tigercatCore.tableEmptyStateClasses,
467
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", "aria-live": "polite", children: emptyText })
468
- }
469
- ) }) });
491
+ return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColumnCount, className: tigercatCore.tableEmptyStateClasses, children: /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", "aria-live": "polite", children: emptyText }) }) }) });
470
492
  }
493
+ const ExpandToggle = ({ rowKey: rk, expandableRow, expanded }) => expandableRow ? /* @__PURE__ */ jsxRuntime.jsx(
494
+ "button",
495
+ {
496
+ className: tigercatCore.classNames(tigercatCore.expandIconButtonClasses, tigercatCore.getExpandIconRotationClasses(expanded)),
497
+ "aria-label": expanded ? "Collapse row" : "Expand row",
498
+ onClick: (e) => {
499
+ e.stopPropagation();
500
+ handleToggleExpand(rk);
501
+ },
502
+ children: /* @__PURE__ */ jsxRuntime.jsx(
503
+ "svg",
504
+ {
505
+ xmlns: "http://www.w3.org/2000/svg",
506
+ viewBox: tigercatCore.icon16ViewBox,
507
+ fill: "currentColor",
508
+ className: "w-4 h-4",
509
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 3l6 5-6 5V3z" })
510
+ }
511
+ )
512
+ }
513
+ ) : null;
471
514
  return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: paginatedData.map((record, index) => {
472
515
  const key = pageRowKeys[index];
473
516
  const isSelected = selectedRowKeySet.has(key);
517
+ const isExpanded = expandedRowKeySet.has(key);
518
+ const isExpandableRow = expandable ? expandable.rowExpandable?.(record) ?? true : false;
474
519
  const rowClass = typeof rowClassName === "function" ? rowClassName(record, index) : rowClassName;
475
- return /* @__PURE__ */ jsxRuntime.jsxs(
476
- "tr",
477
- {
478
- className: tigercatCore.classNames(
479
- tigercatCore.getTableRowClasses(hoverable, striped, index % 2 === 0, rowClass),
480
- fixedColumnsInfo.hasFixedColumns && "group"
481
- ),
482
- onClick: () => handleRowClick(record, index),
483
- children: [
484
- rowSelection && rowSelection.showCheckbox !== false && /* @__PURE__ */ jsxRuntime.jsx("td", { className: tigercatCore.getCheckboxCellClasses(size), children: /* @__PURE__ */ jsxRuntime.jsx(
485
- "input",
486
- {
487
- type: rowSelection?.type === "radio" ? "radio" : "checkbox",
488
- className: rowSelection?.type === "radio" ? "border-gray-300 text-[var(--tiger-primary,#2563eb)] focus:ring-[var(--tiger-primary,#2563eb)]" : "rounded border-gray-300 text-[var(--tiger-primary,#2563eb)] focus:ring-[var(--tiger-primary,#2563eb)]",
489
- checked: isSelected,
490
- disabled: rowSelection?.getCheckboxProps?.(record)?.disabled,
491
- onChange: (e) => handleSelectRow(key, e.target.checked),
492
- onClick: (e) => e.stopPropagation()
493
- }
494
- ) }),
495
- displayColumns.map((column) => {
496
- const dataKey = column.dataKey || column.key;
497
- const cellValue = record[dataKey];
498
- const isFixedLeft = column.fixed === "left";
499
- const isFixedRight = column.fixed === "right";
500
- const fixedStyle = isFixedLeft ? {
501
- position: "sticky",
502
- left: `${fixedColumnsInfo.leftOffsets[column.key] || 0}px`,
503
- zIndex: 10
504
- } : isFixedRight ? {
505
- position: "sticky",
506
- right: `${fixedColumnsInfo.rightOffsets[column.key] || 0}px`,
507
- zIndex: 10
508
- } : void 0;
509
- const widthStyle = column.width ? {
510
- width: typeof column.width === "number" ? `${column.width}px` : column.width
511
- } : void 0;
512
- const style = fixedStyle ? { ...widthStyle, ...fixedStyle } : widthStyle;
513
- const stickyBgClass = striped && index % 2 === 0 ? "bg-[var(--tiger-surface-muted,#f9fafb)]/50" : "bg-[var(--tiger-surface,#ffffff)]";
514
- const stickyCellClass = isFixedLeft || isFixedRight ? tigercatCore.classNames(
515
- stickyBgClass,
516
- hoverable && "group-hover:bg-[var(--tiger-surface-muted,#f9fafb)]"
517
- ) : void 0;
518
- return /* @__PURE__ */ jsxRuntime.jsx(
519
- "td",
520
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
521
+ /* @__PURE__ */ jsxRuntime.jsxs(
522
+ "tr",
523
+ {
524
+ className: tigercatCore.classNames(
525
+ tigercatCore.getTableRowClasses(hoverable, striped, index % 2 === 0, rowClass),
526
+ fixedColumnsInfo.hasFixedColumns && "group"
527
+ ),
528
+ onClick: () => handleRowClick(record, index),
529
+ children: [
530
+ expandable && expandable.expandIconPosition !== "end" && /* @__PURE__ */ jsxRuntime.jsx("td", { className: tigercatCore.getExpandCellClasses(size), children: /* @__PURE__ */ jsxRuntime.jsx(
531
+ ExpandToggle,
520
532
  {
521
- className: tigercatCore.classNames(
522
- tigercatCore.getTableCellClasses(size, column.align || "left", column.className),
523
- stickyCellClass
524
- ),
525
- style,
526
- children: column.render ? column.render(record, index) : cellValue
527
- },
528
- column.key
529
- );
530
- })
531
- ]
532
- },
533
- key
534
- );
533
+ rowKey: key,
534
+ expandableRow: isExpandableRow,
535
+ expanded: isExpanded
536
+ }
537
+ ) }),
538
+ rowSelection && rowSelection.showCheckbox !== false && /* @__PURE__ */ jsxRuntime.jsx("td", { className: tigercatCore.getCheckboxCellClasses(size), children: /* @__PURE__ */ jsxRuntime.jsx(
539
+ "input",
540
+ {
541
+ type: rowSelection?.type === "radio" ? "radio" : "checkbox",
542
+ className: rowSelection?.type === "radio" ? "border-gray-300 text-[var(--tiger-primary,#2563eb)] focus:ring-[var(--tiger-primary,#2563eb)]" : "rounded border-gray-300 text-[var(--tiger-primary,#2563eb)] focus:ring-[var(--tiger-primary,#2563eb)]",
543
+ checked: isSelected,
544
+ disabled: rowSelection?.getCheckboxProps?.(record)?.disabled,
545
+ onChange: (e) => handleSelectRow(key, e.target.checked),
546
+ onClick: (e) => e.stopPropagation()
547
+ }
548
+ ) }),
549
+ displayColumns.map((column) => {
550
+ const dataKey = column.dataKey || column.key;
551
+ const cellValue = record[dataKey];
552
+ const isFixedLeft = column.fixed === "left";
553
+ const isFixedRight = column.fixed === "right";
554
+ const fixedStyle = isFixedLeft ? {
555
+ position: "sticky",
556
+ left: `${fixedColumnsInfo.leftOffsets[column.key] || 0}px`,
557
+ zIndex: 10
558
+ } : isFixedRight ? {
559
+ position: "sticky",
560
+ right: `${fixedColumnsInfo.rightOffsets[column.key] || 0}px`,
561
+ zIndex: 10
562
+ } : void 0;
563
+ const widthStyle = column.width ? {
564
+ width: typeof column.width === "number" ? `${column.width}px` : column.width
565
+ } : void 0;
566
+ const style = fixedStyle ? { ...widthStyle, ...fixedStyle } : widthStyle;
567
+ const stickyBgClass = striped && index % 2 === 0 ? "bg-[var(--tiger-surface-muted,#f9fafb)]/50" : "bg-[var(--tiger-surface,#ffffff)]";
568
+ const stickyCellClass = isFixedLeft || isFixedRight ? tigercatCore.classNames(
569
+ stickyBgClass,
570
+ hoverable && "group-hover:bg-[var(--tiger-surface-muted,#f9fafb)]"
571
+ ) : void 0;
572
+ return /* @__PURE__ */ jsxRuntime.jsx(
573
+ "td",
574
+ {
575
+ className: tigercatCore.classNames(
576
+ tigercatCore.getTableCellClasses(size, column.align || "left", column.className),
577
+ stickyCellClass
578
+ ),
579
+ style,
580
+ children: column.render ? column.render(record, index) : cellValue
581
+ },
582
+ column.key
583
+ );
584
+ }),
585
+ expandable && expandable.expandIconPosition === "end" && /* @__PURE__ */ jsxRuntime.jsx("td", { className: tigercatCore.getExpandCellClasses(size), children: /* @__PURE__ */ jsxRuntime.jsx(
586
+ ExpandToggle,
587
+ {
588
+ rowKey: key,
589
+ expandableRow: isExpandableRow,
590
+ expanded: isExpanded
591
+ }
592
+ ) })
593
+ ]
594
+ }
595
+ ),
596
+ expandable && isExpanded && isExpandableRow && /* @__PURE__ */ jsxRuntime.jsx("tr", { className: tigercatCore.expandedRowContentClasses, children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: totalColumnCount, children: expandable.expandedRowRender(record, index) }) })
597
+ ] }, key);
535
598
  }) });
536
599
  }, [
537
600
  loading,
@@ -547,7 +610,11 @@ function Table({
547
610
  size,
548
611
  handleRowClick,
549
612
  handleSelectRow,
550
- fixedColumnsInfo
613
+ fixedColumnsInfo,
614
+ expandable,
615
+ expandedRowKeySet,
616
+ handleToggleExpand,
617
+ totalColumnCount
551
618
  ]);
552
619
  const renderPagination = react.useCallback(() => {
553
620
  if (pagination === false || !paginationInfo) {
@@ -1,4 +1,4 @@
1
- import { Table } from './chunk-3577FW3I.mjs';
1
+ import { Table } from './chunk-PJ7NS7NX.mjs';
2
2
  import { Select } from './chunk-MDZDPGRK.mjs';
3
3
  import { Pagination } from './chunk-NZLOLMT2.mjs';
4
4
  import { Input } from './chunk-RPTLVIBF.mjs';
@@ -39,9 +39,9 @@ var SubMenu = ({
39
39
  const [isHovered, setIsHovered] = React.useState(false);
40
40
  const [isOpenByKeyboard, setIsOpenByKeyboard] = React.useState(false);
41
41
  const effectiveCollapsed = collapsedOverride ?? (menuContext ? menuContext.collapsed : false);
42
- const isPopup = !!menuContext && menuContext.mode === "vertical" && effectiveCollapsed;
42
+ const isPopup = !!menuContext && (menuContext.mode === "horizontal" || menuContext.mode === "vertical" && effectiveCollapsed);
43
43
  const isOpen = !!menuContext && tigercatCore.isKeyOpen(itemKey, menuContext.openKeys);
44
- const isExpanded = menuContext?.mode === "horizontal" || isPopup ? isHovered || isOpenByKeyboard : isOpen;
44
+ const isExpanded = isPopup ? isHovered || isOpenByKeyboard : isOpen;
45
45
  const isInlineOrVertical = menuContext?.mode !== "horizontal" && !isPopup;
46
46
  const [hasRenderedInline, setHasRenderedInline] = React.useState(
47
47
  () => isInlineOrVertical ? isExpanded : false
@@ -56,11 +56,13 @@ var SubMenu = ({
56
56
  }, [menuContext, disabled, className]);
57
57
  const contentClasses = React.useMemo(() => {
58
58
  if (!menuContext) return "";
59
- if (menuContext.mode === "horizontal") return tigercatCore.submenuContentHorizontalClasses;
59
+ if (menuContext.mode === "horizontal") {
60
+ return level === 0 ? tigercatCore.submenuContentHorizontalClasses : tigercatCore.submenuContentHorizontalNestedClasses;
61
+ }
60
62
  if (isPopup) return tigercatCore.submenuContentPopupClasses;
61
63
  if (menuContext.mode === "inline") return tigercatCore.submenuContentInlineClasses;
62
64
  return tigercatCore.submenuContentVerticalClasses;
63
- }, [menuContext, isPopup]);
65
+ }, [menuContext, isPopup, level]);
64
66
  const handleTitleClick = React.useCallback(() => {
65
67
  if (!menuContext || disabled) return;
66
68
  if (menuContext.mode === "horizontal") return;
@@ -185,19 +187,19 @@ var SubMenu = ({
185
187
  return React__default.default.cloneElement(
186
188
  child,
187
189
  {
188
- level: nextLevel,
189
- collapsed: isPopup ? false : void 0
190
+ level: nextLevel
190
191
  }
191
192
  );
192
193
  }
193
194
  return child;
194
195
  });
195
- if (menuContext.mode === "horizontal" || isPopup) {
196
+ const popupZIndex = isPopup ? tigercatCore.getSubmenuPopupZIndex(level) : {};
197
+ if (isPopup) {
196
198
  return /* @__PURE__ */ jsxRuntime.jsx(
197
199
  "ul",
198
200
  {
199
201
  className: contentClasses,
200
- style: { display: isExpanded ? "block" : "none" },
202
+ style: { display: isExpanded ? "block" : "none", ...popupZIndex },
201
203
  role: "menu",
202
204
  "aria-hidden": isExpanded ? void 0 : "true",
203
205
  children: enhancedChildren
@@ -222,7 +224,7 @@ var SubMenu = ({
222
224
  return /* @__PURE__ */ jsxRuntime.jsxs(
223
225
  "li",
224
226
  {
225
- className: menuContext.mode === "horizontal" || isPopup ? "relative" : "",
227
+ className: isPopup ? "relative" : "",
226
228
  onMouseEnter: handleMouseEnter,
227
229
  onMouseLeave: handleMouseLeave,
228
230
  role: "none",
@@ -0,0 +1,273 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var tigercatCore = require('@expcat/tigercat-core');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ // src/components/InputNumber.tsx
8
+ var InputNumber = ({
9
+ value: controlledValue,
10
+ defaultValue,
11
+ size = "md",
12
+ status = "default",
13
+ min = -Infinity,
14
+ max = Infinity,
15
+ step = 1,
16
+ precision,
17
+ disabled = false,
18
+ readonly = false,
19
+ placeholder,
20
+ name,
21
+ id,
22
+ keyboard = true,
23
+ controls = true,
24
+ controlsPosition = "right",
25
+ formatter,
26
+ parser,
27
+ autoFocus = false,
28
+ onChange,
29
+ onFocus,
30
+ onBlur,
31
+ className
32
+ }) => {
33
+ const isControlled = controlledValue !== void 0;
34
+ const inputRef = react.useRef(null);
35
+ const [focused, setFocused] = react.useState(false);
36
+ const [internalValue, setInternalValue] = react.useState(
37
+ defaultValue ?? controlledValue ?? null
38
+ );
39
+ const [displayValue, setDisplayValue] = react.useState("");
40
+ const currentValue = isControlled ? controlledValue ?? null : internalValue;
41
+ const toDisplayValue = react.useCallback(
42
+ (val) => {
43
+ if (val === null || val === void 0) return "";
44
+ if (formatter) return formatter(val);
45
+ if (precision !== void 0) return val.toFixed(precision);
46
+ return String(val);
47
+ },
48
+ [formatter, precision]
49
+ );
50
+ const parseValue = react.useCallback(
51
+ (str) => {
52
+ if (str === "" || str === "-") return null;
53
+ if (parser) return parser(str);
54
+ const num = Number(str);
55
+ return Number.isNaN(num) ? null : num;
56
+ },
57
+ [parser]
58
+ );
59
+ react.useEffect(() => {
60
+ if (!focused) {
61
+ setDisplayValue(toDisplayValue(currentValue));
62
+ }
63
+ }, [currentValue, focused, toDisplayValue]);
64
+ react.useEffect(() => {
65
+ if (autoFocus && inputRef.current) {
66
+ inputRef.current.focus();
67
+ }
68
+ }, [autoFocus]);
69
+ const commitValue = react.useCallback(
70
+ (val) => {
71
+ let finalVal = val;
72
+ if (finalVal !== null) {
73
+ finalVal = tigercatCore.clampValue(finalVal, min, max);
74
+ if (precision !== void 0) {
75
+ finalVal = tigercatCore.formatPrecision(finalVal, precision);
76
+ }
77
+ }
78
+ if (!isControlled) {
79
+ setInternalValue(finalVal);
80
+ }
81
+ onChange?.(finalVal);
82
+ setDisplayValue(toDisplayValue(finalVal));
83
+ },
84
+ [min, max, precision, isControlled, onChange, toDisplayValue]
85
+ );
86
+ const handleStep = react.useCallback(
87
+ (direction) => {
88
+ if (disabled || readonly) return;
89
+ const next = tigercatCore.stepValue(currentValue, step, direction, min, max, precision);
90
+ commitValue(next);
91
+ },
92
+ [currentValue, step, min, max, precision, disabled, readonly, commitValue]
93
+ );
94
+ const handleInput = react.useCallback((e) => {
95
+ setDisplayValue(e.target.value);
96
+ }, []);
97
+ const handleBlur = react.useCallback(
98
+ (e) => {
99
+ setFocused(false);
100
+ const parsed = parseValue(displayValue);
101
+ commitValue(parsed);
102
+ onBlur?.(e);
103
+ },
104
+ [displayValue, parseValue, commitValue, onBlur]
105
+ );
106
+ const handleFocus = react.useCallback(
107
+ (e) => {
108
+ setFocused(true);
109
+ if (formatter && currentValue !== null) {
110
+ setDisplayValue(String(currentValue));
111
+ }
112
+ onFocus?.(e);
113
+ },
114
+ [formatter, currentValue, onFocus]
115
+ );
116
+ const handleKeyDown = react.useCallback(
117
+ (e) => {
118
+ if (!keyboard || disabled || readonly) return;
119
+ if (e.key === "ArrowUp") {
120
+ e.preventDefault();
121
+ handleStep("up");
122
+ } else if (e.key === "ArrowDown") {
123
+ e.preventDefault();
124
+ handleStep("down");
125
+ } else if (e.key === "Enter") {
126
+ const parsed = parseValue(displayValue);
127
+ commitValue(parsed);
128
+ }
129
+ },
130
+ [keyboard, disabled, readonly, handleStep, parseValue, displayValue, commitValue]
131
+ );
132
+ const atMin = tigercatCore.isAtMin(currentValue, min);
133
+ const atMax = tigercatCore.isAtMax(currentValue, max);
134
+ const wrapperClasses = react.useMemo(
135
+ () => tigercatCore.classNames(
136
+ tigercatCore.getInputNumberWrapperClasses(disabled),
137
+ tigercatCore.getInputNumberStatusClasses(status),
138
+ tigercatCore.getInputNumberSizeClasses(size),
139
+ focused && `ring-2 ${tigercatCore.getInputNumberFocusRingColor(status)}`,
140
+ className
141
+ ),
142
+ [disabled, status, size, focused, className]
143
+ );
144
+ const inputClasses = react.useMemo(
145
+ () => tigercatCore.getInputNumberInputClasses(
146
+ size,
147
+ controls && controlsPosition === "right",
148
+ controls && controlsPosition === "both"
149
+ ),
150
+ [size, controls, controlsPosition]
151
+ );
152
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClasses, children: [
153
+ controls && controlsPosition === "both" && /* @__PURE__ */ jsxRuntime.jsx(
154
+ "button",
155
+ {
156
+ type: "button",
157
+ tabIndex: -1,
158
+ "aria-label": "Decrease",
159
+ className: tigercatCore.getInputNumberSideButtonClasses("left", disabled || atMin),
160
+ disabled: disabled || atMin,
161
+ onMouseDown: (e) => e.preventDefault(),
162
+ onClick: () => handleStep("down"),
163
+ children: /* @__PURE__ */ jsxRuntime.jsx(
164
+ "svg",
165
+ {
166
+ xmlns: "http://www.w3.org/2000/svg",
167
+ viewBox: "0 0 24 24",
168
+ fill: "none",
169
+ stroke: "currentColor",
170
+ strokeWidth: "2",
171
+ className: "w-4 h-4",
172
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: tigercatCore.inputNumberMinusIconPathD })
173
+ }
174
+ )
175
+ }
176
+ ),
177
+ /* @__PURE__ */ jsxRuntime.jsx(
178
+ "input",
179
+ {
180
+ ref: inputRef,
181
+ type: "text",
182
+ inputMode: "decimal",
183
+ role: "spinbutton",
184
+ "aria-valuemin": min === -Infinity ? void 0 : min,
185
+ "aria-valuemax": max === Infinity ? void 0 : max,
186
+ "aria-valuenow": currentValue ?? void 0,
187
+ className: inputClasses,
188
+ value: displayValue,
189
+ placeholder,
190
+ disabled,
191
+ readOnly: readonly,
192
+ name,
193
+ id,
194
+ onChange: handleInput,
195
+ onBlur: handleBlur,
196
+ onFocus: handleFocus,
197
+ onKeyDown: handleKeyDown
198
+ }
199
+ ),
200
+ controls && controlsPosition === "both" && /* @__PURE__ */ jsxRuntime.jsx(
201
+ "button",
202
+ {
203
+ type: "button",
204
+ tabIndex: -1,
205
+ "aria-label": "Increase",
206
+ className: tigercatCore.getInputNumberSideButtonClasses("right", disabled || atMax),
207
+ disabled: disabled || atMax,
208
+ onMouseDown: (e) => e.preventDefault(),
209
+ onClick: () => handleStep("up"),
210
+ children: /* @__PURE__ */ jsxRuntime.jsx(
211
+ "svg",
212
+ {
213
+ xmlns: "http://www.w3.org/2000/svg",
214
+ viewBox: "0 0 24 24",
215
+ fill: "none",
216
+ stroke: "currentColor",
217
+ strokeWidth: "2",
218
+ className: "w-4 h-4",
219
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: tigercatCore.inputNumberPlusIconPathD })
220
+ }
221
+ )
222
+ }
223
+ ),
224
+ controls && controlsPosition === "right" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tigercatCore.inputNumberControlsRightClasses, children: [
225
+ /* @__PURE__ */ jsxRuntime.jsx(
226
+ "button",
227
+ {
228
+ type: "button",
229
+ tabIndex: -1,
230
+ "aria-label": "Increase",
231
+ className: tigercatCore.getInputNumberStepButtonClasses("up", disabled || atMax),
232
+ disabled: disabled || atMax,
233
+ onMouseDown: (e) => e.preventDefault(),
234
+ onClick: () => handleStep("up"),
235
+ children: /* @__PURE__ */ jsxRuntime.jsx(
236
+ "svg",
237
+ {
238
+ xmlns: "http://www.w3.org/2000/svg",
239
+ viewBox: "0 0 24 24",
240
+ fill: "currentColor",
241
+ className: "w-3 h-3",
242
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: tigercatCore.inputNumberUpIconPathD })
243
+ }
244
+ )
245
+ }
246
+ ),
247
+ /* @__PURE__ */ jsxRuntime.jsx(
248
+ "button",
249
+ {
250
+ type: "button",
251
+ tabIndex: -1,
252
+ "aria-label": "Decrease",
253
+ className: tigercatCore.getInputNumberStepButtonClasses("down", disabled || atMin),
254
+ disabled: disabled || atMin,
255
+ onMouseDown: (e) => e.preventDefault(),
256
+ onClick: () => handleStep("down"),
257
+ children: /* @__PURE__ */ jsxRuntime.jsx(
258
+ "svg",
259
+ {
260
+ xmlns: "http://www.w3.org/2000/svg",
261
+ viewBox: "0 0 24 24",
262
+ fill: "currentColor",
263
+ className: "w-3 h-3",
264
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: tigercatCore.inputNumberDownIconPathD })
265
+ }
266
+ )
267
+ }
268
+ )
269
+ ] })
270
+ ] });
271
+ };
272
+
273
+ exports.InputNumber = InputNumber;