@polderlabs/bizar 6.3.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/hooks/sessionend-recall.mjs +3 -3
- package/.claude/hooks/worker-suggest.mjs +110 -0
- package/.claude/settings.json +9 -0
- package/bizar-dash/dist/assets/{EnvVarsSection-B58aiJiE.js → EnvVarsSection-CW6fWKds.js} +3 -3
- package/bizar-dash/dist/assets/{EnvVarsSection-B58aiJiE.js.map → EnvVarsSection-CW6fWKds.js.map} +1 -1
- package/bizar-dash/dist/assets/MobileChat-D7zRhU9K.js +1 -0
- package/bizar-dash/dist/assets/{MobileChat-BJrqwVDd.js.map → MobileChat-D7zRhU9K.js.map} +1 -1
- package/bizar-dash/dist/assets/MobileSettings-K-sNsn_r.js +1 -0
- package/bizar-dash/dist/assets/{MobileSettings-CEQNJNLJ.js.map → MobileSettings-K-sNsn_r.js.map} +1 -1
- package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js → Toast-WTxc3m2g.js} +1 -1
- package/bizar-dash/dist/assets/{Toast-Cpl6-E63.js.map → Toast-WTxc3m2g.js.map} +1 -1
- package/bizar-dash/dist/assets/flow-BpU0-gK2.js +1 -0
- package/bizar-dash/dist/assets/flow-BpU0-gK2.js.map +1 -0
- package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js +1 -0
- package/bizar-dash/dist/assets/fuzzy-l0sNRNKZ.js.map +1 -0
- package/bizar-dash/dist/assets/{icons-Do5N2jmX.js → icons-B0AKnYI3.js} +98 -103
- package/bizar-dash/dist/assets/icons-B0AKnYI3.js.map +1 -0
- package/bizar-dash/dist/assets/main-C-Md3DaY.css +1 -0
- package/bizar-dash/dist/assets/main-CO8fIxQK.js +18 -0
- package/bizar-dash/dist/assets/main-CO8fIxQK.js.map +1 -0
- package/bizar-dash/dist/assets/markdown-w2bDDkAH.js +1 -0
- package/bizar-dash/dist/assets/{markdown-tOLaD6nm.js.map → markdown-w2bDDkAH.js.map} +1 -1
- package/bizar-dash/dist/assets/mobile-DXYCA0hC.js +1 -0
- package/bizar-dash/dist/assets/{mobile-DYCHcUpq.js.map → mobile-DXYCA0hC.js.map} +1 -1
- package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js +2 -0
- package/bizar-dash/dist/assets/mobile-layout-DSmtNPja.js.map +1 -0
- package/bizar-dash/dist/assets/react-vendor-BnuhLJ6X.css +1 -0
- package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js +46 -0
- package/bizar-dash/dist/assets/react-vendor-D3pra6w-.js.map +1 -0
- package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js +2 -0
- package/bizar-dash/dist/assets/useSlashCommands-3DFLOfpk.js.map +1 -0
- package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js +45 -0
- package/bizar-dash/dist/assets/vendor-Di7Cp-rw.js.map +1 -0
- package/bizar-dash/dist/index.html +12 -10
- package/bizar-dash/dist/mobile.html +7 -4
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/server/api.mjs +11 -0
- package/bizar-dash/src/server/memory-consolidator.mjs +218 -0
- package/bizar-dash/src/server/memory-distillation.mjs +296 -0
- package/bizar-dash/src/server/routes/distill.mjs +129 -0
- package/bizar-dash/src/server/routes/goal-planner.mjs +236 -0
- package/bizar-dash/src/web/App.tsx +4 -0
- package/bizar-dash/src/web/components/Tag.tsx +18 -5
- package/bizar-dash/src/web/components/Topbar.tsx +3 -0
- package/bizar-dash/src/web/components/agents/CommunicationLog.tsx +126 -0
- package/bizar-dash/src/web/components/agents/DependencyGraph.tsx +163 -0
- package/bizar-dash/src/web/components/agents/QualityGates.tsx +123 -0
- package/bizar-dash/src/web/components/agents/RealTimeEventLog.tsx +127 -0
- package/bizar-dash/src/web/components/agents/RoutingDecisions.test.tsx +148 -0
- package/bizar-dash/src/web/components/agents/RoutingDecisions.tsx +160 -0
- package/bizar-dash/src/web/components/goals/GoalInput.tsx +86 -0
- package/bizar-dash/src/web/components/goals/PlanVisualization.tsx +111 -0
- package/bizar-dash/src/web/lib/goapPlanner.ts +614 -0
- package/bizar-dash/src/web/lib/types.ts +25 -0
- package/bizar-dash/src/web/styles/agents-redesign.css +311 -0
- package/bizar-dash/src/web/styles/main.css +251 -0
- package/bizar-dash/src/web/styles/tasks-redesign.css +231 -0
- package/bizar-dash/src/web/ui/controls/Button.tsx +77 -0
- package/bizar-dash/src/web/ui/controls/Checkbox.tsx +95 -0
- package/bizar-dash/src/web/ui/controls/IconButton.tsx +66 -0
- package/bizar-dash/src/web/ui/controls/Kbd.tsx +24 -0
- package/bizar-dash/src/web/ui/controls/NumberInput.tsx +77 -0
- package/bizar-dash/src/web/ui/controls/RadioGroup.tsx +109 -0
- package/bizar-dash/src/web/ui/controls/SearchInput.tsx +91 -0
- package/bizar-dash/src/web/ui/controls/Select.tsx +92 -0
- package/bizar-dash/src/web/ui/controls/Slider.tsx +70 -0
- package/bizar-dash/src/web/ui/controls/TextInput.tsx +67 -0
- package/bizar-dash/src/web/ui/controls/Toggle.tsx +79 -0
- package/bizar-dash/src/web/ui/controls/controls.css +454 -0
- package/bizar-dash/src/web/ui/controls/index.ts +33 -0
- package/bizar-dash/src/web/ui/data/BarChart.tsx +60 -0
- package/bizar-dash/src/web/ui/data/DataTable.tsx +216 -0
- package/bizar-dash/src/web/ui/data/EmptyState.tsx +60 -0
- package/bizar-dash/src/web/ui/data/ErrorState.tsx +56 -0
- package/bizar-dash/src/web/ui/data/KeyValueList.tsx +106 -0
- package/bizar-dash/src/web/ui/data/LoadingState.tsx +65 -0
- package/bizar-dash/src/web/ui/data/Sparkline.tsx +87 -0
- package/bizar-dash/src/web/ui/data/StatTile.tsx +87 -0
- package/bizar-dash/src/web/ui/data/data.css +535 -0
- package/bizar-dash/src/web/ui/data/index.ts +31 -0
- package/bizar-dash/src/web/ui/feedback/Badge.tsx +49 -0
- package/bizar-dash/src/web/ui/feedback/Dialog.tsx +209 -0
- package/bizar-dash/src/web/ui/feedback/ProgressBar.tsx +69 -0
- package/bizar-dash/src/web/ui/feedback/StatusDot.tsx +50 -0
- package/bizar-dash/src/web/ui/feedback/Toast.tsx +200 -0
- package/bizar-dash/src/web/ui/feedback/Tooltip.tsx +126 -0
- package/bizar-dash/src/web/ui/feedback/feedback.css +314 -0
- package/bizar-dash/src/web/ui/feedback/index.ts +43 -0
- package/bizar-dash/src/web/ui/index.ts +56 -0
- package/bizar-dash/src/web/ui/layout/AppShell.tsx +51 -0
- package/bizar-dash/src/web/ui/layout/Breadcrumbs.tsx +97 -0
- package/bizar-dash/src/web/ui/layout/Panel.tsx +73 -0
- package/bizar-dash/src/web/ui/layout/PanelHeader.tsx +39 -0
- package/bizar-dash/src/web/ui/layout/Sidebar.tsx +131 -0
- package/bizar-dash/src/web/ui/layout/Tabs.tsx +133 -0
- package/bizar-dash/src/web/ui/layout/Topbar.tsx +42 -0
- package/bizar-dash/src/web/ui/layout/index.ts +33 -0
- package/bizar-dash/src/web/ui/layout/layout.css +413 -0
- package/bizar-dash/src/web/ui/navigation/CommandPalette.tsx +199 -0
- package/bizar-dash/src/web/ui/navigation/NavGroup.tsx +95 -0
- package/bizar-dash/src/web/ui/navigation/NavLink.tsx +93 -0
- package/bizar-dash/src/web/ui/navigation/index.ts +17 -0
- package/bizar-dash/src/web/ui/navigation/navigation.css +343 -0
- package/bizar-dash/src/web/ui/primitives/Box.tsx +91 -0
- package/bizar-dash/src/web/ui/primitives/Grid.tsx +49 -0
- package/bizar-dash/src/web/ui/primitives/Inline.tsx +55 -0
- package/bizar-dash/src/web/ui/primitives/Separator.tsx +46 -0
- package/bizar-dash/src/web/ui/primitives/Stack.tsx +54 -0
- package/bizar-dash/src/web/ui/primitives/VisuallyHidden.tsx +26 -0
- package/bizar-dash/src/web/ui/primitives/index.ts +23 -0
- package/bizar-dash/src/web/ui/primitives/primitives.css +183 -0
- package/bizar-dash/src/web/ui/styles/globals.css +86 -0
- package/bizar-dash/src/web/ui/styles/reset.css +125 -0
- package/bizar-dash/src/web/ui/styles/tokens.css +195 -0
- package/bizar-dash/src/web/ui/theme/ThemeProvider.tsx +142 -0
- package/bizar-dash/src/web/ui/theme/tokens.ts +131 -0
- package/bizar-dash/src/web/ui/theme/useTheme.ts +22 -0
- package/bizar-dash/src/web/ui/utils/cx.ts +42 -0
- package/bizar-dash/src/web/views/Agents.tsx +506 -266
- package/bizar-dash/src/web/views/GoalPlanner.tsx +158 -0
- package/bizar-dash/src/web/views/Overview.tsx +996 -448
- package/bizar-dash/src/web/views/Tasks.tsx +277 -273
- package/bizar-dash/tests/communication-log.test.tsx +67 -0
- package/bizar-dash/tests/dep-graph.test.tsx +40 -0
- package/bizar-dash/tests/event-log.test.tsx +61 -0
- package/bizar-dash/tests/goal-input.test.tsx +72 -0
- package/bizar-dash/tests/goap-planner.test.ts +68 -0
- package/bizar-dash/tests/quality-gates.test.tsx +59 -0
- package/bizar-dash/tests/setup.ts +31 -1
- package/bizar-dash/tests/ui/controls/Button.test.tsx +50 -0
- package/bizar-dash/tests/ui/controls/Checkbox.test.tsx +44 -0
- package/bizar-dash/tests/ui/controls/IconButton.test.tsx +37 -0
- package/bizar-dash/tests/ui/controls/Kbd.test.tsx +39 -0
- package/bizar-dash/tests/ui/controls/NumberInput.test.tsx +56 -0
- package/bizar-dash/tests/ui/controls/RadioGroup.test.tsx +58 -0
- package/bizar-dash/tests/ui/controls/SearchInput.test.tsx +52 -0
- package/bizar-dash/tests/ui/controls/Select.test.tsx +66 -0
- package/bizar-dash/tests/ui/controls/Slider.test.tsx +41 -0
- package/bizar-dash/tests/ui/controls/TextInput.test.tsx +44 -0
- package/bizar-dash/tests/ui/controls/Toggle.test.tsx +39 -0
- package/bizar-dash/tests/ui/data/BarChart.test.tsx +55 -0
- package/bizar-dash/tests/ui/data/DataTable.test.tsx +112 -0
- package/bizar-dash/tests/ui/data/EmptyState.test.tsx +57 -0
- package/bizar-dash/tests/ui/data/ErrorState.test.tsx +47 -0
- package/bizar-dash/tests/ui/data/KeyValueList.test.tsx +59 -0
- package/bizar-dash/tests/ui/data/LoadingState.test.tsx +37 -0
- package/bizar-dash/tests/ui/data/Sparkline.test.tsx +56 -0
- package/bizar-dash/tests/ui/data/StatTile.test.tsx +69 -0
- package/bizar-dash/tests/ui/feedback/Badge.test.tsx +41 -0
- package/bizar-dash/tests/ui/feedback/Dialog.test.tsx +99 -0
- package/bizar-dash/tests/ui/feedback/ProgressBar.test.tsx +66 -0
- package/bizar-dash/tests/ui/feedback/StatusDot.test.tsx +41 -0
- package/bizar-dash/tests/ui/feedback/Toast.test.tsx +124 -0
- package/bizar-dash/tests/ui/feedback/Tooltip.test.tsx +102 -0
- package/bizar-dash/tests/ui/layout/AppShell.test.tsx +50 -0
- package/bizar-dash/tests/ui/layout/Breadcrumbs.test.tsx +85 -0
- package/bizar-dash/tests/ui/layout/Panel.test.tsx +52 -0
- package/bizar-dash/tests/ui/layout/PanelHeader.test.tsx +32 -0
- package/bizar-dash/tests/ui/layout/Sidebar.test.tsx +95 -0
- package/bizar-dash/tests/ui/layout/Tabs.test.tsx +87 -0
- package/bizar-dash/tests/ui/layout/Topbar.test.tsx +41 -0
- package/bizar-dash/tests/ui/navigation/CommandPalette.test.tsx +105 -0
- package/bizar-dash/tests/ui/navigation/NavGroup.test.tsx +55 -0
- package/bizar-dash/tests/ui/navigation/NavLink.test.tsx +61 -0
- package/bizar-dash/tests/ui/primitives/Box.test.tsx +49 -0
- package/bizar-dash/tests/ui/primitives/Grid.test.tsx +37 -0
- package/bizar-dash/tests/ui/primitives/Inline.test.tsx +33 -0
- package/bizar-dash/tests/ui/primitives/Separator.test.tsx +34 -0
- package/bizar-dash/tests/ui/primitives/Stack.test.tsx +45 -0
- package/bizar-dash/tests/ui/primitives/VisuallyHidden.test.tsx +27 -0
- package/bizar-dash/tests/views/Agents.test.tsx +359 -0
- package/bizar-dash/tests/views/Overview.test.tsx +413 -0
- package/bizar-dash/tests/views/Tasks.test.tsx +250 -0
- package/bizar-dash/vitest.config.ts +3 -1
- package/cli/__tests__/cost-gate.test.mjs +301 -0
- package/cli/__tests__/feature-list-bridge.test.mjs +371 -0
- package/cli/bin.mjs +38 -0
- package/cli/commands/claim.mjs +282 -0
- package/cli/commands/cost.mjs +279 -0
- package/cli/cost-gate.mjs +501 -0
- package/cli/feature-list-bridge.mjs +400 -0
- package/cli/memory-constants.mjs +17 -0
- package/cli/worker-dispatcher.mjs +259 -0
- package/cli/worker-dispatcher.test.mjs +204 -0
- package/config/trigger-patterns.json +186 -0
- package/package.json +2 -2
- package/packages/sdk/package.json +1 -1
- package/packages/sdk/src/agent-registry.ts +304 -0
- package/packages/sdk/src/consensus/byzantine.ts +587 -0
- package/packages/sdk/src/consensus/index.ts +147 -0
- package/packages/sdk/src/consensus/queen.ts +173 -0
- package/packages/sdk/src/consensus/types.ts +199 -0
- package/packages/sdk/src/federation/audit.ts +156 -0
- package/packages/sdk/src/federation/budget.ts +269 -0
- package/packages/sdk/src/federation/envelope.ts +144 -0
- package/packages/sdk/src/federation/hmac.ts +160 -0
- package/packages/sdk/src/federation/index.ts +443 -0
- package/packages/sdk/src/federation/pii.ts +241 -0
- package/packages/sdk/src/federation/policy.ts +112 -0
- package/packages/sdk/src/federation/trust.ts +146 -0
- package/packages/sdk/src/index.ts +67 -0
- package/packages/sdk/src/mcp/server.ts +351 -1
- package/packages/sdk/src/router/codemod-intent.ts +125 -0
- package/packages/sdk/src/router/index.ts +247 -0
- package/packages/sdk/src/router/memory-distillation-shim.mjs +18 -0
- package/packages/sdk/src/router/memory-distillation.ts +249 -0
- package/packages/sdk/src/router/model-router.ts +235 -0
- package/packages/sdk/src/router/q-learning-router.ts +304 -0
- package/packages/sdk/src/swarm-topology.ts +279 -0
- package/packages/sdk/tests/agent-registry.test.ts +285 -0
- package/packages/sdk/tests/consensus.test.ts +376 -0
- package/packages/sdk/tests/federation/audit.test.ts +164 -0
- package/packages/sdk/tests/federation/budget.test.ts +189 -0
- package/packages/sdk/tests/federation/envelope.test.ts +120 -0
- package/packages/sdk/tests/federation/hmac.test.ts +194 -0
- package/packages/sdk/tests/federation/orchestrator.test.ts +176 -0
- package/packages/sdk/tests/federation/pii.test.ts +106 -0
- package/packages/sdk/tests/federation/policy.test.ts +140 -0
- package/packages/sdk/tests/federation/trust.test.ts +124 -0
- package/packages/sdk/tests/mcp-tools.test.ts +204 -0
- package/packages/sdk/tests/memory-distillation.test.mjs +186 -0
- package/packages/sdk/tests/model-router.test.mjs +108 -0
- package/packages/sdk/tests/q-learning-router.test.mjs +100 -0
- package/packages/sdk/tests/router-orchestrator.test.mjs +172 -0
- package/packages/sdk/tests/router.test.mjs +91 -0
- package/packages/sdk/tests/sdk.test.mjs +26 -2
- package/packages/sdk/tests/swarm-topology.test.ts +258 -0
- package/scripts/bh-full-e2e.mjs +11 -15
- package/bizar-dash/dist/assets/MobileChat-BJrqwVDd.js +0 -1
- package/bizar-dash/dist/assets/MobileSettings-CEQNJNLJ.js +0 -1
- package/bizar-dash/dist/assets/icons-Do5N2jmX.js.map +0 -1
- package/bizar-dash/dist/assets/main-IvfQAOfy.js +0 -18
- package/bizar-dash/dist/assets/main-IvfQAOfy.js.map +0 -1
- package/bizar-dash/dist/assets/main-ietCEg_R.css +0 -1
- package/bizar-dash/dist/assets/markdown-tOLaD6nm.js +0 -1
- package/bizar-dash/dist/assets/mobile-DYCHcUpq.js +0 -1
- package/bizar-dash/dist/assets/mobile-layout-CBHjpwsb.js +0 -2
- package/bizar-dash/dist/assets/mobile-layout-CBHjpwsb.js.map +0 -1
- package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js +0 -40
- package/bizar-dash/dist/assets/react-vendor-Dn4wqh4Z.js.map +0 -1
- package/bizar-dash/dist/assets/useSlashCommands-Bd7_FA6U.js +0 -2
- package/bizar-dash/dist/assets/useSlashCommands-Bd7_FA6U.js.map +0 -1
- package/bizar-dash/dist/assets/vendor-C843201K.js +0 -29
- package/bizar-dash/dist/assets/vendor-C843201K.js.map +0 -1
- package/packages/sdk/package-lock.json +0 -32
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Sidebar.tsx — Vertical nav rail for the Bizar design system (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Renders grouped vertical navigation: each group is an optional label +
|
|
5
|
+
* a stack of items. Items are simple links/buttons; click an item to fire
|
|
6
|
+
* `onItemSelect(id)` and toggle the `activeId` highlight. Footer slot is
|
|
7
|
+
* pinned to the bottom of the rail and typically holds a settings link or
|
|
8
|
+
* user avatar. Self-contained — does not depend on ui/navigation primitives
|
|
9
|
+
* from sibling Wave 2 subagents, so this works regardless of dispatch order.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ReactNode } from 'react';
|
|
13
|
+
import { cx } from '../utils/cx';
|
|
14
|
+
|
|
15
|
+
export type NavItemIcon = React.ComponentType<{ size?: number | string }>;
|
|
16
|
+
|
|
17
|
+
export type NavLinkProps = {
|
|
18
|
+
id: string;
|
|
19
|
+
label: string;
|
|
20
|
+
icon?: NavItemIcon;
|
|
21
|
+
badge?: string | number;
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
href?: string;
|
|
24
|
+
onClick?: (id: string) => void;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type SidebarGroup = {
|
|
28
|
+
label?: string;
|
|
29
|
+
items: NavLinkProps[];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type SidebarProps = {
|
|
33
|
+
groups: SidebarGroup[];
|
|
34
|
+
activeId?: string;
|
|
35
|
+
onItemSelect?: (id: string) => void;
|
|
36
|
+
footer?: ReactNode;
|
|
37
|
+
width?: number;
|
|
38
|
+
className?: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function Sidebar({
|
|
42
|
+
groups,
|
|
43
|
+
activeId,
|
|
44
|
+
onItemSelect,
|
|
45
|
+
footer,
|
|
46
|
+
width,
|
|
47
|
+
className,
|
|
48
|
+
}: SidebarProps): React.JSX.Element {
|
|
49
|
+
return (
|
|
50
|
+
<nav
|
|
51
|
+
className={cx('bizar-sidebar', className)}
|
|
52
|
+
style={width ? { width } : undefined}
|
|
53
|
+
aria-label="Primary"
|
|
54
|
+
>
|
|
55
|
+
<div style={{ flex: 1, minHeight: 0 }}>
|
|
56
|
+
{groups.map((group, gIdx) => (
|
|
57
|
+
<div key={gIdx} className="bizar-sidebar__group">
|
|
58
|
+
{group.label && (
|
|
59
|
+
<div className="bizar-sidebar__label">{group.label}</div>
|
|
60
|
+
)}
|
|
61
|
+
<div className="bizar-sidebar__items" role="list">
|
|
62
|
+
{group.items.map((item) => {
|
|
63
|
+
const Icon = item.icon;
|
|
64
|
+
const active = activeId === item.id;
|
|
65
|
+
const className = cx(
|
|
66
|
+
'bizar-sidebar__item',
|
|
67
|
+
active && 'bizar-sidebar__item--active',
|
|
68
|
+
);
|
|
69
|
+
const ariaCurrent = active ? 'page' : undefined;
|
|
70
|
+
const onClick = () => {
|
|
71
|
+
if (item.disabled) return;
|
|
72
|
+
item.onClick?.(item.id);
|
|
73
|
+
onItemSelect?.(item.id);
|
|
74
|
+
};
|
|
75
|
+
if (item.href) {
|
|
76
|
+
return (
|
|
77
|
+
<a
|
|
78
|
+
key={item.id}
|
|
79
|
+
href={item.href}
|
|
80
|
+
className={className}
|
|
81
|
+
aria-current={ariaCurrent}
|
|
82
|
+
aria-disabled={item.disabled || undefined}
|
|
83
|
+
onClick={(e) => {
|
|
84
|
+
if (item.disabled) {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
onClick();
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
{Icon && <Icon size={16} />}
|
|
92
|
+
<span className="bizar-sidebar__item-label">
|
|
93
|
+
{item.label}
|
|
94
|
+
</span>
|
|
95
|
+
{item.badge !== undefined && (
|
|
96
|
+
<span className="bizar-sidebar__item-badge">
|
|
97
|
+
{item.badge}
|
|
98
|
+
</span>
|
|
99
|
+
)}
|
|
100
|
+
</a>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return (
|
|
104
|
+
<button
|
|
105
|
+
key={item.id}
|
|
106
|
+
type="button"
|
|
107
|
+
className={className}
|
|
108
|
+
aria-current={ariaCurrent}
|
|
109
|
+
disabled={item.disabled}
|
|
110
|
+
onClick={onClick}
|
|
111
|
+
>
|
|
112
|
+
{Icon && <Icon size={16} />}
|
|
113
|
+
<span className="bizar-sidebar__item-label">
|
|
114
|
+
{item.label}
|
|
115
|
+
</span>
|
|
116
|
+
{item.badge !== undefined && (
|
|
117
|
+
<span className="bizar-sidebar__item-badge">
|
|
118
|
+
{item.badge}
|
|
119
|
+
</span>
|
|
120
|
+
)}
|
|
121
|
+
</button>
|
|
122
|
+
);
|
|
123
|
+
})}
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
))}
|
|
127
|
+
</div>
|
|
128
|
+
{footer && <div className="bizar-sidebar__footer">{footer}</div>}
|
|
129
|
+
</nav>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Tabs.tsx — Horizontal tab strip for the Bizar design system (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Two visual variants:
|
|
5
|
+
* - `underline` (default): the active tab carries a 2px accent border
|
|
6
|
+
* on the bottom edge, no background fill. Used in page-level
|
|
7
|
+
* navigation where space is tight and the active state should be
|
|
8
|
+
* unmistakable but quiet.
|
|
9
|
+
* - `pill`: the active tab has a filled surface-3 background. Used for
|
|
10
|
+
* tool palettes and switchers where every tab should feel clickable.
|
|
11
|
+
*
|
|
12
|
+
* Keyboard support: Left/Right arrows move the active id across non-disabled
|
|
13
|
+
* tabs (matches the WAI-ARIA Authoring Practices for the tabs pattern).
|
|
14
|
+
* Tabs use `role="tab"` + `aria-selected`; the strip carries
|
|
15
|
+
* `role="tablist"`. Disabled tabs receive the `disabled` attribute on the
|
|
16
|
+
* underlying <button> and are skipped during keyboard navigation.
|
|
17
|
+
*
|
|
18
|
+
* `aria-controls` is intentionally NOT set here — the Tabs primitive owns
|
|
19
|
+
* only the strip, not the tabpanels, so we cannot point to a real id. The
|
|
20
|
+
* component that owns both the strip and its panels should set
|
|
21
|
+
* `aria-controls` itself (or wrap this Tabs and add the attribute on the
|
|
22
|
+
* rendered buttons).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { useCallback, type KeyboardEvent } from 'react';
|
|
26
|
+
import type { LucideIcon } from 'lucide-react';
|
|
27
|
+
import { cx } from '../utils/cx';
|
|
28
|
+
|
|
29
|
+
export type TabDef = {
|
|
30
|
+
id: string;
|
|
31
|
+
label: string;
|
|
32
|
+
icon?: LucideIcon;
|
|
33
|
+
badge?: string | number;
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type TabsProps = {
|
|
38
|
+
tabs: TabDef[];
|
|
39
|
+
activeId: string;
|
|
40
|
+
onChange: (id: string) => void;
|
|
41
|
+
variant?: 'underline' | 'pill';
|
|
42
|
+
size?: 'sm' | 'md';
|
|
43
|
+
className?: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export function Tabs({
|
|
47
|
+
tabs,
|
|
48
|
+
activeId,
|
|
49
|
+
onChange,
|
|
50
|
+
variant = 'underline',
|
|
51
|
+
size = 'md',
|
|
52
|
+
className,
|
|
53
|
+
}: TabsProps): React.JSX.Element {
|
|
54
|
+
const enabledIds = tabs.filter((t) => !t.disabled).map((t) => t.id);
|
|
55
|
+
|
|
56
|
+
const moveActive = useCallback(
|
|
57
|
+
(dir: 1 | -1) => {
|
|
58
|
+
if (enabledIds.length === 0) return;
|
|
59
|
+
const idx = enabledIds.indexOf(activeId);
|
|
60
|
+
// If current is not enabled, treat the "right" neighbor as the next
|
|
61
|
+
// enabled tab after the (missing) current.
|
|
62
|
+
const startIdx = idx === -1 ? -1 : idx;
|
|
63
|
+
let nextIdx = startIdx + dir;
|
|
64
|
+
if (nextIdx < 0) nextIdx = enabledIds.length - 1;
|
|
65
|
+
if (nextIdx >= enabledIds.length) nextIdx = 0;
|
|
66
|
+
const next = enabledIds[nextIdx];
|
|
67
|
+
if (next && next !== activeId) onChange(next);
|
|
68
|
+
},
|
|
69
|
+
[activeId, enabledIds, onChange],
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const onKeyDown = (e: KeyboardEvent<HTMLElement>): void => {
|
|
73
|
+
if (e.key === 'ArrowRight') {
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
moveActive(1);
|
|
76
|
+
} else if (e.key === 'ArrowLeft') {
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
moveActive(-1);
|
|
79
|
+
} else if (e.key === 'Home') {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
if (enabledIds[0]) onChange(enabledIds[0]);
|
|
82
|
+
} else if (e.key === 'End') {
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
const last = enabledIds[enabledIds.length - 1];
|
|
85
|
+
if (last) onChange(last);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<div
|
|
91
|
+
className={cx(
|
|
92
|
+
'bizar-tabs',
|
|
93
|
+
`bizar-tabs--${variant}`,
|
|
94
|
+
size === 'sm' && 'bizar-tabs--sm',
|
|
95
|
+
className,
|
|
96
|
+
)}
|
|
97
|
+
role="tablist"
|
|
98
|
+
>
|
|
99
|
+
{tabs.map((tab) => {
|
|
100
|
+
const Icon = tab.icon;
|
|
101
|
+
const active = tab.id === activeId;
|
|
102
|
+
const selectedRef = active;
|
|
103
|
+
return (
|
|
104
|
+
<button
|
|
105
|
+
key={tab.id}
|
|
106
|
+
type="button"
|
|
107
|
+
role="tab"
|
|
108
|
+
aria-selected={selectedRef}
|
|
109
|
+
tabIndex={selectedRef ? 0 : -1}
|
|
110
|
+
disabled={tab.disabled}
|
|
111
|
+
className={cx(
|
|
112
|
+
'bizar-tab',
|
|
113
|
+
active && 'bizar-tab--active',
|
|
114
|
+
)}
|
|
115
|
+
onClick={() => {
|
|
116
|
+
if (tab.disabled) return;
|
|
117
|
+
onChange(tab.id);
|
|
118
|
+
}}
|
|
119
|
+
onKeyDown={(e) => {
|
|
120
|
+
if (active && !tab.disabled) onKeyDown(e);
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
{Icon && <Icon size={14} className="bizar-tab__icon" />}
|
|
124
|
+
<span>{tab.label}</span>
|
|
125
|
+
{tab.badge !== undefined && (
|
|
126
|
+
<span className="bizar-tab__badge">{tab.badge}</span>
|
|
127
|
+
)}
|
|
128
|
+
</button>
|
|
129
|
+
);
|
|
130
|
+
})}
|
|
131
|
+
</div>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Topbar.tsx — Header bar for the Bizar design system (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Three horizontal slots: brand (left), center (typically a search input),
|
|
5
|
+
* right (actions / notifications). Height comes from `--layout-topbar-height`
|
|
6
|
+
* (default 48px) and `sticky=true` (default) pins the bar to the top of
|
|
7
|
+
* the viewport via `position: sticky` and `--z-sticky`. Visual chrome is
|
|
8
|
+
* minimal: a single hairline border-bottom in `--border-subtle`.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ReactNode } from 'react';
|
|
12
|
+
import { cx } from '../utils/cx';
|
|
13
|
+
|
|
14
|
+
export type TopbarProps = {
|
|
15
|
+
brand?: ReactNode;
|
|
16
|
+
center?: ReactNode;
|
|
17
|
+
right?: ReactNode;
|
|
18
|
+
height?: number;
|
|
19
|
+
sticky?: boolean;
|
|
20
|
+
className?: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export function Topbar({
|
|
24
|
+
brand,
|
|
25
|
+
center,
|
|
26
|
+
right,
|
|
27
|
+
height,
|
|
28
|
+
sticky = true,
|
|
29
|
+
className,
|
|
30
|
+
}: TopbarProps): React.JSX.Element {
|
|
31
|
+
return (
|
|
32
|
+
<header
|
|
33
|
+
className={cx('bizar-topbar', sticky && 'bizar-topbar--sticky', className)}
|
|
34
|
+
style={height ? { height } : undefined}
|
|
35
|
+
role="banner"
|
|
36
|
+
>
|
|
37
|
+
<div className="bizar-topbar__brand">{brand}</div>
|
|
38
|
+
{center && <div className="bizar-topbar__center">{center}</div>}
|
|
39
|
+
{right && <div className="bizar-topbar__right">{right}</div>}
|
|
40
|
+
</header>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* layout/index.ts — Barrel export for the Bizar layout primitives (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Side-effect imports ship `layout.css` alongside the JS so consumers
|
|
5
|
+
* only need `import { Topbar, Sidebar } from '../ui/layout'` to mount
|
|
6
|
+
* the visual surface. Exports are deliberately focused — no re-export
|
|
7
|
+
* of legacy components, no prefix collisions.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import './layout.css';
|
|
11
|
+
|
|
12
|
+
export { AppShell, type AppShellProps } from './AppShell';
|
|
13
|
+
export {
|
|
14
|
+
Sidebar,
|
|
15
|
+
type SidebarProps,
|
|
16
|
+
type SidebarGroup,
|
|
17
|
+
type NavLinkProps,
|
|
18
|
+
type NavItemIcon,
|
|
19
|
+
} from './Sidebar';
|
|
20
|
+
export { Topbar, type TopbarProps } from './Topbar';
|
|
21
|
+
export {
|
|
22
|
+
Panel,
|
|
23
|
+
type PanelProps,
|
|
24
|
+
type PanelPadding,
|
|
25
|
+
type PanelVariant,
|
|
26
|
+
} from './Panel';
|
|
27
|
+
export { PanelHeader, type PanelHeaderProps } from './PanelHeader';
|
|
28
|
+
export { Tabs, type TabsProps, type TabDef } from './Tabs';
|
|
29
|
+
export {
|
|
30
|
+
Breadcrumbs,
|
|
31
|
+
type BreadcrumbsProps,
|
|
32
|
+
type BreadcrumbItem,
|
|
33
|
+
} from './Breadcrumbs';
|