@liiift-studio/mac-os9-ui 0.2.21 → 0.2.24
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/fonts/65e59833.woff +0 -0
- package/dist/fonts/6fb9ec6b.woff +0 -0
- package/dist/fonts/9f492b6d.woff2 +0 -0
- package/dist/fonts/e45380e5.woff2 +0 -0
- package/dist/index.cjs +366 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +84 -15
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +425 -34
- package/dist/index.js +364 -55
- 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/MenuBar/MenuDropdown.d.ts +36 -0
- package/dist/types/components/MenuBar/MenuItem.d.ts +4 -0
- package/dist/types/components/MenuBar/index.d.ts +1 -0
- 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 +5 -4
- 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/fonts/2bc2468e.woff +0 -0
- package/dist/fonts/3306dfd5.woff +0 -0
- package/dist/fonts/b9e24cd1.woff2 +0 -0
- package/dist/fonts/cf596b2d.woff2 +0 -0
- package/dist/fonts/pixelOperator/PixelOperator-Bold.ttf +0 -0
- package/dist/fonts/pixelOperator/PixelOperator.ttf +0 -0
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,100 @@ 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
|
+
// Store drag start info
|
|
843
|
+
dragStartRef.current = {
|
|
844
|
+
x: event.clientX - rect.left,
|
|
845
|
+
y: event.clientY - rect.top,
|
|
846
|
+
};
|
|
847
|
+
setIsDragging(true);
|
|
848
|
+
}, [draggable]);
|
|
849
|
+
// Handle mouse move during drag
|
|
850
|
+
React.useEffect(() => {
|
|
851
|
+
if (!isDragging || !dragStartRef.current)
|
|
852
|
+
return;
|
|
853
|
+
const handleMouseMove = (event) => {
|
|
854
|
+
event.preventDefault();
|
|
855
|
+
if (!dragStartRef.current)
|
|
856
|
+
return;
|
|
857
|
+
const newPosition = {
|
|
858
|
+
x: event.clientX - dragStartRef.current.x,
|
|
859
|
+
y: event.clientY - dragStartRef.current.y,
|
|
860
|
+
};
|
|
861
|
+
// Update position
|
|
862
|
+
if (controlledPosition && onPositionChange) {
|
|
863
|
+
onPositionChange(newPosition);
|
|
864
|
+
}
|
|
865
|
+
else {
|
|
866
|
+
setInternalPosition(newPosition);
|
|
867
|
+
}
|
|
868
|
+
// Mark as dragged
|
|
869
|
+
if (!hasBeenDragged) {
|
|
870
|
+
setHasBeenDragged(true);
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
const handleMouseUp = () => {
|
|
874
|
+
setIsDragging(false);
|
|
875
|
+
dragStartRef.current = null;
|
|
876
|
+
};
|
|
877
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
878
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
879
|
+
return () => {
|
|
880
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
881
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
882
|
+
};
|
|
883
|
+
}, [isDragging, controlledPosition, onPositionChange, hasBeenDragged]);
|
|
758
884
|
// 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(' ');
|
|
885
|
+
const windowClassNames = mergeClasses(styles$6.window, active ? styles$6['window--active'] : styles$6['window--inactive'], draggable && hasBeenDragged && styles$6['window--draggable'], className, classes?.root);
|
|
886
|
+
const contentClassNames = mergeClasses(styles$6.content, contentClassName, classes?.content);
|
|
887
|
+
const titleBarClassNames = mergeClasses(styles$6.titleBar, draggable && styles$6['titleBar--draggable'], isDragging && styles$6['titleBar--dragging'], classes?.titleBar);
|
|
767
888
|
// Window style
|
|
768
889
|
const windowStyle = {};
|
|
769
890
|
if (width !== 'auto') {
|
|
@@ -772,13 +893,19 @@ const Window = React.forwardRef(({ children, title, titleBar, active = true, wid
|
|
|
772
893
|
if (height !== 'auto') {
|
|
773
894
|
windowStyle.height = typeof height === 'number' ? `${height}px` : height;
|
|
774
895
|
}
|
|
896
|
+
// Apply position if draggable and has been dragged
|
|
897
|
+
if (draggable && hasBeenDragged && currentPosition) {
|
|
898
|
+
windowStyle.position = 'absolute';
|
|
899
|
+
windowStyle.left = `${currentPosition.x}px`;
|
|
900
|
+
windowStyle.top = `${currentPosition.y}px`;
|
|
901
|
+
}
|
|
775
902
|
// Render title bar if title provided and no custom titleBar
|
|
776
903
|
const renderTitleBar = () => {
|
|
777
904
|
if (titleBar) {
|
|
778
905
|
return titleBar;
|
|
779
906
|
}
|
|
780
907
|
if (title) {
|
|
781
|
-
return (jsxRuntime.jsxs("div", { className:
|
|
908
|
+
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
909
|
}
|
|
783
910
|
return null;
|
|
784
911
|
};
|
|
@@ -915,7 +1042,7 @@ const Dialog = React.forwardRef(({ open = false, onClose, closeOnBackdropClick =
|
|
|
915
1042
|
});
|
|
916
1043
|
Dialog.displayName = 'Dialog';
|
|
917
1044
|
|
|
918
|
-
var styles$4 = {"menuBar":"MenuBar-module_menuBar","leftContent":"MenuBar-module_leftContent","menusContainer":"MenuBar-module_menusContainer","menuContainer":"MenuBar-module_menuContainer","rightContent":"MenuBar-module_rightContent","menuButton":"MenuBar-module_menuButton","menuButton--disabled":"MenuBar-module_menuButton--disabled","menuButton--open":"MenuBar-module_menuButton--open","dropdown":"MenuBar-module_dropdown"};
|
|
1045
|
+
var styles$4 = {"menuBar":"MenuBar-module_menuBar","leftContent":"MenuBar-module_leftContent","menusContainer":"MenuBar-module_menusContainer","menuContainer":"MenuBar-module_menuContainer","rightContent":"MenuBar-module_rightContent","menuButton":"MenuBar-module_menuButton","menuButton--disabled":"MenuBar-module_menuButton--disabled","menuButton--open":"MenuBar-module_menuButton--open","dropdown":"MenuBar-module_dropdown","dropdown--right":"MenuBar-module_dropdown--right"};
|
|
919
1046
|
|
|
920
1047
|
/**
|
|
921
1048
|
* Mac OS 9 style MenuBar component
|
|
@@ -972,41 +1099,56 @@ var styles$4 = {"menuBar":"MenuBar-module_menuBar","leftContent":"MenuBar-module
|
|
|
972
1099
|
const MenuBar = React.forwardRef(({ menus, openMenuIndex, onMenuOpen, onMenuClose, className = '', dropdownClassName = '', leftContent, rightContent, }, ref) => {
|
|
973
1100
|
const [menuBarElement, setMenuBarElement] = React.useState(null);
|
|
974
1101
|
const [focusedIndex, setFocusedIndex] = React.useState(-1);
|
|
1102
|
+
const [internalOpenIndex, setInternalOpenIndex] = React.useState(undefined);
|
|
1103
|
+
const isControlled = openMenuIndex !== undefined;
|
|
1104
|
+
const activeOpenIndex = isControlled ? openMenuIndex : internalOpenIndex;
|
|
1105
|
+
const handleMenuOpenInternal = (index) => {
|
|
1106
|
+
if (!isControlled) {
|
|
1107
|
+
setInternalOpenIndex(index);
|
|
1108
|
+
}
|
|
1109
|
+
onMenuOpen?.(index);
|
|
1110
|
+
};
|
|
1111
|
+
const handleMenuCloseInternal = () => {
|
|
1112
|
+
if (!isControlled) {
|
|
1113
|
+
setInternalOpenIndex(undefined);
|
|
1114
|
+
}
|
|
1115
|
+
onMenuClose?.();
|
|
1116
|
+
};
|
|
975
1117
|
// Handle click outside to close menu
|
|
976
1118
|
React.useEffect(() => {
|
|
977
|
-
if (
|
|
1119
|
+
if (activeOpenIndex === undefined || !menuBarElement)
|
|
978
1120
|
return;
|
|
979
1121
|
const handleClickOutside = (event) => {
|
|
980
1122
|
if (menuBarElement && !menuBarElement.contains(event.target)) {
|
|
981
|
-
|
|
1123
|
+
handleMenuCloseInternal();
|
|
982
1124
|
}
|
|
983
1125
|
};
|
|
984
1126
|
document.addEventListener('mousedown', handleClickOutside);
|
|
985
1127
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
986
|
-
}, [
|
|
1128
|
+
}, [activeOpenIndex, onMenuClose, menuBarElement, isControlled]);
|
|
987
1129
|
// Handle Escape key to close menu
|
|
988
1130
|
React.useEffect(() => {
|
|
989
|
-
if (
|
|
1131
|
+
if (activeOpenIndex === undefined)
|
|
990
1132
|
return;
|
|
991
1133
|
const handleEscape = (event) => {
|
|
992
1134
|
if (event.key === 'Escape') {
|
|
993
1135
|
event.preventDefault();
|
|
994
|
-
|
|
1136
|
+
handleMenuCloseInternal();
|
|
995
1137
|
}
|
|
996
1138
|
};
|
|
997
1139
|
document.addEventListener('keydown', handleEscape);
|
|
998
1140
|
return () => document.removeEventListener('keydown', handleEscape);
|
|
999
|
-
}, [
|
|
1141
|
+
}, [activeOpenIndex, onMenuClose, isControlled]);
|
|
1000
1142
|
// Handle keyboard navigation
|
|
1001
1143
|
const handleKeyDown = React.useCallback((event) => {
|
|
1002
1144
|
switch (event.key) {
|
|
1003
1145
|
case 'ArrowLeft':
|
|
1004
1146
|
event.preventDefault();
|
|
1005
|
-
if (
|
|
1147
|
+
if (activeOpenIndex !== undefined) {
|
|
1006
1148
|
// Move to previous menu
|
|
1007
|
-
const prevIndex =
|
|
1149
|
+
const prevIndex = activeOpenIndex > 0 ? activeOpenIndex - 1 : menus.length - 1;
|
|
1008
1150
|
if (!menus[prevIndex]?.disabled) {
|
|
1009
|
-
|
|
1151
|
+
handleMenuOpenInternal(prevIndex);
|
|
1010
1152
|
}
|
|
1011
1153
|
}
|
|
1012
1154
|
else if (focusedIndex > 0) {
|
|
@@ -1015,11 +1157,11 @@ const MenuBar = React.forwardRef(({ menus, openMenuIndex, onMenuOpen, onMenuClos
|
|
|
1015
1157
|
break;
|
|
1016
1158
|
case 'ArrowRight':
|
|
1017
1159
|
event.preventDefault();
|
|
1018
|
-
if (
|
|
1160
|
+
if (activeOpenIndex !== undefined) {
|
|
1019
1161
|
// Move to next menu
|
|
1020
|
-
const nextIndex =
|
|
1162
|
+
const nextIndex = activeOpenIndex < menus.length - 1 ? activeOpenIndex + 1 : 0;
|
|
1021
1163
|
if (!menus[nextIndex]?.disabled) {
|
|
1022
|
-
|
|
1164
|
+
handleMenuOpenInternal(nextIndex);
|
|
1023
1165
|
}
|
|
1024
1166
|
}
|
|
1025
1167
|
else if (focusedIndex < menus.length - 1) {
|
|
@@ -1028,18 +1170,18 @@ const MenuBar = React.forwardRef(({ menus, openMenuIndex, onMenuOpen, onMenuClos
|
|
|
1028
1170
|
break;
|
|
1029
1171
|
case 'ArrowDown':
|
|
1030
1172
|
event.preventDefault();
|
|
1031
|
-
if (
|
|
1173
|
+
if (activeOpenIndex === undefined && focusedIndex >= 0) {
|
|
1032
1174
|
// Open the focused menu (only if it's a dropdown)
|
|
1033
1175
|
const menu = menus[focusedIndex];
|
|
1034
1176
|
if (!menu?.disabled && menu?.type !== 'link') {
|
|
1035
|
-
|
|
1177
|
+
handleMenuOpenInternal(focusedIndex);
|
|
1036
1178
|
}
|
|
1037
1179
|
}
|
|
1038
1180
|
break;
|
|
1039
1181
|
case 'Enter':
|
|
1040
1182
|
case ' ':
|
|
1041
1183
|
event.preventDefault();
|
|
1042
|
-
if (
|
|
1184
|
+
if (activeOpenIndex === undefined && focusedIndex >= 0) {
|
|
1043
1185
|
const menu = menus[focusedIndex];
|
|
1044
1186
|
if (!menu?.disabled) {
|
|
1045
1187
|
if (menu.type === 'link') {
|
|
@@ -1048,13 +1190,13 @@ const MenuBar = React.forwardRef(({ menus, openMenuIndex, onMenuOpen, onMenuClos
|
|
|
1048
1190
|
}
|
|
1049
1191
|
else {
|
|
1050
1192
|
// Open the focused dropdown menu
|
|
1051
|
-
|
|
1193
|
+
handleMenuOpenInternal(focusedIndex);
|
|
1052
1194
|
}
|
|
1053
1195
|
}
|
|
1054
1196
|
}
|
|
1055
1197
|
break;
|
|
1056
1198
|
}
|
|
1057
|
-
}, [
|
|
1199
|
+
}, [activeOpenIndex, focusedIndex, menus, onMenuOpen, onMenuClose, isControlled]);
|
|
1058
1200
|
// Handle menu button click
|
|
1059
1201
|
const handleMenuClick = (index) => {
|
|
1060
1202
|
const menu = menus[index];
|
|
@@ -1065,13 +1207,13 @@ const MenuBar = React.forwardRef(({ menus, openMenuIndex, onMenuOpen, onMenuClos
|
|
|
1065
1207
|
menu.onClick?.();
|
|
1066
1208
|
return;
|
|
1067
1209
|
}
|
|
1068
|
-
if (
|
|
1210
|
+
if (activeOpenIndex === index) {
|
|
1069
1211
|
// Clicking the same menu closes it
|
|
1070
|
-
|
|
1212
|
+
handleMenuCloseInternal();
|
|
1071
1213
|
}
|
|
1072
1214
|
else {
|
|
1073
1215
|
// Open the clicked menu
|
|
1074
|
-
|
|
1216
|
+
handleMenuOpenInternal(index);
|
|
1075
1217
|
}
|
|
1076
1218
|
};
|
|
1077
1219
|
// Class names
|
|
@@ -1088,7 +1230,7 @@ const MenuBar = React.forwardRef(({ menus, openMenuIndex, onMenuOpen, onMenuClos
|
|
|
1088
1230
|
}
|
|
1089
1231
|
}, [ref]);
|
|
1090
1232
|
return (jsxRuntime.jsxs("div", { ref: handleRef, className: menuBarClassNames, role: "menubar", onKeyDown: handleKeyDown, children: [leftContent && (jsxRuntime.jsx("div", { className: styles$4.leftContent, children: leftContent })), jsxRuntime.jsx("div", { className: styles$4.menusContainer, children: menus.map((menu, index) => {
|
|
1091
|
-
const isOpen =
|
|
1233
|
+
const isOpen = activeOpenIndex === index;
|
|
1092
1234
|
const isDropdown = menu.type !== 'link';
|
|
1093
1235
|
const menuButtonClassNames = [
|
|
1094
1236
|
styles$4.menuButton,
|
|
@@ -1107,14 +1249,14 @@ const MenuBar = React.forwardRef(({ menus, openMenuIndex, onMenuOpen, onMenuClos
|
|
|
1107
1249
|
}, onFocus: () => setFocusedIndex(index), onBlur: () => setFocusedIndex(-1), "aria-disabled": menu.disabled, children: jsxRuntime.jsx("h3", { children: menu.label }) }) }, index));
|
|
1108
1250
|
}
|
|
1109
1251
|
// Standard dropdown menu or link without href
|
|
1110
|
-
return (jsxRuntime.jsxs("div", { className: styles$4.menuContainer, children: [jsxRuntime.jsx("button", { type: "button", className: menuButtonClassNames, onClick: () => handleMenuClick(index), onFocus: () => setFocusedIndex(index), onBlur: () => setFocusedIndex(-1), disabled: menu.disabled, "aria-haspopup": isDropdown ? 'true' : undefined, "aria-expanded": isOpen, "aria-disabled": menu.disabled, children: menu.label }), isOpen && isDropdown && menu.items && (jsxRuntime.jsx("div", { className: dropdownClassNames, role: "menu", children: menu.items }))] }, index));
|
|
1252
|
+
return (jsxRuntime.jsxs("div", { className: styles$4.menuContainer, children: [jsxRuntime.jsx("button", { type: "button", className: menuButtonClassNames, onClick: () => handleMenuClick(index), onFocus: () => setFocusedIndex(index), onBlur: () => setFocusedIndex(-1), disabled: menu.disabled, "aria-haspopup": isDropdown ? 'true' : undefined, "aria-expanded": isOpen, "aria-disabled": menu.disabled, children: jsxRuntime.jsx("h3", { children: menu.label }) }), isOpen && isDropdown && menu.items && (jsxRuntime.jsx("div", { className: dropdownClassNames, role: "menu", children: menu.items }))] }, index));
|
|
1111
1253
|
}) }), rightContent && (jsxRuntime.jsx("div", { className: styles$4.rightContent, children: Array.isArray(rightContent)
|
|
1112
1254
|
? rightContent.map((item, index) => (jsxRuntime.jsx(React.Fragment, { children: item }, index)))
|
|
1113
1255
|
: rightContent }))] }));
|
|
1114
1256
|
});
|
|
1115
1257
|
MenuBar.displayName = 'MenuBar';
|
|
1116
1258
|
|
|
1117
|
-
var styles$3 = {"menuItem":"MenuItem-module_menuItem","menuItem--disabled":"MenuItem-module_menuItem--disabled","menuItem--selected":"MenuItem-module_menuItem--selected","menuItem--separator":"MenuItem-module_menuItem--separator","checkmark":"MenuItem-module_checkmark","icon":"MenuItem-module_icon","label":"MenuItem-module_label","shortcut":"MenuItem-module_shortcut","submenuArrow":"MenuItem-module_submenuArrow","separatorLine":"MenuItem-module_separatorLine"};
|
|
1259
|
+
var styles$3 = {"menuItem":"MenuItem-module_menuItem","menuItem--disabled":"MenuItem-module_menuItem--disabled","menuItem--selected":"MenuItem-module_menuItem--selected","menuItem--separator":"MenuItem-module_menuItem--separator","checkmark":"MenuItem-module_checkmark","icon":"MenuItem-module_icon","label":"MenuItem-module_label","shortcut":"MenuItem-module_shortcut","submenuArrow":"MenuItem-module_submenuArrow","submenu":"MenuItem-module_submenu","separatorLine":"MenuItem-module_separatorLine"};
|
|
1118
1260
|
|
|
1119
1261
|
/**
|
|
1120
1262
|
* Mac OS 9 style MenuItem component
|
|
@@ -1153,7 +1295,9 @@ var styles$3 = {"menuItem":"MenuItem-module_menuItem","menuItem--disabled":"Menu
|
|
|
1153
1295
|
* <MenuItem label="Recent Files" hasSubmenu />
|
|
1154
1296
|
* ```
|
|
1155
1297
|
*/
|
|
1156
|
-
const MenuItem = React.forwardRef(({ label, shortcut, disabled = false, selected = false, separator = false, checked = false, icon, onClick, onFocus, onBlur, className = '', hasSubmenu = false, }, ref) => {
|
|
1298
|
+
const MenuItem = React.forwardRef(({ label, shortcut, disabled = false, selected = false, separator = false, checked = false, icon, onClick, onFocus, onBlur, className = '', hasSubmenu = false, items, }, ref) => {
|
|
1299
|
+
const [isSubmenuOpen, setIsSubmenuOpen] = React.useState(false);
|
|
1300
|
+
const effectiveHasSubmenu = hasSubmenu || !!items;
|
|
1157
1301
|
// Class names
|
|
1158
1302
|
const menuItemClassNames = [
|
|
1159
1303
|
styles$3.menuItem,
|
|
@@ -1172,10 +1316,66 @@ const MenuItem = React.forwardRef(({ label, shortcut, disabled = false, selected
|
|
|
1172
1316
|
}
|
|
1173
1317
|
onClick?.(event);
|
|
1174
1318
|
};
|
|
1175
|
-
return (jsxRuntime.jsxs(
|
|
1319
|
+
return (jsxRuntime.jsxs("div", { className: styles$3.menuItemContainer, onMouseEnter: () => setIsSubmenuOpen(true), onMouseLeave: () => setIsSubmenuOpen(false), style: { position: 'relative', width: '100%' }, children: [jsxRuntime.jsxs("button", { ref: ref, type: "button", className: menuItemClassNames, onClick: handleClick, onFocus: onFocus, onBlur: onBlur, disabled: disabled, role: "menuitem", "aria-disabled": disabled, "aria-checked": checked ? 'true' : undefined, children: [jsxRuntime.jsx("span", { className: styles$3.checkmark, children: checked && '✓' }), icon && jsxRuntime.jsx("span", { className: styles$3.icon, children: icon }), jsxRuntime.jsx("span", { className: styles$3.label, children: label }), shortcut && jsxRuntime.jsx("span", { className: styles$3.shortcut, children: shortcut }), effectiveHasSubmenu && jsxRuntime.jsx("span", { className: styles$3.submenuArrow, children: "\u25B6" })] }), items && isSubmenuOpen && (jsxRuntime.jsx("div", { className: styles$3.submenu, role: "menu", children: items })), separator && jsxRuntime.jsx("div", { className: styles$3.separatorLine, role: "separator" })] }));
|
|
1176
1320
|
});
|
|
1177
1321
|
MenuItem.displayName = 'MenuItem';
|
|
1178
1322
|
|
|
1323
|
+
/**
|
|
1324
|
+
* Mac OS 9 style MenuDropdown component
|
|
1325
|
+
*
|
|
1326
|
+
* A standalone dropdown menu that shares the styling of the MenuBar.
|
|
1327
|
+
* Useful for placing menus in the status area (rightContent) or other parts of the app.
|
|
1328
|
+
*/
|
|
1329
|
+
const MenuDropdown = ({ label, items, disabled = false, className = '', dropdownClassName = '', align = 'left', }) => {
|
|
1330
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
1331
|
+
const containerRef = React.useRef(null);
|
|
1332
|
+
// Handle click outside to close menu
|
|
1333
|
+
React.useEffect(() => {
|
|
1334
|
+
if (!isOpen)
|
|
1335
|
+
return;
|
|
1336
|
+
const handleClickOutside = (event) => {
|
|
1337
|
+
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
1338
|
+
setIsOpen(false);
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
1342
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
1343
|
+
}, [isOpen]);
|
|
1344
|
+
// Handle Escape key to close menu
|
|
1345
|
+
React.useEffect(() => {
|
|
1346
|
+
if (!isOpen)
|
|
1347
|
+
return;
|
|
1348
|
+
const handleEscape = (event) => {
|
|
1349
|
+
if (event.key === 'Escape') {
|
|
1350
|
+
event.preventDefault();
|
|
1351
|
+
setIsOpen(false);
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
document.addEventListener('keydown', handleEscape);
|
|
1355
|
+
return () => document.removeEventListener('keydown', handleEscape);
|
|
1356
|
+
}, [isOpen]);
|
|
1357
|
+
const handleToggle = () => {
|
|
1358
|
+
if (!disabled) {
|
|
1359
|
+
setIsOpen(!isOpen);
|
|
1360
|
+
}
|
|
1361
|
+
};
|
|
1362
|
+
const menuContainerClassNames = [
|
|
1363
|
+
styles$4.menuContainer,
|
|
1364
|
+
className
|
|
1365
|
+
].filter(Boolean).join(' ');
|
|
1366
|
+
const menuButtonClassNames = [
|
|
1367
|
+
styles$4.menuButton,
|
|
1368
|
+
isOpen ? styles$4['menuButton--open'] : '',
|
|
1369
|
+
disabled ? styles$4['menuButton--disabled'] : '',
|
|
1370
|
+
].filter(Boolean).join(' ');
|
|
1371
|
+
const dropdownClassNames = [
|
|
1372
|
+
styles$4.dropdown,
|
|
1373
|
+
align === 'right' ? styles$4['dropdown--right'] : '',
|
|
1374
|
+
dropdownClassName
|
|
1375
|
+
].filter(Boolean).join(' ');
|
|
1376
|
+
return (jsxRuntime.jsxs("div", { ref: containerRef, className: menuContainerClassNames, children: [jsxRuntime.jsx("button", { type: "button", className: menuButtonClassNames, onClick: handleToggle, disabled: disabled, "aria-haspopup": "true", "aria-expanded": isOpen, "aria-disabled": disabled, children: typeof label === 'string' ? jsxRuntime.jsx("h3", { children: label }) : label }), isOpen && (jsxRuntime.jsx("div", { className: dropdownClassNames, role: "menu", onClick: () => setIsOpen(false), children: items }))] }));
|
|
1377
|
+
};
|
|
1378
|
+
|
|
1179
1379
|
var styles$2 = {"scrollbar":"Scrollbar-module_scrollbar","scrollbar--vertical":"Scrollbar-module_scrollbar--vertical","scrollbar--horizontal":"Scrollbar-module_scrollbar--horizontal","scrollbar--disabled":"Scrollbar-module_scrollbar--disabled","arrow":"Scrollbar-module_arrow","arrowIcon":"Scrollbar-module_arrowIcon","arrow--start":"Scrollbar-module_arrow--start","arrow--end":"Scrollbar-module_arrow--end","track":"Scrollbar-module_track","thumb":"Scrollbar-module_thumb"};
|
|
1180
1380
|
|
|
1181
1381
|
// Scrollbar component - Mac OS 9 style
|
|
@@ -1311,11 +1511,13 @@ var styles$1 = {"listView":"ListView-module_listView","header":"ListView-module_
|
|
|
1311
1511
|
* />
|
|
1312
1512
|
* ```
|
|
1313
1513
|
*/
|
|
1314
|
-
const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelectionChange, onItemOpen, onItemMouseEnter, onSort, className = '', height = 'auto', }, ref) => {
|
|
1514
|
+
const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelectionChange, onItemOpen, onItemMouseEnter, onItemMouseLeave, onSort, className = '', height = 'auto', classes, renderRow, renderCell, renderHeaderCell, onCellClick, onCellMouseEnter, onCellMouseLeave, }, ref) => {
|
|
1315
1515
|
const [sortColumn, setSortColumn] = React.useState(null);
|
|
1316
1516
|
const [sortDirection, setSortDirection] = React.useState('asc');
|
|
1517
|
+
const [hoveredRow, setHoveredRow] = React.useState(null);
|
|
1518
|
+
const [hoveredCell, setHoveredCell] = React.useState(null);
|
|
1317
1519
|
// Class names
|
|
1318
|
-
const classNames =
|
|
1520
|
+
const classNames = mergeClasses(styles$1.listView, className, classes?.root);
|
|
1319
1521
|
// Handle column header click
|
|
1320
1522
|
const handleColumnClick = React.useCallback((columnKey, sortable = true) => {
|
|
1321
1523
|
if (!sortable || !onSort)
|
|
@@ -1360,7 +1562,7 @@ const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelecti
|
|
|
1360
1562
|
}
|
|
1361
1563
|
}, [onItemOpen]);
|
|
1362
1564
|
// Handle row mouse enter
|
|
1363
|
-
|
|
1565
|
+
React.useCallback((item) => {
|
|
1364
1566
|
if (onItemMouseEnter) {
|
|
1365
1567
|
onItemMouseEnter(item);
|
|
1366
1568
|
}
|
|
@@ -1370,17 +1572,108 @@ const ListView = React.forwardRef(({ columns, items, selectedIds = [], onSelecti
|
|
|
1370
1572
|
if (height !== 'auto') {
|
|
1371
1573
|
containerStyle.height = typeof height === 'number' ? `${height}px` : height;
|
|
1372
1574
|
}
|
|
1373
|
-
return (jsxRuntime.jsxs("div", { ref: ref, className: classNames, style: containerStyle, children: [jsxRuntime.jsx("div", { className: styles$1.header, children: columns.map((column) =>
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1575
|
+
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) => {
|
|
1576
|
+
const isSorted = sortColumn === column.key;
|
|
1577
|
+
const headerState = {
|
|
1578
|
+
isSorted,
|
|
1579
|
+
sortDirection: isSorted ? sortDirection : undefined,
|
|
1580
|
+
};
|
|
1581
|
+
const headerDefaultProps = {
|
|
1582
|
+
key: column.key,
|
|
1583
|
+
className: mergeClasses(styles$1.headerCell, column.sortable !== false && styles$1.sortable, classes?.headerCell),
|
|
1584
|
+
style: {
|
|
1585
|
+
width: typeof column.width === 'number'
|
|
1586
|
+
? `${column.width}px`
|
|
1587
|
+
: column.width,
|
|
1588
|
+
},
|
|
1589
|
+
onClick: () => handleColumnClick(column.key, column.sortable),
|
|
1590
|
+
'data-column': column.key,
|
|
1591
|
+
'data-sortable': column.sortable !== false,
|
|
1592
|
+
...(isSorted && {
|
|
1593
|
+
'data-sorted': true,
|
|
1594
|
+
'data-sort-direction': sortDirection,
|
|
1595
|
+
}),
|
|
1596
|
+
};
|
|
1597
|
+
// Use custom render or default
|
|
1598
|
+
if (renderHeaderCell) {
|
|
1599
|
+
return renderHeaderCell(column, headerState, headerDefaultProps);
|
|
1600
|
+
}
|
|
1601
|
+
// Default header cell rendering
|
|
1602
|
+
return (jsxRuntime.jsxs("div", { ...headerDefaultProps, children: [column.label, isSorted && (jsxRuntime.jsx("span", { className: styles$1.sortIndicator, children: sortDirection === 'asc' ? '▲' : '▼' }))] }));
|
|
1603
|
+
}) }), jsxRuntime.jsx("div", { className: mergeClasses(styles$1.body, classes?.body), children: items.map((item, rowIndex) => {
|
|
1378
1604
|
const isSelected = selectedIds.includes(item.id);
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1605
|
+
const isHovered = hoveredRow === item.id;
|
|
1606
|
+
const rowState = {
|
|
1607
|
+
isSelected,
|
|
1608
|
+
isHovered,
|
|
1609
|
+
index: rowIndex,
|
|
1610
|
+
};
|
|
1611
|
+
const rowDefaultProps = {
|
|
1612
|
+
key: item.id,
|
|
1613
|
+
className: mergeClasses(styles$1.row, isSelected && styles$1.selected, classes?.row),
|
|
1614
|
+
onClick: (e) => handleRowClick(item.id, e),
|
|
1615
|
+
onDoubleClick: () => handleRowDoubleClick(item),
|
|
1616
|
+
onMouseEnter: () => {
|
|
1617
|
+
setHoveredRow(item.id);
|
|
1618
|
+
onItemMouseEnter?.(item);
|
|
1619
|
+
},
|
|
1620
|
+
onMouseLeave: () => {
|
|
1621
|
+
setHoveredRow(null);
|
|
1622
|
+
setHoveredCell(null);
|
|
1623
|
+
onItemMouseLeave?.(item);
|
|
1624
|
+
},
|
|
1625
|
+
'data-selected': isSelected,
|
|
1626
|
+
'data-index': rowIndex,
|
|
1627
|
+
'data-item-id': item.id,
|
|
1628
|
+
};
|
|
1629
|
+
// Use custom row render or default
|
|
1630
|
+
if (renderRow) {
|
|
1631
|
+
return renderRow(item, rowState, rowDefaultProps);
|
|
1632
|
+
}
|
|
1633
|
+
// Default row rendering
|
|
1634
|
+
return (jsxRuntime.jsx("div", { ...rowDefaultProps, children: columns.map((column, columnIndex) => {
|
|
1635
|
+
const value = item[column.key];
|
|
1636
|
+
const isCellHovered = hoveredCell?.rowId === item.id &&
|
|
1637
|
+
hoveredCell?.columnKey === column.key;
|
|
1638
|
+
const cellState = {
|
|
1639
|
+
isHovered: isCellHovered,
|
|
1640
|
+
isRowSelected: isSelected,
|
|
1641
|
+
columnIndex,
|
|
1642
|
+
rowIndex,
|
|
1643
|
+
};
|
|
1644
|
+
// Cell event handlers
|
|
1645
|
+
const handleCellClick = (e) => {
|
|
1646
|
+
if (onCellClick) {
|
|
1647
|
+
onCellClick(item, column, e);
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
const handleCellMouseEnter = () => {
|
|
1651
|
+
setHoveredCell({ rowId: item.id, columnKey: column.key });
|
|
1652
|
+
if (onCellMouseEnter) {
|
|
1653
|
+
onCellMouseEnter(item, column);
|
|
1654
|
+
}
|
|
1655
|
+
};
|
|
1656
|
+
const handleCellMouseLeave = () => {
|
|
1657
|
+
setHoveredCell(null);
|
|
1658
|
+
if (onCellMouseLeave) {
|
|
1659
|
+
onCellMouseLeave(item, column);
|
|
1660
|
+
}
|
|
1661
|
+
};
|
|
1662
|
+
// Use custom cell render or default
|
|
1663
|
+
if (renderCell) {
|
|
1664
|
+
return (jsxRuntime.jsx("div", { className: mergeClasses(styles$1.cell, classes?.cell), style: {
|
|
1665
|
+
width: typeof column.width === 'number'
|
|
1666
|
+
? `${column.width}px`
|
|
1667
|
+
: column.width,
|
|
1668
|
+
}, "data-column": column.key, "data-hovered": isCellHovered, onClick: handleCellClick, onMouseEnter: handleCellMouseEnter, onMouseLeave: handleCellMouseLeave, children: renderCell(value, item, column, cellState) }, column.key));
|
|
1669
|
+
}
|
|
1670
|
+
// Default cell rendering
|
|
1671
|
+
return (jsxRuntime.jsxs("div", { className: mergeClasses(styles$1.cell, classes?.cell), style: {
|
|
1672
|
+
width: typeof column.width === 'number'
|
|
1673
|
+
? `${column.width}px`
|
|
1674
|
+
: column.width,
|
|
1675
|
+
}, "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));
|
|
1676
|
+
}) }));
|
|
1384
1677
|
}) })] }));
|
|
1385
1678
|
});
|
|
1386
1679
|
ListView.displayName = 'ListView';
|
|
@@ -1397,6 +1690,7 @@ var styles = {"folderListContent":"FolderList-module_folderListContent","listVie
|
|
|
1397
1690
|
*
|
|
1398
1691
|
* @example
|
|
1399
1692
|
* ```tsx
|
|
1693
|
+
* // Basic folder list
|
|
1400
1694
|
* <FolderList
|
|
1401
1695
|
* title="My Documents"
|
|
1402
1696
|
* items={[
|
|
@@ -1406,8 +1700,14 @@ var styles = {"folderListContent":"FolderList-module_folderListContent","listVie
|
|
|
1406
1700
|
* selectedIds={['1']}
|
|
1407
1701
|
* onSelectionChange={(ids) => console.log('Selected:', ids)}
|
|
1408
1702
|
* onItemOpen={(item) => console.log('Open:', item.name)}
|
|
1409
|
-
*
|
|
1410
|
-
*
|
|
1703
|
+
* />
|
|
1704
|
+
*
|
|
1705
|
+
* // Draggable folder list
|
|
1706
|
+
* <FolderList
|
|
1707
|
+
* title="My Documents"
|
|
1708
|
+
* items={items}
|
|
1709
|
+
* draggable
|
|
1710
|
+
* defaultPosition={{ x: 100, y: 100 }}
|
|
1411
1711
|
* />
|
|
1412
1712
|
* ```
|
|
1413
1713
|
*/
|
|
@@ -1415,9 +1715,18 @@ const FolderList = React.forwardRef(({ columns = [
|
|
|
1415
1715
|
{ key: 'name', label: 'Name', width: '40%' },
|
|
1416
1716
|
{ key: 'modified', label: 'Date Modified', width: '30%' },
|
|
1417
1717
|
{ key: 'size', label: 'Size', width: '30%' },
|
|
1418
|
-
], items, selectedIds, onSelectionChange, onItemOpen, onItemMouseEnter, onSort, onMouseEnter, listHeight = 400, ...windowProps }, ref) => {
|
|
1718
|
+
], items, selectedIds, onSelectionChange, onItemOpen, onItemMouseEnter, onItemMouseLeave, onSort, onMouseEnter, listHeight = 400, classes, renderRow, renderCell, renderHeaderCell, onCellClick, onCellMouseEnter, onCellMouseLeave, ...windowProps }, ref) => {
|
|
1719
|
+
// Build ListView classes from FolderList classes
|
|
1720
|
+
const listViewClasses = classes ? {
|
|
1721
|
+
root: classes.listView,
|
|
1722
|
+
header: classes.header,
|
|
1723
|
+
headerCell: classes.headerCell,
|
|
1724
|
+
body: classes.body,
|
|
1725
|
+
row: classes.row,
|
|
1726
|
+
cell: classes.cell,
|
|
1727
|
+
} : undefined;
|
|
1419
1728
|
// Window content with ListView
|
|
1420
|
-
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 }) }));
|
|
1729
|
+
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 }) }));
|
|
1421
1730
|
});
|
|
1422
1731
|
FolderList.displayName = 'FolderList';
|
|
1423
1732
|
|
|
@@ -1649,6 +1958,7 @@ exports.IconButton = IconButton;
|
|
|
1649
1958
|
exports.IconLibrary = IconLibrary;
|
|
1650
1959
|
exports.ListView = ListView;
|
|
1651
1960
|
exports.MenuBar = MenuBar;
|
|
1961
|
+
exports.MenuDropdown = MenuDropdown;
|
|
1652
1962
|
exports.MenuItem = MenuItem;
|
|
1653
1963
|
exports.Radio = Radio;
|
|
1654
1964
|
exports.Scrollbar = Scrollbar;
|
|
@@ -1659,6 +1969,8 @@ exports.TextField = TextField;
|
|
|
1659
1969
|
exports.Window = Window;
|
|
1660
1970
|
exports.borders = borders;
|
|
1661
1971
|
exports.colors = colors;
|
|
1972
|
+
exports.createClassBuilder = createClassBuilder;
|
|
1973
|
+
exports.mergeClasses = mergeClasses;
|
|
1662
1974
|
exports.shadows = shadows;
|
|
1663
1975
|
exports.spacing = spacing;
|
|
1664
1976
|
exports.tokens = tokens;
|