@papernote/ui 1.1.0 → 1.2.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.
Files changed (75) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +455 -455
  3. package/dist/components/CurrencyInput.d.ts +52 -0
  4. package/dist/components/CurrencyInput.d.ts.map +1 -0
  5. package/dist/components/DataTable.d.ts +3 -1
  6. package/dist/components/DataTable.d.ts.map +1 -1
  7. package/dist/components/Modal.d.ts.map +1 -1
  8. package/dist/components/Page.d.ts +2 -0
  9. package/dist/components/Page.d.ts.map +1 -1
  10. package/dist/components/PageLayout.d.ts +5 -1
  11. package/dist/components/PageLayout.d.ts.map +1 -1
  12. package/dist/components/index.d.ts +4 -0
  13. package/dist/components/index.d.ts.map +1 -1
  14. package/dist/index.d.ts +204 -4
  15. package/dist/index.esm.js +415 -88
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.js +413 -82
  18. package/dist/index.js.map +1 -1
  19. package/dist/styles.css +2877 -2675
  20. package/dist/utils/excelExport.d.ts +143 -0
  21. package/dist/utils/excelExport.d.ts.map +1 -0
  22. package/dist/utils/index.d.ts +2 -0
  23. package/dist/utils/index.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/AdminModal.css +49 -49
  26. package/src/components/CurrencyInput.stories.tsx +290 -0
  27. package/src/components/CurrencyInput.tsx +193 -0
  28. package/src/components/DataTable.tsx +78 -14
  29. package/src/components/Modal.stories.tsx +64 -0
  30. package/src/components/Modal.tsx +15 -2
  31. package/src/components/Page.stories.tsx +76 -0
  32. package/src/components/Page.tsx +35 -3
  33. package/src/components/PageLayout.stories.tsx +75 -0
  34. package/src/components/PageLayout.tsx +28 -9
  35. package/src/components/RoleManager.css +10 -10
  36. package/src/components/Spreadsheet.css +216 -216
  37. package/src/components/Spreadsheet.stories.tsx +362 -362
  38. package/src/components/Spreadsheet.tsx +351 -351
  39. package/src/components/SpreadsheetSimple.stories.tsx +27 -27
  40. package/src/components/Tabs.tsx +152 -152
  41. package/src/components/index.ts +5 -0
  42. package/src/styles/index.css +41 -4
  43. package/src/utils/excelExport.stories.tsx +535 -0
  44. package/src/utils/excelExport.ts +225 -0
  45. package/src/utils/index.ts +3 -0
  46. package/tailwind.config.js +253 -253
  47. package/dist/components/Button.stories.d.ts +0 -51
  48. package/dist/components/Button.stories.d.ts.map +0 -1
  49. package/dist/components/ChartVisualizationUI.d.ts +0 -21
  50. package/dist/components/ChartVisualizationUI.d.ts.map +0 -1
  51. package/dist/components/ChatUI.d.ts +0 -23
  52. package/dist/components/ChatUI.d.ts.map +0 -1
  53. package/dist/components/CommissionDashboardUI.d.ts +0 -25
  54. package/dist/components/CommissionDashboardUI.d.ts.map +0 -1
  55. package/dist/components/DataTable.stories.d.ts +0 -23
  56. package/dist/components/DataTable.stories.d.ts.map +0 -1
  57. package/dist/components/FormField.d.ts +0 -35
  58. package/dist/components/FormField.d.ts.map +0 -1
  59. package/dist/components/Input.stories.d.ts +0 -366
  60. package/dist/components/Input.stories.d.ts.map +0 -1
  61. package/dist/components/InsightsPanelUI.d.ts +0 -21
  62. package/dist/components/InsightsPanelUI.d.ts.map +0 -1
  63. package/dist/components/PaymentHistoryTimeline.d.ts +0 -34
  64. package/dist/components/PaymentHistoryTimeline.d.ts.map +0 -1
  65. package/dist/components/RelationshipManagerUI.d.ts +0 -60
  66. package/dist/components/RelationshipManagerUI.d.ts.map +0 -1
  67. package/dist/components/RoleManager.d.ts +0 -19
  68. package/dist/components/RoleManager.d.ts.map +0 -1
  69. package/dist/components/SplitCommissionBadge.d.ts +0 -18
  70. package/dist/components/SplitCommissionBadge.d.ts.map +0 -1
  71. package/dist/components/Spreadsheet.css +0 -216
  72. package/dist/components/__tests__/Button.test.d.ts +0 -2
  73. package/dist/components/__tests__/Button.test.d.ts.map +0 -1
  74. package/dist/components/__tests__/Input.test.d.ts +0 -2
  75. package/dist/components/__tests__/Input.test.d.ts.map +0 -1
package/dist/index.esm.js CHANGED
@@ -2530,6 +2530,7 @@ const sizeClasses$4 = {
2530
2530
  };
2531
2531
  function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton = true, animation = 'scale', }) {
2532
2532
  const modalRef = useRef(null);
2533
+ const mouseDownOnBackdrop = useRef(false);
2533
2534
  const titleId = useId();
2534
2535
  // Handle escape key
2535
2536
  useEffect(() => {
@@ -2547,11 +2548,22 @@ function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton
2547
2548
  document.body.style.overflow = 'unset';
2548
2549
  };
2549
2550
  }, [isOpen, onClose]);
