diff --git a/src/components/actions/Actions.module.css b/src/components/actions/Actions.module.css index 0c1ffd8..92c53b8 100644 --- a/src/components/actions/Actions.module.css +++ b/src/components/actions/Actions.module.css @@ -143,4 +143,83 @@ border-radius: 1rem; background-color: var(--foreground-color-c); margin: 0.5rem auto; +} + +.Header-menu { + display: flex; + width: inherit; + height: inherit; +} + +.Header-menu .Dropdown { + display: block; + width: auto; + height: 100%; + padding: 0 0.5rem; + background: none; + border: none; + outline: none; + font-size: 0.85rem; + cursor: pointer; +} + +.Header-menu .Dropdown:hover, .Header-menu .Dropdown:focus-visible { + background-color: rgba(255, 255, 255, 5%); +} + +.Header-menu .Dropdown > .Label { + display: flex; + justify-content: center; + align-items: center; + height: 100%; +} + +.Header-menu .Dropdown-arrow { + display: none; +} + +.Header-menu .Dropdown-content { + display: flex; + flex-direction: column; + position: absolute; + top: 100%; + left: 0; + padding: 0.35rem; + background-color: var(--background-color-b); + border-bottom-left-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.Header-menu .Dropdown:not(.Active) .Dropdown-content { + opacity: 0; + pointer-events: none; +} + +.Header-menu .Button { + display: flex; + gap: 0.75rem; + justify-content: space-between; + width: 100%; + padding: 0.25rem 0.5rem; + background: none; + border: none; + border-radius: 0.5rem; + outline: none; + font-size: 0.85rem; + text-align: start; + white-space: nowrap; + cursor: pointer; +} + +.Header-menu .Button:hover, .Header-menu .Button:focus-visible { + background-color: hsla(var(--background-color-a-hsl), 75%); +} + +.Header-menu .Dropdown > .Label > p, .Header-menu .Button > .Label > p { + margin: 0; +} + +.Header-menu .Shortcut { + color: var(--foreground-color-b); + margin: 0; } \ No newline at end of file diff --git a/src/components/actions/Actions.tsx b/src/components/actions/Actions.tsx index 59e8f62..2a86e13 100644 --- a/src/components/actions/Actions.tsx +++ b/src/components/actions/Actions.tsx @@ -6,6 +6,7 @@ import { useScreenBounds } from "../../hooks/_utils/screen"; export const STYLES = { CONTEXT_MENU: styles["Context-menu"], SHORTCUTS_LISTENER: styles["Shortcuts-listener"], + HEADER_MENU: styles["Header-menu"] }; export interface ActionProps { @@ -63,12 +64,13 @@ export function Actions({ children, className, onAnyTrigger, triggerParams, avoi if (isListener) { return iterateOverChildren((child.props as ActionProps).children); } - + return cloneElement(child, { ...child.props, actionId, children: iterateOverChildren((child.props as ActionProps).children), onTrigger: (event, ...args) => { + console.log(event); onAnyTrigger?.(event, triggerParams, ...args); onTrigger?.(event, triggerParams, ...args); } diff --git a/src/components/actions/actions/DropdownAction.tsx b/src/components/actions/actions/DropdownAction.tsx index d5e3650..730094b 100644 --- a/src/components/actions/actions/DropdownAction.tsx +++ b/src/components/actions/actions/DropdownAction.tsx @@ -3,28 +3,39 @@ import styles from "../Actions.module.css"; import { faCaretRight, IconDefinition } from "@fortawesome/free-solid-svg-icons"; import { ReactElement, useState } from "react"; import { ActionProps } from "../Actions"; +import OutsideClickListener from "../../../hooks/_utils/outsideClick"; -export function DropdownAction({ label, icon, children }: ActionProps): ReactElement { +interface DropdownActionProps extends ActionProps { + showOnHover?: boolean; +} + +export function DropdownAction({ label, icon, children, showOnHover = true }: DropdownActionProps): ReactElement { const [showContent, setShowContent] = useState(false); const classNames = [styles.Dropdown]; if (showContent) classNames.push(styles.Active); - return
{ setShowContent(true); }} - onMouseLeave={() => { setShowContent(false); }} - > - - {icon &&
} -

{label}

-
-
-
- {children} + return { + if (!showOnHover) + setShowContent(false); + }}> +
{ setShowContent(true); } : null} + onMouseLeave={showOnHover ? () => { setShowContent(false); } : null} + onClick={!showOnHover ? () => { setShowContent(!showContent); } : null} + > + + {icon &&
} +

{label}

+
+
+
+ {children} +
-
; + ; } \ No newline at end of file diff --git a/src/components/apps/_utils/header-menu/HeaderMenu.module.css b/src/components/apps/_utils/header-menu/HeaderMenu.module.css index 6d293dc..2ae7269 100644 --- a/src/components/apps/_utils/header-menu/HeaderMenu.module.css +++ b/src/components/apps/_utils/header-menu/HeaderMenu.module.css @@ -2,5 +2,6 @@ display: flex; width: 100%; height: 1.5rem; + min-height: 1.5rem; background-color: var(--background-color-a); } \ No newline at end of file diff --git a/src/components/apps/_utils/header-menu/HeaderMenu.tsx b/src/components/apps/_utils/header-menu/HeaderMenu.tsx index 2a873bc..549c18c 100644 --- a/src/components/apps/_utils/header-menu/HeaderMenu.tsx +++ b/src/components/apps/_utils/header-menu/HeaderMenu.tsx @@ -1,20 +1,11 @@ -import { useShortcuts } from "../../../../hooks/_utils/keyboard"; -import { DropdownButton } from "../../../_utils/dropdown-button/DropdownButton"; import styles from "./HeaderMenu.module.css"; +import { ActionsProps, Actions, STYLES } from "../../../actions/Actions"; -interface HeaderMenuProps { - options: Record> | Record; - shortcuts: Record> | Record; -} -export function HeaderMenu({ options, shortcuts }: HeaderMenuProps) { - useShortcuts({ options, shortcuts }); - - return ( -
- {Object.entries(options).map(([key, value]) => - - )} -
- ); +export function HeaderMenu({ children, ...props }: ActionsProps) { + return
+ + {children} + +
; } \ No newline at end of file diff --git a/src/components/apps/text-editor/TextEditor.tsx b/src/components/apps/text-editor/TextEditor.tsx index 8ab0fdb..6f4a1e5 100644 --- a/src/components/apps/text-editor/TextEditor.tsx +++ b/src/components/apps/text-editor/TextEditor.tsx @@ -15,6 +15,8 @@ import { FileSelector } from "../../modals/file-selector/FileSelector"; import { SELECTOR_MODE } from "../../../config/apps/fileExplorer.config"; import { VirtualFile } from "../../../features/virtual-drive/file/virtualFile"; import { WindowProps } from "../../windows/WindowView"; +import { DropdownAction } from "../../actions/actions/DropdownAction"; +import { ClickAction } from "../../actions/actions/ClickAction"; const OVERRIDES = { a: MarkdownLink, @@ -125,60 +127,36 @@ export function TextEditor({ file, setTitle, setIconUrl, close, mode, app, modal return (
- { - openWindowedModal({ - size: DEFAULT_FILE_SELECTOR_SIZE, - Modal: (props) => { - setCurrentFile(file); - setUnsavedChanges(false); - }} - {...props} - /> - }); - }, - "Save": saveText, - // "Save As": saveTextAs, - "Quit": () => { - close(); - }, - }, - "View": { - [currentMode === "view" ? "Edit mode" : "Preview mode"]: () => { - setCurrentMode(currentMode === "view" ? "edit" : "view"); - }, - "Zoom In": () => { - setZoom(zoom + ZOOM_FACTOR); - }, - "Zoom Out": () => { - setZoom(zoom - ZOOM_FACTOR); - }, - "Reset Zoom": () => { - setZoom(DEFAULT_ZOOM); - } - } - }} - shortcuts={{ - "File": { - "New": ["Control", "e"], - "Open": ["Control", "o"], - "Save": ["Control", "s"], - "Quit": ["Control", "q"], - }, - "View": { - "Zoom In": ["Control", "+"], - "Zoom Out": ["Control", "-"], - "Reset Zoom": ["Control", "0"], - "Edit mode": ["Control v"], - "Preview mode": ["Control v"], - } - }} - /> + { + console.log(event); + }}> + + { newText(); }} shortcut={["Control", "e"]}/> + { + openWindowedModal({ + size: DEFAULT_FILE_SELECTOR_SIZE, + Modal: (props) => { + setCurrentFile(file); + setUnsavedChanges(false); + }} + {...props} + /> + }); + }} shortcut={["Control", "o"]}/> + { saveText(); }} shortcut={["Control", "s"]}/> + { close(); }} shortcut={["Control", "q"]}/> + + + { + setCurrentMode(currentMode === "view" ? "edit" : "view"); + }} shortcut={["Control", "v"]}/> + { setZoom(zoom + ZOOM_FACTOR); }} shortcut={["Control", "+"]}/> + { setZoom(zoom - ZOOM_FACTOR); }} shortcut={["Control", "-"]}/> + { setZoom(DEFAULT_ZOOM); }} shortcut={["Control", "0"]}/> + + {currentMode === "view" ? CODE_FORMATS.includes(currentFile?.extension) ?