diff --git a/src/KonvaContainer/ContextualToolbarImage.tsx b/src/KonvaContainer/ContextualToolbarImage.tsx index 3430e8cb33..e8262f6ef6 100644 --- a/src/KonvaContainer/ContextualToolbarImage.tsx +++ b/src/KonvaContainer/ContextualToolbarImage.tsx @@ -1,23 +1,45 @@ +import { MouseEventHandler } from "react"; import { useSignals } from "@preact/signals-react/runtime"; import { Transition } from "@headlessui/react"; import { twMerge } from "tailwind-merge"; import { ToolbarImage } from "~/components/features/ToolbarImage"; import { uiAccess } from "~/signals/uiAccess"; +import { dispatchUiEvents } from "~/signals/uiEvents"; +import { ToolbarImageButtonNames } from "~/components/features/ToolbarImage/enums"; import { transitionTimingStyles } from "~/components/styles"; export const ContextualToolbarImage = () => { useSignals(); - const { isShowing, ...rest } = uiAccess.imageToolbar.signal.value; - + const { isShowing, position, ...rest } = uiAccess.imageToolbar.signal.value; + const buttonsProps = Object.values(ToolbarImageButtonNames).reduce( + (acc, buttonName) => { + acc[buttonName] = { + onClick: dispatchUiEvents.imageToolbar[buttonName], + }; + return acc; + }, + {} as { + [key in ToolbarImageButtonNames]: { + onClick: MouseEventHandler; + }; + }, + ); return (
- +
); diff --git a/src/components/features/ToolbarButtons.tsx b/src/components/features/ToolbarButton.tsx similarity index 73% rename from src/components/features/ToolbarButtons.tsx rename to src/components/features/ToolbarButton.tsx index 2a17f0c117..ed6c67d469 100644 --- a/src/components/features/ToolbarButtons.tsx +++ b/src/components/features/ToolbarButton.tsx @@ -6,33 +6,41 @@ import { } from "@fortawesome/react-fontawesome"; import { IconDefinition } from "@fortawesome/pro-solid-svg-icons"; -export const ToolbarButtons = ({ +export interface ToolbarButtonProps + extends ButtonHTMLAttributes { + active?: boolean; +} + +export const ToolbarButton = ({ icon, onClick, - buttonProps = { className: "" }, + buttonProps = {}, iconProps, }: { icon: IconDefinition; onClick?: MouseEventHandler; - buttonProps?: ButtonHTMLAttributes; + buttonProps?: ToolbarButtonProps; iconProps?: Omit; }) => { const { className: customButtonClassNames, disabled, + active, + onClick: customOnClick, ...restButtonProps } = buttonProps; const mergedButtonClasses = twMerge( "size-10 rounded-2xl p-2 hover:bg-secondary-500 hover:text-white", disabled && "pointer-events-none text-secondary-300", + active && "pointer-events-none text-primary ", customButtonClassNames, ); return ( diff --git a/src/components/features/ToolbarImage/index.tsx b/src/components/features/ToolbarImage/index.tsx index 0344b09719..cd9446aedd 100644 --- a/src/components/features/ToolbarImage/index.tsx +++ b/src/components/features/ToolbarImage/index.tsx @@ -1,66 +1,42 @@ -import { MouseEventHandler } from "react"; import { twMerge } from "tailwind-merge"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faImage } from "@fortawesome/pro-solid-svg-icons"; -import { ToolbarButtons } from "~/components/features/ToolbarButtons"; +import { + ToolbarButton, + ToolbarButtonProps, +} from "~/components/features/ToolbarButton"; import { paperWrapperStyles } from "~/components/styles"; import { ToolbarImageButtonNames } from "./enums"; import { ToolbarImageButtonData } from "./data"; -export const ToolbarImage = ({ - position, - disabled, - buttonStates, - buttonCallbacks, -}: { - position: { - x: number; - y: number; - }; +export interface ToolbarImageProps { disabled?: boolean; - buttonStates?: { - [key in ToolbarImageButtonNames]: { - disabled: boolean; - }; + buttonsProps?: { + [key in ToolbarImageButtonNames]: ToolbarButtonProps; }; - buttonCallbacks?: { - [key in ToolbarImageButtonNames]: - | MouseEventHandler - | undefined; - }; -}) => { +} +export const ToolbarImage = ({ disabled, buttonsProps }: ToolbarImageProps) => { return (
{ToolbarImageButtonData.map((buttonDatum, idx) => { - const buttonProps = - buttonStates && buttonStates[buttonDatum.name] - ? { disabled: buttonStates[buttonDatum.name].disabled } - : undefined; - const buttonCallback = - buttonCallbacks && buttonCallbacks[buttonDatum.name] - ? buttonCallbacks[buttonDatum.name] - : undefined; + const buttonProps = buttonsProps?.[buttonDatum.name]; + return ( - ); })} diff --git a/src/components/features/ToolbarMain/index.tsx b/src/components/features/ToolbarMain/index.tsx index 4a8f202078..5df832a1f7 100644 --- a/src/components/features/ToolbarMain/index.tsx +++ b/src/components/features/ToolbarMain/index.tsx @@ -9,17 +9,13 @@ import { faFilePlus, faFilm, faFloppyDisk, - // faHand, faHatWizard, faImage, faLocationArrow, - - // faPlus, - // faMinus, faSquareDashed, } from "@fortawesome/pro-solid-svg-icons"; -import { ToolbarButtons } from "../ToolbarButtons"; +import { ToolbarButton } from "../ToolbarButton"; import { twMerge } from "tailwind-merge"; import { UploadImage } from "../UploadImage"; @@ -76,14 +72,14 @@ export const ToolbarMain = () => { )} >
- - + - +
- { setState({ ...state, isUploadSubmenuOpen: true }); @@ -96,7 +92,7 @@ export const ToolbarMain = () => { paperWrapperStyles, )} > - setState({ @@ -106,7 +102,7 @@ export const ToolbarMain = () => { }) } /> - setState({ @@ -119,14 +115,14 @@ export const ToolbarMain = () => {
)}
- - + +
- - - - + + + +
diff --git a/src/components/features/UploadImage/index.tsx b/src/components/features/UploadImage/index.tsx index 98a1aae3f9..ad9bab50d5 100644 --- a/src/components/features/UploadImage/index.tsx +++ b/src/components/features/UploadImage/index.tsx @@ -6,7 +6,7 @@ import { FileUploader, IMAGE_FILE_TYPE } from "../FileUploader"; import { Button } from "~/components/ui"; import { paperWrapperStyles } from "~/components/styles"; -import { addImageToEngine } from "~/signals/uiEvents"; +import { dispatchUiEvents } from "~/signals/uiEvents/"; export const UploadImage = ({ isOpen, @@ -24,7 +24,7 @@ export const UploadImage = ({ function handleEnter() { if (assetFile) { - addImageToEngine(assetFile); + dispatchUiEvents.addImageToEngine(assetFile); } handleClose(); } diff --git a/src/components/features/UploadVideo/index.tsx b/src/components/features/UploadVideo/index.tsx index 232511d25a..4f135d4110 100644 --- a/src/components/features/UploadVideo/index.tsx +++ b/src/components/features/UploadVideo/index.tsx @@ -6,7 +6,7 @@ import { FileUploader, VIDEO_FILE_TYPE } from "../FileUploader"; import { Button } from "~/components/ui"; import { paperWrapperStyles } from "~/components/styles"; -import { addVideoToEngine } from "~/signals/uiEvents"; +import { dispatchUiEvents } from "~/signals/uiEvents"; export const UploadVideo = ({ isOpen, @@ -24,7 +24,7 @@ export const UploadVideo = ({ function handleEnter() { if (assetFile) { - addVideoToEngine(assetFile); + dispatchUiEvents.addVideoToEngine(assetFile); } handleClose(); } diff --git a/src/signals/uiEvents/addMedia.ts b/src/signals/uiEvents/addMedia.ts new file mode 100644 index 0000000000..169d0017bc --- /dev/null +++ b/src/signals/uiEvents/addMedia.ts @@ -0,0 +1,40 @@ +import { signal } from "@preact/signals-core"; +import { effect } from "@preact/signals-react"; + +const stagedImage = signal(null); + +const addImageToEngine = (image: File) => { + stagedImage.value = image; +}; + +const onGetStagedImage = (callback: (file: File) => void) => { + effect(() => { + if (stagedImage.value) { + callback(stagedImage.value); + } + }); +}; + +const stagedVideo = signal(null); + +const addVideoToEngine = (video: File) => { + stagedVideo.value = video; +}; + +const onGetStagedVideo = (callback: (file: File) => void) => { + effect(() => { + if (stagedVideo.value) { + callback(stagedVideo.value); + } + }); +}; + +export const dispatchers = { + addImageToEngine, + addVideoToEngine, +}; + +export const events = { + onGetStagedImage, + onGetStagedVideo, +}; diff --git a/src/signals/uiEvents/imageToolbar.ts b/src/signals/uiEvents/imageToolbar.ts new file mode 100644 index 0000000000..baafdb2417 --- /dev/null +++ b/src/signals/uiEvents/imageToolbar.ts @@ -0,0 +1,46 @@ +import { MouseEventHandler } from "react"; +import { signal, effect } from "@preact/signals-core"; + +import { ToolbarImageButtonNames } from "~/components/features/ToolbarImage/enums"; + +const events = signal<{ + [key in ToolbarImageButtonNames]?: React.MouseEvent< + HTMLButtonElement, + MouseEvent + >; +}>(); + +export const eventsHandlers = Object.values(ToolbarImageButtonNames).reduce( + (acc, buttonName) => { + acc[buttonName] = { + onClick: (callback: MouseEventHandler) => { + effect(() => { + if (events.value?.[buttonName]) { + callback(events.value?.[buttonName]); + } + }); + }, + }; + return acc; + }, + {} as { + [key in ToolbarImageButtonNames]: { + onClick: (callback: MouseEventHandler) => void; + }; + }, +); + +export const dispatchers = Object.values(ToolbarImageButtonNames).reduce( + (acc, buttonName) => { + acc[buttonName] = (e: React.MouseEvent) => { + events.value = { + ...events.value, + [buttonName]: e, + }; + }; + return acc; + }, + {} as { + [key in ToolbarImageButtonNames]: MouseEventHandler; + }, +); diff --git a/src/signals/uiEvents/index.ts b/src/signals/uiEvents/index.ts index 6296e79c5c..3f79c64a54 100644 --- a/src/signals/uiEvents/index.ts +++ b/src/signals/uiEvents/index.ts @@ -1,35 +1,17 @@ -import { signal } from "@preact/signals-core"; -import { effect } from "@preact/signals-react"; - -const stagedImage = signal(null); - -export const addImageToEngine = (image: File) => { - stagedImage.value = image; -}; - -const onGetStagedImage = (callback: (file: File) => void) => { - effect(() => { - if (stagedImage.value) { - callback(stagedImage.value); - } - }); -}; - -const stagedVideo = signal(null); - -export const addVideoToEngine = (video: File) => { - stagedVideo.value = video; -}; - -const onGetStagedVideo = (callback: (file: File) => void) => { - effect(() => { - if (stagedVideo.value) { - callback(stagedVideo.value); - } - }); -}; +import { + dispatchers as addMediaDispatchers, + events as addMediaEvents, +} from "./addMedia"; +import { + dispatchers as imageToolbarDispatchers, + eventsHandlers as imageToolbarEvents, +} from "./imageToolbar"; export const uiEvents = { - onGetStagedImage, - onGetStagedVideo, + ...addMediaEvents, + imageToolbar: imageToolbarEvents, +}; +export const dispatchUiEvents = { + ...addMediaDispatchers, + imageToolbar: imageToolbarDispatchers, };