@wener/console
Version:
Base console UI toolkit
208 lines (207 loc) • 6.42 kB
JavaScript
import React, { memo, useEffect } from "react";
import { Rnd } from "react-rnd";
import { Closer } from "@wener/utils";
import { clsx } from "clsx";
import { useStore } from "zustand";
import { useShallow } from "zustand/react/shallow";
import { getRootWindow, WindowContext } from "./ReactWindow.js";
import { WindowController } from "./WindowController.js";
import { WindowFrame } from "./WindowFrame.js";
export const WindowGuest = /*#__PURE__*/ memo(({ win }) => {
const { store } = win;
const [zIndex, minimized, x, y, width, height, canResize, canDrag, minWidth, minHeight, maxWidth, maxHeight] = useStore(store, useShallow(({ zIndex, minimized, x, y, width, height, canResize, maximized, canDrag, minWidth, minHeight, maxWidth, maxHeight }) => {
return [
zIndex,
minimized,
x,
y,
width,
height,
canResize && !maximized,
canDrag,
minWidth,
minHeight,
maxWidth,
maxHeight
];
}));
return /*#__PURE__*/ React.createElement(Rnd, {
id: `win-${win.id}`,
"data-dnd-window-id": win.id,
className: clsx(!minimized && "pointer-events-auto"),
default: {
x: 0,
y: 0,
width: 320,
height: 200
},
size: {
width,
height
},
position: {
x,
y
},
onDragStop: (e, d) => {
store.setState({
x: d.x,
y: d.y
});
},
onResize: (e, direction, ref, delta, position) => {
store.setState({
width: ref.offsetWidth,
height: ref.offsetHeight,
...position
});
},
dragHandleClassName: "WindowDragHandle",
cancel: ".WindowDragCancel",
enableResizing: canResize,
disableDragging: !canDrag,
bounds: document.body,
minWidth: minWidth,
minHeight: minHeight,
maxWidth: maxWidth,
maxHeight: maxHeight,
style: {
zIndex
},
ref: (ref) => {
let ele = ref?.resizableElement.current;
if (ele && win.state.windowElement !== ele) {
win.store.setState({
windowElement: ele
});
}
}
}, /*#__PURE__*/ React.createElement(WinContent, {
win: win
}));
});
const WinContent = /*#__PURE__*/ memo(({ win }) => {
const store = win.store;
const [frameless] = useStore(store, useShallow(({ frameless, minimized, canMinimize, canMaximize, title, render }) => {
return [
frameless,
minimized,
canMinimize,
canMaximize,
title,
render
];
}));
let rw = getRootWindow();
useEffect(() => {
let closer = new Closer();
let windowElement;
const handleWindowElement = (ele) => {
if (!ele) {
return;
}
if (ele === windowElement) {
return;
}
ele.addEventListener("mousedown", () => {
rw.setActive(win);
});
};
handleWindowElement(store.getState().windowElement);
closer.add(store.subscribe((s) => {
handleWindowElement(s.windowElement);
}));
return () => {
closer.close();
};
}, []);
if (frameless) {
return /*#__PURE__*/ React.createElement(WinFramelessContent, {
win: win
});
}
return /*#__PURE__*/ React.createElement(WinFrameContent, {
win: win
});
});
const WinFramelessContent = ({ win }) => {
const store = win.store;
const [minimized, render] = useStore(store, useShallow(({ minimized, render }) => {
return [
minimized,
render
];
}));
return /*#__PURE__*/ React.createElement("div", {
ref: (ref) => {
win.setBody(ref);
},
className: clsx("rounded-lg bg-base-100 shadow outline-none @container focus-within:shadow-lg", minimized && "hidden"),
tabIndex: -1,
inert: minimized,
...getWindowProps(win)
}, /*#__PURE__*/ React.createElement(WindowRenderer, {
render: render
}));
};
const WinFrameContent = /*#__PURE__*/ memo(({ win }) => {
const store = win.store;
const [minimized, canMinimize, canMaximize, title, render] = useStore(store, useShallow(({ minimized, canMinimize, canMaximize, title, render }) => {
return [
minimized,
canMinimize,
canMaximize,
title,
render
];
}));
return /*#__PURE__*/ React.createElement(WindowContext.Provider, {
value: win
}, /*#__PURE__*/ React.createElement(WindowFrame, {
inert: minimized,
controller: /*#__PURE__*/ React.createElement(WindowController, {
close: {
onClick: () => {
win.close();
}
},
minimize: {
disabled: !canMinimize,
onClick: () => {
win.minimize();
}
},
maximize: {
disabled: !canMaximize,
onClick: () => {
win.maximize();
}
}
}),
onToggleMaximize: () => {
win.maximize();
},
className: clsx("h-full w-full", minimized && "hidden"),
title: title,
...getWindowProps(win)
}, /*#__PURE__*/ React.createElement("main", {
className: "relative flex-1 overflow-hidden"
}, /*#__PURE__*/ React.createElement("div", {
className: "absolute inset-0 overflow-auto @container",
ref: (ref) => {
win.setBody(ref);
},
tabIndex: -1
}, /*#__PURE__*/ React.createElement(WindowRenderer, {
render: render
})))));
});
const WindowRenderer = ({ render }) => {
return render?.();
};
function getWindowProps(win) {
// https://github.com/facebook/react/issues/6410#issuecomment-207064994
// 会导致 window 内 input 无法获取焦点
return {};
}
//# sourceMappingURL=WindowGuest.js.map