UNPKG

@wener/console

Version:
135 lines (134 loc) 4.6 kB
import React, { cloneElement, isValidElement, useEffect, useRef } from "react"; import { createPortal } from "react-dom"; import { PiBrowser } from "react-icons/pi"; import { getGlobalStates } from "@wener/utils"; import { uniqBy } from "es-toolkit"; import { createStore, useStore } from "zustand"; import { mutative } from "zustand-mutative"; import { getConsoleEmitter } from "../ConsoleEmitter.js"; import { ConsoleEventType } from "../context.js"; function createLauncherStore() { return createStore(mutative(function () { return { open: false, items: [] }; })); } function LauncherHost() { var emitter = getConsoleEmitter(); useEffect(function () { return emitter.on(ConsoleEventType.LauncherToggle, function (param) { var open = param.open; Launcher.toggle(open); }); }, [ emitter ]); var store = Launcher.useStore(); var open = useStore(store, function (s) { return s.open; }); if (!open) { return null; } return /*#__PURE__*/ createPortal(/*#__PURE__*/ React.createElement(LauncherContent, { onLaunch: function (v) { var _v_onLaunch; (_v_onLaunch = v.onLaunch) === null || _v_onLaunch === void 0 ? void 0 : _v_onLaunch.call(v); } }), document.body, "Launcher"); } /** * @deprecated use {@link Launcher.Host} instead */ export var ConsoleLauncher = LauncherHost; var LauncherContent = function (param) { var onLaunch = param.onLaunch; var store = Launcher.useStore(); var items = store.getState().items; var ref = useRef(null); useEffect(function () { var _ref_current; (_ref_current = ref.current) === null || _ref_current === void 0 ? void 0 : _ref_current.focus(); }, [ ref.current ]); // note 左侧留出来 dock 的位置 // dismiss layer // esc to close // 初次渲染自动获取 focus return /*#__PURE__*/ React.createElement("div", { className: "absolute inset-0 z-[100]", onClick: function () { store.setState({ open: false }); }, tabIndex: -1, onKeyDown: function (e) { if (e.key === "Escape") { store.setState({ open: false }); } }, ref: ref }, /*#__PURE__*/ React.createElement("div", { className: "bg-base-300/20 absolute inset-0 left-14 backdrop-blur" }, /*#__PURE__*/ React.createElement("div", { className: "flex flex-wrap gap-10 px-20 py-10" }, items.map(function (v) { var key = v.key, title = v.title, icon = v.icon; var ico = icon || /*#__PURE__*/ React.createElement(PiBrowser, null); if ( /*#__PURE__*/isValidElement(ico)) { ico = /*#__PURE__*/ cloneElement(ico, { className: "w-24 h-24 drop-shadow-lg" }); } return /*#__PURE__*/ React.createElement("button", { key: key, type: "button", className: "flex flex-col items-center justify-center gap-1 rounded-lg bg-gray-300/0 p-2 pt-1 transition-all hover:bg-gray-300/40", onClick: function () { onLaunch === null || onLaunch === void 0 ? void 0 : onLaunch(v); } }, /*#__PURE__*/ React.createElement("div", null, ico), /*#__PURE__*/ React.createElement("div", { className: "text-sm" }, title)); })))); }; (function (Launcher) { var _getStore = function () { return getGlobalStates("LauncherStore", createLauncherStore); }; function setStoreProvider(provider) { _getStore = provider; } Launcher.setStoreProvider = setStoreProvider; function getStore() { return _getStore(); } Launcher.getStore = getStore; function useStore() { return getStore(); } Launcher.useStore = useStore; Launcher.Host = LauncherHost; function toggle(open) { getStore().setState(function (s) { s.open = open !== null && open !== void 0 ? open : !s.open; }); } Launcher.toggle = toggle; function addItems(items) { getStore().setState(function (s) { s.items = uniqBy(s.items.concat(items), function (v) { return v.key; }).sort(function (a, b) { return a.title.localeCompare(b.title); }); }); } Launcher.addItems = addItems; })(Launcher || (Launcher = {})); export var Launcher;