Skip to content

Commit

Permalink
Merge pull request #8 from Pettor/feature/drawer
Browse files Browse the repository at this point in the history
feat: use drawer for application menu
  • Loading branch information
Pettor authored Feb 20, 2024
2 parents 43614f4 + 0752003 commit 3c2e37e
Show file tree
Hide file tree
Showing 14 changed files with 59 additions and 102 deletions.
1 change: 0 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"endOfLine": "auto",
"plugins": ["prettier-plugin-tailwindcss"],
"printWidth": 120,
"singleQuote": false,
"tabWidth": 2,
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "never",
"source.fixAll.eslint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!doctype html>
<html lang="en">
<html lang="en" class="light" data-theme="light">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
"playwright": "1.41.1",
"postcss": "8.4.33",
"prettier": "3.2.4",
"prettier-plugin-tailwindcss": "0.5.11",
"rimraf": "5.0.5",
"start-server-and-test": "2.0.3",
"storybook": "7.6.10",
Expand Down
55 changes: 0 additions & 55 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/library/image-editor/Editor.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type Story = StoryObj<typeof meta>;

const commonProps = {
url: cardImgUrl,
toolbarMenuProps: {
appdrawerProps: {
onNewImage: () => {},
},
ErrorComponent: () => <div>Error</div>,
Expand Down
4 changes: 4 additions & 0 deletions src/components/library/image-editor/atoms/DrawerAtoms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { atom } from "jotai";

export const drawerOpenedAtom = atom(false);
export const toggleDrawerAtom = atom(null, (_get, set) => set(drawerOpenedAtom, (prev) => !prev));
10 changes: 6 additions & 4 deletions src/components/library/image-editor/content/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import type { ReactElement } from "react";
import type { AppDrawerProps } from "../drawer/AppDrawer";
import { AppDrawer } from "../drawer/AppDrawer";
import { StageComponent } from "../stage/StageComponent";
import type { ToolbarMenuProps } from "../toolbar/ToolbarMenu";
import { ToolbarMenu } from "../toolbar/ToolbarMenu";
import { ToolbarTools } from "../toolbar/ToolbarTools";
import { ToolbarZoom } from "../toolbar/ToolbarZoom";

export interface ContentProps {
toolbarMenuProps: ToolbarMenuProps;
appdrawerProps: AppDrawerProps;
}

export function Content({ toolbarMenuProps }: ContentProps): ReactElement {
export function Content({ appdrawerProps }: ContentProps): ReactElement {
return (
<div className="relative flex h-full w-full flex-col">
<ToolbarMenu {...toolbarMenuProps} />
<AppDrawer {...appdrawerProps} />
<ToolbarMenu />
<ToolbarTools />
<ToolbarZoom />
<StageComponent />
Expand Down
34 changes: 34 additions & 0 deletions src/components/library/image-editor/drawer/AppDrawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useRef, type ReactElement } from "react";
import { FolderPlusIcon } from "@heroicons/react/24/solid";
import { useAtomValue, useSetAtom } from "jotai";
import { useOnClickOutside } from "usehooks-ts";
import { drawerOpenedAtom, toggleDrawerAtom } from "../atoms/DrawerAtoms";

export interface AppDrawerProps {
onNewImage: () => void;
}

export function AppDrawer({ onNewImage }: AppDrawerProps): ReactElement {
const drawerState = useAtomValue(drawerOpenedAtom);
const swapDrawer = useSetAtom(toggleDrawerAtom);
const menuRef = useRef<HTMLUListElement>(null);
useOnClickOutside(menuRef, () => drawerState && swapDrawer());

return (
<div className="drawer z-30">
<input id="my-drawer" type="checkbox" checked={drawerState} className="drawer-toggle" />
<div className="drawer-side">
<label htmlFor="my-drawer" aria-label="close sidebar" className="drawer-overlay" />

<ul ref={menuRef} className="menu min-h-full w-60 bg-base-200 p-4 text-base text-base-content md:w-80">
<li onClick={onNewImage}>
<a>
<FolderPlusIcon className="h-6 w-6" />
New Image
</a>
</li>
</ul>
</div>
</div>
);
}
42 changes: 7 additions & 35 deletions src/components/library/image-editor/toolbar/ToolbarMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,18 @@
import type { MouseEvent } from "react";
import { useState, type ReactElement, useRef } from "react";
import { type ReactElement } from "react";
import { Bars3Icon } from "@heroicons/react/24/solid";
import { useOnClickOutside } from "usehooks-ts";
import { useSetAtom } from "jotai";
import { toggleDrawerAtom } from "../atoms/DrawerAtoms";

export interface ToolbarMenuProps {
onNewImage: () => void;
}

export function ToolbarMenu({ onNewImage }: ToolbarMenuProps): ReactElement {
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
const menuRef = useRef<HTMLUListElement>(null);
useOnClickOutside(menuRef, () => setAnchorEl(null));

function handleMenuClick(event: MouseEvent): void {
if (anchorEl) {
setAnchorEl(null);
return;
}

setAnchorEl(event.currentTarget as HTMLElement);
}

function contextMenu(): ReactElement {
return (
<div className="absolute bottom-16 right-5 z-10 md:left-5 md:top-16">
<ul ref={menuRef} className="menu w-56 rounded-box bg-base-200 shadow-xl">
<li onClick={onNewImage}>
<a>New Image</a>
</li>
</ul>
</div>
);
}
export function ToolbarMenu(): ReactElement {
const toggleDrawer = useSetAtom(toggleDrawerAtom);

return (
<div className="absolute z-20 flex items-center justify-center p-4 max-sm:bottom-0 max-sm:right-0">
<div className="glass navbar flex h-10 min-h-0 rounded-box bg-base-300 bg-opacity-80 shadow-xl md:h-12 dark:bg-opacity-80 dark:bg-none">
<button className="btn btn-square btn-ghost btn-sm" onClick={handleMenuClick}>
<div className="glass navbar flex h-10 min-h-0 rounded-box bg-base-300 bg-opacity-80 shadow-xl dark:bg-opacity-80 dark:bg-none md:h-12">
<button className="btn btn-square btn-ghost btn-sm" onClick={toggleDrawer}>
<Bars3Icon className="h-4 w-4 md:h-6 md:w-6" />
</button>
</div>
{anchorEl && contextMenu()}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function ToolbarTools(): ReactElement {

return (
<div className="absolute z-10 mr-2 flex w-full justify-center p-4 md:mr-0">
<div className="glass navbar h-10 min-h-0 w-auto rounded-box border border-neutral bg-base-300 bg-opacity-60 shadow-xl md:h-12 dark:bg-opacity-80 dark:bg-none">
<div className="glass navbar h-10 min-h-0 w-auto rounded-box border border-neutral bg-base-300 bg-opacity-60 shadow-xl dark:bg-opacity-80 dark:bg-none md:h-12">
<div className="tooltip tooltip-bottom" data-tip={lock ? undefined : "Lock image to center"}>
<button
className={clsx("btn btn-square btn-ghost swap btn-sm ml-2", lock && "btn-active")}
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/EditorView.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Story = StoryObj<typeof meta>;

const commonProps = {
url: cardImgUrl,
toolbarMenuProps: {
appdrawerProps: {
onNewImage: () => {},
},
ErrorComponent: () => <div>Error</div>,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/image-editor/ImageEditorPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function ImageEditorPage({ url }: ImageEditorPageProps): ReactElement {
return (
<ImageEditor
url={url}
toolbarMenuProps={{
appdrawerProps={{
onNewImage: handleOnNewImage,
}}
LoaderComponent={() => <LoadingView />}
Expand Down
2 changes: 2 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
module.exports = {
content: ["./src/**/*.{js,ts,jsx,tsx}"],
daisyui: {
darkMode: "class",
darkTheme: "dark",
logs: false,
},
darkMode: "class",
mode: "jit",
theme: {
extend: {
Expand Down

0 comments on commit 3c2e37e

Please sign in to comment.