@liiift-studio/mac-os9-ui 0.2.25 → 0.3.1
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/README.md +29 -2
- package/dist/base.css +99 -0
- package/dist/base.css.map +1 -0
- package/dist/index.cjs +81 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +7 -57
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +26 -0
- package/dist/index.js +81 -6
- package/dist/index.js.map +1 -1
- package/dist/types/components/Window/Window.d.ts +26 -0
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -963,6 +963,32 @@ interface WindowProps {
|
|
|
963
963
|
* @default false
|
|
964
964
|
*/
|
|
965
965
|
resizable?: boolean;
|
|
966
|
+
/**
|
|
967
|
+
* Minimum width when resizing
|
|
968
|
+
* @default 200
|
|
969
|
+
*/
|
|
970
|
+
minWidth?: number;
|
|
971
|
+
/**
|
|
972
|
+
* Minimum height when resizing
|
|
973
|
+
* @default 100
|
|
974
|
+
*/
|
|
975
|
+
minHeight?: number;
|
|
976
|
+
/**
|
|
977
|
+
* Maximum width when resizing
|
|
978
|
+
*/
|
|
979
|
+
maxWidth?: number;
|
|
980
|
+
/**
|
|
981
|
+
* Maximum height when resizing
|
|
982
|
+
*/
|
|
983
|
+
maxHeight?: number;
|
|
984
|
+
/**
|
|
985
|
+
* Callback when window is resized
|
|
986
|
+
* Only called when resizable is true
|
|
987
|
+
*/
|
|
988
|
+
onResize?: (size: {
|
|
989
|
+
width: number;
|
|
990
|
+
height: number;
|
|
991
|
+
}) => void;
|
|
966
992
|
/**
|
|
967
993
|
* Whether the window can be dragged by its title bar
|
|
968
994
|
* Window starts in normal flow and becomes absolutely positioned when dragged
|
package/dist/index.js
CHANGED
|
@@ -816,14 +816,24 @@ var styles$6 = {"window":"Window-module_window","window--active":"Window-module_
|
|
|
816
816
|
* </Window>
|
|
817
817
|
* ```
|
|
818
818
|
*/
|
|
819
|
-
const Window = 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) => {
|
|
819
|
+
const Window = forwardRef(({ children, title, titleBar, active = true, width = 'auto', height = 'auto', className = '', contentClassName = '', classes, showControls = true, onClose, onMinimize, onMaximize, onMouseEnter, resizable = false, minWidth = 200, minHeight = 100, maxWidth, maxHeight, onResize, draggable = false, defaultPosition, position: controlledPosition, onPositionChange, }, ref) => {
|
|
820
820
|
// Drag state management
|
|
821
821
|
const [internalPosition, setInternalPosition] = useState(defaultPosition || null);
|
|
822
822
|
const [isDragging, setIsDragging] = useState(false);
|
|
823
823
|
const [hasBeenDragged, setHasBeenDragged] = useState(!!(defaultPosition || controlledPosition));
|
|
824
824
|
const dragStartRef = useRef(null);
|
|
825
|
+
// Resize state management
|
|
826
|
+
const [internalSize, setInternalSize] = useState({
|
|
827
|
+
width,
|
|
828
|
+
height,
|
|
829
|
+
});
|
|
830
|
+
const [isResizing, setIsResizing] = useState(false);
|
|
831
|
+
const resizeStartRef = useRef(null);
|
|
825
832
|
// Use controlled position if provided, otherwise use internal state
|
|
826
833
|
const currentPosition = controlledPosition || internalPosition;
|
|
834
|
+
// Use internal size state for resize tracking
|
|
835
|
+
const currentWidth = isResizing ? internalSize.width : width;
|
|
836
|
+
const currentHeight = isResizing ? internalSize.height : height;
|
|
827
837
|
// Handle mouse down on title bar to start dragging
|
|
828
838
|
const handleTitleBarMouseDown = useCallback((event) => {
|
|
829
839
|
if (!draggable)
|
|
@@ -848,6 +858,69 @@ const Window = forwardRef(({ children, title, titleBar, active = true, width = '
|
|
|
848
858
|
};
|
|
849
859
|
setIsDragging(true);
|
|
850
860
|
}, [draggable]);
|
|
861
|
+
// Handle mouse down on resize handle to start resizing
|
|
862
|
+
const handleResizeMouseDown = useCallback((event) => {
|
|
863
|
+
if (!resizable)
|
|
864
|
+
return;
|
|
865
|
+
event.preventDefault();
|
|
866
|
+
event.stopPropagation();
|
|
867
|
+
const windowElement = event.currentTarget.closest(`.${styles$6.window}`);
|
|
868
|
+
if (!windowElement)
|
|
869
|
+
return;
|
|
870
|
+
const rect = windowElement.getBoundingClientRect();
|
|
871
|
+
// Store resize start info
|
|
872
|
+
resizeStartRef.current = {
|
|
873
|
+
width: rect.width,
|
|
874
|
+
height: rect.height,
|
|
875
|
+
mouseX: event.clientX,
|
|
876
|
+
mouseY: event.clientY,
|
|
877
|
+
};
|
|
878
|
+
setIsResizing(true);
|
|
879
|
+
}, [resizable]);
|
|
880
|
+
// Handle mouse move during resize
|
|
881
|
+
useEffect(() => {
|
|
882
|
+
if (!isResizing || !resizeStartRef.current)
|
|
883
|
+
return;
|
|
884
|
+
const handleMouseMove = (event) => {
|
|
885
|
+
event.preventDefault();
|
|
886
|
+
if (!resizeStartRef.current)
|
|
887
|
+
return;
|
|
888
|
+
// Calculate delta
|
|
889
|
+
const deltaX = event.clientX - resizeStartRef.current.mouseX;
|
|
890
|
+
const deltaY = event.clientY - resizeStartRef.current.mouseY;
|
|
891
|
+
// Calculate new size
|
|
892
|
+
let newWidth = resizeStartRef.current.width + deltaX;
|
|
893
|
+
let newHeight = resizeStartRef.current.height + deltaY;
|
|
894
|
+
// Apply constraints
|
|
895
|
+
if (newWidth < minWidth)
|
|
896
|
+
newWidth = minWidth;
|
|
897
|
+
if (newHeight < minHeight)
|
|
898
|
+
newHeight = minHeight;
|
|
899
|
+
if (maxWidth && newWidth > maxWidth)
|
|
900
|
+
newWidth = maxWidth;
|
|
901
|
+
if (maxHeight && newHeight > maxHeight)
|
|
902
|
+
newHeight = maxHeight;
|
|
903
|
+
// Update size
|
|
904
|
+
setInternalSize({
|
|
905
|
+
width: newWidth,
|
|
906
|
+
height: newHeight,
|
|
907
|
+
});
|
|
908
|
+
// Call callback if provided
|
|
909
|
+
if (onResize) {
|
|
910
|
+
onResize({ width: newWidth, height: newHeight });
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
const handleMouseUp = () => {
|
|
914
|
+
setIsResizing(false);
|
|
915
|
+
resizeStartRef.current = null;
|
|
916
|
+
};
|
|
917
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
918
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
919
|
+
return () => {
|
|
920
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
921
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
922
|
+
};
|
|
923
|
+
}, [isResizing, minWidth, minHeight, maxWidth, maxHeight, onResize]);
|
|
851
924
|
// Handle mouse move during drag
|
|
852
925
|
useEffect(() => {
|
|
853
926
|
if (!isDragging || !dragStartRef.current)
|
|
@@ -905,11 +978,13 @@ const Window = forwardRef(({ children, title, titleBar, active = true, width = '
|
|
|
905
978
|
const titleBarClassNames = mergeClasses(styles$6.titleBar, draggable && styles$6['titleBar--draggable'], isDragging && styles$6['titleBar--dragging'], classes?.titleBar);
|
|
906
979
|
// Window style
|
|
907
980
|
const windowStyle = {};
|
|
908
|
-
|
|
909
|
-
|
|
981
|
+
// Apply width - use currentWidth during resize, otherwise use prop
|
|
982
|
+
if (currentWidth !== 'auto') {
|
|
983
|
+
windowStyle.width = typeof currentWidth === 'number' ? `${currentWidth}px` : currentWidth;
|
|
910
984
|
}
|
|
911
|
-
|
|
912
|
-
|
|
985
|
+
// Apply height - use currentHeight during resize, otherwise use prop
|
|
986
|
+
if (currentHeight !== 'auto') {
|
|
987
|
+
windowStyle.height = typeof currentHeight === 'number' ? `${currentHeight}px` : currentHeight;
|
|
913
988
|
}
|
|
914
989
|
// Apply position if draggable and has been dragged
|
|
915
990
|
if (draggable && hasBeenDragged && currentPosition) {
|
|
@@ -927,7 +1002,7 @@ const Window = forwardRef(({ children, title, titleBar, active = true, width = '
|
|
|
927
1002
|
}
|
|
928
1003
|
return null;
|
|
929
1004
|
};
|
|
930
|
-
return (jsxs("div", { ref: ref, className: windowClassNames, style: windowStyle, onMouseEnter: onMouseEnter, children: [renderTitleBar(), jsx("div", { className: contentClassNames, children: children }), resizable && jsx("div", { className: styles$6.resizeHandle, "aria-hidden": "true" })] }));
|
|
1005
|
+
return (jsxs("div", { ref: ref, className: windowClassNames, style: windowStyle, onMouseEnter: onMouseEnter, children: [renderTitleBar(), jsx("div", { className: contentClassNames, children: children }), resizable && (jsx("div", { className: styles$6.resizeHandle, onMouseDown: handleResizeMouseDown, "aria-hidden": "true" }))] }));
|
|
931
1006
|
});
|
|
932
1007
|
Window.displayName = 'Window';
|
|
933
1008
|
|