2550
- // Handle click outside
2551
- const handleBackdropClick = (e) => {
2551
+ // Track if mousedown originated on the backdrop
2552
+ const handleBackdropMouseDown = (e) => {
2552
2553
  if (e.target === e.currentTarget) {
2554
+ mouseDownOnBackdrop.current = true;
2555
+ }
2556
+ else {
2557
+ mouseDownOnBackdrop.current = false;
2558
+ }
2559
+ };
2560
+ // Handle click outside - only close if both mousedown and click happened on backdrop
2561
+ const handleBackdropClick = (e) => {
2562
+ if (e.target === e.currentTarget && mouseDownOnBackdrop.current) {
2553
2563
  onClose();
2554
2564
  }
2565
+ // Reset the flag after handling click
2566
+ mouseDownOnBackdrop.current = false;
2555
2567
  };
2556
2568
  const getAnimationClass = () => {
2557
2569
  switch (animation) {
@@ -2571,7 +2583,7 @@ function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton
2571
2583
  };
2572
2584
  if (!isOpen)
2573
2585
  return null;
2574
- return (jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onClick: handleBackdropClick, children: jsxs("div", { ref: modalRef, className: `${sizeClasses$4[size]} w-full bg-white bg-subtle-grain rounded-xl shadow-2xl border border-paper-200 ${getAnimationClass()}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: [jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-paper-200", children: [jsx("h3", { id: titleId, className: "text-lg font-medium text-ink-900", children: title }), showCloseButton && (jsx("button", { onClick: onClose, className: "text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close modal", children: jsx(X, { className: "h-5 w-5" }) }))] }), jsx("div", { className: "px-6 py-4", children: children })] }) }));
2586
+ return (jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-ink-900 bg-opacity-50 backdrop-blur-sm animate-fade-in", onMouseDown: handleBackdropMouseDown, onClick: handleBackdropClick, children: jsxs("div", { ref: modalRef, className: `${sizeClasses$4[size]} w-full bg-white bg-subtle-grain rounded-xl shadow-2xl border border-paper-200 ${getAnimationClass()}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: [jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-paper-200", children: [jsx("h3", { id: titleId, className: "text-lg font-medium text-ink-900", children: title }), showCloseButton && (jsx("button", { onClick: onClose, className: "text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close modal", children: jsx(X, { className: "h-5 w-5" }) }))] }), jsx("div", { className: "px-6 py-4", children: children })] }) }));
2575
2587
  }
2576
2588
  function ModalFooter({ children }) {
2577
2589
  return (jsx("div", { className: "flex items-center justify-end gap-3 px-6 py-4 border-t border-paper-200 bg-paper-50", children: children }));
@@ -5956,19 +5968,19 @@ function Tabs({ tabs, activeTab: controlledActiveTab, defaultTab, variant = 'und
5956
5968
  spacing: orientation === 'vertical' ? 'mt-8' : 'mt-8',
5957
5969
  },
5958
5970
  };
5959
- return (jsxs("div", { className: `w-full ${orientation === 'vertical' ? `flex ${sizeClasses[size].gap}` : ''}`, children: [jsx("div", { className: `
5960
- flex ${orientation === 'vertical' ? 'flex-col' : ''}
5971
+ return (jsxs("div", { className: `w-full ${orientation === 'vertical' ? `flex ${sizeClasses[size].gap}` : ''}`, children: [jsx("div", { className: `
5972
+ flex ${orientation === 'vertical' ? 'flex-col' : ''}
5961
5973
  ${variant === 'underline'
5962
5974
  ? orientation === 'vertical'
5963
5975
  ? `border-r border-paper-200 ${sizeClasses[size].gap} pr-6`
5964
5976
  : `border-b border-paper-200 ${sizeClasses[size].gap}`
5965
- : `${sizeClasses[size].gap} p-1 bg-paper-50 rounded-lg`}
5966
- ${sizeClasses[size].minWidth}
5977
+ : `${sizeClasses[size].gap} p-1 bg-paper-50 rounded-lg`}
5978
+ ${sizeClasses[size].minWidth}
5967
5979
  `, role: "tablist", children: tabs.map((tab) => {
5968
5980
  const isActive = activeTab === tab.id;
5969
- return (jsxs("button", { role: "tab", "aria-selected": isActive, "aria-controls": `panel-${tab.id}`, disabled: tab.disabled, onClick: () => !tab.disabled && handleTabChange(tab.id), className: `
5970
- flex items-center gap-2 ${sizeClasses[size].padding} ${sizeClasses[size].text} font-medium transition-all duration-200
5971
- ${orientation === 'vertical' ? 'w-full justify-start' : ''}
5981
+ return (jsxs("button", { role: "tab", "aria-selected": isActive, "aria-controls": `panel-${tab.id}`, disabled: tab.disabled, onClick: () => !tab.disabled && handleTabChange(tab.id), className: `
5982
+ flex items-center gap-2 ${sizeClasses[size].padding} ${sizeClasses[size].text} font-medium transition-all duration-200
5983
+ ${orientation === 'vertical' ? 'w-full justify-start' : ''}
5972
5984
  ${variant === 'underline'
5973
5985
  ? isActive
5974
5986
  ? orientation === 'vertical'
@@ -5979,8 +5991,8 @@ function Tabs({ tabs, activeTab: controlledActiveTab, defaultTab, variant = 'und
5979
5991
  : 'text-ink-600 hover:text-ink-900 border-b-2 border-transparent'
5980
5992
  : isActive
5981
5993
  ? 'bg-white text-accent-900 rounded-md shadow-xs'
5982
- : 'text-ink-600 hover:text-ink-900 hover:bg-white/50 rounded-md'}
5983
- ${tab.disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
5994
+ : 'text-ink-600 hover:text-ink-900 hover:bg-white/50 rounded-md'}
5995
+ ${tab.disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
5984
5996
  `, children: [tab.icon && jsx("span", { className: `flex-shrink-0 ${sizeClasses[size].icon}`, children: tab.icon }), jsx("span", { children: tab.label })] }, tab.id));
5985
5997
  }) }), jsx("div", { className: `${orientation === 'vertical' ? 'flex-1' : sizeClasses[size].spacing}`, children: tabs.map((tab) => (jsx("div", { id: `panel-${tab.id}`, role: "tabpanel", "aria-labelledby": tab.id, hidden: activeTab !== tab.id, className: activeTab === tab.id ? 'animate-fade-in' : '', children: activeTab === tab.id && tab.content }, tab.id))) })] }));
5986
5998
  }
@@ -6908,8 +6920,35 @@ const TwoColumnContent = ({ sidebar, children, className = '', }) => {
6908
6920
  * </PageLayout>
6909
6921
  * ```
6910
6922
  */
6911
- const Page = ({ children, maxWidth: _maxWidth = '7xl', className = '', padding: _padding = 'normal' }) => {
6912
- return (jsx("div", { className: "min-h-screen bg-paper-100", children: jsx("div", { className: `notebook-page notebook-margin notebook-ruled ${className}`, children: children }) }));
6923
+ const Page = ({ children, maxWidth = '7xl', className = '', padding = 'normal', fixed = false }) => {
6924
+ // Max width classes
6925
+ const maxWidthClasses = {
6926
+ '4xl': 'max-w-4xl',
6927
+ '5xl': 'max-w-5xl',
6928
+ '6xl': 'max-w-6xl',
6929
+ '7xl': 'max-w-7xl',
6930
+ 'full': 'max-w-full',
6931
+ };
6932
+ // Padding classes - responsive (fixed left/top, responsive right/bottom) vs all fixed
6933
+ const paddingClasses = {
6934
+ none: fixed ? 'p-0' : 'pt-0 pl-0 pr-0 pb-0',
6935
+ sm: fixed ? 'p-4' : 'pt-4 pl-4 pr-4 pb-4 sm:pr-6 md:pr-8 sm:pb-6 md:pb-8',
6936
+ normal: fixed ? 'pt-12 pl-20 pr-16 pb-12' : 'pt-12 pl-20 pr-4 pb-4 sm:pr-8 md:pr-12 lg:pr-16 sm:pb-8 md:pb-12 lg:pb-16',
6937
+ lg: fixed ? 'pt-16 pl-24 pr-20 pb-16' : 'pt-16 pl-24 pr-6 pb-6 sm:pr-12 md:pr-16 lg:pr-20 sm:pb-12 md:pb-16 lg:pb-20',
6938
+ };
6939
+ // Margin classes - responsive (fixed left/top, responsive right/bottom) vs all fixed
6940
+ const marginClasses = fixed
6941
+ ? 'mt-4 ml-4 mr-4 mb-4'
6942
+ : 'mt-4 ml-4 mr-4 mb-4 sm:mr-6 md:mr-8 lg:mr-auto sm:mb-6 md:mb-8';
6943
+ return (jsx("div", { className: "min-h-screen bg-paper-100", children: jsx("div", { className: `
6944
+ bg-white bg-subtle-grain rounded-sm shadow-lg border-l-4 border-paper-300
6945
+ min-h-[calc(100vh-2rem)] relative
6946
+ notebook-margin notebook-ruled
6947
+ ${maxWidthClasses[maxWidth]}
6948
+ ${paddingClasses[padding]}
6949
+ ${marginClasses}
6950
+ ${className}
6951
+ `.trim().replace(/\s+/g, ' '), children: children }) }));
6913
6952
  };
6914
6953
 
6915
6954
  /**
@@ -7244,7 +7283,7 @@ function getColumnStyle(column, dynamicWidth) {
7244
7283
  * />
7245
7284
  * ```
7246
7285
  */
7247
- function DataTable({ data, columns, loading = false, error = null, emptyMessage = 'No data available', loadingRows = 5, className = '', onSortChange, currentSort = null, onEdit, onDelete, actions = [], onRowClick, onRowDoubleClick, selectable = false, selectedRows: externalSelectedRows, onRowSelect, keyExtractor, expandable = false, expandedRows: externalExpandedRows, renderExpandedRow, expandedRowConfig, showExpandChevron = false,
7286
+ function DataTable({ data, columns, loading = false, error = null, emptyMessage = 'No data available', loadingRows = 5, className = '', onSortChange, currentSort = null, onEdit, onDelete, actions = [], enableContextMenu = true, onRowClick, onRowDoubleClick, selectable = false, selectedRows: externalSelectedRows, onRowSelect, keyExtractor, expandable = false, expandedRows: externalExpandedRows, renderExpandedRow, expandedRowConfig, showExpandChevron = false,
7248
7287
  // Visual customization props
7249
7288
  striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, highlightedRowId, bordered = false, borderColor = 'border-paper-200', disableHover = false, hiddenColumns = [], headerClassName = '', renderEmptyState: customRenderEmptyState, resizable = false, onColumnResize, reorderable = false, onColumnReorder, virtualized = false, virtualHeight = '600px', virtualRowHeight = 60, }) {
7250
7289
  // Column resizing state
@@ -7261,6 +7300,12 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
7261
7300
  const tableContainerRef = useRef(null);
7262
7301
  // Row hover state (for coordinating primary + secondary row highlighting)
7263
7302
  const [hoveredRowKey, setHoveredRowKey] = useState(null);
7303
+ // Context menu state
7304
+ const [contextMenuState, setContextMenuState] = useState({
7305
+ isOpen: false,
7306
+ position: { x: 0, y: 0 },
7307
+ item: null,
7308
+ });
7264
7309
  // Filter columns based on hiddenColumns
7265
7310
  const baseVisibleColumns = columns.filter(col => !hiddenColumns.includes(String(col.key)));
7266
7311
  // Initialize column order on mount or when columns change
@@ -7483,6 +7528,28 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
7483
7528
  });
7484
7529
  }
7485
7530
  const allActions = [...builtInActions, ...actions];
7531
+ // Convert actions to menu items for context menu
7532
+ const convertActionsToMenuItems = (item) => {
7533
+ const visibleActions = allActions.filter(action => !action.show || action.show(item));
7534
+ return visibleActions.map((action, idx) => {
7535
+ let iconElement = null;
7536
+ if (action.icon) {
7537
+ if (React__default.isValidElement(action.icon)) {
7538
+ iconElement = action.icon;
7539
+ }
7540
+ else {
7541
+ iconElement = React__default.createElement(action.icon, { className: 'h-4 w-4' });
7542
+ }
7543
+ }
7544
+ return {
7545
+ id: `action-${idx}`,
7546
+ label: action.label,
7547
+ icon: iconElement,
7548
+ onClick: () => action.onClick(item),
7549
+ danger: action.variant === 'danger',
7550
+ };
7551
+ });
7552
+ };
7486
7553
  // Selection state management
7487
7554
  const [internalSelectedRows, setInternalSelectedRows] = useState(new Set());
7488
7555
  // Expansion state management
@@ -7640,7 +7707,19 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
7640
7707
  // Hover state for row pair (primary + secondary)
7641
7708
  const isHovered = hoveredRowKey === rowKey;
7642
7709
  const hoverClass = disableHover ? '' : (isHovered ? 'bg-paper-100' : '');
7643
- return (jsxs(React__default.Fragment, { children: [jsxs("tr", { className: `table-row-stable ${onRowDoubleClick || onRowClick || onEdit || expandedRowConfig?.edit || expandedRowConfig?.details || expandedRowConfig?.addRelated?.length || expandedRowConfig?.manageRelated?.length ? 'cursor-pointer' : ''} ${isSelected ? 'bg-accent-50 border-l-2 border-accent-500' : hoverClass || rowBgClass} ${borderClass}`, onMouseEnter: () => !disableHover && setHoveredRowKey(rowKey), onMouseLeave: () => !disableHover && setHoveredRowKey(null), onClick: () => onRowClick?.(item), onDoubleClick: () => {
7710
+ return (jsxs(React__default.Fragment, { children: [jsxs("tr", { className: `table-row-stable ${onRowDoubleClick || onRowClick || onEdit || expandedRowConfig?.edit || expandedRowConfig?.details || expandedRowConfig?.addRelated?.length || expandedRowConfig?.manageRelated?.length ? 'cursor-pointer' : ''} ${isSelected ? 'bg-accent-50 border-l-2 border-accent-500' : hoverClass || rowBgClass} ${borderClass}`, onMouseEnter: () => !disableHover && setHoveredRowKey(rowKey), onMouseLeave: () => !disableHover && setHoveredRowKey(null), onClick: () => onRowClick?.(item), onContextMenu: (e) => {
7711
+ if (enableContextMenu && allActions.length > 0) {
7712
+ e.preventDefault();
7713
+ e.stopPropagation();
7714
+ const x = e.clientX;
7715
+ const y = e.clientY;
7716
+ setContextMenuState({
7717
+ isOpen: true,
7718
+ position: { x, y },
7719
+ item,
7720
+ });
7721
+ }
7722
+ }, onDoubleClick: () => {
7644
7723
  // Priority 1: If there's an onEdit handler (legacy), trigger it
7645
7724
  if (onEdit) {
7646
7725
  onEdit(item);
@@ -7796,10 +7875,9 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
7796
7875
  }, children: jsx("div", { className: "absolute right-0 top-0 bottom-0 w-1 bg-paper-300 group-hover:bg-accent-400 transition-colors" }) }))] }, columnKey));
7797
7876
  })] }) }), jsx("tbody", { className: "bg-white table-loading transition-opacity duration-200", children: loading && data.length === 0 ? (renderLoadingSkeleton()) : data.length === 0 ? (renderEmptyStateContent()) : (renderDataRows()) })] })] }));
