@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.
- package/LICENSE +21 -21
- package/README.md +455 -455
- package/dist/components/CurrencyInput.d.ts +52 -0
- package/dist/components/CurrencyInput.d.ts.map +1 -0
- package/dist/components/DataTable.d.ts +3 -1
- package/dist/components/DataTable.d.ts.map +1 -1
- package/dist/components/Modal.d.ts.map +1 -1
- package/dist/components/Page.d.ts +2 -0
- package/dist/components/Page.d.ts.map +1 -1
- package/dist/components/PageLayout.d.ts +5 -1
- package/dist/components/PageLayout.d.ts.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.d.ts +204 -4
- package/dist/index.esm.js +415 -88
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +413 -82
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2877 -2675
- package/dist/utils/excelExport.d.ts +143 -0
- package/dist/utils/excelExport.d.ts.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/AdminModal.css +49 -49
- package/src/components/CurrencyInput.stories.tsx +290 -0
- package/src/components/CurrencyInput.tsx +193 -0
- package/src/components/DataTable.tsx +78 -14
- package/src/components/Modal.stories.tsx +64 -0
- package/src/components/Modal.tsx +15 -2
- package/src/components/Page.stories.tsx +76 -0
- package/src/components/Page.tsx +35 -3
- package/src/components/PageLayout.stories.tsx +75 -0
- package/src/components/PageLayout.tsx +28 -9
- package/src/components/RoleManager.css +10 -10
- package/src/components/Spreadsheet.css +216 -216
- package/src/components/Spreadsheet.stories.tsx +362 -362
- package/src/components/Spreadsheet.tsx +351 -351
- package/src/components/SpreadsheetSimple.stories.tsx +27 -27
- package/src/components/Tabs.tsx +152 -152
- package/src/components/index.ts +5 -0
- package/src/styles/index.css +41 -4
- package/src/utils/excelExport.stories.tsx +535 -0
- package/src/utils/excelExport.ts +225 -0
- package/src/utils/index.ts +3 -0
- package/tailwind.config.js +253 -253
- package/dist/components/Button.stories.d.ts +0 -51
- package/dist/components/Button.stories.d.ts.map +0 -1
- package/dist/components/ChartVisualizationUI.d.ts +0 -21
- package/dist/components/ChartVisualizationUI.d.ts.map +0 -1
- package/dist/components/ChatUI.d.ts +0 -23
- package/dist/components/ChatUI.d.ts.map +0 -1
- package/dist/components/CommissionDashboardUI.d.ts +0 -25
- package/dist/components/CommissionDashboardUI.d.ts.map +0 -1
- package/dist/components/DataTable.stories.d.ts +0 -23
- package/dist/components/DataTable.stories.d.ts.map +0 -1
- package/dist/components/FormField.d.ts +0 -35
- package/dist/components/FormField.d.ts.map +0 -1
- package/dist/components/Input.stories.d.ts +0 -366
- package/dist/components/Input.stories.d.ts.map +0 -1
- package/dist/components/InsightsPanelUI.d.ts +0 -21
- package/dist/components/InsightsPanelUI.d.ts.map +0 -1
- package/dist/components/PaymentHistoryTimeline.d.ts +0 -34
- package/dist/components/PaymentHistoryTimeline.d.ts.map +0 -1
- package/dist/components/RelationshipManagerUI.d.ts +0 -60
- package/dist/components/RelationshipManagerUI.d.ts.map +0 -1
- package/dist/components/RoleManager.d.ts +0 -19
- package/dist/components/RoleManager.d.ts.map +0 -1
- package/dist/components/SplitCommissionBadge.d.ts +0 -18
- package/dist/components/SplitCommissionBadge.d.ts.map +0 -1
- package/dist/components/Spreadsheet.css +0 -216
- package/dist/components/__tests__/Button.test.d.ts +0 -2
- package/dist/components/__tests__/Button.test.d.ts.map +0 -1
- package/dist/components/__tests__/Input.test.d.ts +0 -2
- package/dist/components/__tests__/Input.test.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2550,6 +2550,7 @@ const sizeClasses$4 = {
|
|
|
2550
2550
|
};
|
|
2551
2551
|
function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton = true, animation = 'scale', }) {
|
|
2552
2552
|
const modalRef = React.useRef(null);
|
|
2553
|
+
const mouseDownOnBackdrop = React.useRef(false);
|
|
2553
2554
|
const titleId = React.useId();
|
|
2554
2555
|
// Handle escape key
|
|
2555
2556
|
React.useEffect(() => {
|
|
@@ -2567,11 +2568,22 @@ function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton
|
|
|
2567
2568
|
document.body.style.overflow = 'unset';
|
|
2568
2569
|
};
|
|
2569
2570
|
}, [isOpen, onClose]);
|
|
2570
|
-
//
|
|
2571
|
-
const
|
|
2571
|
+
// Track if mousedown originated on the backdrop
|
|
2572
|
+
const handleBackdropMouseDown = (e) => {
|
|
2572
2573
|
if (e.target === e.currentTarget) {
|
|
2574
|
+
mouseDownOnBackdrop.current = true;
|
|
2575
|
+
}
|
|
2576
|
+
else {
|
|
2577
|
+
mouseDownOnBackdrop.current = false;
|
|
2578
|
+
}
|
|
2579
|
+
};
|
|
2580
|
+
// Handle click outside - only close if both mousedown and click happened on backdrop
|
|
2581
|
+
const handleBackdropClick = (e) => {
|
|
2582
|
+
if (e.target === e.currentTarget && mouseDownOnBackdrop.current) {
|
|
2573
2583
|
onClose();
|
|
2574
2584
|
}
|
|
2585
|
+
// Reset the flag after handling click
|
|
2586
|
+
mouseDownOnBackdrop.current = false;
|
|
2575
2587
|
};
|
|
2576
2588
|
const getAnimationClass = () => {
|
|
2577
2589
|
switch (animation) {
|
|
@@ -2591,7 +2603,7 @@ function Modal({ isOpen, onClose, title, children, size = 'md', showCloseButton
|
|
|
2591
2603
|
};
|
|
2592
2604
|
if (!isOpen)
|
|
2593
2605
|
return null;
|
|
2594
|
-
return (jsxRuntime.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: jsxRuntime.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: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-paper-200", children: [jsxRuntime.jsx("h3", { id: titleId, className: "text-lg font-medium text-ink-900", children: title }), showCloseButton && (jsxRuntime.jsx("button", { onClick: onClose, className: "text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close modal", children: jsxRuntime.jsx(lucideReact.X, { className: "h-5 w-5" }) }))] }), jsxRuntime.jsx("div", { className: "px-6 py-4", children: children })] }) }));
|
|
2606
|
+
return (jsxRuntime.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: jsxRuntime.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: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-paper-200", children: [jsxRuntime.jsx("h3", { id: titleId, className: "text-lg font-medium text-ink-900", children: title }), showCloseButton && (jsxRuntime.jsx("button", { onClick: onClose, className: "text-ink-400 hover:text-ink-600 transition-colors", "aria-label": "Close modal", children: jsxRuntime.jsx(lucideReact.X, { className: "h-5 w-5" }) }))] }), jsxRuntime.jsx("div", { className: "px-6 py-4", children: children })] }) }));
|
|
2595
2607
|
}
|
|
2596
2608
|
function ModalFooter({ children }) {
|
|
2597
2609
|
return (jsxRuntime.jsx("div", { className: "flex items-center justify-end gap-3 px-6 py-4 border-t border-paper-200 bg-paper-50", children: children }));
|
|
@@ -5976,19 +5988,19 @@ function Tabs({ tabs, activeTab: controlledActiveTab, defaultTab, variant = 'und
|
|
|
5976
5988
|
spacing: orientation === 'vertical' ? 'mt-8' : 'mt-8',
|
|
5977
5989
|
},
|
|
5978
5990
|
};
|
|
5979
|
-
return (jsxRuntime.jsxs("div", { className: `w-full ${orientation === 'vertical' ? `flex ${sizeClasses[size].gap}` : ''}`, children: [jsxRuntime.jsx("div", { className: `
|
|
5980
|
-
flex ${orientation === 'vertical' ? 'flex-col' : ''}
|
|
5991
|
+
return (jsxRuntime.jsxs("div", { className: `w-full ${orientation === 'vertical' ? `flex ${sizeClasses[size].gap}` : ''}`, children: [jsxRuntime.jsx("div", { className: `
|
|
5992
|
+
flex ${orientation === 'vertical' ? 'flex-col' : ''}
|
|
5981
5993
|
${variant === 'underline'
|
|
5982
5994
|
? orientation === 'vertical'
|
|
5983
5995
|
? `border-r border-paper-200 ${sizeClasses[size].gap} pr-6`
|
|
5984
5996
|
: `border-b border-paper-200 ${sizeClasses[size].gap}`
|
|
5985
|
-
: `${sizeClasses[size].gap} p-1 bg-paper-50 rounded-lg`}
|
|
5986
|
-
${sizeClasses[size].minWidth}
|
|
5997
|
+
: `${sizeClasses[size].gap} p-1 bg-paper-50 rounded-lg`}
|
|
5998
|
+
${sizeClasses[size].minWidth}
|
|
5987
5999
|
`, role: "tablist", children: tabs.map((tab) => {
|
|
5988
6000
|
const isActive = activeTab === tab.id;
|
|
5989
|
-
return (jsxRuntime.jsxs("button", { role: "tab", "aria-selected": isActive, "aria-controls": `panel-${tab.id}`, disabled: tab.disabled, onClick: () => !tab.disabled && handleTabChange(tab.id), className: `
|
|
5990
|
-
flex items-center gap-2 ${sizeClasses[size].padding} ${sizeClasses[size].text} font-medium transition-all duration-200
|
|
5991
|
-
${orientation === 'vertical' ? 'w-full justify-start' : ''}
|
|
6001
|
+
return (jsxRuntime.jsxs("button", { role: "tab", "aria-selected": isActive, "aria-controls": `panel-${tab.id}`, disabled: tab.disabled, onClick: () => !tab.disabled && handleTabChange(tab.id), className: `
|
|
6002
|
+
flex items-center gap-2 ${sizeClasses[size].padding} ${sizeClasses[size].text} font-medium transition-all duration-200
|
|
6003
|
+
${orientation === 'vertical' ? 'w-full justify-start' : ''}
|
|
5992
6004
|
${variant === 'underline'
|
|
5993
6005
|
? isActive
|
|
5994
6006
|
? orientation === 'vertical'
|
|
@@ -5999,8 +6011,8 @@ function Tabs({ tabs, activeTab: controlledActiveTab, defaultTab, variant = 'und
|
|
|
5999
6011
|
: 'text-ink-600 hover:text-ink-900 border-b-2 border-transparent'
|
|
6000
6012
|
: isActive
|
|
6001
6013
|
? 'bg-white text-accent-900 rounded-md shadow-xs'
|
|
6002
|
-
: 'text-ink-600 hover:text-ink-900 hover:bg-white/50 rounded-md'}
|
|
6003
|
-
${tab.disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
|
|
6014
|
+
: 'text-ink-600 hover:text-ink-900 hover:bg-white/50 rounded-md'}
|
|
6015
|
+
${tab.disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
|
|
6004
6016
|
`, children: [tab.icon && jsxRuntime.jsx("span", { className: `flex-shrink-0 ${sizeClasses[size].icon}`, children: tab.icon }), jsxRuntime.jsx("span", { children: tab.label })] }, tab.id));
|
|
6005
6017
|
}) }), jsxRuntime.jsx("div", { className: `${orientation === 'vertical' ? 'flex-1' : sizeClasses[size].spacing}`, children: tabs.map((tab) => (jsxRuntime.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))) })] }));
|
|
6006
6018
|
}
|
|
@@ -6928,8 +6940,35 @@ const TwoColumnContent = ({ sidebar, children, className = '', }) => {
|
|
|
6928
6940
|
* </PageLayout>
|
|
6929
6941
|
* ```
|
|
6930
6942
|
*/
|
|
6931
|
-
const Page = ({ children, maxWidth
|
|
6932
|
-
|
|
6943
|
+
const Page = ({ children, maxWidth = '7xl', className = '', padding = 'normal', fixed = false }) => {
|
|
6944
|
+
// Max width classes
|
|
6945
|
+
const maxWidthClasses = {
|
|
6946
|
+
'4xl': 'max-w-4xl',
|
|
6947
|
+
'5xl': 'max-w-5xl',
|
|
6948
|
+
'6xl': 'max-w-6xl',
|
|
6949
|
+
'7xl': 'max-w-7xl',
|
|
6950
|
+
'full': 'max-w-full',
|
|
6951
|
+
};
|
|
6952
|
+
// Padding classes - responsive (fixed left/top, responsive right/bottom) vs all fixed
|
|
6953
|
+
const paddingClasses = {
|
|
6954
|
+
none: fixed ? 'p-0' : 'pt-0 pl-0 pr-0 pb-0',
|
|
6955
|
+
sm: fixed ? 'p-4' : 'pt-4 pl-4 pr-4 pb-4 sm:pr-6 md:pr-8 sm:pb-6 md:pb-8',
|
|
6956
|
+
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',
|
|
6957
|
+
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',
|
|
6958
|
+
};
|
|
6959
|
+
// Margin classes - responsive (fixed left/top, responsive right/bottom) vs all fixed
|
|
6960
|
+
const marginClasses = fixed
|
|
6961
|
+
? 'mt-4 ml-4 mr-4 mb-4'
|
|
6962
|
+
: 'mt-4 ml-4 mr-4 mb-4 sm:mr-6 md:mr-8 lg:mr-auto sm:mb-6 md:mb-8';
|
|
6963
|
+
return (jsxRuntime.jsx("div", { className: "min-h-screen bg-paper-100", children: jsxRuntime.jsx("div", { className: `
|
|
6964
|
+
bg-white bg-subtle-grain rounded-sm shadow-lg border-l-4 border-paper-300
|
|
6965
|
+
min-h-[calc(100vh-2rem)] relative
|
|
6966
|
+
notebook-margin notebook-ruled
|
|
6967
|
+
${maxWidthClasses[maxWidth]}
|
|
6968
|
+
${paddingClasses[padding]}
|
|
6969
|
+
${marginClasses}
|
|
6970
|
+
${className}
|
|
6971
|
+
`.trim().replace(/\s+/g, ' '), children: children }) }));
|
|
6933
6972
|
};
|
|
6934
6973
|
|
|
6935
6974
|
/**
|
|
@@ -7264,7 +7303,7 @@ function getColumnStyle(column, dynamicWidth) {
|
|
|
7264
7303
|
* />
|
|
7265
7304
|
* ```
|
|
7266
7305
|
*/
|
|
7267
|
-
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,
|
|
7306
|
+
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,
|
|
7268
7307
|
// Visual customization props
|
|
7269
7308
|
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, }) {
|
|
7270
7309
|
// Column resizing state
|
|
@@ -7281,6 +7320,12 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
|
|
|
7281
7320
|
const tableContainerRef = React.useRef(null);
|
|
7282
7321
|
// Row hover state (for coordinating primary + secondary row highlighting)
|
|
7283
7322
|
const [hoveredRowKey, setHoveredRowKey] = React.useState(null);
|
|
7323
|
+
// Context menu state
|
|
7324
|
+
const [contextMenuState, setContextMenuState] = React.useState({
|
|
7325
|
+
isOpen: false,
|
|
7326
|
+
position: { x: 0, y: 0 },
|
|
7327
|
+
item: null,
|
|
7328
|
+
});
|
|
7284
7329
|
// Filter columns based on hiddenColumns
|
|
7285
7330
|
const baseVisibleColumns = columns.filter(col => !hiddenColumns.includes(String(col.key)));
|
|
7286
7331
|
// Initialize column order on mount or when columns change
|
|
@@ -7503,6 +7548,28 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
|
|
|
7503
7548
|
});
|
|
7504
7549
|
}
|
|
7505
7550
|
const allActions = [...builtInActions, ...actions];
|
|
7551
|
+
// Convert actions to menu items for context menu
|
|
7552
|
+
const convertActionsToMenuItems = (item) => {
|
|
7553
|
+
const visibleActions = allActions.filter(action => !action.show || action.show(item));
|
|
7554
|
+
return visibleActions.map((action, idx) => {
|
|
7555
|
+
let iconElement = null;
|
|
7556
|
+
if (action.icon) {
|
|
7557
|
+
if (React.isValidElement(action.icon)) {
|
|
7558
|
+
iconElement = action.icon;
|
|
7559
|
+
}
|
|
7560
|
+
else {
|
|
7561
|
+
iconElement = React.createElement(action.icon, { className: 'h-4 w-4' });
|
|
7562
|
+
}
|
|
7563
|
+
}
|
|
7564
|
+
return {
|
|
7565
|
+
id: `action-${idx}`,
|
|
7566
|
+
label: action.label,
|
|
7567
|
+
icon: iconElement,
|
|
7568
|
+
onClick: () => action.onClick(item),
|
|
7569
|
+
danger: action.variant === 'danger',
|
|
7570
|
+
};
|
|
7571
|
+
});
|
|
7572
|
+
};
|
|
7506
7573
|
// Selection state management
|
|
7507
7574
|
const [internalSelectedRows, setInternalSelectedRows] = React.useState(new Set());
|
|
7508
7575
|
// Expansion state management
|
|
@@ -7660,7 +7727,19 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
|
|
|
7660
7727
|
// Hover state for row pair (primary + secondary)
|
|
7661
7728
|
const isHovered = hoveredRowKey === rowKey;
|
|
7662
7729
|
const hoverClass = disableHover ? '' : (isHovered ? 'bg-paper-100' : '');
|
|
7663
|
-
return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.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),
|
|
7730
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.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) => {
|
|
7731
|
+
if (enableContextMenu && allActions.length > 0) {
|
|
7732
|
+
e.preventDefault();
|
|
7733
|
+
e.stopPropagation();
|
|
7734
|
+
const x = e.clientX;
|
|
7735
|
+
const y = e.clientY;
|
|
7736
|
+
setContextMenuState({
|
|
7737
|
+
isOpen: true,
|
|
7738
|
+
position: { x, y },
|
|
7739
|
+
item,
|
|
7740
|
+
});
|
|
7741
|
+
}
|
|
7742
|
+
}, onDoubleClick: () => {
|
|
7664
7743
|
// Priority 1: If there's an onEdit handler (legacy), trigger it
|
|
7665
7744
|
if (onEdit) {
|
|
7666
7745
|
onEdit(item);
|
|
@@ -7816,10 +7895,9 @@ striped = false, stripedColor, density = 'normal', rowClassName, rowHighlight, h
|
|
|
7816
7895
|
}, children: jsxRuntime.jsx("div", { className: "absolute right-0 top-0 bottom-0 w-1 bg-paper-300 group-hover:bg-accent-400 transition-colors" }) }))] }, columnKey));
|
|
7817
7896
|
})] }) }), jsxRuntime.jsx("tbody", { className: "bg-white table-loading transition-opacity duration-200", children: loading && data.length === 0 ? (renderLoadingSkeleton()) : data.length === 0 ? (renderEmptyStateContent()) : (renderDataRows()) })] })] }));
|
|
7818
7897
|
// Wrap in scrollable container if virtualized
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
}
|
|
7822
|
-
return tableContent;
|
|
7898
|
+
const finalContent = virtualized ? (jsxRuntime.jsx("div", { ref: tableContainerRef, onScroll: handleScroll, style: { height: virtualHeight, overflow: 'auto' }, className: "rounded-lg", children: tableContent })) : tableContent;
|
|
7899
|
+
// Render with context menu
|
|
7900
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [finalContent, contextMenuState.isOpen && contextMenuState.item && (jsxRuntime.jsx(Menu, { items: convertActionsToMenuItems(contextMenuState.item), position: contextMenuState.position, onClose: () => setContextMenuState({ isOpen: false, position: { x: 0, y: 0 }, item: null }) }))] }));
|
|
7823
7901
|
}
|
|
7824
7902
|
|
|
7825
7903
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -11631,12 +11709,12 @@ var bessel$1 = {};
|
|
|
11631
11709
|
|
|
11632
11710
|
/* bessel.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
|
11633
11711
|
|
|
11634
|
-
(function (exports) {
|
|
11712
|
+
(function (exports$1) {
|
|
11635
11713
|
(function (factory) {
|
|
11636
11714
|
/*jshint ignore:start */
|
|
11637
11715
|
if(typeof DO_NOT_EXPORT_BESSEL === 'undefined') {
|
|
11638
11716
|
{
|
|
11639
|
-
factory(exports);
|
|
11717
|
+
factory(exports$1);
|
|
11640
11718
|
}
|
|
11641
11719
|
} else {
|
|
11642
11720
|
factory({});
|
|
@@ -11870,7 +11948,7 @@ var bessel$1 = {};
|
|
|
11870
11948
|
|
|
11871
11949
|
var jstat = {exports: {}};
|
|
11872
11950
|
|
|
11873
|
-
(function (module, exports) {
|
|
11951
|
+
(function (module, exports$1) {
|
|
11874
11952
|
(function (window, factory) {
|
|
11875
11953
|
{
|
|
11876
11954
|
module.exports = factory();
|
|
@@ -30527,7 +30605,7 @@ var hasRequiredScheduler_production;
|
|
|
30527
30605
|
function requireScheduler_production () {
|
|
30528
30606
|
if (hasRequiredScheduler_production) return scheduler_production;
|
|
30529
30607
|
hasRequiredScheduler_production = 1;
|
|
30530
|
-
(function (exports) {
|
|
30608
|
+
(function (exports$1) {
|
|
30531
30609
|
function push(heap, node) {
|
|
30532
30610
|
var index = heap.length;
|
|
30533
30611
|
heap.push(node);
|
|
@@ -30576,16 +30654,16 @@ function requireScheduler_production () {
|
|
|
30576
30654
|
var diff = a.sortIndex - b.sortIndex;
|
|
30577
30655
|
return 0 !== diff ? diff : a.id - b.id;
|
|
30578
30656
|
}
|
|
30579
|
-
exports.unstable_now = void 0;
|
|
30657
|
+
exports$1.unstable_now = void 0;
|
|
30580
30658
|
if ("object" === typeof performance && "function" === typeof performance.now) {
|
|
30581
30659
|
var localPerformance = performance;
|
|
30582
|
-
exports.unstable_now = function () {
|
|
30660
|
+
exports$1.unstable_now = function () {
|
|
30583
30661
|
return localPerformance.now();
|
|
30584
30662
|
};
|
|
30585
30663
|
} else {
|
|
30586
30664
|
var localDate = Date,
|
|
30587
30665
|
initialTime = localDate.now();
|
|
30588
|
-
exports.unstable_now = function () {
|
|
30666
|
+
exports$1.unstable_now = function () {
|
|
30589
30667
|
return localDate.now() - initialTime;
|
|
30590
30668
|
};
|
|
30591
30669
|
}
|
|
@@ -30633,14 +30711,14 @@ function requireScheduler_production () {
|
|
|
30633
30711
|
function shouldYieldToHost() {
|
|
30634
30712
|
return needsPaint
|
|
30635
30713
|
? true
|
|
30636
|
-
: exports.unstable_now() - startTime < frameInterval
|
|
30714
|
+
: exports$1.unstable_now() - startTime < frameInterval
|
|
30637
30715
|
? false
|
|
30638
30716
|
: true;
|
|
30639
30717
|
}
|
|
30640
30718
|
function performWorkUntilDeadline() {
|
|
30641
30719
|
needsPaint = false;
|
|
30642
30720
|
if (isMessageLoopRunning) {
|
|
30643
|
-
var currentTime = exports.unstable_now();
|
|
30721
|
+
var currentTime = exports$1.unstable_now();
|
|
30644
30722
|
startTime = currentTime;
|
|
30645
30723
|
var hasMoreWork = true;
|
|
30646
30724
|
try {
|
|
@@ -30670,7 +30748,7 @@ function requireScheduler_production () {
|
|
|
30670
30748
|
var continuationCallback = callback(
|
|
30671
30749
|
currentTask.expirationTime <= currentTime
|
|
30672
30750
|
);
|
|
30673
|
-
currentTime = exports.unstable_now();
|
|
30751
|
+
currentTime = exports$1.unstable_now();
|
|
30674
30752
|
if ("function" === typeof continuationCallback) {
|
|
30675
30753
|
currentTask.callback = continuationCallback;
|
|
30676
30754
|
advanceTimers(currentTime);
|
|
@@ -30726,29 +30804,29 @@ function requireScheduler_production () {
|
|
|
30726
30804
|
};
|
|
30727
30805
|
function requestHostTimeout(callback, ms) {
|
|
30728
30806
|
taskTimeoutID = localSetTimeout(function () {
|
|
30729
|
-
callback(exports.unstable_now());
|
|
30807
|
+
callback(exports$1.unstable_now());
|
|
30730
30808
|
}, ms);
|
|
30731
30809
|
}
|
|
30732
|
-
exports.unstable_IdlePriority = 5;
|
|
30733
|
-
exports.unstable_ImmediatePriority = 1;
|
|
30734
|
-
exports.unstable_LowPriority = 4;
|
|
30735
|
-
exports.unstable_NormalPriority = 3;
|
|
30736
|
-
exports.unstable_Profiling = null;
|
|
30737
|
-
exports.unstable_UserBlockingPriority = 2;
|
|
30738
|
-
exports.unstable_cancelCallback = function (task) {
|
|
30810
|
+
exports$1.unstable_IdlePriority = 5;
|
|
30811
|
+
exports$1.unstable_ImmediatePriority = 1;
|
|
30812
|
+
exports$1.unstable_LowPriority = 4;
|
|
30813
|
+
exports$1.unstable_NormalPriority = 3;
|
|
30814
|
+
exports$1.unstable_Profiling = null;
|
|
30815
|
+
exports$1.unstable_UserBlockingPriority = 2;
|
|
30816
|
+
exports$1.unstable_cancelCallback = function (task) {
|
|
30739
30817
|
task.callback = null;
|
|
30740
30818
|
};
|
|
30741
|
-
exports.unstable_forceFrameRate = function (fps) {
|
|
30819
|
+
exports$1.unstable_forceFrameRate = function (fps) {
|
|
30742
30820
|
0 > fps || 125 < fps
|
|
30743
30821
|
? console.error(
|
|
30744
30822
|
"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"
|
|
30745
30823
|
)
|
|
30746
30824
|
: (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);
|
|
30747
30825
|
};
|
|
30748
|
-
exports.unstable_getCurrentPriorityLevel = function () {
|
|
30826
|
+
exports$1.unstable_getCurrentPriorityLevel = function () {
|
|
30749
30827
|
return currentPriorityLevel;
|
|
30750
30828
|
};
|
|
30751
|
-
exports.unstable_next = function (eventHandler) {
|
|
30829
|
+
exports$1.unstable_next = function (eventHandler) {
|
|
30752
30830
|
switch (currentPriorityLevel) {
|
|
30753
30831
|
case 1:
|
|
30754
30832
|
case 2:
|
|
@@ -30766,10 +30844,10 @@ function requireScheduler_production () {
|
|
|
30766
30844
|
currentPriorityLevel = previousPriorityLevel;
|
|
30767
30845
|
}
|
|
30768
30846
|
};
|
|
30769
|
-
exports.unstable_requestPaint = function () {
|
|
30847
|
+
exports$1.unstable_requestPaint = function () {
|
|
30770
30848
|
needsPaint = true;
|
|
30771
30849
|
};
|
|
30772
|
-
exports.unstable_runWithPriority = function (priorityLevel, eventHandler) {
|
|
30850
|
+
exports$1.unstable_runWithPriority = function (priorityLevel, eventHandler) {
|
|
30773
30851
|
switch (priorityLevel) {
|
|
30774
30852
|
case 1:
|
|
30775
30853
|
case 2:
|
|
@@ -30788,12 +30866,12 @@ function requireScheduler_production () {
|
|
|
30788
30866
|
currentPriorityLevel = previousPriorityLevel;
|
|
30789
30867
|
}
|
|
30790
30868
|
};
|
|
30791
|
-
exports.unstable_scheduleCallback = function (
|
|
30869
|
+
exports$1.unstable_scheduleCallback = function (
|
|
30792
30870
|
priorityLevel,
|
|
30793
30871
|
callback,
|
|
30794
30872
|
options
|
|
30795
30873
|
) {
|
|
30796
|
-
var currentTime = exports.unstable_now();
|
|
30874
|
+
var currentTime = exports$1.unstable_now();
|
|
30797
30875
|
"object" === typeof options && null !== options
|
|
30798
30876
|
? ((options = options.delay),
|
|
30799
30877
|
(options =
|
|
@@ -30844,8 +30922,8 @@ function requireScheduler_production () {
|
|
|
30844
30922
|
((isMessageLoopRunning = true), schedulePerformWorkUntilDeadline())));
|
|
30845
30923
|
return priorityLevel;
|
|
30846
30924
|
};
|
|
30847
|
-
exports.unstable_shouldYield = shouldYieldToHost;
|
|
30848
|
-
exports.unstable_wrapCallback = function (callback) {
|
|
30925
|
+
exports$1.unstable_shouldYield = shouldYieldToHost;
|
|
30926
|
+
exports$1.unstable_wrapCallback = function (callback) {
|
|
30849
30927
|
var parentPriorityLevel = currentPriorityLevel;
|
|
30850
30928
|
return function () {
|
|
30851
30929
|
var previousPriorityLevel = currentPriorityLevel;
|
|
@@ -30878,13 +30956,13 @@ var hasRequiredScheduler_development;
|
|
|
30878
30956
|
function requireScheduler_development () {
|
|
30879
30957
|
if (hasRequiredScheduler_development) return scheduler_development;
|
|
30880
30958
|
hasRequiredScheduler_development = 1;
|
|
30881
|
-
(function (exports) {
|
|
30959
|
+
(function (exports$1) {
|
|
30882
30960
|
"production" !== process.env.NODE_ENV &&
|
|
30883
30961
|
(function () {
|
|
30884
30962
|
function performWorkUntilDeadline() {
|
|
30885
30963
|
needsPaint = false;
|
|
30886
30964
|
if (isMessageLoopRunning) {
|
|
30887
|
-
var currentTime = exports.unstable_now();
|
|
30965
|
+
var currentTime = exports$1.unstable_now();
|
|
30888
30966
|
startTime = currentTime;
|
|
30889
30967
|
var hasMoreWork = true;
|
|
30890
30968
|
try {
|
|
@@ -30915,7 +30993,7 @@ function requireScheduler_development () {
|
|
|
30915
30993
|
var continuationCallback = callback(
|
|
30916
30994
|
currentTask.expirationTime <= currentTime
|
|
30917
30995
|
);
|
|
30918
|
-
currentTime = exports.unstable_now();
|
|
30996
|
+
currentTime = exports$1.unstable_now();
|
|
30919
30997
|
if ("function" === typeof continuationCallback) {
|
|
30920
30998
|
currentTask.callback = continuationCallback;
|
|
30921
30999
|
advanceTimers(currentTime);
|
|
@@ -31036,32 +31114,32 @@ function requireScheduler_development () {
|
|
|
31036
31114
|
function shouldYieldToHost() {
|
|
31037
31115
|
return needsPaint
|
|
31038
31116
|
? true
|
|
31039
|
-
: exports.unstable_now() - startTime < frameInterval
|
|
31117
|
+
: exports$1.unstable_now() - startTime < frameInterval
|
|
31040
31118
|
? false
|
|
31041
31119
|
: true;
|
|
31042
31120
|
}
|
|
31043
31121
|
function requestHostTimeout(callback, ms) {
|
|
31044
31122
|
taskTimeoutID = localSetTimeout(function () {
|
|
31045
|
-
callback(exports.unstable_now());
|
|
31123
|
+
callback(exports$1.unstable_now());
|
|
31046
31124
|
}, ms);
|
|
31047
31125
|
}
|
|
31048
31126
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
31049
31127
|
"function" ===
|
|
31050
31128
|
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
|
|
31051
31129
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
31052
|
-
exports.unstable_now = void 0;
|
|
31130
|
+
exports$1.unstable_now = void 0;
|
|
31053
31131
|
if (
|
|
31054
31132
|
"object" === typeof performance &&
|
|
31055
31133
|
"function" === typeof performance.now
|
|
31056
31134
|
) {
|
|
31057
31135
|
var localPerformance = performance;
|
|
31058
|
-
exports.unstable_now = function () {
|
|
31136
|
+
exports$1.unstable_now = function () {
|
|
31059
31137
|
return localPerformance.now();
|
|
31060
31138
|
};
|
|
31061
31139
|
} else {
|
|
31062
31140
|
var localDate = Date,
|
|
31063
31141
|
initialTime = localDate.now();
|
|
31064
|
-
exports.unstable_now = function () {
|
|
31142
|
+
exports$1.unstable_now = function () {
|
|
31065
31143
|
return localDate.now() - initialTime;
|
|
31066
31144
|
};
|
|
31067
31145
|
}
|
|
@@ -31098,26 +31176,26 @@ function requireScheduler_development () {
|
|
|
31098
31176
|
schedulePerformWorkUntilDeadline = function () {
|
|
31099
31177
|
localSetTimeout(performWorkUntilDeadline, 0);
|
|
31100
31178
|
};
|
|
31101
|
-
exports.unstable_IdlePriority = 5;
|
|
31102
|
-
exports.unstable_ImmediatePriority = 1;
|
|
31103
|
-
exports.unstable_LowPriority = 4;
|
|
31104
|
-
exports.unstable_NormalPriority = 3;
|
|
31105
|
-
exports.unstable_Profiling = null;
|
|
31106
|
-
exports.unstable_UserBlockingPriority = 2;
|
|
31107
|
-
exports.unstable_cancelCallback = function (task) {
|
|
31179
|
+
exports$1.unstable_IdlePriority = 5;
|
|
31180
|
+
exports$1.unstable_ImmediatePriority = 1;
|
|
31181
|
+
exports$1.unstable_LowPriority = 4;
|
|
31182
|
+
exports$1.unstable_NormalPriority = 3;
|
|
31183
|
+
exports$1.unstable_Profiling = null;
|
|
31184
|
+
exports$1.unstable_UserBlockingPriority = 2;
|
|
31185
|
+
exports$1.unstable_cancelCallback = function (task) {
|
|
31108
31186
|
task.callback = null;
|
|
31109
31187
|
};
|
|
31110
|
-
exports.unstable_forceFrameRate = function (fps) {
|
|
31188
|
+
exports$1.unstable_forceFrameRate = function (fps) {
|
|
31111
31189
|
0 > fps || 125 < fps
|
|
31112
31190
|
? console.error(
|
|
31113
31191
|
"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"
|
|
31114
31192
|
)
|
|
31115
31193
|
: (frameInterval = 0 < fps ? Math.floor(1e3 / fps) : 5);
|
|
31116
31194
|
};
|
|
31117
|
-
exports.unstable_getCurrentPriorityLevel = function () {
|
|
31195
|
+
exports$1.unstable_getCurrentPriorityLevel = function () {
|
|
31118
31196
|
return currentPriorityLevel;
|
|
31119
31197
|
};
|
|
31120
|
-
exports.unstable_next = function (eventHandler) {
|
|
31198
|
+
exports$1.unstable_next = function (eventHandler) {
|
|
31121
31199
|
switch (currentPriorityLevel) {
|
|
31122
31200
|
case 1:
|
|
31123
31201
|
case 2:
|
|
@@ -31135,10 +31213,10 @@ function requireScheduler_development () {
|
|
|
31135
31213
|
currentPriorityLevel = previousPriorityLevel;
|
|
31136
31214
|
}
|
|
31137
31215
|
};
|
|
31138
|
-
exports.unstable_requestPaint = function () {
|
|
31216
|
+
exports$1.unstable_requestPaint = function () {
|
|
31139
31217
|
needsPaint = true;
|
|
31140
31218
|
};
|
|
31141
|
-
exports.unstable_runWithPriority = function (priorityLevel, eventHandler) {
|
|
31219
|
+
exports$1.unstable_runWithPriority = function (priorityLevel, eventHandler) {
|
|
31142
31220
|
switch (priorityLevel) {
|
|
31143
31221
|
case 1:
|
|
31144
31222
|
case 2:
|
|
@@ -31157,12 +31235,12 @@ function requireScheduler_development () {
|
|
|
31157
31235
|
currentPriorityLevel = previousPriorityLevel;
|
|
31158
31236
|
}
|
|
31159
31237
|
};
|
|
31160
|
-
exports.unstable_scheduleCallback = function (
|
|
31238
|
+
exports$1.unstable_scheduleCallback = function (
|
|
31161
31239
|
priorityLevel,
|
|
31162
31240
|
callback,
|
|
31163
31241
|
options
|
|
31164
31242
|
) {
|
|
31165
|
-
var currentTime = exports.unstable_now();
|
|
31243
|
+
var currentTime = exports$1.unstable_now();
|
|
31166
31244
|
"object" === typeof options && null !== options
|
|
31167
31245
|
? ((options = options.delay),
|
|
31168
31246
|
(options =
|
|
@@ -31214,8 +31292,8 @@ function requireScheduler_development () {
|
|
|
31214
31292
|
schedulePerformWorkUntilDeadline())));
|
|
31215
31293
|
return priorityLevel;
|
|
31216
31294
|
};
|
|
31217
|
-
exports.unstable_shouldYield = shouldYieldToHost;
|
|
31218
|
-
exports.unstable_wrapCallback = function (callback) {
|
|
31295
|
+
exports$1.unstable_shouldYield = shouldYieldToHost;
|
|
31296
|
+
exports$1.unstable_wrapCallback = function (callback) {
|
|
31219
31297
|
var parentPriorityLevel = currentPriorityLevel;
|
|
31220
31298
|
return function () {
|
|
31221
31299
|
var previousPriorityLevel = currentPriorityLevel;
|
|
@@ -35476,8 +35554,8 @@ return CRC32;
|
|
|
35476
35554
|
})();
|
|
35477
35555
|
/* [MS-CFB] v20171201 */
|
|
35478
35556
|
var CFB = /*#__PURE__*/(function _CFB(){
|
|
35479
|
-
var exports = {};
|
|
35480
|
-
exports.version = '1.2.1';
|
|
35557
|
+
var exports$1 = {};
|
|
35558
|
+
exports$1.version = '1.2.1';
|
|
35481
35559
|
/* [MS-CFB] 2.6.4 */
|
|
35482
35560
|
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
|
35483
35561
|
var L = l.split("/"), R = r.split("/");
|
|
@@ -37149,12 +37227,12 @@ function cfb_mov(cfb/*:CFBContainer*/, old_name/*:string*/, new_name/*:string*/)
|
|
|
37149
37227
|
|
|
37150
37228
|
function cfb_gc(cfb/*:CFBContainer*/)/*:void*/ { rebuild_cfb(cfb, true); }
|
|
37151
37229
|
|
|
37152
|
-
exports.find = find;
|
|
37153
|
-
exports.read = read;
|
|
37154
|
-
exports.parse = parse;
|
|
37155
|
-
exports.write = write;
|
|
37156
|
-
exports.writeFile = write_file;
|
|
37157
|
-
exports.utils = {
|
|
37230
|
+
exports$1.find = find;
|
|
37231
|
+
exports$1.read = read;
|
|
37232
|
+
exports$1.parse = parse;
|
|
37233
|
+
exports$1.write = write;
|
|
37234
|
+
exports$1.writeFile = write_file;
|
|
37235
|
+
exports$1.utils = {
|
|
37158
37236
|
cfb_new: cfb_new,
|
|
37159
37237
|
cfb_add: cfb_add,
|
|
37160
37238
|
cfb_del: cfb_del,
|
|
@@ -37170,7 +37248,7 @@ exports.utils = {
|
|
|
37170
37248
|
consts: consts
|
|
37171
37249
|
};
|
|
37172
37250
|
|
|
37173
|
-
return exports;
|
|
37251
|
+
return exports$1;
|
|
37174
37252
|
})();
|
|
37175
37253
|
|
|
37176
37254
|
/* normalize data for blob ctor */
|
|
@@ -58633,6 +58711,137 @@ function CurrencyDisplay({ amount, currency = 'USD', locale = 'en-US', className
|
|
|
58633
58711
|
return (jsxRuntime.jsx("span", { className: combinedClasses, title: `${currency} ${safeAmount.toFixed(precision)}`, children: displayValue }));
|
|
58634
58712
|
}
|
|
58635
58713
|
|
|
58714
|
+
/**
|
|
58715
|
+
* CurrencyInput - Specialized input for monetary values
|
|
58716
|
+
*
|
|
58717
|
+
* Automatically formats currency values with proper symbols and thousands separators.
|
|
58718
|
+
* Handles parsing and validation of numeric currency input.
|
|
58719
|
+
*
|
|
58720
|
+
* @example Basic usage
|
|
58721
|
+
* ```tsx
|
|
58722
|
+
* <CurrencyInput
|
|
58723
|
+
* label="Price"
|
|
58724
|
+
* value={price}
|
|
58725
|
+
* onChange={setPrice}
|
|
58726
|
+
* currency="USD"
|
|
58727
|
+
* />
|
|
58728
|
+
* ```
|
|
58729
|
+
*
|
|
58730
|
+
* @example With validation
|
|
58731
|
+
* ```tsx
|
|
58732
|
+
* <CurrencyInput
|
|
58733
|
+
* label="Budget"
|
|
58734
|
+
* value={budget}
|
|
58735
|
+
* onChange={setBudget}
|
|
58736
|
+
* min={0}
|
|
58737
|
+
* max={10000}
|
|
58738
|
+
* validationState={budget > 10000 ? 'error' : null}
|
|
58739
|
+
* validationMessage={budget > 10000 ? 'Exceeds maximum budget' : ''}
|
|
58740
|
+
* />
|
|
58741
|
+
* ```
|
|
58742
|
+
*/
|
|
58743
|
+
const CurrencyInput = React.forwardRef(({ value, onChange, currency = 'USD', locale = 'en-US', precision = 2, allowNegative = false, min, max, onBlur, onFocus, ...props }, ref) => {
|
|
58744
|
+
const [displayValue, setDisplayValue] = React.useState('');
|
|
58745
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
58746
|
+
// Get currency symbol
|
|
58747
|
+
const getCurrencySymbol = () => {
|
|
58748
|
+
const formatter = new Intl.NumberFormat(locale, {
|
|
58749
|
+
style: 'currency',
|
|
58750
|
+
currency,
|
|
58751
|
+
});
|
|
58752
|
+
const parts = formatter.formatToParts(0);
|
|
58753
|
+
const symbolPart = parts.find(part => part.type === 'currency');
|
|
58754
|
+
return symbolPart?.value || '$';
|
|
58755
|
+
};
|
|
58756
|
+
const currencySymbol = getCurrencySymbol();
|
|
58757
|
+
// Format number as currency
|
|
58758
|
+
const formatCurrency = (num) => {
|
|
58759
|
+
const formatter = new Intl.NumberFormat(locale, {
|
|
58760
|
+
minimumFractionDigits: isFocused ? 0 : precision,
|
|
58761
|
+
maximumFractionDigits: precision,
|
|
58762
|
+
});
|
|
58763
|
+
return formatter.format(num);
|
|
58764
|
+
};
|
|
58765
|
+
// Parse display value to number
|
|
58766
|
+
const parseValue = (str) => {
|
|
58767
|
+
if (!str || str === '')
|
|
58768
|
+
return null;
|
|
58769
|
+
// Remove all non-numeric characters except decimal point and minus sign
|
|
58770
|
+
let cleaned = str.replace(/[^\d.-]/g, '');
|
|
58771
|
+
// Handle multiple decimal points
|
|
58772
|
+
const parts = cleaned.split('.');
|
|
58773
|
+
if (parts.length > 2) {
|
|
58774
|
+
cleaned = parts[0] + '.' + parts.slice(1).join('');
|
|
58775
|
+
}
|
|
58776
|
+
// Handle multiple minus signs (keep only first)
|
|
58777
|
+
const minusCount = (cleaned.match(/-/g) || []).length;
|
|
58778
|
+
if (minusCount > 1) {
|
|
58779
|
+
const hasLeadingMinus = cleaned.startsWith('-');
|
|
58780
|
+
cleaned = cleaned.replace(/-/g, '');
|
|
58781
|
+
if (hasLeadingMinus)
|
|
58782
|
+
cleaned = '-' + cleaned;
|
|
58783
|
+
}
|
|
58784
|
+
// Parse to float
|
|
58785
|
+
const num = parseFloat(cleaned);
|
|
58786
|
+
if (isNaN(num))
|
|
58787
|
+
return null;
|
|
58788
|
+
// Apply precision
|
|
58789
|
+
return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision);
|
|
58790
|
+
};
|
|
58791
|
+
// Update display value when external value changes
|
|
58792
|
+
React.useEffect(() => {
|
|
58793
|
+
if (value === undefined || value === null || value === '') {
|
|
58794
|
+
setDisplayValue('');
|
|
58795
|
+
}
|
|
58796
|
+
else {
|
|
58797
|
+
const numValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
58798
|
+
if (!isNaN(numValue)) {
|
|
58799
|
+
setDisplayValue(formatCurrency(numValue));
|
|
58800
|
+
}
|
|
58801
|
+
}
|
|
58802
|
+
}, [value, isFocused]);
|
|
58803
|
+
const handleChange = (e) => {
|
|
58804
|
+
const inputValue = e.target.value;
|
|
58805
|
+
setDisplayValue(inputValue);
|
|
58806
|
+
const numValue = parseValue(inputValue);
|
|
58807
|
+
// Validate constraints
|
|
58808
|
+
if (numValue !== null) {
|
|
58809
|
+
if (!allowNegative && numValue < 0)
|
|
58810
|
+
return;
|
|
58811
|
+
if (min !== undefined && numValue < min)
|
|
58812
|
+
return;
|
|
58813
|
+
if (max !== undefined && numValue > max)
|
|
58814
|
+
return;
|
|
58815
|
+
}
|
|
58816
|
+
onChange?.(numValue);
|
|
58817
|
+
};
|
|
58818
|
+
const handleFocus = (e) => {
|
|
58819
|
+
setIsFocused(true);
|
|
58820
|
+
// Remove formatting when focused for easier editing
|
|
58821
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
58822
|
+
const numValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
58823
|
+
if (!isNaN(numValue)) {
|
|
58824
|
+
setDisplayValue(numValue.toString());
|
|
58825
|
+
}
|
|
58826
|
+
}
|
|
58827
|
+
onFocus?.(e);
|
|
58828
|
+
};
|
|
58829
|
+
const handleBlur = (e) => {
|
|
58830
|
+
setIsFocused(false);
|
|
58831
|
+
// Reformat on blur
|
|
58832
|
+
const numValue = parseValue(displayValue);
|
|
58833
|
+
if (numValue !== null) {
|
|
58834
|
+
setDisplayValue(formatCurrency(numValue));
|
|
58835
|
+
}
|
|
58836
|
+
else if (displayValue === '') {
|
|
58837
|
+
setDisplayValue('');
|
|
58838
|
+
}
|
|
58839
|
+
onBlur?.(e);
|
|
58840
|
+
};
|
|
58841
|
+
return (jsxRuntime.jsx(Input, { ref: ref, type: "text", value: displayValue, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, prefix: currencySymbol, ...props }));
|
|
58842
|
+
});
|
|
58843
|
+
CurrencyInput.displayName = 'CurrencyInput';
|
|
58844
|
+
|
|
58636
58845
|
const formatOptions = {
|
|
58637
58846
|
short: {
|
|
58638
58847
|
year: 'numeric',
|
|
@@ -59543,8 +59752,19 @@ const AppLayout = ({ children, toolbarSections = [], className = '', showToolbar
|
|
|
59543
59752
|
* </Layout>
|
|
59544
59753
|
* ```
|
|
59545
59754
|
*/
|
|
59546
|
-
function PageLayout({ title, description, children, className = '', headerContent }) {
|
|
59547
|
-
|
|
59755
|
+
function PageLayout({ title, description, children, className = '', headerContent, maxWidth = '7xl', fixed = false }) {
|
|
59756
|
+
// Responsive padding classes - fixed left/top, responsive right/bottom
|
|
59757
|
+
const paddingClasses = fixed
|
|
59758
|
+
? 'p-6 pb-20'
|
|
59759
|
+
: 'pt-6 pl-6 pr-2 pb-8 sm:pr-4 md:pr-6 sm:pb-12 md:pb-16 lg:pb-20';
|
|
59760
|
+
const maxWidthClasses = {
|
|
59761
|
+
'4xl': 'max-w-4xl',
|
|
59762
|
+
'5xl': 'max-w-5xl',
|
|
59763
|
+
'6xl': 'max-w-6xl',
|
|
59764
|
+
'7xl': 'max-w-7xl',
|
|
59765
|
+
'full': 'max-w-full',
|
|
59766
|
+
};
|
|
59767
|
+
return (jsxRuntime.jsxs(Page, { padding: "none", maxWidth: maxWidth, fixed: fixed, children: [headerContent, jsxRuntime.jsxs("div", { className: `${paddingClasses} ${maxWidthClasses[maxWidth]} mx-auto ${className}`, children: [jsxRuntime.jsxs("div", { className: "mb-8", children: [jsxRuntime.jsx("h1", { className: "text-3xl font-bold text-ink-900 mb-2", children: title }), description && (jsxRuntime.jsx("p", { className: "text-ink-600", children: description }))] }), children] })] }));
|
|
59548
59768
|
}
|
|
59549
59769
|
|
|
59550
59770
|
const sizeClasses = {
|
|
@@ -59916,6 +60136,113 @@ function loadColumnOrder(tableId) {
|
|
|
59916
60136
|
}
|
|
59917
60137
|
}
|
|
59918
60138
|
|
|
60139
|
+
/**
|
|
60140
|
+
* Export data to Excel file
|
|
60141
|
+
*
|
|
60142
|
+
* A standalone utility for exporting any data array to Excel format.
|
|
60143
|
+
* Works independently of the Spreadsheet component.
|
|
60144
|
+
*
|
|
60145
|
+
* **Features:**
|
|
60146
|
+
* - Export arrays of objects to Excel
|
|
60147
|
+
* - Custom column headers and ordering
|
|
60148
|
+
* - Value formatting with custom functions
|
|
60149
|
+
* - Multi-sheet support
|
|
60150
|
+
* - Automatic type handling
|
|
60151
|
+
*
|
|
60152
|
+
* @example
|
|
60153
|
+
* ```typescript
|
|
60154
|
+
* // Simple export - uses object keys as headers
|
|
60155
|
+
* const data = [
|
|
60156
|
+
* { id: 1, name: 'Product A', price: 29.99 },
|
|
60157
|
+
* { id: 2, name: 'Product B', price: 49.99 },
|
|
60158
|
+
* ];
|
|
60159
|
+
* exportToExcel({ data, filename: 'products.xlsx' });
|
|
60160
|
+
*
|
|
60161
|
+
* // Custom columns with formatting
|
|
60162
|
+
* exportToExcel({
|
|
60163
|
+
* data: users,
|
|
60164
|
+
* filename: 'users.xlsx',
|
|
60165
|
+
* columns: [
|
|
60166
|
+
* { key: 'id', label: 'ID' },
|
|
60167
|
+
* { key: 'name', label: 'Full Name' },
|
|
60168
|
+
* { key: 'email', label: 'Email Address' },
|
|
60169
|
+
* { key: 'createdAt', label: 'Joined', format: (date) => new Date(date).toLocaleDateString() },
|
|
60170
|
+
* { key: 'isActive', label: 'Status', format: (active) => active ? 'Active' : 'Inactive' },
|
|
60171
|
+
* ],
|
|
60172
|
+
* });
|
|
60173
|
+
*
|
|
60174
|
+
* // Multi-sheet export
|
|
60175
|
+
* const wb = utils.book_new();
|
|
60176
|
+
* exportToExcel({ data: products, sheetName: 'Products', workbook: wb });
|
|
60177
|
+
* exportToExcel({ data: orders, sheetName: 'Orders', workbook: wb });
|
|
60178
|
+
* writeFile(wb, 'multi-sheet.xlsx');
|
|
60179
|
+
* ```
|
|
60180
|
+
*
|
|
60181
|
+
* @param options - Export configuration options
|
|
60182
|
+
* @returns WorkBook if workbook option provided, otherwise void (auto-downloads)
|
|
60183
|
+
*/
|
|
60184
|
+
function exportToExcel({ data, filename = 'export.xlsx', sheetName = 'Sheet1', columns, includeHeaders = true, workbook, }) {
|
|
60185
|
+
if (!data || data.length === 0) {
|
|
60186
|
+
throw new Error('No data provided for export');
|
|
60187
|
+
}
|
|
60188
|
+
let worksheetData;
|
|
60189
|
+
if (columns) {
|
|
60190
|
+
// Use custom columns with specific ordering and formatting
|
|
60191
|
+
const headers = columns.map((col) => col.label);
|
|
60192
|
+
const rows = data.map((row) => columns.map((col) => {
|
|
60193
|
+
const value = row[col.key];
|
|
60194
|
+
return col.format ? col.format(value) : value ?? '';
|
|
60195
|
+
}));
|
|
60196
|
+
worksheetData = includeHeaders ? [headers, ...rows] : rows;
|
|
60197
|
+
}
|
|
60198
|
+
else {
|
|
60199
|
+
// Auto-generate from object keys
|
|
60200
|
+
if (includeHeaders) {
|
|
60201
|
+
const headers = Object.keys(data[0]);
|
|
60202
|
+
const rows = data.map((row) => headers.map((key) => row[key] ?? ''));
|
|
60203
|
+
worksheetData = [headers, ...rows];
|
|
60204
|
+
}
|
|
60205
|
+
else {
|
|
60206
|
+
const headers = Object.keys(data[0]);
|
|
60207
|
+
worksheetData = data.map((row) => headers.map((key) => row[key] ?? ''));
|
|
60208
|
+
}
|
|
60209
|
+
}
|
|
60210
|
+
const worksheet = utils.aoa_to_sheet(worksheetData);
|
|
60211
|
+
// If workbook provided, add sheet and return (for multi-sheet exports)
|
|
60212
|
+
if (workbook) {
|
|
60213
|
+
utils.book_append_sheet(workbook, worksheet, sheetName);
|
|
60214
|
+
return workbook;
|
|
60215
|
+
}
|
|
60216
|
+
// Otherwise, create workbook and download
|
|
60217
|
+
const newWorkbook = utils.book_new();
|
|
60218
|
+
utils.book_append_sheet(newWorkbook, worksheet, sheetName);
|
|
60219
|
+
writeFileSync(newWorkbook, filename);
|
|
60220
|
+
}
|
|
60221
|
+
function exportDataTableToExcel({ data, columns, filename = 'export.xlsx', sheetName = 'Sheet1', }) {
|
|
60222
|
+
const excelColumns = columns.map((col) => ({
|
|
60223
|
+
key: col.key,
|
|
60224
|
+
label: col.header,
|
|
60225
|
+
}));
|
|
60226
|
+
exportToExcel({
|
|
60227
|
+
data,
|
|
60228
|
+
columns: excelColumns,
|
|
60229
|
+
filename,
|
|
60230
|
+
sheetName,
|
|
60231
|
+
});
|
|
60232
|
+
}
|
|
60233
|
+
function createMultiSheetExcel({ filename, sheets }) {
|
|
60234
|
+
const workbook = utils.book_new();
|
|
60235
|
+
sheets.forEach((sheet) => {
|
|
60236
|
+
exportToExcel({
|
|
60237
|
+
data: sheet.data,
|
|
60238
|
+
sheetName: sheet.name,
|
|
60239
|
+
columns: sheet.columns,
|
|
60240
|
+
workbook,
|
|
60241
|
+
});
|
|
60242
|
+
});
|
|
60243
|
+
writeFileSync(workbook, filename);
|
|
60244
|
+
}
|
|
60245
|
+
|
|
59919
60246
|
function useColumnResize(options = {}) {
|
|
59920
60247
|
const { tableId, persist = false } = options;
|
|
59921
60248
|
const [columnWidths, setColumnWidths] = React.useState({});
|
|
@@ -60066,6 +60393,7 @@ exports.ConfirmDialog = ConfirmDialog;
|
|
|
60066
60393
|
exports.ContextMenu = ContextMenu;
|
|
60067
60394
|
exports.ControlBar = ControlBar;
|
|
60068
60395
|
exports.CurrencyDisplay = CurrencyDisplay;
|
|
60396
|
+
exports.CurrencyInput = CurrencyInput;
|
|
60069
60397
|
exports.Dashboard = Dashboard;
|
|
60070
60398
|
exports.DashboardContent = DashboardContent;
|
|
60071
60399
|
exports.DashboardHeader = DashboardHeader;
|
|
@@ -60169,8 +60497,11 @@ exports.addWarningMessage = addWarningMessage;
|
|
|
60169
60497
|
exports.calculateColumnWidth = calculateColumnWidth;
|
|
60170
60498
|
exports.createActionsSection = createActionsSection;
|
|
60171
60499
|
exports.createFiltersSection = createFiltersSection;
|
|
60500
|
+
exports.createMultiSheetExcel = createMultiSheetExcel;
|
|
60172
60501
|
exports.createPageControlsSection = createPageControlsSection;
|
|
60173
60502
|
exports.createQueryDetailsSection = createQueryDetailsSection;
|
|
60503
|
+
exports.exportDataTableToExcel = exportDataTableToExcel;
|
|
60504
|
+
exports.exportToExcel = exportToExcel;
|
|
60174
60505
|
exports.formatStatisticValue = formatStatisticValue;
|
|
60175
60506
|
exports.formatStatistics = formatStatistics;
|
|
60176
60507
|
exports.loadColumnOrder = loadColumnOrder;
|