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