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 ;
}
\ 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)
?