Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d02d64b61c |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@richiesnitch/ads3-design-system",
|
"name": "@richiesnitch/ads3-design-system",
|
||||||
"version": "0.2.0",
|
"version": "0.2.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState, type ReactNode } from 'react'
|
import { useState, type ReactNode } from 'react'
|
||||||
import { Settings, Grid3x3 } from 'lucide-react'
|
import { Settings, Grid3x3, Menu } from 'lucide-react'
|
||||||
import { TopBar } from '@/components/organisms/TopBar'
|
import { TopBar } from '@/components/organisms/TopBar'
|
||||||
import { IconButton } from '@/components/atoms/IconButton'
|
import { IconButton } from '@/components/atoms/IconButton'
|
||||||
import { Badge } from '@/components/atoms/Badge'
|
import { Badge } from '@/components/atoms/Badge'
|
||||||
@@ -29,7 +29,7 @@ export const SDC_TOOLS: SdcTool[] = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export interface SdcTopBarProps {
|
export interface SdcTopBarProps {
|
||||||
/** App name shown top-left. */
|
/** App name shown top-left, to the right of the app-directory grid. */
|
||||||
appName: string
|
appName: string
|
||||||
/** Slug of the current tool, marked active and non-navigating in the menu. */
|
/** Slug of the current tool, marked active and non-navigating in the menu. */
|
||||||
activeTool?: string
|
activeTool?: string
|
||||||
@@ -37,13 +37,19 @@ export interface SdcTopBarProps {
|
|||||||
logo?: ReactNode
|
logo?: ReactNode
|
||||||
/** Override the tool list (defaults to the full SDC suite). */
|
/** Override the tool list (defaults to the full SDC suite). */
|
||||||
tools?: SdcTool[]
|
tools?: SdcTool[]
|
||||||
|
/**
|
||||||
|
* If provided, renders a hamburger button at the very left (before the app-directory grid)
|
||||||
|
* that calls this on click — for apps that have a collapsible side navigation.
|
||||||
|
*/
|
||||||
|
onMenuClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared top bar for the SDC tool suite: app name (left), API settings (cog), and the
|
* Shared top bar for the SDC tool suite. Left → right: [optional hamburger] [app-directory grid]
|
||||||
* suite app directory (grid). Wraps the ADS TopBar; uses the shared `sdc_*` credentials.
|
* [app name] … [no-key badge] [API settings cog]. Wraps the ADS TopBar; uses the shared
|
||||||
|
* `sdc_*` credentials.
|
||||||
*/
|
*/
|
||||||
export function SdcTopBar({ appName, activeTool, logo, tools = SDC_TOOLS }: SdcTopBarProps) {
|
export function SdcTopBar({ appName, activeTool, logo, tools = SDC_TOOLS, onMenuClick }: SdcTopBarProps) {
|
||||||
const [settingsOpen, setSettingsOpen] = useState(false)
|
const [settingsOpen, setSettingsOpen] = useState(false)
|
||||||
const [toolsOpen, setToolsOpen] = useState(false)
|
const [toolsOpen, setToolsOpen] = useState(false)
|
||||||
const [hasCreds, setHasCreds] = useState(() => checkCredentials())
|
const [hasCreds, setHasCreds] = useState(() => checkCredentials())
|
||||||
@@ -56,12 +62,61 @@ export function SdcTopBar({ appName, activeTool, logo, tools = SDC_TOOLS }: SdcT
|
|||||||
g.items.push(t)
|
g.items.push(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const leading = (
|
||||||
|
<div className="flex items-center gap-1 text-white">
|
||||||
|
{onMenuClick && (
|
||||||
|
<IconButton
|
||||||
|
icon={<Menu />}
|
||||||
|
aria-label="Toggle navigation"
|
||||||
|
variant="tertiary"
|
||||||
|
className="!text-white hover:!bg-white/10"
|
||||||
|
onClick={onMenuClick}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Popover placement="bottom-start" open={toolsOpen} onOpenChange={setToolsOpen}>
|
||||||
|
<PopoverTrigger>
|
||||||
|
<IconButton
|
||||||
|
icon={<Grid3x3 />}
|
||||||
|
aria-label="SDC AI Tools"
|
||||||
|
variant="tertiary"
|
||||||
|
className="!text-white hover:!bg-white/10"
|
||||||
|
/>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent>
|
||||||
|
<div className="w-64">
|
||||||
|
<List>
|
||||||
|
{groups.map((group) => (
|
||||||
|
<div key={group.name}>
|
||||||
|
<ListSubheader>{group.name}</ListSubheader>
|
||||||
|
{group.items.map((item) => {
|
||||||
|
const isActive = item.slug === activeTool
|
||||||
|
return (
|
||||||
|
<ListItem
|
||||||
|
key={item.slug}
|
||||||
|
active={isActive}
|
||||||
|
href={isActive ? undefined : item.href}
|
||||||
|
onClick={() => isActive && setToolsOpen(false)}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</ListItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
<ListDivider />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBar title={appName} logo={logo}>
|
<TopBar title={appName} logo={logo} leading={leading}>
|
||||||
<div className="flex items-center gap-1 text-white">
|
<div className="flex items-center gap-1 text-white">
|
||||||
{!hasCreds && <Badge variant="warning-light">No API key</Badge>}
|
{!hasCreds && <Badge variant="warning-light">No API key</Badge>}
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<Settings />}
|
icon={<Settings />}
|
||||||
aria-label="API settings"
|
aria-label="API settings"
|
||||||
@@ -69,42 +124,6 @@ export function SdcTopBar({ appName, activeTool, logo, tools = SDC_TOOLS }: SdcT
|
|||||||
className="!text-white hover:!bg-white/10"
|
className="!text-white hover:!bg-white/10"
|
||||||
onClick={() => setSettingsOpen(true)}
|
onClick={() => setSettingsOpen(true)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Popover placement="bottom-end" open={toolsOpen} onOpenChange={setToolsOpen}>
|
|
||||||
<PopoverTrigger>
|
|
||||||
<IconButton
|
|
||||||
icon={<Grid3x3 />}
|
|
||||||
aria-label="SDC AI Tools"
|
|
||||||
variant="tertiary"
|
|
||||||
className="!text-white hover:!bg-white/10"
|
|
||||||
/>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent>
|
|
||||||
<div className="w-64">
|
|
||||||
<List>
|
|
||||||
{groups.map((group) => (
|
|
||||||
<div key={group.name}>
|
|
||||||
<ListSubheader>{group.name}</ListSubheader>
|
|
||||||
{group.items.map((item) => {
|
|
||||||
const isActive = item.slug === activeTool
|
|
||||||
return (
|
|
||||||
<ListItem
|
|
||||||
key={item.slug}
|
|
||||||
active={isActive}
|
|
||||||
href={isActive ? undefined : item.href}
|
|
||||||
onClick={() => isActive && setToolsOpen(false)}
|
|
||||||
>
|
|
||||||
{item.label}
|
|
||||||
</ListItem>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
<ListDivider />
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</List>
|
|
||||||
</div>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
</div>
|
||||||
</TopBar>
|
</TopBar>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user