diff --git a/app/web/src/components/EditorMenu/AllShortcutsModal.tsx b/app/web/src/components/EditorMenu/AllShortcutsModal.tsx index c37d3f1..5af3486 100644 --- a/app/web/src/components/EditorMenu/AllShortcutsModal.tsx +++ b/app/web/src/components/EditorMenu/AllShortcutsModal.tsx @@ -21,7 +21,7 @@ const AllShortcutsModal = () => { setOpen(false)} className={classes.root}>

All Shortcuts

- { editorMenuConfig.map(menu => menu.items.length ? ( + { editorMenuConfig.filter(menu => menu.items.length).map(menu =>

{ menu.label }

@@ -32,7 +32,7 @@ const AllShortcutsModal = () => {
))} - ) : <>)} + )}
) diff --git a/app/web/src/components/EditorMenu/Dropdowns.tsx b/app/web/src/components/EditorMenu/Dropdowns.tsx new file mode 100644 index 0000000..4672635 --- /dev/null +++ b/app/web/src/components/EditorMenu/Dropdowns.tsx @@ -0,0 +1,49 @@ +import { Menu } from '@headlessui/react' +import { useHotkeys } from 'react-hotkeys-hook'; + +export function DropdownItem({ config, state, thunkDispatch }) { + console.log({ name: config.label, shortcut: config.shortcut, callback: handleClick}) + useHotkeys(config.shortcut, handleClick) + + function handleClick(e) { + console.log(e, config) + e.preventDefault() + config.callback(e, {state, thunkDispatch}) + } + return ( + + {({ active }) => ( + + )} + + ) + } + +export function Dropdown({ + label, + disabled, + children, + }: { + label: string, + disabled: boolean, + children: React.ReactNode, + }) { + return ( +
+ + {label} + { children && + + {children} + + } + +
+ ) + } \ No newline at end of file diff --git a/app/web/src/components/EditorMenu/EditorMenu.tsx b/app/web/src/components/EditorMenu/EditorMenu.tsx index ac3e9d2..4a749fa 100644 --- a/app/web/src/components/EditorMenu/EditorMenu.tsx +++ b/app/web/src/components/EditorMenu/EditorMenu.tsx @@ -1,31 +1,12 @@ -import { Menu } from '@headlessui/react' -import { useHotkeys } from 'react-hotkeys-hook'; import { useIdeContext } from 'src/helpers/hooks/useIdeContext' import Svg from 'src/components/Svg/Svg' -import { useRender } from 'src/components/IdeWrapper/useRender' -import { makeStlDownloadHandler, PullTitleFromFirstLine } from './helpers' -import { useSaveCode } from 'src/components/IdeWrapper/useSaveCode' import CadPackage from 'src/components/CadPackage/CadPackage' -import { EditorMenuConfig, EditorMenuItemConfig, editorMenuConfig } from './menuConfig' +import { editorMenuConfig } from './menuConfig' import AllShortcutsModal from './AllShortcutsModal' +import { Dropdown } from './Dropdowns'; const EditorMenu = () => { - const handleRender = useRender() - const saveCode = useSaveCode() const { state, thunkDispatch } = useIdeContext() - const handleStlDownload = makeStlDownloadHandler({ - type: state.objectData?.type, - ideType: state.ideType, - geometry: state.objectData?.data, - quality: state.objectData?.quality, - fileName: PullTitleFromFirstLine(state.code || ''), - thunkDispatch, - }) - - editorMenuConfig.forEach(menu => - menu.items.forEach(({shortcut, callback}) => - useHotkeys(shortcut, callback), [state]) - ) return (<>
@@ -36,8 +17,12 @@ const EditorMenu = () => {
{ editorMenuConfig.map(menu => ( - { menu.items.map(itemConfig => ( - ) + { menu.items.map(itemConfig => + ) } )) } @@ -56,43 +41,4 @@ const EditorMenu = () => { ) } -export default EditorMenu - -function DropdownItem({ config }) { - return ( - - {({ active }) => ( - - )} - - ) -} - -function Dropdown({ - label, - disabled, - children, -}: { - label: string, - disabled: boolean, - children: React.ReactNode, -}) { - return ( -
- - {label} - { children && - - {children} - - } - -
- ) -} +export default EditorMenu \ No newline at end of file diff --git a/app/web/src/components/EditorMenu/menuConfig.tsx b/app/web/src/components/EditorMenu/menuConfig.tsx index 433b1d5..b72cd63 100644 --- a/app/web/src/components/EditorMenu/menuConfig.tsx +++ b/app/web/src/components/EditorMenu/menuConfig.tsx @@ -1,10 +1,12 @@ import React from 'react' -import { useIdeContext } from 'src/helpers/hooks/useIdeContext' import { useRender } from 'src/components/IdeWrapper/useRender' import { makeStlDownloadHandler, PullTitleFromFirstLine } from './helpers' import { useSaveCode } from 'src/components/IdeWrapper/useSaveCode' -import Svg from 'src/components/Svg/Svg' +import { DropdownItem } from './Dropdowns' +export function cmdOrCtrl() { + return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? '⌘' : 'Ctrl' +} const fileMenuConfig = { name: 'file', @@ -14,30 +16,51 @@ const fileMenuConfig = { { label: 'Save & Render', shortcut: 'ctrl+s, command+s', - shortcutLabel: <> S, - // This is my main issue. How do I pass in a callback that relies on the hooks and state within the component? - // Put another way, how do I make the state and hooks used within a component configurable from outside the component itself? - callback: (e, /* { options } */) => { - // These do not work - // const handleRender = useRender() - // const saveCode = useSaveCode() - // handleRender() - // saveCode({ code: state.code }) - e.preventDefault() - alert('Saving & Rendering!') + shortcutLabel: cmdOrCtrl() + ' S', + component: (props) => { + const { state, config } = props + const handleRender = useRender() + const saveCode = useSaveCode() + function onRender(e) { + e.preventDefault() + handleRender() + saveCode({ code: state.code }) + } + + config.callback = onRender + + return }, }, { label: 'Download STL', shortcut: 'ctrl+shift+d, command+shift+d', - shortcutLabel: <> Shift D, - callback: () => alert('Downloading STL!'), + shortcutLabel: cmdOrCtrl() + ' Shift D', + component: (props) => { + const { state, thunkDispatch, config } = props + const handleStlDownload = makeStlDownloadHandler({ + type: state.objectData?.type, + ideType: state.ideType, + geometry: state.objectData?.data, + quality: state.objectData?.quality, + fileName: PullTitleFromFirstLine(state.code || ''), + thunkDispatch, + }) + + config.callback = handleStlDownload + + return + } }, { label: 'Cook Donut', - shortcut: 'ctrl+d, command+d', - shortcutLabel: <> D, - callback: () => alert('Donut is cooked!'), + shortcut: 'ctrl+os+d', + shortcutLabel: cmdOrCtrl() + ' D', + component: (props) => { + const { config } = props + config.callback = () => alert('Donut is cooked!') + return + } } ] } @@ -57,8 +80,12 @@ const viewMenuConfig = { { label: 'Reset layout', shortcut: 'ctrl+alt+r, command+alt+r', - shortcutLabel: <> Alt R, - callback: () => alert('Resetting the layout!'), + shortcutLabel: cmdOrCtrl() + ' Alt R', + component: (props) => { + const { config, thunkDispatch } = props + config.callback = () => thunkDispatch({ type: 'resetLayout' }) + return + } }, ], } @@ -82,8 +109,4 @@ export interface EditorMenuConfig { label: string, disabled: boolean, items: Array, -} - -function CmdOrCtrl() { - return { /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? '⌘' : 'Ctrl' } } \ No newline at end of file