7798
7877
  // Wrap in scrollable container if virtualized
7799
- if (virtualized) {
7800
- return (jsx("div", { ref: tableContainerRef, onScroll: handleScroll, style: { height: virtualHeight, overflow: 'auto' }, className: "rounded-lg", children: tableContent }));
7801
- }
7802
- return tableContent;
7878
+ const finalContent = virtualized ? (jsx("div", { ref: tableContainerRef, onScroll: handleScroll, style: { height: virtualHeight, overflow: 'auto' }, className: "rounded-lg", children: tableContent })) : tableContent;
7879
+ // Render with context menu
7880
+ return (jsxs(Fragment, { children: [finalContent, contextMenuState.isOpen && contextMenuState.item && (jsx(Menu, { items: convertActionsToMenuItems(contextMenuState.item), position: contextMenuState.position, onClose: () => setContextMenuState({ isOpen: false, position: { x: 0, y: 0 }, item: null }) }))] }));
7803
7881
  }
7804
7882
 
7805
7883
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -11611,12 +11689,12 @@ var bessel$1 = {};
11611
11689
 
11612
11690
  /* bessel.js (C) 2013-present SheetJS -- http://sheetjs.com */
11613
11691
 
11614
- (function (exports) {
11692
+ (function (exports$1) {
11615
11693
  (function (factory) {
11616
11694
  /*jshint ignore:start */
11617
11695
  if(typeof DO_NOT_EXPORT_BESSEL === 'undefined') {
11618
11696
  {
11619
- factory(exports);
11697
+ factory(exports$1);
11620
11698
  }
11621
11699
  } else {
11622
11700
  factory({});
@@ -11850,7 +11928,7 @@ var bessel$1 = {};
11850
11928
 
11851
11929
  var jstat = {exports: {}};
11852
11930
 
11853
- (function (module, exports) {
11931
+ (function (module, exports$1) {
11854
11932
  (function (window, factory) {
11855
11933
  {
11856
11934
  module.exports = factory();
@@ -30467,7 +30545,7 @@ var hooks = {
30467
30545
  DepParser: DepParser$1,
30468
30546
  };
30469
30547
 
30470
- const {FormulaParser} = hooks$1;
30548
+ const {FormulaParser: FormulaParser$1} = hooks$1;
30471
30549
  const {DepParser} = hooks;
30472
30550
  const SSF = ssf$1;
30473
30551
  const FormulaError = requireError();
@@ -30477,16 +30555,16 @@ const FormulaError = requireError();
30477
30555
  // `\nTotal: ${funs.length}/477, ${funs.length/477*100}% implemented.`);
30478
30556
 
30479
30557
 
30480
- Object.assign(FormulaParser, {
30558
+ Object.assign(FormulaParser$1, {
30481
30559
  MAX_ROW: 1048576,
30482
30560
  MAX_COLUMN: 16384,
30483
30561
  SSF,
30484
30562
  DepParser,
30485
30563
  FormulaError, ...requireHelpers()
30486
30564
  });
30487
- var fastFormulaParser = FormulaParser;
30565
+ var fastFormulaParser = FormulaParser$1;
30488
30566
 
30489
- var FormulaParser$1 = /*@__PURE__*/getDefaultExportFromCjs(fastFormulaParser);
30567
+ var FormulaParser = /*@__PURE__*/getDefaultExportFromCjs(fastFormulaParser);
30490
30568
 
30491
30569
  var scheduler = {exports: {}};
30492
30570
 
@@ -30507,7 +30585,7 @@ var hasRequiredScheduler_production;
30507
30585
  function requireScheduler_production () {
30508
30586
  if (hasRequiredScheduler_production) return scheduler_production;
30509
30587
  hasRequiredScheduler_production = 1;
30510
- (function (exports) {
30588
+ (function (exports$1) {
30511
30589
  function push(heap, node) {
30512
30590
  var index = heap.length;
30513
30591
  heap.push(node);
@@ -30556,16 +30634,16 @@ function requireScheduler_production () {
30556
30634
  var diff = a.sortIndex - b.sortIndex;
30557
30635
  return 0 !== diff ? diff : a.id - b.id;
30558
30636
  }
30559
- exports.unstable_now = void 0;
30637
+ exports$1.unstable_now = void 0;
30560
30638
  if ("object" === typeof performance && "function" === typeof performance.now) {
30561
30639
  var localPerformance = performance;
30562
- exports.unstable_now = function () {
30640
+ exports$1.unstable_now = function () {
30563
30641
  return localPerformance.now();
30564
30642
  };
30565
30643
  } else {
30566
30644
  var localDate = Date,
30567
30645
  initialTime = localDate.now();
30568
- exports.unstable_now = function () {
30646
+ exports$1.unstable_now = function () {
30569
30647
  return localDate.now() - initialTime;
30570
30648
  };
30571
30649
  }
@@ -30613,14 +30691,14 @@ function requireScheduler_production () {
30613
30691
  function shouldYieldToHost() {
30614
30692
  return needsPaint
30615
30693
  ? true
30616
- : exports.unstable_now() - startTime < frameInterval
30694
+ : exports$1.unstable_now() - startTime < frameInterval
30617
30695
  ? false
30618
30696
  : true;
30619
30697
  }
30620
30698
  function performWorkUntilDeadline() {
30621
30699
  needsPaint = false;
30622
30700
  if (isMessageLoopRunning) {
30623
- var currentTime = exports.unstable_now();
30701
+ var currentTime = exports$1.unstable_now();
30624
30702
  startTime = currentTime;
30625
30703
  var hasMoreWork = true;
30626
30704
  try {
@@ -30650,7 +30728,7 @@ function requireScheduler_production () {
30650
30728
  var continuationCallback = callback(
30651
30729
  currentTask.expirationTime <= currentTime
30652
30730
  );
30653
- currentTime = exports.unstable_now();
30731
+ currentTime = exports$1.unstable_now();
30654
30732
  if ("function" === typeof continuationCallback) {
30655
30733
  currentTask.callback = continuationCallback;
30656
30734
  advanceTimers(currentTime);
@@ -30706,29 +30784,29 @@ function requireScheduler_production () {
30706
30784
  };
30707
30785
  function requestHostTimeout(callback, ms) {
30708
30786
  taskTimeoutID = localSetTimeout(function () {
30709
- callback(exports.unstable_now());
30787
+ callback(exports$1.unstable_now());
30710
30788
  }, ms);
30711
30789
  }
30712
- exports.unstable_IdlePriority = 5;
30713
- exports.unstable_ImmediatePriority = 1;
30714
- exports.unstable_LowPriority = 4;
30715
- exports.unstable_NormalPriority = 3;
30716
- exports.unstable_Profiling = null;
30717
- exports.unstable_UserBlockingPriority = 2;
30718
- exports.unstable_cancelCallback = function (task) {
30790
+ exports$1.unstable_IdlePriority = 5;
30791
+ exports$1.unstable_ImmediatePriority = 1;
30792
+ exports$1.unstable_LowPriority = 4;
30793
+ exports$1.unstable_NormalPriority = 3;
30794
+ exports$1.unstable_Profiling = null;
30795
+ exports$1.unstable_UserBlockingPriority = 2;
30796
+ exports$1.unstable_cancelCallback = function (task) {
30719
30797
  task.callback = null;
30720
30798
  };
30721
- exports.unstable_forceFrameRate = function (fps) {
30799
+ exports$1.unstable_forceFrameRate = function (fps) {
30722
30800
  0 > fps || 125 < fps
30723
30801
  ? console.error(
30724
30802
  "forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"
30725
30803
  )
30726
30804
  : (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);
30727
30805
  };
30728
- exports.unstable_getCurrentPriorityLevel = function () {
30806
+ exports$1.unstable_getCurrentPriorityLevel = function () {
30729
30807
  return currentPriorityLevel;
30730
30808
  };
30731
- exports.unstable_next = function (eventHandler) {
30809
+ exports$1.unstable_next = function (eventHandler) {
30732
30810
  switch (currentPriorityLevel) {
30733
30811
  case 1:
30734
30812
  case 2:
@@ -30746,10 +30824,10 @@ function requireScheduler_production () {
30746
30824
  currentPriorityLevel = previousPriorityLevel;
30747
30825
  }
30748
30826
  };
30749
- exports.unstable_requestPaint = function () {
30827
+ exports$1.unstable_requestPaint = function () {
30750
30828
  needsPaint = true;
30751
30829
  };
30752
- exports.unstable_runWithPriority = function (priorityLevel, eventHandler) {
30830
+ exports$1.unstable_runWithPriority = function (priorityLevel, eventHandler) {
30753
30831
  switch (priorityLevel) {
30754
30832
  case 1:
30755
30833
  case 2:
@@ -30768,12 +30846,12 @@ function requireScheduler_production () {
30768
30846
  currentPriorityLevel = previousPriorityLevel;
30769
30847
  }
30770
30848
  };
30771
- exports.unstable_scheduleCallback = function (
30849
+ exports$1.unstable_scheduleCallback = function (
30772
30850
  priorityLevel,
30773
30851
  callback,
30774
30852
  options
30775
30853
  ) {
30776
- var currentTime = exports.unstable_now();
30854
+ var currentTime = exports$1.unstable_now();
30777
30855
  "object" === typeof options && null !== options
30778
30856
  ? ((options = options.delay),
30779
30857
  (options =
@@ -30824,8 +30902,8 @@ function requireScheduler_production () {
30824
30902
  ((isMessageLoopRunning = true), schedulePerformWorkUntilDeadline())));
30825
30903
  return priorityLevel;
30826
30904
  };
30827
- exports.unstable_shouldYield = shouldYieldToHost;
30828
- exports.unstable_wrapCallback = function (callback) {
30905
+ exports$1.unstable_shouldYield = shouldYieldToHost;
30906
+ exports$1.unstable_wrapCallback = function (callback) {
30829
30907
  var parentPriorityLevel = currentPriorityLevel;
30830
30908
  return function () {
30831
30909
  var previousPriorityLevel = currentPriorityLevel;
@@ -30858,13 +30936,13 @@ var hasRequiredScheduler_development;
30858
30936
  function requireScheduler_development () {
30859
30937
  if (hasRequiredScheduler_development) return scheduler_development;
30860
30938
  hasRequiredScheduler_development = 1;
30861
- (function (exports) {
30939
+ (function (exports$1) {
30862
30940
  "production" !== process.env.NODE_ENV &&
30863
30941
  (function () {
30864
30942
  function performWorkUntilDeadline() {
30865
30943
  needsPaint = false;
30866
30944
  if (isMessageLoopRunning) {
30867
- var currentTime = exports.unstable_now();
30945
+ var currentTime = exports$1.unstable_now();
30868
30946
  startTime = currentTime;
30869
30947
  var hasMoreWork = true;
30870
30948
  try {
@@ -30895,7 +30973,7 @@ function requireScheduler_development () {
30895
30973
  var continuationCallback = callback(
30896
30974
  currentTask.expirationTime <= currentTime
30897
30975
  );
30898
- currentTime = exports.unstable_now();
30976
+ currentTime = exports$1.unstable_now();
30899
30977
  if ("function" === typeof continuationCallback) {
30900
30978
  currentTask.callback = continuationCallback;
30901
30979
  advanceTimers(currentTime);
@@ -31016,32 +31094,32 @@ function requireScheduler_development () {
31016
31094
  function shouldYieldToHost() {
31017
31095
  return needsPaint
31018
31096
  ? true
31019
- : exports.unstable_now() - startTime < frameInterval
31097
+ : exports$1.unstable_now() - startTime < frameInterval
31020
31098
  ? false
31021
31099
  : true;
31022
31100
  }
31023
31101
  function requestHostTimeout(callback, ms) {
31024
31102
  taskTimeoutID = localSetTimeout(function () {
31025
- callback(exports.unstable_now());
31103
+ callback(exports$1.unstable_now());
31026
31104
  }, ms);
31027
31105
  }
31028
31106
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
31029
31107
  "function" ===
31030
31108
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
31031
31109
  __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
31032
- exports.unstable_now = void 0;
31110
+ exports$1.unstable_now = void 0;
31033
31111
  if (
31034
31112
  "object" === typeof performance &&
31035
31113
  "function" === typeof performance.now
31036
31114
  ) {
31037
31115
  var localPerformance = performance;
31038
- exports.unstable_now = function () {
31116
+ exports$1.unstable_now = function () {
31039
31117
  return localPerformance.now();
31040
31118
  };
31041
31119
  } else {
31042
31120
  var localDate = Date,
31043
31121
  initialTime = localDate.now();
31044
- exports.unstable_now = function () {
31122
+ exports$1.unstable_now = function () {
31045
31123
  return localDate.now() - initialTime;
31046
31124
  };
31047
31125
  }
@@ -31078,26 +31156,26 @@ function requireScheduler_development () {
31078
31156
  schedulePerformWorkUntilDeadline = function () {
31079
31157
  localSetTimeout(performWorkUntilDeadline, 0);
31080
31158
  };
31081
- exports.unstable_IdlePriority = 5;
31082
- exports.unstable_ImmediatePriority = 1;
31083
- exports.unstable_LowPriority = 4;
31084
- exports.unstable_NormalPriority = 3;
31085
- exports.unstable_Profiling = null;
31086
- exports.unstable_UserBlockingPriority = 2;
31087
- exports.unstable_cancelCallback = function (task) {
31159
+ exports$1.unstable_IdlePriority = 5;
31160
+ exports$1.unstable_ImmediatePriority = 1;
31161
+ exports$1.unstable_LowPriority = 4;
31162
+ exports$1.unstable_NormalPriority = 3;
31163
+ exports$1.unstable_Profiling = null;
31164
+ exports$1.unstable_UserBlockingPriority = 2;
31165
+ exports$1.unstable_cancelCallback = function (task) {
31088
31166
  task.callback = null;
31089
31167
  };
31090
- exports.unstable_forceFrameRate = function (fps) {
31168
+ exports$1.unstable_forceFrameRate = function (fps) {
31091
31169
  0 > fps || 125 < fps
31092
31170
  ? console.error(
31093
31171
  "forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"
31094
31172
  )
31095
31173
  : (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);
31096
31174
  };
31097
- exports.unstable_getCurrentPriorityLevel = function () {
31175
+ exports$1.unstable_getCurrentPriorityLevel = function () {
31098
31176
  return currentPriorityLevel;
31099
31177
  };
31100
- exports.unstable_next = function (eventHandler) {
31178
+ exports$1.unstable_next = function (eventHandler) {
31101
31179
  switch (currentPriorityLevel) {
31102
31180
  case 1:
31103
31181
  case 2:
@@ -31115,10 +31193,10 @@ function requireScheduler_development () {
31115
31193
  currentPriorityLevel = previousPriorityLevel;
31116
31194
  }
31117
31195
  };
31118
- exports.unstable_requestPaint = function () {
31196
+ exports$1.unstable_requestPaint = function () {
31119
31197
  needsPaint = true;
31120
31198
  };
31121
- exports.unstable_runWithPriority = function (priorityLevel, eventHandler) {
31199
+ exports$1.unstable_runWithPriority = function (priorityLevel, eventHandler) {
31122
31200
  switch (priorityLevel) {
31123
31201
  case 1:
31124
31202
  case 2:
@@ -31137,12 +31215,12 @@ function requireScheduler_development () {
31137
31215
  currentPriorityLevel = previousPriorityLevel;
31138
31216
  }
31139
31217
  };
31140
- exports.unstable_scheduleCallback = function (
31218
+ exports$1.unstable_scheduleCallback = function (
31141
31219
  priorityLevel,
31142
31220
  callback,
31143
31221
  options
31144
31222
  ) {
31145
- var currentTime = exports.unstable_now();
31223
+ var currentTime = exports$1.unstable_now();
31146
31224
  "object" === typeof options && null !== options
31147
31225
  ? ((options = options.delay),
31148
31226
  (options =
@@ -31194,8 +31272,8 @@ function requireScheduler_development () {
31194
31272
  schedulePerformWorkUntilDeadline())));
31195
31273
  return priorityLevel;
31196
31274
  };
31197
- exports.unstable_shouldYield = shouldYieldToHost;
31198
- exports.unstable_wrapCallback = function (callback) {
31275
+ exports$1.unstable_shouldYield = shouldYieldToHost;
31276
+ exports$1.unstable_wrapCallback = function (callback) {
31199
31277
  var parentPriorityLevel = currentPriorityLevel;
31200
31278
  return function () {
31201
31279
  var previousPriorityLevel = currentPriorityLevel;
@@ -32450,7 +32528,7 @@ function extractFormula(value) {
32450
32528
  return value.slice(1);
32451
32529
  }
32452
32530
  function createFormulaParser(data, config) {
32453
- return new FormulaParser$1(__assign(__assign({}, config), { onCell: function (ref) {
32531
+ return new FormulaParser(__assign(__assign({}, config), { onCell: function (ref) {
32454
32532
  var point = {
32455
32533
  row: ref.row - 1,
32456
32534
  column: ref.col - 1,
@@ -35456,8 +35534,8 @@ return CRC32;
35456
35534
  })();
35457
35535
  /* [MS-CFB] v20171201 */
35458
35536
  var CFB = /*#__PURE__*/(function _CFB(){
35459
- var exports = {};
35460
- exports.version = '1.2.1';
35537
+ var exports$1 = {};
35538
+ exports$1.version = '1.2.1';
35461
35539
  /* [MS-CFB] 2.6.4 */
35462
35540
  function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
35463
35541
  var L = l.split("/"), R = r.split("/");
@@ -37129,12 +37207,12 @@ function cfb_mov(cfb/*:CFBContainer*/, old_name/*:string*/, new_name/*:string*/)
37129
37207
 
37130
37208
  function cfb_gc(cfb/*:CFBContainer*/)/*:void*/ { rebuild_cfb(cfb, true); }
37131
37209
 
37132
- exports.find = find;
37133
- exports.read = read;
37134
- exports.parse = parse;
37135
- exports.write = write;
37136
- exports.writeFile = write_file;
37137
- exports.utils = {
37210
+ exports$1.find = find;
37211
+ exports$1.read = read;
37212
+ exports$1.parse = parse;
37213
+ exports$1.write = write;
37214
+ exports$1.writeFile = write_file;
37215
+ exports$1.utils = {
37138
37216
  cfb_new: cfb_new,
37139
37217
  cfb_add: cfb_add,
37140
37218
  cfb_del: cfb_del,
@@ -37150,7 +37228,7 @@ exports.utils = {
37150
37228
  consts: consts
37151
37229
  };
37152
37230
 
37153
- return exports;
37231
+ return exports$1;
37154
37232
  })();
37155
37233
 
37156
37234
  /* normalize data for blob ctor */
@@ -58613,6 +58691,137 @@ function CurrencyDisplay({ amount, currency = 'USD', locale = 'en-US', className
58613
58691
  return (jsx("span", { className: combinedClasses, title: `${currency} ${safeAmount.toFixed(precision)}`, children: displayValue }));
58614
58692
  }
58615
58693
 
58694
+ /**
58695
+ * CurrencyInput - Specialized input for monetary values
58696
+ *
58697
+ * Automatically formats currency values with proper symbols and thousands separators.
58698
+ * Handles parsing and validation of numeric currency input.
58699
+ *
58700
+ * @example Basic usage
58701
+ * ```tsx
58702
+ * <CurrencyInput
58703
+ * label="Price"
58704
+ * value={price}
58705
+ * onChange={setPrice}
58706
+ * currency="USD"
58707
+ * />
58708
+ * ```
58709
+ *
58710
+ * @example With validation
58711
+ * ```tsx
58712
+ * <CurrencyInput
58713
+ * label="Budget"
58714
+ * value={budget}
58715
+ * onChange={setBudget}
58716
+ * min={0}
58717
+ * max={10000}
58718
+ * validationState={budget > 10000 ? 'error' : null}
58719
+ * validationMessage={budget > 10000 ? 'Exceeds maximum budget' : ''}
58720
+ * />
58721
+ * ```
58722
+ */
58723
+ const CurrencyInput = forwardRef(({ value, onChange, currency = 'USD', locale = 'en-US', precision = 2, allowNegative = false, min, max, onBlur, onFocus, ...props }, ref) => {
58724
+ const [displayValue, setDisplayValue] = useState('');
58725
+ const [isFocused, setIsFocused] = useState(false);
58726
+ // Get currency symbol
58727
+ const getCurrencySymbol = () => {
58728
+ const formatter = new Intl.NumberFormat(locale, {
58729
+ style: 'currency',
58730
+ currency,
58731
+ });
58732
+ const parts = formatter.formatToParts(0);
58733
+ const symbolPart = parts.find(part => part.type === 'currency');
58734
+ return symbolPart?.value || '$';
58735
+ };
58736
+ const currencySymbol = getCurrencySymbol();
58737
+ // Format number as currency
58738
+ const formatCurrency = (num) => {
58739
+ const formatter = new Intl.NumberFormat(locale, {
58740
+ minimumFractionDigits: isFocused ? 0 : precision,
58741
+ maximumFractionDigits: precision,
58742
+ });
58743
+ return formatter.format(num);
58744
+ };
58745
+ // Parse display value to number
58746
+ const parseValue = (str) => {
58747
+ if (!str || str === '')
58748
+ return null;
58749
+ // Remove all non-numeric characters except decimal point and minus sign
58750
+ let cleaned = str.replace(/[^\d.-]/g, '');
58751
+ // Handle multiple decimal points
58752
+ const parts = cleaned.split('.');
58753
+ if (parts.length > 2) {
58754
+ cleaned = parts[0] + '.' + parts.slice(1).join('');
58755
+ }
58756
+ // Handle multiple minus signs (keep only first)
58757
+ const minusCount = (cleaned.match(/-/g) || []).length;
58758
+ if (minusCount > 1) {
58759
+ const hasLeadingMinus = cleaned.startsWith('-');
58760
+ cleaned = cleaned.replace(/-/g, '');
58761
+ if (hasLeadingMinus)
58762
+ cleaned = '-' + cleaned;
58763
+ }
58764
+ // Parse to float
58765
+ const num = parseFloat(cleaned);
58766
+ if (isNaN(num))
58767
+ return null;
58768
+ // Apply precision
58769
+ return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision);
58770
+ };
58771
+ // Update display value when external value changes
58772
+ useEffect(() => {
58773
+ if (value === undefined || value === null || value === '') {
58774
+ setDisplayValue('');
58775
+ }
58776
+ else {
58777
+ const numValue = typeof value === 'string' ? parseFloat(value) : value;
58778
+ if (!isNaN(numValue)) {
58779
+ setDisplayValue(formatCurrency(numValue));
58780
+ }
58781
+ }
58782
+ }, [value, isFocused]);
58783
+ const handleChange = (e) => {
58784
+ const inputValue = e.target.value;
58785
+ setDisplayValue(inputValue);
58786
+ const numValue = parseValue(inputValue);
58787
+ // Validate constraints
58788
+ if (numValue !== null) {
58789
+ if (!allowNegative && numValue < 0)
58790
+ return;
58791
+ if (min !== undefined && numValue < min)
58792
+ return;
58793
+ if (max !== undefined && numValue > max)
58794
+ return;
58795
+ }
58796
+ onChange?.(numValue);
58797
+ };
58798
+ const handleFocus = (e) => {
58799
+ setIsFocused(true);
58800
+ // Remove formatting when focused for easier editing
58801
+ if (value !== undefined && value !== null && value !== '') {
58802
+ const numValue = typeof value === 'string' ? parseFloat(value) : value;
58803
+ if (!isNaN(numValue)) {
58804
+ setDisplayValue(numValue.toString());
58805
+ }
58806
+ }
58807
+ onFocus?.(e);
58808
+ };
58809
+ const handleBlur = (e) => {
58810
+ setIsFocused(false);
58811
+ // Reformat on blur
58812
+ const numValue = parseValue(displayValue);
58813
+ if (numValue !== null) {
58814
+ setDisplayValue(formatCurrency(numValue));
58815
+ }
58816
+ else if (displayValue === '') {
58817
+ setDisplayValue('');
58818
+ }
58819
+ onBlur?.(e);
58820
+ };
58821
+ return (jsx(Input, { ref: ref, type: "text", value: displayValue, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, prefix: currencySymbol, ...props }));
58822
+ });
58823
+ CurrencyInput.displayName = 'CurrencyInput';
58824
+
58616
58825
  const formatOptions = {
58617
58826
  short: {
58618
58827
  year: 'numeric',
@@ -59523,8 +59732,19 @@ const AppLayout = ({ children, toolbarSections = [], className = '', showToolbar
59523
59732
  * </Layout>
59524
59733
  * ```
59525
59734
  */
59526
- function PageLayout({ title, description, children, className = '', headerContent }) {
59527
- return (jsxs(Page, { children: [headerContent, jsxs("div", { className: `p-6 max-w-7xl mx-auto pb-20 ${className}`, children: [jsxs("div", { className: "mb-8", children: [jsx("h1", { className: "text-3xl font-bold text-ink-900 mb-2", children: title }), description && (jsx("p", { className: "text-ink-600", children: description }))] }), children] })] }));
59735
+ function PageLayout({ title, description, children, className = '', headerContent, maxWidth = '7xl', fixed = false }) {
59736
+ // Responsive padding classes - fixed left/top, responsive right/bottom
59737
+ const paddingClasses = fixed
59738
+ ? 'p-6 pb-20'
59739
+ : 'pt-6 pl-6 pr-2 pb-8 sm:pr-4 md:pr-6 sm:pb-12 md:pb-16 lg:pb-20';
59740
+ const maxWidthClasses = {
59741
+ '4xl': 'max-w-4xl',
59742
+ '5xl': 'max-w-5xl',
59743
+ '6xl': 'max-w-6xl',
59744
+ '7xl': 'max-w-7xl',
59745
+ 'full': 'max-w-full',
59746
+ };
59747
+ return (jsxs(Page, { padding: "none", maxWidth: maxWidth, fixed: fixed, children: [headerContent, jsxs("div", { className: `${paddingClasses} ${maxWidthClasses[maxWidth]} mx-auto ${className}`, children: [jsxs("div", { className: "mb-8", children: [jsx("h1", { className: "text-3xl font-bold text-ink-900 mb-2", children: title }), description && (jsx("p", { className: "text-ink-600", children: description }))] }), children] })] }));
59528
59748
  }
59529
59749
 
59530
59750
  const sizeClasses = {
@@ -59896,6 +60116,113 @@ function loadColumnOrder(tableId) {
59896
60116
  }
59897
60117
  }
59898
60118
 
60119
+ /**
60120
+ * Export data to Excel file
60121
+ *
60122
+ * A standalone utility for exporting any data array to Excel format.
60123
+ * Works independently of the Spreadsheet component.
60124
+ *
60125
+ * **Features:**
60126
+ * - Export arrays of objects to Excel
60127
+ * - Custom column headers and ordering
60128
+ * - Value formatting with custom functions
60129
+ * - Multi-sheet support
60130
+ * - Automatic type handling
60131
+ *
60132
+ * @example
60133
+ * ```typescript
60134
+ * // Simple export - uses object keys as headers
60135
+ * const data = [
60136
+ * { id: 1, name: 'Product A', price: 29.99 },
60137
+ * { id: 2, name: 'Product B', price: 49.99 },
60138
+ * ];
60139
+ * exportToExcel({ data, filename: 'products.xlsx' });
60140
+ *
60141
+ * // Custom columns with formatting
60142
+ * exportToExcel({
60143
+ * data: users,
60144
+ * filename: 'users.xlsx',
60145
+ * columns: [
60146
+ * { key: 'id', label: 'ID' },
60147
+ * { key: 'name', label: 'Full Name' },
60148
+ * { key: 'email', label: 'Email Address' },
60149
+ * { key: 'createdAt', label: 'Joined', format: (date) => new Date(date).toLocaleDateString() },
60150
+ * { key: 'isActive', label: 'Status', format: (active) => active ? 'Active' : 'Inactive' },
60151
+ * ],
60152
+ * });
60153
+ *
60154
+ * // Multi-sheet export
60155
+ * const wb = utils.book_new();
60156
+ * exportToExcel({ data: products, sheetName: 'Products', workbook: wb });
60157
+ * exportToExcel({ data: orders, sheetName: 'Orders', workbook: wb });
60158
+ * writeFile(wb, 'multi-sheet.xlsx');
60159
+ * ```
60160
+ *
60161
+ * @param options - Export configuration options
60162
+ * @returns WorkBook if workbook option provided, otherwise void (auto-downloads)
60163
+ */
60164
+ function exportToExcel({ data, filename = 'export.xlsx', sheetName = 'Sheet1', columns, includeHeaders = true, workbook, }) {
60165
+ if (!data || data.length === 0) {
60166
+ throw new Error('No data provided for export');
60167
+ }
60168
+ let worksheetData;
60169
+ if (columns) {
60170
+ // Use custom columns with specific ordering and formatting
60171
+ const headers = columns.map((col) => col.label);
60172
+ const rows = data.map((row) => columns.map((col) => {
60173
+ const value = row[col.key];
60174
+ return col.format ? col.format(value) : value ?? '';
60175
+ }));
60176
+ worksheetData = includeHeaders ? [headers, ...rows] : rows;
60177
+ }
60178
+ else {
60179
+ // Auto-generate from object keys
60180
+ if (includeHeaders) {
60181
+ const headers = Object.keys(data[0]);
60182
+ const rows = data.map((row) => headers.map((key) => row[key] ?? ''));
60183
+ worksheetData = [headers, ...rows];
60184
+ }
60185
+ else {
60186
+ const headers = Object.keys(data[0]);
60187
+ worksheetData = data.map((row) => headers.map((key) => row[key] ?? ''));
60188
+ }
60189
+ }
60190
+ const worksheet = utils.aoa_to_sheet(worksheetData);
60191
+ // If workbook provided, add sheet and return (for multi-sheet exports)
60192
+ if (workbook) {
60193
+ utils.book_append_sheet(workbook, worksheet, sheetName);
60194
+ return workbook;
60195
+ }
60196
+ // Otherwise, create workbook and download
60197
+ const newWorkbook = utils.book_new();
60198
+ utils.book_append_sheet(newWorkbook, worksheet, sheetName);
60199
+ writeFileSync(newWorkbook, filename);
60200
+ }
60201
+ function exportDataTableToExcel({ data, columns, filename = 'export.xlsx', sheetName = 'Sheet1', }) {
60202
+ const excelColumns = columns.map((col) => ({
60203
+ key: col.key,
60204
+ label: col.header,
60205
+ }));
60206
+ exportToExcel({
60207
+ data,
60208
+ columns: excelColumns,
60209
+ filename,
60210
+ sheetName,
60211
+ });
60212
+ }
60213
+ function createMultiSheetExcel({ filename, sheets }) {
60214
+ const workbook = utils.book_new();
60215
+ sheets.forEach((sheet) => {
60216
+ exportToExcel({
60217
+ data: sheet.data,
60218
+ sheetName: sheet.name,
60219
+ columns: sheet.columns,
60220
+ workbook,
60221
+ });
60222
+ });
60223
+ writeFileSync(workbook, filename);
60224
+ }
60225
+
59899
60226
  function useColumnResize(options = {}) {
59900
60227
  const { tableId, persist = false } = options;
59901
60228
  const [columnWidths, setColumnWidths] = useState({});
@@ -60012,5 +60339,5 @@ function useColumnReorder(initialColumns, options = {}) {
60012
60339
  };
60013
60340
  }
60014
60341
 
60015
- export { Accordion, ActionButton, AdminModal, Alert, AlertDialog, AppLayout, Autocomplete, Avatar, Badge, BottomSheet, Box, Breadcrumbs, Button, ButtonGroup, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CardView, Carousel, Checkbox, Chip, Collapsible, ColorPicker, Combobox, ComingSoon, CommandPalette, ConfirmDialog, ContextMenu, ControlBar, CurrencyDisplay, Dashboard, DashboardContent, DashboardHeader, DataTable, DateDisplay, DatePicker, DateRangePicker, DateTimePicker, Drawer, DrawerFooter, DropZone, Dropdown, DropdownTrigger, EmptyState, ErrorBoundary, ExpandableRowButton, ExpandableToolbar, ExpandedRowEditForm, ExportButton, FieldArray, FileUpload, FilterBar, FilterControls, FilterStatusBanner, Form, FormContext, FormControl, FormWizard, Grid, GridItem, Hide, HoverCard, InfiniteScroll, Input, KanbanBoard, Layout, Loading, LoadingOverlay, Logo, MarkdownEditor, MaskedInput, Menu, MenuDivider, Modal, ModalFooter, MultiSelect, NotificationBar, NotificationIndicator, NumberInput, Page, PageLayout, PageNavigation, Pagination, PasswordInput, Popover, Progress, QueryTransparency, RadioGroup, Rating, RichTextEditor, SearchBar, Select, Separator, Show, Sidebar, SidebarGroup, Skeleton, SkeletonCard, SkeletonTable, Slider, Spreadsheet, SpreadsheetReport, Stack, StatCard, StatItem, StatsCardGrid, StatsGrid, StatusBadge, StatusBar, StepIndicator, Stepper, Switch, Table$1 as Table, Tabs, Text, Textarea, ThemeToggle, TimePicker, Timeline, Toast, ToastContainer, Tooltip, Transfer, TreeView, TwoColumnContent, UserProfileButton, addErrorMessage, addInfoMessage, addSuccessMessage, addWarningMessage, calculateColumnWidth, createActionsSection, createFiltersSection, createPageControlsSection, createQueryDetailsSection, formatStatisticValue, formatStatistics, loadColumnOrder, loadColumnWidths, reorderArray, saveColumnOrder, saveColumnWidths, statusManager, useColumnReorder, useColumnResize, useCommandPalette, useConfirmDialog, useFormContext, useMediaQuery };
60342
+ export { Accordion, ActionButton, AdminModal, Alert, AlertDialog, AppLayout, Autocomplete, Avatar, Badge, BottomSheet, Box, Breadcrumbs, Button, ButtonGroup, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CardView, Carousel, Checkbox, Chip, Collapsible, ColorPicker, Combobox, ComingSoon, CommandPalette, ConfirmDialog, ContextMenu, ControlBar, CurrencyDisplay, CurrencyInput, Dashboard, DashboardContent, DashboardHeader, DataTable, DateDisplay, DatePicker, DateRangePicker, DateTimePicker, Drawer, DrawerFooter, DropZone, Dropdown, DropdownTrigger, EmptyState, ErrorBoundary, ExpandableRowButton, ExpandableToolbar, ExpandedRowEditForm, ExportButton, FieldArray, FileUpload, FilterBar, FilterControls, FilterStatusBanner, Form, FormContext, FormControl, FormWizard, Grid, GridItem, Hide, HoverCard, InfiniteScroll, Input, KanbanBoard, Layout, Loading, LoadingOverlay, Logo, MarkdownEditor, MaskedInput, Menu, MenuDivider, Modal, ModalFooter, MultiSelect, NotificationBar, NotificationIndicator, NumberInput, Page, PageLayout, PageNavigation, Pagination, PasswordInput, Popover, Progress, QueryTransparency, RadioGroup, Rating, RichTextEditor, SearchBar, Select, Separator, Show, Sidebar, SidebarGroup, Skeleton, SkeletonCard, SkeletonTable, Slider, Spreadsheet, SpreadsheetReport, Stack, StatCard, StatItem, StatsCardGrid, StatsGrid, StatusBadge, StatusBar, StepIndicator, Stepper, Switch, Table$1 as Table, Tabs, Text, Textarea, ThemeToggle, TimePicker, Timeline, Toast, ToastContainer, Tooltip, Transfer, TreeView, TwoColumnContent, UserProfileButton, addErrorMessage, addInfoMessage, addSuccessMessage, addWarningMessage, calculateColumnWidth, createActionsSection, createFiltersSection, createMultiSheetExcel, createPageControlsSection, createQueryDetailsSection, exportDataTableToExcel, exportToExcel, formatStatisticValue, formatStatistics, loadColumnOrder, loadColumnWidths, reorderArray, saveColumnOrder, saveColumnWidths, statusManager, useColumnReorder, useColumnResize, useCommandPalette, useConfirmDialog, useFormContext, useMediaQuery };
60016
60343
  //# sourceMappingURL=index.esm.js.map