Sorted out using <details> element, got ancestor clicks closing out to their level
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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' ? (
|
||||
|
||||
@@ -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 && (
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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: (
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user