Sorted out using <details> element, got ancestor clicks closing out to their level

This commit is contained in:
Frank Johnson
2021-09-12 17:13:30 -04:00
parent 69c83d33b1
commit 2ec3a0b202
9 changed files with 313 additions and 165 deletions

View File

@@ -34,9 +34,16 @@ const EditorMenu = () => {
))}
</div>
<button
className="text-ch-gray-300 h-full cursor-not-allowed"
className="text-ch-gray-300 h-full"
aria-label="editor settings"
disabled
onClick={() =>
thunkDispatch((dispatch) =>
dispatch({
type: 'settingsButtonClicked',
payload: ['Settings', 'editor'],
})
)
}
>
<Svg name="gear" className="w-6 p-px" />
</button>

View File

@@ -42,19 +42,40 @@ const ELEMENT_MAP = {
}
const TOOLBAR_MAP = {
Editor: (
Editor: () => (
<div className="w-full">
<EditorMenu />
</div>
),
Viewer: (
Viewer: (thunkDispatch) => (
<div>
<PanelToolbar panelName="Viewer" />
<PanelToolbar
panelName="Viewer"
onClick={() =>
thunkDispatch((dispatch) =>
dispatch({
type: 'settingsButtonClicked',
payload: ['Settings', 'viewer'],
})
)
}
/>
</div>
),
Console: (
Console: (thunkDispatch) => (
<div>
<PanelToolbar panelName="Console" showTopGradient />
<PanelToolbar
panelName="Console"
showTopGradient
onClick={() =>
thunkDispatch((dispatch) =>
dispatch({
type: 'settingsButtonClicked',
payload: ['Settings', 'console'],
})
)
}
/>
</div>
),
}
@@ -74,7 +95,7 @@ const IdeContainer = () => {
return (
<MosaicWindow
path={path}
renderToolbar={() => TOOLBAR_MAP[id]}
renderToolbar={() => TOOLBAR_MAP[id](thunkDispatch)}
className={`${id.toLowerCase()} ${id.toLowerCase()}-tile`}
>
{id === 'Viewer' ? (

View File

@@ -71,28 +71,30 @@ const IdeHeader = ({
<Svg className="w-12 p-0.5" name="favicon" />
</Link>
</div>
{_projectId && <>
<span className="bg-ch-gray-700 h-full grid grid-flow-col-dense items-center gap-2 px-4">
<Gravatar
image={project?.user?.image || projectOwnerImage}
className="w-10"
{_projectId && (
<>
<span className="bg-ch-gray-700 h-full grid grid-flow-col-dense items-center gap-2 px-4">
<Gravatar
image={project?.user?.image || projectOwnerImage}
className="w-10"
/>
<Link
to={routes.user({
userName: _projectOwner,
})}
>
{_projectOwner}
</Link>
</span>
<EditableProjectTitle
id={_projectId}
userName={_projectOwner}
projectTitle={project?.title || projectTitle}
canEdit={canEdit}
shouldRouteToIde={!projectTitle}
/>
<Link
to={routes.user({
userName: _projectOwner,
})}
>
{_projectOwner}
</Link>
</span>
<EditableProjectTitle
id={_projectId}
userName={_projectOwner}
projectTitle={project?.title || projectTitle}
canEdit={canEdit}
shouldRouteToIde={!projectTitle}
/>
</>}
</>
)}
</div>
<div className="text-gray-200 grid grid-flow-col-dense gap-4 mr-4 items-center">
{canEdit && !projectTitle && (

View File

@@ -1,22 +1,30 @@
import { useState } from 'react'
import Svg from 'src/components/Svg/Svg'
import { sidebarTopConfig, sidebarBottomConfig, sidebarCombinedConfig } from './sidebarConfig'
import {
sidebarTopConfig,
sidebarBottomConfig,
sidebarCombinedConfig,
} from './sidebarConfig'
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
function TabToggle({ item, className = "", active, onChange, onClick }) {
function TabToggle({ item, className = '', active, onChange, onClick }) {
return (
<label
className={`tabToggle${item.disabled ? ' disabled' : ''}${active ? ' active' : ''} ${className}`}>
<input name="sidebar-tabs"
type="radio"
disabled={item.disabled}
value={ item.name }
onChange={ onChange }
onClick={ onClick }
className="visually-hidden"
/>
<Svg name={item.icon} className="w-8 mx-auto"/>
</label>
<label
className={`tabToggle${item.disabled ? ' disabled' : ''}${
active ? ' active' : ''
} ${className}`}
>
<input
name="sidebar-tabs"
type="radio"
disabled={item.disabled}
value={item.name}
onChange={onChange}
onClick={onClick}
className="visually-hidden"
/>
<Svg name={item.icon} className="w-8 mx-auto" />
</label>
)
}
@@ -24,44 +32,52 @@ const IdeSideBar = () => {
const { state, thunkDispatch } = useIdeContext()
function onTabClick(name) {
return function() {
thunkDispatch({type: 'settingsButtonClicked', payload: [name]})
return function () {
thunkDispatch({ type: 'settingsButtonClicked', payload: [name] })
}
}
const selectedTab = React.useMemo(() => sidebarCombinedConfig.find(item => item.name === state.sideTray[0]), [state.sideTray])
const selectedTab = React.useMemo(
() => sidebarCombinedConfig.find((item) => item.name === state.sideTray[0]),
[state.sideTray]
)
return (
<section className="flex h-full bg-ch-gray-900 border border-red-500">
<section className="flex h-full bg-ch-gray-900">
<fieldset className="h-full flex flex-col justify-between bg-ch-gray-700">
<div>
{ sidebarTopConfig.map((topItem, i) => (
{sidebarTopConfig.map((topItem, i) => (
<TabToggle
item={topItem}
active={ state.sideTray[0] === topItem.name }
onChange={ () => onTabClick(topItem.name) }
onClick={ onTabClick(topItem.name) }
key={ 'tab-' + i }
active={state.sideTray[0] === topItem.name}
onChange={() => onTabClick(topItem.name)}
onClick={onTabClick(topItem.name)}
key={'tab-' + i}
/>
))}
</div>
<div>
{ sidebarBottomConfig.map((bottomItem, i) => (
{sidebarBottomConfig.map((bottomItem, i) => (
<TabToggle
item={bottomItem}
active={ state.sideTray[0] === bottomItem.name }
onChange={ () => onTabClick(bottomItem.name) }
onClick={ onTabClick(bottomItem.name) }
key={ 'tab-' + (sidebarTopConfig.length+i) }
/>
item={bottomItem}
active={state.sideTray[0] === bottomItem.name}
onChange={() => onTabClick(bottomItem.name)}
onClick={onTabClick(bottomItem.name)}
key={'tab-' + (sidebarTopConfig.length + i)}
/>
))}
</div>
</fieldset>
{ selectedTab?.panel && (
<div className="w-56 bg-ch-gray-900 text-ch-gray-300 border border-ch-pink-800 border-opacity-30" style={{ height: 'calc(100% - 6px)', margin: '3px'}}>
<h2 className="flex items-center h-9 px-4 bg-ch-pink-800 bg-opacity-30">{ selectedTab.name }</h2>
{ selectedTab.panel }
{selectedTab?.panel && (
<div
className="w-56 bg-ch-gray-900 text-ch-gray-300 border border-ch-pink-800 border-opacity-30"
style={{ height: 'calc(100% - 6px)', margin: '3px' }}
>
<h2 className="flex items-center h-9 px-4 bg-ch-pink-800 bg-opacity-30">
{selectedTab.name}
</h2>
{selectedTab.panel}
</div>
) }
)}
</section>
)
}

View File

@@ -3,100 +3,154 @@ import { SvgNames } from 'src/components/Svg/Svg'
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
interface SidebarConfigType {
name: string,
icon: SvgNames,
disabled: boolean,
panel: ReactNode | null,
name: string
icon: SvgNames
disabled: boolean
panel: ReactNode | null
}
export const sidebarTopConfig : SidebarConfigType[] = [
{
name: 'Files',
icon: 'files',
disabled: false,
panel: <article className="px-2 py-4">
<p><em>Coming Soon</em></p>
<hr className="my-4"/>
<p>
We're working on multi-file support in tandem with the GitHub integration.
</p>
</article>,
},
{
name: 'GitHub',
icon: 'github',
disabled: false,
panel: <article className="px-2 py-4">
<p><em>Coming Soon</em></p>
<hr className="my-4"/>
<p>
This integration will allow you to sync a project with a GitHub repo and push changes back to it as a commit!
</p>
</article>,
},
{
name: 'Visibility',
icon: 'eye',
disabled: true,
panel: null,
},
export const sidebarTopConfig: SidebarConfigType[] = [
{
name: 'Files',
icon: 'files',
disabled: false,
panel: (
<article className="px-2 py-4">
<p>
<em>Coming Soon</em>
</p>
<hr className="my-4" />
<p>
We're working on multi-file support in tandem with the GitHub
integration.
</p>
</article>
),
},
{
name: 'GitHub',
icon: 'github',
disabled: false,
panel: (
<article className="px-2 py-4">
<p>
<em>Coming Soon</em>
</p>
<hr className="my-4" />
<p>
This integration will allow you to sync a project with a GitHub repo
and push changes back to it as a commit!
</p>
</article>
),
},
{
name: 'Visibility',
icon: 'eye',
disabled: true,
panel: null,
},
]
const DiscordLink = () => (
<a className="underline text-ch-pink-300"
href="https://discord.gg/SD7zFRNjGH"
target="_blank"
rel="noreferrer"
>
Discord
</a>
)
const settingsConfig = [
{
title: "Editor",
name: "editor",
open: false,
content: <p className="p-2">This text will go in a details element!</p>,
},
{
title: "Viewer",
name: "viewer",
open: false,
content: <p className="p-2">This text will go in a details element!</p>
},
{
title: "Console",
name: "console",
open: false,
content: <p className="p-2">This text will go in a details element!</p>
},
{
title: 'Editor',
name: 'editor',
open: false,
content: (
<div className="p-2">
<p>
<em>Coming Soon</em>
</p>
<hr className="my-2" />
<p className="p-2">
We're building configuration settings for the Viewer pane now. Join us on <DiscordLink/> if you want to lend a hand!
</p>
</div>
),
},
{
title: 'Viewer',
name: 'viewer',
open: false,
content: (
<div className="p-2">
<p>
<em>Coming Soon</em>
</p>
<hr className="my-2" />
<p className="p-2">
We're building configuration settings for the Viewer pane now. Join us on <DiscordLink/> if you want to lend a hand!
</p>
</div>
),
},
{
title: 'Console',
name: 'console',
open: false,
content: (
<div className="p-2">
<p>
<em>Coming Soon</em>
</p>
<hr className="my-2" />
<p className="p-2">
We're building configuration settings for the Viewer pane now. Join us on <DiscordLink/> if you want to lend a hand!
</p>
</div>
),
},
]
export const sidebarBottomConfig : SidebarConfigType[] = [
{
name: 'Settings',
icon: 'gear',
disabled: false,
panel: <SettingsMenu parentName="Settings"/>,
},
export const sidebarBottomConfig: SidebarConfigType[] = [
{
name: 'Settings',
icon: 'gear',
disabled: false,
panel: <SettingsMenu parentName="Settings" />,
},
]
export const sidebarCombinedConfig = [
...sidebarTopConfig,
...sidebarBottomConfig,
...sidebarTopConfig,
...sidebarBottomConfig,
]
function SettingsMenu({parentName}: {parentName: string}) {
const { state, thunkDispatch } = useIdeContext()
return (
<article className="">
{ settingsConfig.map(item => (
<li className="list-none" key={'settings-tray-'+item.name}>
<button className="px-2 py-2 bg-ch-pink-800 bg-opacity-10 my-px" onClick={() => {
console.log('i was clicked')
thunkDispatch((dispatch) => dispatch({type: 'settingsButtonClicked', payload:[parentName, item.name]}))
}} >{ item.title }</button>
{ state.sideTray.slice(-1)[0] === item.name && item.content }
</li>
// <details key={'settings-tray-'+item.name} open={state.sideTray.slice(-1)[0] === item.name}>
// <summary className="px-2 py-2 bg-ch-pink-800 bg-opacity-10 my-px"
// onClick={() => thunkDispatch((dispatch) => dispatch({type: 'settingsButtonClicked', payload:[parentName, item.name]}))}
// >{ item.title }hi there</summary>
// { state.sideTray.slice(-1)[0] === item.name && item.content }
// {state.sideTray.slice(-1)[0]}
// </details>
))}
</article>
)
function SettingsMenu({ parentName }: { parentName: string }) {
const { state, thunkDispatch } = useIdeContext()
return (
<article className="">
{settingsConfig.map((item) => (
<details
key={'settings-tray-' + item.name}
open={state.sideTray.slice(-1)[0] === item.name}
onClick={(e) => {
e.preventDefault()
thunkDispatch((dispatch) =>
dispatch({
type: 'settingsButtonClicked',
payload: [parentName, item.name],
})
)
}}
>
<summary className="px-2 py-2 bg-ch-pink-800 bg-opacity-10 my-px cursor-pointer">
{item.title}
</summary>
{item.content}
</details>
))}
</article>
)
}

View File

@@ -32,17 +32,17 @@ const IdeWrapper = ({ cadPackage }: Props) => {
return (
<div className="h-full flex flex-col">
<ShortcutsModalContext.Provider value={shortcutModalContextValues}>
<nav className="flex">
<nav className="flex">
<IdeHeader handleRender={onRender} />
</nav>
<div className="h-full flex flex-grow bg-ch-gray-900">
<div className="flex-shrink-0">
<IdeSideBar />
</nav>
<div className="h-full flex flex-grow bg-ch-gray-900">
<div className="flex-shrink-0">
<IdeSideBar />
</div>
<div className="h-full flex flex-grow">
<IdeContainer />
</div>
</div>
<div className="h-full flex flex-grow">
<IdeContainer />
</div>
</div>
</ShortcutsModalContext.Provider>
</div>
)

View File

@@ -1,4 +1,4 @@
import { useContext } from 'react'
import { MouseEventHandler, useContext } from 'react'
import { MosaicWindowContext } from 'react-mosaic-component'
import Svg from 'src/components/Svg/Svg'
import OpenscadStaticImageMessage from 'src/components/OpenscadStaticImageMessage/OpenscadStaticImageMessage'
@@ -6,9 +6,11 @@ import OpenscadStaticImageMessage from 'src/components/OpenscadStaticImageMessag
const PanelToolbar = ({
panelName,
showTopGradient,
onClick,
}: {
panelName: 'Viewer' | 'Console'
showTopGradient?: boolean
onClick?: MouseEventHandler
}) => {
const { mosaicWindowActions } = useContext(MosaicWindowContext)
return (
@@ -19,9 +21,13 @@ const PanelToolbar = ({
<div className="absolute top-0 right-0 flex items-center h-9">
{panelName === 'Viewer' && <OpenscadStaticImageMessage />}
<button
className="bg-ch-gray-760 text-ch-gray-300 px-3 rounded-bl-lg h-full cursor-not-allowed"
className={
'bg-ch-gray-760 text-ch-gray-300 px-3 rounded-bl-lg h-full ' +
(!onClick ? 'cursor-not-allowed' : '')
}
aria-label={`${panelName} settings`}
disabled
onClick={onClick}
disabled={!onClick}
>
<Svg name="gear" className="w-7 p-0.5" />
</button>

View File

@@ -181,8 +181,19 @@ const Svg = ({
),
eye: (
<svg viewBox="0 0 34 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M33.6281 10.3992C33.9385 10.0498 33.9385 9.53738 33.6281 9.18801C31.7613 7.08739 25.0664 0.242065 17.0935 0.242065C9.12069 0.242065 2.42579 7.08739 0.559031 9.18801C0.248552 9.53738 0.248552 10.0498 0.559031 10.3992C2.42579 12.4998 9.12069 19.3451 17.0935 19.3451C25.0664 19.3451 31.7613 12.4998 33.6281 10.3992ZM17.0935 17.7936C21.5118 17.7936 25.0935 14.2119 25.0935 9.79359C25.0935 5.37532 21.5118 1.7936 17.0935 1.7936C12.6753 1.7936 9.09354 5.37532 9.09354 9.79359C9.09354 14.2119 12.6753 17.7936 17.0935 17.7936Z" fill="currentColor"/>
<ellipse cx="17.0932" cy="9.79354" rx="4.31588" ry="4.31588" fill="currentColor"/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M33.6281 10.3992C33.9385 10.0498 33.9385 9.53738 33.6281 9.18801C31.7613 7.08739 25.0664 0.242065 17.0935 0.242065C9.12069 0.242065 2.42579 7.08739 0.559031 9.18801C0.248552 9.53738 0.248552 10.0498 0.559031 10.3992C2.42579 12.4998 9.12069 19.3451 17.0935 19.3451C25.0664 19.3451 31.7613 12.4998 33.6281 10.3992ZM17.0935 17.7936C21.5118 17.7936 25.0935 14.2119 25.0935 9.79359C25.0935 5.37532 21.5118 1.7936 17.0935 1.7936C12.6753 1.7936 9.09354 5.37532 9.09354 9.79359C9.09354 14.2119 12.6753 17.7936 17.0935 17.7936Z"
fill="currentColor"
/>
<ellipse
cx="17.0932"
cy="9.79354"
rx="4.31588"
ry="4.31588"
fill="currentColor"
/>
</svg>
),
favicon: (
@@ -286,8 +297,18 @@ const Svg = ({
),
files: (
<svg viewBox="0 0 30 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M4.54121 6.31592C3.23314 6.31592 2.17274 7.37633 2.17274 8.6844V28.6849C2.17274 29.9929 3.23314 31.0534 4.54121 31.0534H19.2784C20.5865 31.0534 21.6469 29.9929 21.6469 28.6849V26.342H23.2259V28.6849C23.2259 30.865 21.4585 32.6323 19.2784 32.6323H4.54121C2.36109 32.6323 0.59375 30.865 0.59375 28.6849V8.6844C0.59375 6.50428 2.36109 4.73694 4.54121 4.73694H8.50454V6.31592H4.54121Z" fill="currentColor"/>
<path fillRule="evenodd" clipRule="evenodd" d="M20.871 0H11.699C9.95489 0 8.54102 1.41387 8.54102 3.15797V23.1584C8.54102 24.9025 9.95489 26.3164 11.699 26.3164H26.4362C28.1803 26.3164 29.5942 24.9025 29.5942 23.1584V8.90104L20.871 0ZM26.6096 8.11155L21.6605 3.0615V5.74308C21.6605 7.05115 22.7209 8.11155 24.029 8.11155H26.6096ZM20.0815 1.57898H11.699C10.8269 1.57898 10.12 2.28592 10.12 3.15797V23.1584C10.12 24.0305 10.8269 24.7374 11.699 24.7374H26.4362C27.3082 24.7374 28.0152 24.0305 28.0152 23.1584V9.69054H24.029C21.8489 9.69054 20.0815 7.9232 20.0815 5.74308V1.57898Z" fill="currentColor"/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4.54121 6.31592C3.23314 6.31592 2.17274 7.37633 2.17274 8.6844V28.6849C2.17274 29.9929 3.23314 31.0534 4.54121 31.0534H19.2784C20.5865 31.0534 21.6469 29.9929 21.6469 28.6849V26.342H23.2259V28.6849C23.2259 30.865 21.4585 32.6323 19.2784 32.6323H4.54121C2.36109 32.6323 0.59375 30.865 0.59375 28.6849V8.6844C0.59375 6.50428 2.36109 4.73694 4.54121 4.73694H8.50454V6.31592H4.54121Z"
fill="currentColor"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M20.871 0H11.699C9.95489 0 8.54102 1.41387 8.54102 3.15797V23.1584C8.54102 24.9025 9.95489 26.3164 11.699 26.3164H26.4362C28.1803 26.3164 29.5942 24.9025 29.5942 23.1584V8.90104L20.871 0ZM26.6096 8.11155L21.6605 3.0615V5.74308C21.6605 7.05115 22.7209 8.11155 24.029 8.11155H26.6096ZM20.0815 1.57898H11.699C10.8269 1.57898 10.12 2.28592 10.12 3.15797V23.1584C10.12 24.0305 10.8269 24.7374 11.699 24.7374H26.4362C27.3082 24.7374 28.0152 24.0305 28.0152 23.1584V9.69054H24.029C21.8489 9.69054 20.0815 7.9232 20.0815 5.74308V1.57898Z"
fill="currentColor"
/>
</svg>
),
flag: (
@@ -373,7 +394,12 @@ const Svg = ({
),
github: (
<svg viewBox="0 0 35 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M17.0938 0.632324C7.70125 0.632324 0.09375 8.23982 0.09375 17.6323C0.09375 25.1548 4.96 31.5086 11.7175 33.7611C12.5675 33.9098 12.8862 33.3998 12.8862 32.9536C12.8862 32.5498 12.865 31.2111 12.865 29.7873C8.59375 30.5736 7.48875 28.7461 7.14875 27.7898C6.9575 27.3011 6.12875 25.7923 5.40625 25.3886C4.81125 25.0698 3.96125 24.2836 5.385 24.2623C6.72375 24.2411 7.68 25.4948 7.99875 26.0048C9.52875 28.5761 11.9725 27.8536 12.95 27.4073C13.0988 26.3023 13.545 25.5586 14.0337 25.1336C10.2513 24.7086 6.29875 23.2423 6.29875 16.7398C6.29875 14.8911 6.9575 13.3611 8.04125 12.1711C7.87125 11.7461 7.27625 10.0036 8.21125 7.66607C8.21125 7.66607 9.635 7.21983 12.8862 9.40858C14.2463 9.02608 15.6913 8.83482 17.1363 8.83482C18.5813 8.83482 20.0263 9.02608 21.3863 9.40858C24.6375 7.19858 26.0613 7.66607 26.0613 7.66607C26.9963 10.0036 26.4013 11.7461 26.2313 12.1711C27.315 13.3611 27.9737 14.8698 27.9737 16.7398C27.9737 23.2636 24 24.7086 20.2175 25.1336C20.8337 25.6648 21.365 26.6848 21.365 28.2786C21.365 30.5523 21.3438 32.3798 21.3438 32.9536C21.3438 33.3998 21.6625 33.9311 22.5125 33.7611C29.2275 31.5086 34.0938 25.1336 34.0938 17.6323C34.0938 8.23982 26.4862 0.632324 17.0938 0.632324Z" fill="currentColor"/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M17.0938 0.632324C7.70125 0.632324 0.09375 8.23982 0.09375 17.6323C0.09375 25.1548 4.96 31.5086 11.7175 33.7611C12.5675 33.9098 12.8862 33.3998 12.8862 32.9536C12.8862 32.5498 12.865 31.2111 12.865 29.7873C8.59375 30.5736 7.48875 28.7461 7.14875 27.7898C6.9575 27.3011 6.12875 25.7923 5.40625 25.3886C4.81125 25.0698 3.96125 24.2836 5.385 24.2623C6.72375 24.2411 7.68 25.4948 7.99875 26.0048C9.52875 28.5761 11.9725 27.8536 12.95 27.4073C13.0988 26.3023 13.545 25.5586 14.0337 25.1336C10.2513 24.7086 6.29875 23.2423 6.29875 16.7398C6.29875 14.8911 6.9575 13.3611 8.04125 12.1711C7.87125 11.7461 7.27625 10.0036 8.21125 7.66607C8.21125 7.66607 9.635 7.21983 12.8862 9.40858C14.2463 9.02608 15.6913 8.83482 17.1363 8.83482C18.5813 8.83482 20.0263 9.02608 21.3863 9.40858C24.6375 7.19858 26.0613 7.66607 26.0613 7.66607C26.9963 10.0036 26.4013 11.7461 26.2313 12.1711C27.315 13.3611 27.9737 14.8698 27.9737 16.7398C27.9737 23.2636 24 24.7086 20.2175 25.1336C20.8337 25.6648 21.365 26.6848 21.365 28.2786C21.365 30.5523 21.3438 32.3798 21.3438 32.9536C21.3438 33.3998 21.6625 33.9311 22.5125 33.7611C29.2275 31.5086 34.0938 25.1336 34.0938 17.6323C34.0938 8.23982 26.4862 0.632324 17.0938 0.632324Z"
fill="currentColor"
/>
</svg>
),
lightbulb: (

View File

@@ -244,11 +244,27 @@ const reducer = (state: State, { type, payload }): State => {
state.sideTray.length &&
state.sideTray.length === payload.length &&
state.sideTray.every((original, index) => original === payload[index])
const payloadInOriginal =
payload.length && state.sideTray.indexOf(payload[0])
const isAncestorClick =
state.sideTray.length &&
state.sideTray.length > payload.length &&
payloadInOriginal >= 0 &&
payload.every(
(incoming, i) => incoming === state.sideTray[i + payloadInOriginal]
)
if (isReClick) {
return {
...state,
sideTray: state.sideTray.slice(0, -1),
}
} else if (isAncestorClick) {
return {
...state,
sideTray: state.sideTray.slice(0, payload.length * -1 - 1),
}
}
return {
...state,