got working toggle tabs! I don't like HeadlessUI's Tabs, they don't appear to support programmatic opening
This commit is contained in:
@@ -65,8 +65,13 @@ const IdeHeader = ({
|
||||
|
||||
return (
|
||||
<div className="h-16 w-full bg-ch-gray-900 flex justify-between items-center text-lg">
|
||||
{_projectId ? (
|
||||
<div className="h-full text-gray-300 flex items-center">
|
||||
<div className="w-14 h-16 flex items-center justify-center bg-ch-gray-900">
|
||||
<Link to={routes.home()}>
|
||||
<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}
|
||||
@@ -87,10 +92,8 @@ const IdeHeader = ({
|
||||
canEdit={canEdit}
|
||||
shouldRouteToIde={!projectTitle}
|
||||
/>
|
||||
</>}
|
||||
</div>
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
<div className="text-gray-200 grid grid-flow-col-dense gap-4 mr-4 items-center">
|
||||
{canEdit && !projectTitle && (
|
||||
<CaptureButton
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ReactNode, useState } from 'react'
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
import { Tab } from '@headlessui/react'
|
||||
import Svg, { SvgNames } from 'src/components/Svg/Svg'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
interface SidebarConfigType {
|
||||
name: string,
|
||||
@@ -15,13 +15,13 @@ const sidebarTopConfig : SidebarConfigType[] = [
|
||||
name: 'Files',
|
||||
icon: 'files',
|
||||
disabled: false,
|
||||
panel: () => { <h2>Some Files!</h2> },
|
||||
panel: <h2>Some Files!</h2>,
|
||||
},
|
||||
{
|
||||
name: 'GitHub',
|
||||
icon: 'github',
|
||||
disabled: false,
|
||||
panel: () => { <h2>Le GitHub Integration™️</h2> },
|
||||
panel: <h2>Le GitHub Integration™️</h2>,
|
||||
},
|
||||
{
|
||||
name: 'Visibility',
|
||||
@@ -40,42 +40,74 @@ const sidebarBottomConfig : SidebarConfigType[] = [
|
||||
},
|
||||
]
|
||||
|
||||
const IdeSideBar = () => {
|
||||
const combinedConfig = [
|
||||
...sidebarTopConfig,
|
||||
...sidebarBottomConfig,
|
||||
]
|
||||
|
||||
function TabToggle({ item, className = "", active, onChange, onClick }) {
|
||||
return (
|
||||
<div className="h-full flex flex-col justify-between">
|
||||
<div className="w-14 h-16 flex items-center justify-center bg-ch-gray-900">
|
||||
<Link to={routes.home()}>
|
||||
<Svg className="w-12 p-0.5" name="favicon" />
|
||||
</Link>
|
||||
</div>
|
||||
<Tab.Group vertical>
|
||||
<Tab.List className="h-full flex flex-col justify-between">
|
||||
<label
|
||||
key={'tab-'+item.name}
|
||||
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>
|
||||
)
|
||||
}
|
||||
|
||||
const IdeSideBar = () => {
|
||||
const [selectedTab, setSelectedTab] = useState("")
|
||||
const [lastOpen, setLastOpen] = useState("")
|
||||
|
||||
function onTabClick(name) {
|
||||
return function() {
|
||||
if (selectedTab === name) {
|
||||
setLastOpen(selectedTab)
|
||||
setSelectedTab("")
|
||||
} else if (selectedTab === "" && lastOpen === name) {
|
||||
setSelectedTab(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="flex h-full bg-ch-gray-700">
|
||||
<fieldset className="h-full flex flex-col justify-between border-r-2 border-ch-gray-900">
|
||||
<div>
|
||||
{ sidebarTopConfig.map(topItem => (
|
||||
<Tab disabled={topItem.disabled}
|
||||
key={'tab-'+topItem.name}
|
||||
className="text-gray-300 p-3 pb-6 flex justify-center">
|
||||
<Svg name={topItem.icon} className="w-8 mx-auto"/>
|
||||
</Tab>
|
||||
{ sidebarTopConfig.map((topItem, i) => (
|
||||
<TabToggle
|
||||
item={topItem}
|
||||
active={ selectedTab === topItem.name }
|
||||
onChange={ () => setSelectedTab(topItem.name) }
|
||||
onClick={ onTabClick(topItem.name) }
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div>
|
||||
{ sidebarBottomConfig.map(bottomItem => (
|
||||
<Tab disabled={bottomItem.disabled}
|
||||
key={'tab-'+bottomItem.name}
|
||||
className="text-gray-300 p-3 pb-6 flex justify-center">
|
||||
<Svg name={bottomItem.icon} className="w-8 mx-auto" />
|
||||
</Tab>
|
||||
{ sidebarBottomConfig.map((bottomItem, i) => (
|
||||
<TabToggle
|
||||
item={bottomItem}
|
||||
active={ selectedTab === bottomItem.name }
|
||||
onChange={ () => setSelectedTab(bottomItem.name) }
|
||||
onClick={ onTabClick(bottomItem.name) }
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Tab.List>
|
||||
<Tab.Panels>
|
||||
{ ([...sidebarTopConfig, ...sidebarBottomConfig]).map(item => item.panel && (
|
||||
<Tab.Panel key={'panel-'+item.name}>{ item.panel }</Tab.Panel>
|
||||
)) }
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
</fieldset>
|
||||
{ combinedConfig.find(item => item.name === selectedTab)?.panel && (
|
||||
<div className="w-56 h-full bg-ch-gray-700 py-4 px-2 text-ch-gray-300 border-t-2 border-ch-gray-900">
|
||||
{ combinedConfig.find(item => item.name === selectedTab).panel }
|
||||
</div>
|
||||
) }
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -24,17 +24,19 @@ const IdeWrapper = ({ cadPackage }: Props) => {
|
||||
useIdeInit(cadPackage, project?.code || state?.code)
|
||||
|
||||
return (
|
||||
<div className="h-full flex">
|
||||
<div className="w-14 bg-ch-gray-700 flex-shrink-0">
|
||||
<IdeSideBar />
|
||||
</div>
|
||||
<div className="h-full flex flex-grow flex-col">
|
||||
<div className="h-full flex flex-col">
|
||||
<nav className="flex">
|
||||
<IdeHeader handleRender={onRender} />
|
||||
</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>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,29 @@
|
||||
body {
|
||||
font-family: 'Fira Sans', ui-sans-serif, system-ui, -apple-system, system-ui, "Segoe UI", "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
}
|
||||
|
||||
/* https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/ */
|
||||
.visually-hidden {
|
||||
clip: rect(0 0 0 0);
|
||||
clip-path: inset(50%);
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.tabToggle {
|
||||
@apply text-ch-gray-300 p-3 mb-3 flex justify-center;
|
||||
}
|
||||
.tabToggle.active {
|
||||
@apply bg-ch-pink-800 text-ch-pink-300 bg-opacity-30;
|
||||
}
|
||||
.tabToggle.disabled {
|
||||
@apply text-ch-gray-550 cursor-not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user