@liiift-studio/mac-os9-ui 0.2.23 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +286 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +34 -6
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +385 -34
- package/dist/index.js +285 -29
- package/dist/index.js.map +1 -1
- package/dist/types/components/FolderList/FolderList.d.ts +102 -5
- package/dist/types/components/FolderList/index.d.ts +1 -1
- package/dist/types/components/ListView/ListView.d.ts +124 -1
- package/dist/types/components/ListView/index.d.ts +1 -1
- package/dist/types/components/Window/Window.d.ts +69 -0
- package/dist/types/components/Window/index.d.ts +1 -1
- package/dist/types/index.d.ts +4 -3
- package/dist/types/types/index.d.ts +36 -2
- package/dist/types/utils/classNames.d.ts +29 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -718,7 +718,45 @@ const Tabs = ({ children, defaultActiveTab = 0, activeTab: controlledActiveTab,
|
|
|
718
718
|
};
|
|
719
719
|
Tabs.displayName = 'Tabs';
|
|
720
720
|
|
|
721
|
-
|
|
721
|
+
// Utility for merging CSS class names
|
|
722
|
+
// Filters out falsy values and joins valid class names with spaces
|
|
723
|
+
/**
|
|
724
|
+
* Merges multiple class names into a single string
|
|
725
|
+
* Filters out undefined, null, false, and empty strings
|
|
726
|
+
*
|
|
727
|
+
* @param classes - Class names to merge
|
|
728
|
+
* @returns Merged class name string
|
|
729
|
+
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```ts
|
|
732
|
+
* mergeClasses('base', isActive && 'active', undefined, 'custom')
|
|
733
|
+
* // Returns: "base active custom"
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
const mergeClasses = (...classes) => {
|
|
737
|
+
return classes.filter(Boolean).join(' ');
|
|
738
|
+
};
|
|
739
|
+
/**
|
|
740
|
+
* Creates a class name builder function with a base class
|
|
741
|
+
* Useful for component-level class management
|
|
742
|
+
*
|
|
743
|
+
* @param baseClass - Base class name
|
|
744
|
+
* @returns Function that merges additional classes with base
|
|
745
|
+
*
|
|
746
|
+
* @example
|
|
747
|
+
* ```ts
|
|
748
|
+
* const cn = createClassBuilder('button');
|
|
749
|
+
* cn('primary', isDisabled && 'disabled')
|
|
750
|
+
* // Returns: "button primary disabled"
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
const createClassBuilder = (baseClass) => {
|
|
754
|
+
return (...additionalClasses) => {
|
|
755
|
+
return mergeClasses(baseClass, ...additionalClasses);
|
|
756
|
+
};
|
|
757
|
+
};
|
|
758
|
+
|
|
759
|
+
var styles$6 = {"window":"Window-module_window","window--active":"Window-module_window--active","window--inactive":"Window-module_window--inactive","window--draggable":"Window-module_window--draggable","titleBar":"Window-module_titleBar","titleCenter":"Window-module_titleCenter","titleBar--draggable":"Window-module_titleBar--draggable","titleBar--dragging":"Window-module_titleBar--dragging","controls":"Window-module_controls","controlButton":"Window-module_controlButton","closeBox":"Window-module_closeBox","minimizeBox":"Window-module_minimizeBox","maximizeBox":"Window-module_maximizeBox","titleText":"Window-module_titleText","content":"Window-module_content","resizeHandle":"Window-module_resizeHandle"};
|
|
722
760
|
|
|
723
761
|
/**
|
|
724
762
|
* Mac OS 9 style Window component
|
|
@@ -731,6 +769,7 @@ var styles$6 = {"window":"Window-module_window","window--active":"Window-module_
|
|
|
731
769
|
* - Active/inactive states
|
|
732
770
|
* - Composable with custom TitleBar component
|
|
733
771
|
* - Flexible sizing
|
|
772
|
+
* - Draggable windows (optional) - drag by title bar
|
|
734
773
|
*
|
|
735
774
|
* @example
|
|
736
775
|
* ```tsx
|
|
@@ -752,18 +791,120 @@ var styles$6 = {"window":"Window-module_window","window--active":"Window-module_
|
|
|
752
791
|
* >
|
|
753
792
|
* <p>Content</p>
|
|
754
793
|
* </Window>
|
|
794
|
+
*
|
|
795
|
+
* // Draggable window (uncontrolled)
|
|
796
|
+
* <Window title="Draggable" draggable>
|
|
797
|
+
* <p>Drag me by the title bar!</p>
|
|
798
|
+
* </Window>
|
|
799
|
+
*
|
|
800
|
+
* // Draggable window with initial position
|
|
801
|
+
* <Window
|
|
802
|
+
* title="Positioned"
|
|
803
|
+
* draggable
|
|
804
|
+
* defaultPosition={{ x: 100, y: 100 }}
|
|
805
|
+
* >
|
|
806
|
+
* <p>Starts at a specific position</p>
|
|
807
|
+
* </Window>
|
|
808
|
+
*
|
|
809
|
+
* // Controlled draggable window
|
|
810
|
+
* const [pos, setPos] = useState({ x: 0, y: 0 });
|
|
811
|
+
* <Window
|
|
812
|
+
* title="Controlled"
|
|
813
|
+
* draggable
|
|
814
|
+
* position={pos}
|
|
815
|
+
* onPositionChange={setPos}
|
|
816
|
+
* >
|
|
817
|
+
* <p>Parent controls position</p>
|
|
818
|
+
* </Window>
|
|
755
819
|
* ```
|
|
756
820
|
*/
|
|
757
|
-
const Window = React.forwardRef(({ children, title, titleBar, active = true, width = 'auto', height = 'auto', className = '', contentClassName = '', showControls = true, onClose, onMinimize, onMaximize, onMouseEnter, resizable = false, }, ref) => {
|
|
821
|
+
const Window = React.forwardRef(({ children, title, titleBar, active = true, width = 'auto', height = 'auto', className = '', contentClassName = '', classes, showControls = true, onClose, onMinimize, onMaximize, onMouseEnter, resizable = false, draggable = false, defaultPosition, position: controlledPosition, onPositionChange, }, ref) => {
|
|
822
|
+
// Drag state management
|
|
823
|
+
const [internalPosition, setInternalPosition] = React.useState(defaultPosition || null);
|
|
824
|
+
const [isDragging, setIsDragging] = React.useState(false);
|
|
825
|
+
const [hasBeenDragged, setHasBeenDragged] = React.useState(!!(defaultPosition || controlledPosition));
|
|
826
|
+
const dragStartRef = React.useRef(null);
|
|
827
|
+
// Use controlled position if provided, otherwise use internal state
|
|
828
|
+
const currentPosition = controlledPosition || internalPosition;
|
|
829
|
+
// Handle mouse down on title bar to start dragging
|
|
830
|
+
const handleTitleBarMouseDown = React.useCallback((event) => {
|
|
831
|
+
if (!draggable)
|
|
832
|
+
return;
|
|
833
|
+
// Don't start drag if clicking on buttons
|
|
834
|
+
if (event.target.closest('button')) {
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
event.preventDefault();
|
|
838
|
+
const windowElement = event.currentTarget.closest(`.${styles$6.window}`);
|
|
839
|
+
if (!windowElement)
|
|
840
|
+
return;
|
|
841
|
+
const rect = windowElement.getBoundingClientRect();
|
|
842
|
+
// Get the parent container to calculate position relative to it
|
|
843
|
+
const parent = windowElement.offsetParent;
|
|
844
|
+
const parentRect = parent ? parent.getBoundingClientRect() : { left: 0, top: 0 };
|
|
845
|
+
// Store drag start info - offset from mouse to window position within parent
|
|
846
|
+
// This accounts for the parent's coordinate system
|
|
847
|
+
dragStartRef.current = {
|
|
848
|
+
x: event.clientX - (rect.left - parentRect.left),
|
|
849
|
+
y: event.clientY - (rect.top - parentRect.top),
|
|
850
|
+
};
|
|
851
|
+
setIsDragging(true);
|
|
852
|
+
}, [draggable]);
|
|
853
|
+
// Handle mouse move during drag
|
|
854
|
+
React.useEffect(() => {
|
|
855
|
+
if (!isDragging || !dragStartRef.current)
|
|
856
|
+
return;
|
|
857
|
+
const handleMouseMove = (event) => {
|
|
858
|
+
event.preventDefault();
|
|
859
|
+
if (!dragStartRef.current)
|
|
860
|
+
return;
|
|
861
|
+
// Get the window element to find its parent
|
|
862
|
+
const windowElements = document.querySelectorAll(`.${styles$6.window}`);
|
|
863
|
+
let windowElement = null;
|
|
864
|
+
// Find the dragging window (the one with position absolute or the first one)
|
|
865
|
+
for (const el of Array.from(windowElements)) {
|
|
866
|
+
const htmlEl = el;
|
|
867
|
+
if (htmlEl.style.position === 'absolute' || windowElements.length === 1) {
|
|
868
|
+
windowElement = htmlEl;
|
|
869
|
+
break;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
if (!windowElement)
|
|
873
|
+
return;
|
|
874
|
+
// Get parent container to calculate position relative to it
|
|
875
|
+
const parent = windowElement.offsetParent;
|
|
876
|
+
const parentRect = parent ? parent.getBoundingClientRect() : { left: 0, top: 0 };
|
|
877
|
+
const newPosition = {
|
|
878
|
+
x: event.clientX - parentRect.left - dragStartRef.current.x,
|
|
879
|
+
y: event.clientY - parentRect.top - dragStartRef.current.y,
|
|
880
|
+
};
|
|
881
|
+
// Update position
|
|
882
|
+
if (controlledPosition && onPositionChange) {
|
|
883
|
+
onPositionChange(newPosition);
|
|
884
|
+
}
|
|
885
|
+
else {
|
|
886
|
+
setInternalPosition(newPosition);
|
|
887
|
+
}
|
|
888
|
+
// Mark as dragged
|
|
889
|
+
if (!hasBeenDragged) {
|
|
890
|
+
setHasBeenDragged(true);
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
const handleMouseUp = () => {
|
|
894
|
+
setIsDragging(false);
|
|
895
|
+
dragStartRef.current = null;
|
|
896
|
+
};
|
|
897
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
898
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
899
|
+
return () => {
|
|
900
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
901
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
902
|
+
};
|
|
903
|
+
}, [isDragging, controlledPosition, onPositionChange, hasBeenDragged]);
|
|
758
904
|
// Class names
|
|
759
|
-
const windowClassNames = [
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
className,
|
|
763
|
-
]
|
|
764
|
-
.filter(Boolean)
|
|
765
|
-
.join(' ');
|
|
766
|
-
const contentClassNames = [styles$6.content, contentClassName].filter(Boolean).join(' ');
|
|
905
|
+
const windowClassNames = mergeClasses(styles$6.window, active ? styles$6['window--active'] : styles$6['window--inactive'], draggable && hasBeenDragged && styles$6['window--draggable'], className, classes?.root);
|
|
906
|
+
const contentClassNames = mergeClasses(styles$6.content, contentClassName, classes?.content);
|
|
907
|
+
const titleBarClassNames = mergeClasses(styles$6.titleBar, draggable && styles$6['titleBar--draggable'], isDragging && styles$6['titleBar--dragging'], classes?.titleBar);
|
|
767
908
|
// Window style
|
|
768
909
|
const windowStyle = {};
|
|
769
910
|
if (width !== 'auto') {
|
|
@@ -772,13 +913,19 @@ const Window = React.forwardRef(({ children, title, titleBar, active = true, wid
|
|
|
772
913
|
if (height !== 'auto') {
|
|
773
914
|
windowStyle.height = typeof height === 'number' ? `${height}px` : height;
|
|
774
915
|
}
|
|
916
|
+
// Apply position if draggable and has been dragged
|
|
917
|
+
if (draggable && hasBeenDragged && currentPosition) {
|
|
918
|
+
windowStyle.position = 'absolute';
|
|
919
|
+
windowStyle.left = `${currentPosition.x}px`;
|
|
920
|
+
windowStyle.top = `${currentPosition.y}px`;
|
|
921
|
+
}
|
|
775
922
|
// Render title bar if title provided and no custom titleBar
|
|
776
923
|
const renderTitleBar = () => {
|
|
777
924
|
if (titleBar) {
|
|
778
925
|
return titleBar;
|
|
779
926
|
}
|
|
780
927
|
if (title) {
|
|
781
|
-
return (jsxRuntime.jsxs("div", { className:
|
|
928
|
+
return (jsxRuntime.jsxs("div", { className: titleBarClassNames, "data-numControls": [onClose, onMinimize, onMaximize].filter(Boolean).length, onMouseDown: handleTitleBarMouseDown, children: [showControls && (jsxRuntime.jsxs("div", { className: mergeClasses(styles$6.controls, classes?.controls), children: [onClose && (jsxRuntime.jsx("button", { type: "button", className: mergeClasses(styles$6.controlButton, classes?.controlButton), onClick: onClose, "aria-label": "Close", title: "Close", children: jsxRuntime.jsx("div", { className: styles$6.closeBox }) })), onMinimize && (jsxRuntime.jsx("button", { type: "button", className: mergeClasses(styles$6.controlButton, classes?.controlButton), onClick: onMinimize, "aria-label": "Minimize", title: "Minimize", children: jsxRuntime.jsx("div", { className: styles$6.minimizeBox }) })), onMaximize && (jsxRuntime.jsx("button", { type: "button", className: mergeClasses(styles$6.controlButton, classes?.controlButton), onClick: onMaximize, "aria-label": "Maximize", title: "Maximize", children: jsxRuntime.jsx("div", { className: styles$6.maximizeBox }) }))] })), jsxRuntime.jsxs("div", { className: styles$6.titleCenter, children: [jsxRuntime.jsxs("svg", { width: "132", height: "13", viewBox: "0 0 132 13", fill: "none", preserveAspectRatio: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntime.jsx("rect", { width: "130.517", height: "13", fill: "#DDDDDD" }), jsxRuntime.jsx("rect", { width: "1", height: "13", fill: "#EEEEEE" }), jsxRuntime.jsx("rect", { x: "130", width: "1", height: "13", fill: "#C5C5C5" }), jsxRuntime.jsx("rect", { y: "1", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "5", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "9", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "3", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "7", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "11", width: "131.268", height: "1", fill: "#999999" })] }), jsxRuntime.jsx("div", { className: mergeClasses(styles$6.titleText, classes?.titleText, 'bold'), children: title }), jsxRuntime.jsxs("svg", { width: "132", height: "13", viewBox: "0 0 132 13", fill: "none", preserveAspectRatio: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntime.jsx("rect", { width: "130.517", height: "13", fill: "#DDDDDD" }), jsxRuntime.jsx("rect", { width: "1", height: "13", fill: "#EEEEEE" }), jsxRuntime.jsx("rect", { x: "130", width: "1", height: "13", fill: "#C5C5C5" }), jsxRuntime.jsx("rect", { y: "1", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "5", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "9", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "3", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "7", width: "131.268", height: "1", fill: "#999999" }), jsxRuntime.jsx("rect", { y: "11", width: "131.268", height: "1", fill: "#999999" })] })] })] }));
|
|
782
929
|
}
|
|
783
930
|
return null;
|
|
784
931
|
};
|
|
@@ -1384,11 +1531,13 @@ var styles$1 = {"listView":"ListView-module_listView","header":"ListView-module_
|
|
|
1384
1531
|
* />
|
|
1385
1532
|
* ```
|
|
1386
1533
|
*/
|
|
1387
|
-
const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelectionChange, onItemOpen, onItemMouseEnter, onSort, className = '', height = 'auto', }, ref) => {
|
|
1534
|
+
const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelectionChange, onItemOpen, onItemMouseEnter, onItemMouseLeave, onSort, className = '', height = 'auto', classes, renderRow, renderCell, renderHeaderCell, onCellClick, onCellMouseEnter, onCellMouseLeave, }, ref) => {
|
|
1388
1535
|
const [sortColumn, setSortColumn] = React.useState(null);
|
|
1389
1536
|
const [sortDirection, setSortDirection] = React.useState('asc');
|
|
1537
|
+
const [hoveredRow, setHoveredRow] = React.useState(null);
|
|
1538
|
+
const [hoveredCell, setHoveredCell] = React.useState(null);
|
|
1390
1539
|
// Class names
|
|
1391
|
-
const classNames =
|
|
1540
|
+
const classNames = mergeClasses(styles$1.listView, className, classes?.root);
|
|
1392
1541
|
// Handle column header click
|
|
1393
1542
|
const handleColumnClick = React.useCallback((columnKey, sortable = true) => {
|
|
1394
1543
|
if (!sortable || !onSort)
|
|
@@ -1433,7 +1582,7 @@ const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelecti
|
|
|
1433
1582
|
}
|
|
1434
1583
|
}, [onItemOpen]);
|
|
1435
1584
|
// Handle row mouse enter
|
|
1436
|
-
|
|
1585
|
+
React.useCallback((item) => {
|
|
1437
1586
|
if (onItemMouseEnter) {
|
|
1438
1587
|
onItemMouseEnter(item);
|
|
1439
1588
|
}
|
|
@@ -1443,17 +1592,108 @@ const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelecti
|
|
|
1443
1592
|
if (height !== 'auto') {
|
|
1444
1593
|
containerStyle.height = typeof height === 'number' ? `${height}px` : height;
|
|
1445
1594
|
}
|
|
1446
|
-
return (jsxRuntime.jsxs("div", { ref: ref, className: classNames, style: containerStyle, children: [jsxRuntime.jsx("div", { className: styles$1.header, children: columns.map((column) =>
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1595
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: classNames, style: containerStyle, children: [jsxRuntime.jsx("div", { className: mergeClasses(styles$1.header, classes?.header), children: columns.map((column) => {
|
|
1596
|
+
const isSorted = sortColumn === column.key;
|
|
1597
|
+
const headerState = {
|
|
1598
|
+
isSorted,
|
|
1599
|
+
sortDirection: isSorted ? sortDirection : undefined,
|
|
1600
|
+
};
|
|
1601
|
+
const headerDefaultProps = {
|
|
1602
|
+
key: column.key,
|
|
1603
|
+
className: mergeClasses(styles$1.headerCell, column.sortable !== false && styles$1.sortable, classes?.headerCell),
|
|
1604
|
+
style: {
|
|
1605
|
+
width: typeof column.width === 'number'
|
|
1606
|
+
? `${column.width}px`
|
|
1607
|
+
: column.width,
|
|
1608
|
+
},
|
|
1609
|
+
onClick: () => handleColumnClick(column.key, column.sortable),
|
|
1610
|
+
'data-column': column.key,
|
|
1611
|
+
'data-sortable': column.sortable !== false,
|
|
1612
|
+
...(isSorted && {
|
|
1613
|
+
'data-sorted': true,
|
|
1614
|
+
'data-sort-direction': sortDirection,
|
|
1615
|
+
}),
|
|
1616
|
+
};
|
|
1617
|
+
// Use custom render or default
|
|
1618
|
+
if (renderHeaderCell) {
|
|
1619
|
+
return renderHeaderCell(column, headerState, headerDefaultProps);
|
|
1620
|
+
}
|
|
1621
|
+
// Default header cell rendering
|
|
1622
|
+
return (jsxRuntime.jsxs("div", { ...headerDefaultProps, children: [column.label, isSorted && (jsxRuntime.jsx("span", { className: styles$1.sortIndicator, children: sortDirection === 'asc' ? '▲' : '▼' }))] }));
|
|
1623
|
+
}) }), jsxRuntime.jsx("div", { className: mergeClasses(styles$1.body, classes?.body), children: items.map((item, rowIndex) => {
|
|
1451
1624
|
const isSelected = selectedIds.includes(item.id);
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1625
|
+
const isHovered = hoveredRow === item.id;
|
|
1626
|
+
const rowState = {
|
|
1627
|
+
isSelected,
|
|
1628
|
+
isHovered,
|
|
1629
|
+
index: rowIndex,
|
|
1630
|
+
};
|
|
1631
|
+
const rowDefaultProps = {
|
|
1632
|
+
key: item.id,
|
|
1633
|
+
className: mergeClasses(styles$1.row, isSelected && styles$1.selected, classes?.row),
|
|
1634
|
+
onClick: (e) => handleRowClick(item.id, e),
|
|
1635
|
+
onDoubleClick: () => handleRowDoubleClick(item),
|
|
1636
|
+
onMouseEnter: () => {
|
|
1637
|
+
setHoveredRow(item.id);
|
|
1638
|
+
onItemMouseEnter?.(item);
|
|
1639
|
+
},
|
|
1640
|
+
onMouseLeave: () => {
|
|
1641
|
+
setHoveredRow(null);
|
|
1642
|
+
setHoveredCell(null);
|
|
1643
|
+
onItemMouseLeave?.(item);
|
|
1644
|
+
},
|
|
1645
|
+
'data-selected': isSelected,
|
|
1646
|
+
'data-index': rowIndex,
|
|
1647
|
+
'data-item-id': item.id,
|
|
1648
|
+
};
|
|
1649
|
+
// Use custom row render or default
|
|
1650
|
+
if (renderRow) {
|
|
1651
|
+
return renderRow(item, rowState, rowDefaultProps);
|
|
1652
|
+
}
|
|
1653
|
+
// Default row rendering
|
|
1654
|
+
return (jsxRuntime.jsx("div", { ...rowDefaultProps, children: columns.map((column, columnIndex) => {
|
|
1655
|
+
const value = item[column.key];
|
|
1656
|
+
const isCellHovered = hoveredCell?.rowId === item.id &&
|
|
1657
|
+
hoveredCell?.columnKey === column.key;
|
|
1658
|
+
const cellState = {
|
|
1659
|
+
isHovered: isCellHovered,
|
|
1660
|
+
isRowSelected: isSelected,
|
|
1661
|
+
columnIndex,
|
|
1662
|
+
rowIndex,
|
|
1663
|
+
};
|
|
1664
|
+
// Cell event handlers
|
|
1665
|
+
const handleCellClick = (e) => {
|
|
1666
|
+
if (onCellClick) {
|
|
1667
|
+
onCellClick(item, column, e);
|
|
1668
|
+
}
|
|
1669
|
+
};
|
|
1670
|
+
const handleCellMouseEnter = () => {
|
|
1671
|
+
setHoveredCell({ rowId: item.id, columnKey: column.key });
|
|
1672
|
+
if (onCellMouseEnter) {
|
|
1673
|
+
onCellMouseEnter(item, column);
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1676
|
+
const handleCellMouseLeave = () => {
|
|
1677
|
+
setHoveredCell(null);
|
|
1678
|
+
if (onCellMouseLeave) {
|
|
1679
|
+
onCellMouseLeave(item, column);
|
|
1680
|
+
}
|
|
1681
|
+
};
|
|
1682
|
+
// Use custom cell render or default
|
|
1683
|
+
if (renderCell) {
|
|
1684
|
+
return (jsxRuntime.jsx("div", { className: mergeClasses(styles$1.cell, classes?.cell), style: {
|
|
1685
|
+
width: typeof column.width === 'number'
|
|
1686
|
+
? `${column.width}px`
|
|
1687
|
+
: column.width,
|
|
1688
|
+
}, "data-column": column.key, "data-hovered": isCellHovered, onClick: handleCellClick, onMouseEnter: handleCellMouseEnter, onMouseLeave: handleCellMouseLeave, children: renderCell(value, item, column, cellState) }, column.key));
|
|
1689
|
+
}
|
|
1690
|
+
// Default cell rendering
|
|
1691
|
+
return (jsxRuntime.jsxs("div", { className: mergeClasses(styles$1.cell, classes?.cell), style: {
|
|
1692
|
+
width: typeof column.width === 'number'
|
|
1693
|
+
? `${column.width}px`
|
|
1694
|
+
: column.width,
|
|
1695
|
+
}, "data-column": column.key, "data-hovered": isCellHovered, onClick: handleCellClick, onMouseEnter: handleCellMouseEnter, onMouseLeave: handleCellMouseLeave, children: [columnIndex === 0 && item.icon && (jsxRuntime.jsx("span", { className: styles$1.icon, children: item.icon })), value] }, column.key));
|
|
1696
|
+
}) }));
|
|
1457
1697
|
}) })] }));
|
|
1458
1698
|
});
|
|
1459
1699
|
ListView.displayName = 'ListView';
|
|
@@ -1470,6 +1710,7 @@ var styles = {"folderListContent":"FolderList-module_folderListContent","listVie
|
|
|
1470
1710
|
*
|
|
1471
1711
|
* @example
|
|
1472
1712
|
* ```tsx
|
|
1713
|
+
* // Basic folder list
|
|
1473
1714
|
* <FolderList
|
|
1474
1715
|
* title="My Documents"
|
|
1475
1716
|
* items={[
|
|
@@ -1479,8 +1720,14 @@ var styles = {"folderListContent":"FolderList-module_folderListContent","listVie
|
|
|
1479
1720
|
* selectedIds={['1']}
|
|
1480
1721
|
* onSelectionChange={(ids) => console.log('Selected:', ids)}
|
|
1481
1722
|
* onItemOpen={(item) => console.log('Open:', item.name)}
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1723
|
+
* />
|
|
1724
|
+
*
|
|
1725
|
+
* // Draggable folder list
|
|
1726
|
+
* <FolderList
|
|
1727
|
+
* title="My Documents"
|
|
1728
|
+
* items={items}
|
|
1729
|
+
* draggable
|
|
1730
|
+
* defaultPosition={{ x: 100, y: 100 }}
|
|
1484
1731
|
* />
|
|
1485
1732
|
* ```
|
|
1486
1733
|
*/
|
|
@@ -1488,9 +1735,18 @@ const FolderList = React.forwardRef(({ columns = [
|
|
|
1488
1735
|
{ key: 'name', label: 'Name', width: '40%' },
|
|
1489
1736
|
{ key: 'modified', label: 'Date Modified', width: '30%' },
|
|
1490
1737
|
{ key: 'size', label: 'Size', width: '30%' },
|
|
1491
|
-
], items, selectedIds, onSelectionChange, onItemOpen, onItemMouseEnter, onSort, onMouseEnter, listHeight = 400, ...windowProps }, ref) => {
|
|
1738
|
+
], items, selectedIds, onSelectionChange, onItemOpen, onItemMouseEnter, onItemMouseLeave, onSort, onMouseEnter, listHeight = 400, classes, renderRow, renderCell, renderHeaderCell, onCellClick, onCellMouseEnter, onCellMouseLeave, ...windowProps }, ref) => {
|
|
1739
|
+
// Build ListView classes from FolderList classes
|
|
1740
|
+
const listViewClasses = classes ? {
|
|
1741
|
+
root: classes.listView,
|
|
1742
|
+
header: classes.header,
|
|
1743
|
+
headerCell: classes.headerCell,
|
|
1744
|
+
body: classes.body,
|
|
1745
|
+
row: classes.row,
|
|
1746
|
+
cell: classes.cell,
|
|
1747
|
+
} : undefined;
|
|
1492
1748
|
// Window content with ListView
|
|
1493
|
-
return (jsxRuntime.jsx(Window, { ref: ref, contentClassName: styles.folderListContent, onMouseEnter: onMouseEnter, ...windowProps, children: jsxRuntime.jsx(ListView, { columns: columns, items: items, selectedIds: selectedIds, onSelectionChange: onSelectionChange, onItemOpen: onItemOpen, onItemMouseEnter: onItemMouseEnter, onSort: onSort, height: listHeight, className: styles.listView }) }));
|
|
1749
|
+
return (jsxRuntime.jsx(Window, { ref: ref, contentClassName: styles.folderListContent, onMouseEnter: onMouseEnter, className: classes?.root, ...windowProps, children: jsxRuntime.jsx(ListView, { columns: columns, items: items, selectedIds: selectedIds, onSelectionChange: onSelectionChange, onItemOpen: onItemOpen, onItemMouseEnter: onItemMouseEnter, onItemMouseLeave: onItemMouseLeave, onSort: onSort, height: listHeight, className: styles.listView, classes: listViewClasses, renderRow: renderRow, renderCell: renderCell, renderHeaderCell: renderHeaderCell, onCellClick: onCellClick, onCellMouseEnter: onCellMouseEnter, onCellMouseLeave: onCellMouseLeave }) }));
|
|
1494
1750
|
});
|
|
1495
1751
|
FolderList.displayName = 'FolderList';
|
|
1496
1752
|
|
|
@@ -1733,6 +1989,8 @@ exports.TextField = TextField;
|
|
|
1733
1989
|
exports.Window = Window;
|
|
1734
1990
|
exports.borders = borders;
|
|
1735
1991
|
exports.colors = colors;
|
|
1992
|
+
exports.createClassBuilder = createClassBuilder;
|
|
1993
|
+
exports.mergeClasses = mergeClasses;
|
|
1736
1994
|
exports.shadows = shadows;
|
|
1737
1995
|
exports.spacing = spacing;
|
|
1738
1996
|
exports.tokens = tokens;
|