@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,314 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* feedback.css — Styles for Bizar feedback components (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Ships the visual surface for Toast, Dialog, Tooltip, Badge, StatusDot,
|
|
5
|
+
* and ProgressBar. Every value references a token — no literals. Side-
|
|
6
|
+
* effect import from `ui/feedback/index.ts`. Class names are scoped
|
|
7
|
+
* under `.bizar-` so the new feedback components never collide with
|
|
8
|
+
* legacy `.toast` / `.modal` / `.spinner` rules in main.css.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
12
|
+
* Toast
|
|
13
|
+
* ──────────────────────────────────────────────────────────────────── */
|
|
14
|
+
|
|
15
|
+
.bizar-toast-viewport {
|
|
16
|
+
position: fixed;
|
|
17
|
+
right: var(--space-5);
|
|
18
|
+
bottom: var(--space-5);
|
|
19
|
+
z-index: var(--z-toast);
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column-reverse;
|
|
22
|
+
gap: var(--space-2);
|
|
23
|
+
max-width: min(360px, calc(100vw - 32px));
|
|
24
|
+
pointer-events: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.bizar-toast {
|
|
28
|
+
display: grid;
|
|
29
|
+
grid-template-columns: auto 1fr auto;
|
|
30
|
+
align-items: center;
|
|
31
|
+
gap: var(--space-3);
|
|
32
|
+
padding: var(--space-3) var(--space-4);
|
|
33
|
+
border: 1px solid var(--border-default);
|
|
34
|
+
border-radius: var(--radius-md);
|
|
35
|
+
background: var(--surface-0);
|
|
36
|
+
color: var(--text-primary);
|
|
37
|
+
font-size: var(--text-base);
|
|
38
|
+
box-shadow: var(--shadow-overlay);
|
|
39
|
+
pointer-events: auto;
|
|
40
|
+
animation: bizar-toast-in var(--duration-normal) var(--ease-out);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@keyframes bizar-toast-in {
|
|
44
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
45
|
+
to { opacity: 1; transform: translateY(0); }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.bizar-toast--info { border-left: 3px solid var(--info); }
|
|
49
|
+
.bizar-toast--success { border-left: 3px solid var(--success); }
|
|
50
|
+
.bizar-toast--warning { border-left: 3px solid var(--warning); }
|
|
51
|
+
.bizar-toast--error { border-left: 3px solid var(--danger); }
|
|
52
|
+
|
|
53
|
+
.bizar-toast__icon {
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
justify-content: center;
|
|
57
|
+
width: 18px;
|
|
58
|
+
height: 18px;
|
|
59
|
+
flex-shrink: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.bizar-toast--info .bizar-toast__icon { color: var(--info); }
|
|
63
|
+
.bizar-toast--success .bizar-toast__icon { color: var(--success); }
|
|
64
|
+
.bizar-toast--warning .bizar-toast__icon { color: var(--warning); }
|
|
65
|
+
.bizar-toast--error .bizar-toast__icon { color: var(--danger); }
|
|
66
|
+
|
|
67
|
+
.bizar-toast__message {
|
|
68
|
+
line-height: var(--leading-snug);
|
|
69
|
+
word-break: break-word;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.bizar-toast__close {
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
justify-content: center;
|
|
76
|
+
width: 22px;
|
|
77
|
+
height: 22px;
|
|
78
|
+
border: 0;
|
|
79
|
+
background: transparent;
|
|
80
|
+
color: var(--text-tertiary);
|
|
81
|
+
border-radius: var(--radius-sm);
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.bizar-toast__close:hover {
|
|
86
|
+
background: var(--surface-overlay);
|
|
87
|
+
color: var(--text-primary);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
91
|
+
* Dialog
|
|
92
|
+
* ──────────────────────────────────────────────────────────────────── */
|
|
93
|
+
|
|
94
|
+
.bizar-dialog-backdrop {
|
|
95
|
+
position: fixed;
|
|
96
|
+
inset: 0;
|
|
97
|
+
background: rgba(0, 0, 0, 0.4);
|
|
98
|
+
backdrop-filter: blur(2px);
|
|
99
|
+
z-index: var(--z-modal);
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
justify-content: center;
|
|
103
|
+
padding: var(--space-5);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.bizar-dialog {
|
|
107
|
+
background: var(--surface-0);
|
|
108
|
+
color: var(--text-primary);
|
|
109
|
+
border: 1px solid var(--border-default);
|
|
110
|
+
border-radius: var(--radius-md);
|
|
111
|
+
box-shadow: var(--shadow-overlay);
|
|
112
|
+
width: 100%;
|
|
113
|
+
max-width: 480px;
|
|
114
|
+
max-height: calc(100vh - 64px);
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
outline: 0;
|
|
118
|
+
animation: bizar-dialog-in var(--duration-normal) var(--ease-out);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@keyframes bizar-dialog-in {
|
|
122
|
+
from { opacity: 0; transform: translateY(8px) scale(0.98); }
|
|
123
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.bizar-dialog__header {
|
|
127
|
+
padding: var(--space-5) var(--space-6) var(--space-3);
|
|
128
|
+
display: flex;
|
|
129
|
+
align-items: flex-start;
|
|
130
|
+
gap: var(--space-4);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.bizar-dialog__title {
|
|
134
|
+
margin: 0;
|
|
135
|
+
font-size: var(--text-lg);
|
|
136
|
+
font-weight: var(--weight-semibold);
|
|
137
|
+
line-height: var(--leading-tight);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.bizar-dialog__description {
|
|
141
|
+
margin: var(--space-1) 0 0;
|
|
142
|
+
color: var(--text-secondary);
|
|
143
|
+
font-size: var(--text-base);
|
|
144
|
+
line-height: var(--leading-snug);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.bizar-dialog__close {
|
|
148
|
+
margin-left: auto;
|
|
149
|
+
display: inline-flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
width: 28px;
|
|
153
|
+
height: 28px;
|
|
154
|
+
border: 0;
|
|
155
|
+
background: transparent;
|
|
156
|
+
color: var(--text-secondary);
|
|
157
|
+
border-radius: var(--radius-md);
|
|
158
|
+
cursor: pointer;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.bizar-dialog__close:hover {
|
|
162
|
+
background: var(--surface-overlay);
|
|
163
|
+
color: var(--text-primary);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.bizar-dialog__body {
|
|
167
|
+
padding: var(--space-3) var(--space-6) var(--space-5);
|
|
168
|
+
overflow: auto;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.bizar-dialog__actions {
|
|
172
|
+
display: flex;
|
|
173
|
+
align-items: center;
|
|
174
|
+
justify-content: flex-end;
|
|
175
|
+
gap: var(--space-2);
|
|
176
|
+
padding: var(--space-4) var(--space-6);
|
|
177
|
+
border-top: 1px solid var(--border-subtle);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
181
|
+
* Tooltip
|
|
182
|
+
* ──────────────────────────────────────────────────────────────────── */
|
|
183
|
+
|
|
184
|
+
.bizar-tooltip {
|
|
185
|
+
position: relative;
|
|
186
|
+
display: inline-flex;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.bizar-tooltip__popup {
|
|
190
|
+
position: absolute;
|
|
191
|
+
z-index: var(--z-tooltip);
|
|
192
|
+
padding: var(--space-2) var(--space-3);
|
|
193
|
+
background: var(--surface-3);
|
|
194
|
+
color: var(--text-primary);
|
|
195
|
+
font-size: var(--text-sm);
|
|
196
|
+
line-height: var(--leading-snug);
|
|
197
|
+
border: 1px solid var(--border-default);
|
|
198
|
+
border-radius: var(--radius-md);
|
|
199
|
+
box-shadow: var(--shadow-tooltip);
|
|
200
|
+
white-space: nowrap;
|
|
201
|
+
pointer-events: none;
|
|
202
|
+
animation: bizar-tooltip-in var(--duration-fast) var(--ease-out);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@keyframes bizar-tooltip-in {
|
|
206
|
+
from { opacity: 0; }
|
|
207
|
+
to { opacity: 1; }
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.bizar-tooltip__popup--top { bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); }
|
|
211
|
+
.bizar-tooltip__popup--right { left: calc(100% + 6px); top: 50%; transform: translateY(-50%); }
|
|
212
|
+
.bizar-tooltip__popup--bottom { top: calc(100% + 6px); left: 50%; transform: translateX(-50%); }
|
|
213
|
+
.bizar-tooltip__popup--left { right: calc(100% + 6px); top: 50%; transform: translateY(-50%); }
|
|
214
|
+
|
|
215
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
216
|
+
* Badge
|
|
217
|
+
* ──────────────────────────────────────────────────────────────────── */
|
|
218
|
+
|
|
219
|
+
.bizar-badge {
|
|
220
|
+
display: inline-flex;
|
|
221
|
+
align-items: center;
|
|
222
|
+
gap: var(--space-2);
|
|
223
|
+
padding: 2px 6px;
|
|
224
|
+
border-radius: var(--radius-full);
|
|
225
|
+
font-size: var(--text-xs);
|
|
226
|
+
font-weight: var(--weight-medium);
|
|
227
|
+
line-height: var(--leading-tight);
|
|
228
|
+
background: var(--surface-overlay);
|
|
229
|
+
color: var(--text-secondary);
|
|
230
|
+
white-space: nowrap;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.bizar-badge--sm { padding: 1px 5px; font-size: 10px; }
|
|
234
|
+
.bizar-badge--md { padding: 2px 6px; }
|
|
235
|
+
|
|
236
|
+
.bizar-badge--info { background: var(--info-subtle); color: var(--info); }
|
|
237
|
+
.bizar-badge--success { background: var(--success-subtle); color: var(--success); }
|
|
238
|
+
.bizar-badge--warning { background: var(--warning-subtle); color: var(--warning); }
|
|
239
|
+
.bizar-badge--danger { background: var(--danger-subtle); color: var(--danger); }
|
|
240
|
+
.bizar-badge--accent { background: var(--accent-subtle); color: var(--accent); }
|
|
241
|
+
|
|
242
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
243
|
+
* StatusDot
|
|
244
|
+
* ──────────────────────────────────────────────────────────────────── */
|
|
245
|
+
|
|
246
|
+
.bizar-status-dot {
|
|
247
|
+
display: inline-block;
|
|
248
|
+
border-radius: var(--radius-full);
|
|
249
|
+
background: var(--text-tertiary);
|
|
250
|
+
flex-shrink: 0;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.bizar-status-dot--sm { width: 6px; height: 6px; }
|
|
254
|
+
.bizar-status-dot--md { width: 8px; height: 8px; }
|
|
255
|
+
|
|
256
|
+
.bizar-status-dot--info { background: var(--info); }
|
|
257
|
+
.bizar-status-dot--success { background: var(--success); }
|
|
258
|
+
.bizar-status-dot--warning { background: var(--warning); }
|
|
259
|
+
.bizar-status-dot--danger { background: var(--danger); }
|
|
260
|
+
|
|
261
|
+
@keyframes bizar-status-dot-pulse {
|
|
262
|
+
0%, 100% { opacity: 1; }
|
|
263
|
+
50% { opacity: 0.35; }
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.bizar-status-dot--pulse {
|
|
267
|
+
animation: bizar-status-dot-pulse 2s var(--ease-in-out) infinite;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* ─────────────────────────────────────────────────────────────────────
|
|
271
|
+
* ProgressBar
|
|
272
|
+
* ──────────────────────────────────────────────────────────────────── */
|
|
273
|
+
|
|
274
|
+
.bizar-progress {
|
|
275
|
+
width: 100%;
|
|
276
|
+
background: var(--surface-2);
|
|
277
|
+
border-radius: var(--radius-full);
|
|
278
|
+
overflow: hidden;
|
|
279
|
+
display: block;
|
|
280
|
+
position: relative;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.bizar-progress--sm { height: 4px; }
|
|
284
|
+
.bizar-progress--md { height: 6px; }
|
|
285
|
+
.bizar-progress--lg { height: 10px; }
|
|
286
|
+
|
|
287
|
+
.bizar-progress__fill {
|
|
288
|
+
height: 100%;
|
|
289
|
+
background: var(--accent);
|
|
290
|
+
border-radius: var(--radius-full);
|
|
291
|
+
transition: width var(--duration-normal) var(--ease-out);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.bizar-progress__fill--accent { background: var(--accent); }
|
|
295
|
+
.bizar-progress__fill--neutral { background: var(--text-tertiary); }
|
|
296
|
+
.bizar-progress__fill--success { background: var(--success); }
|
|
297
|
+
.bizar-progress__fill--danger { background: var(--danger); }
|
|
298
|
+
|
|
299
|
+
@keyframes bizar-progress-indeterminate {
|
|
300
|
+
0% { transform: translateX(-100%); }
|
|
301
|
+
100% { transform: translateX(400%); }
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.bizar-progress--indeterminate .bizar-progress__fill {
|
|
305
|
+
width: 25%;
|
|
306
|
+
animation: bizar-progress-indeterminate 1.4s linear infinite;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.bizar-progress__label {
|
|
310
|
+
display: block;
|
|
311
|
+
margin-bottom: var(--space-2);
|
|
312
|
+
font-size: var(--text-sm);
|
|
313
|
+
color: var(--text-secondary);
|
|
314
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* feedback/index.ts — Barrel export for the Bizar feedback components (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Side-effect imports ship `feedback.css` alongside the JS so consumers
|
|
5
|
+
* only need `import { ToastProvider, useToast } from '../ui/feedback'`
|
|
6
|
+
* to mount the visual surface. Exports are deliberately focused — no
|
|
7
|
+
* re-export of legacy components, no prefix collisions.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import './feedback.css';
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
ToastProvider,
|
|
14
|
+
useToast,
|
|
15
|
+
type ToastProviderProps,
|
|
16
|
+
type ToastApi,
|
|
17
|
+
type ToastItem,
|
|
18
|
+
type ToastKind,
|
|
19
|
+
} from './Toast';
|
|
20
|
+
export { Dialog, type DialogProps } from './Dialog';
|
|
21
|
+
export {
|
|
22
|
+
Tooltip,
|
|
23
|
+
type TooltipProps,
|
|
24
|
+
type TooltipSide,
|
|
25
|
+
} from './Tooltip';
|
|
26
|
+
export {
|
|
27
|
+
Badge,
|
|
28
|
+
type BadgeProps,
|
|
29
|
+
type BadgeVariant,
|
|
30
|
+
type BadgeSize,
|
|
31
|
+
} from './Badge';
|
|
32
|
+
export {
|
|
33
|
+
StatusDot,
|
|
34
|
+
type StatusDotProps,
|
|
35
|
+
type StatusDotVariant,
|
|
36
|
+
type StatusDotSize,
|
|
37
|
+
} from './StatusDot';
|
|
38
|
+
export {
|
|
39
|
+
ProgressBar,
|
|
40
|
+
type ProgressBarProps,
|
|
41
|
+
type ProgressVariant,
|
|
42
|
+
type ProgressSize,
|
|
43
|
+
} from './ProgressBar';
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* index.ts — Barrel export for the Bizar design system.
|
|
3
|
+
*
|
|
4
|
+
* One stop for every primitive, control, data, layout, navigation, and
|
|
5
|
+
* feedback component. Side-effect CSS imports ship every stylesheet
|
|
6
|
+
* (reset + tokens + globals) to any consumer that imports from this
|
|
7
|
+
* module graph. The legacy main.css also imports globals.css directly
|
|
8
|
+
* so non-TS code paths still get the tokens via the CSS pipeline alone.
|
|
9
|
+
*
|
|
10
|
+
* Naming collision: `layout/Sidebar` re-exports its own `NavLinkProps`
|
|
11
|
+
* (self-contained Sidebar.tsx, doesn't depend on navigation/NavLink to
|
|
12
|
+
* avoid a parallel-Wave 2 dependency cycle). We intentionally drop
|
|
13
|
+
* layout's `NavLinkProps` here and re-export `navigation/NavLink`'s
|
|
14
|
+
* canonical `NavLinkProps` instead — the two have identical shape but
|
|
15
|
+
* the navigation one is the public API.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// foundation styles (side-effect)
|
|
19
|
+
import './styles/reset.css';
|
|
20
|
+
import './styles/tokens.css';
|
|
21
|
+
import './styles/globals.css';
|
|
22
|
+
|
|
23
|
+
// theme
|
|
24
|
+
export { ThemeProvider, type Theme } from './theme/ThemeProvider';
|
|
25
|
+
export type { ThemeContextValue } from './theme/ThemeProvider';
|
|
26
|
+
export { useTheme } from './theme/useTheme';
|
|
27
|
+
export * as tokens from './theme/tokens';
|
|
28
|
+
|
|
29
|
+
// utils
|
|
30
|
+
export { cx, type ClassValue } from './utils/cx';
|
|
31
|
+
|
|
32
|
+
// primitives
|
|
33
|
+
export * from './primitives';
|
|
34
|
+
|
|
35
|
+
// controls
|
|
36
|
+
export * from './controls';
|
|
37
|
+
|
|
38
|
+
// data
|
|
39
|
+
export * from './data';
|
|
40
|
+
|
|
41
|
+
// navigation (must come before layout — its NavLinkProps is canonical)
|
|
42
|
+
export * from './navigation';
|
|
43
|
+
|
|
44
|
+
// layout (selective: drop layout's shadow NavLinkProps in favour of navigation's)
|
|
45
|
+
export {
|
|
46
|
+
AppShell, type AppShellProps,
|
|
47
|
+
Sidebar, type SidebarProps, type SidebarGroup, type NavItemIcon,
|
|
48
|
+
Topbar, type TopbarProps,
|
|
49
|
+
Panel, type PanelProps, type PanelPadding, type PanelVariant,
|
|
50
|
+
PanelHeader, type PanelHeaderProps,
|
|
51
|
+
Tabs, type TabsProps, type TabDef,
|
|
52
|
+
Breadcrumbs, type BreadcrumbsProps, type BreadcrumbItem,
|
|
53
|
+
} from './layout';
|
|
54
|
+
|
|
55
|
+
// feedback
|
|
56
|
+
export * from './feedback';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* AppShell.tsx — Outer shell layout for the Bizar design system (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Composes a sticky topbar above a sidebar + main content area using a CSS
|
|
5
|
+
* grid. Tokens `--layout-sidebar-width` and `--layout-topbar-height` drive
|
|
6
|
+
* the dimensions so theming/sizing changes flow through CSS only. Pass
|
|
7
|
+
* `sidebarCollapsed=true` to collapse the rail (animated width-zero via the
|
|
8
|
+
* `--collapsed` modifier). This component is additive — it does not replace
|
|
9
|
+
* the existing App.tsx shell; old layouts continue to render unchanged.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ReactNode } from 'react';
|
|
13
|
+
import { cx } from '../utils/cx';
|
|
14
|
+
|
|
15
|
+
export type AppShellProps = {
|
|
16
|
+
topbar?: ReactNode;
|
|
17
|
+
sidebar?: ReactNode;
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
/** When true the sidebar collapses to a 0px rail. Default false. */
|
|
20
|
+
sidebarCollapsed?: boolean;
|
|
21
|
+
/** Optional className on the outermost grid. */
|
|
22
|
+
className?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function AppShell({
|
|
26
|
+
topbar,
|
|
27
|
+
sidebar,
|
|
28
|
+
children,
|
|
29
|
+
sidebarCollapsed = false,
|
|
30
|
+
className,
|
|
31
|
+
}: AppShellProps): React.JSX.Element {
|
|
32
|
+
return (
|
|
33
|
+
<div className={cx('bizar-app-shell', className)}>
|
|
34
|
+
{topbar && (
|
|
35
|
+
<div className="bizar-app-shell__topbar">{topbar}</div>
|
|
36
|
+
)}
|
|
37
|
+
{sidebar && !sidebarCollapsed && (
|
|
38
|
+
<aside className="bizar-app-shell__sidebar">{sidebar}</aside>
|
|
39
|
+
)}
|
|
40
|
+
{sidebar && sidebarCollapsed && (
|
|
41
|
+
<aside
|
|
42
|
+
className="bizar-app-shell__sidebar bizar-app-shell__sidebar--collapsed"
|
|
43
|
+
aria-hidden="true"
|
|
44
|
+
/>
|
|
45
|
+
)}
|
|
46
|
+
<main className="bizar-app-shell__main">
|
|
47
|
+
<div className="bizar-app-shell__main-inner">{children}</div>
|
|
48
|
+
</main>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Breadcrumbs.tsx — Breadcrumb trail for the Bizar design system (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Renders a horizontal chain of clickable crumbs separated by a chevron.
|
|
5
|
+
* Default separator is the lucide `ChevronRight` icon (15px, muted), but
|
|
6
|
+
* callers can replace it with any ReactNode — including a custom glyph,
|
|
7
|
+
* "/", or "›". The final crumb is rendered in `--text-primary` with
|
|
8
|
+
* medium weight and is not interactive: it represents the current page.
|
|
9
|
+
* Items with `href` render as <a>; items with only `onClick` render as
|
|
10
|
+
* <button>; the current item renders as a non-interactive <span>.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { ReactNode } from 'react';
|
|
14
|
+
import { ChevronRight } from 'lucide-react';
|
|
15
|
+
import { cx } from '../utils/cx';
|
|
16
|
+
|
|
17
|
+
export type BreadcrumbItem = {
|
|
18
|
+
label: string;
|
|
19
|
+
href?: string;
|
|
20
|
+
onClick?: () => void;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type BreadcrumbsProps = {
|
|
24
|
+
items: BreadcrumbItem[];
|
|
25
|
+
separator?: ReactNode;
|
|
26
|
+
className?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function Breadcrumbs({
|
|
30
|
+
items,
|
|
31
|
+
separator,
|
|
32
|
+
className,
|
|
33
|
+
}: BreadcrumbsProps): React.JSX.Element {
|
|
34
|
+
return (
|
|
35
|
+
<nav className={cx('bizar-breadcrumbs', className)} aria-label="Breadcrumb">
|
|
36
|
+
<ol
|
|
37
|
+
style={{
|
|
38
|
+
display: 'contents',
|
|
39
|
+
listStyle: 'none',
|
|
40
|
+
margin: 0,
|
|
41
|
+
padding: 0,
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
{items.map((item, idx) => {
|
|
45
|
+
const isCurrent = idx === items.length - 1;
|
|
46
|
+
const sep =
|
|
47
|
+
idx < items.length - 1 ? (
|
|
48
|
+
<span className="bizar-breadcrumbs__separator" aria-hidden="true">
|
|
49
|
+
{separator ?? <ChevronRight size={15} />}
|
|
50
|
+
</span>
|
|
51
|
+
) : null;
|
|
52
|
+
|
|
53
|
+
if (isCurrent) {
|
|
54
|
+
return (
|
|
55
|
+
<li
|
|
56
|
+
key={idx}
|
|
57
|
+
aria-current="page"
|
|
58
|
+
className="bizar-breadcrumbs__item bizar-breadcrumbs__item--current"
|
|
59
|
+
>
|
|
60
|
+
{item.label}
|
|
61
|
+
{sep}
|
|
62
|
+
</li>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (item.href) {
|
|
67
|
+
return (
|
|
68
|
+
<li key={idx}>
|
|
69
|
+
<a
|
|
70
|
+
href={item.href}
|
|
71
|
+
className="bizar-breadcrumbs__item"
|
|
72
|
+
onClick={() => item.onClick?.()}
|
|
73
|
+
>
|
|
74
|
+
{item.label}
|
|
75
|
+
</a>
|
|
76
|
+
{sep}
|
|
77
|
+
</li>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<li key={idx}>
|
|
83
|
+
<button
|
|
84
|
+
type="button"
|
|
85
|
+
className="bizar-breadcrumbs__item"
|
|
86
|
+
onClick={() => item.onClick?.()}
|
|
87
|
+
>
|
|
88
|
+
{item.label}
|
|
89
|
+
</button>
|
|
90
|
+
{sep}
|
|
91
|
+
</li>
|
|
92
|
+
);
|
|
93
|
+
})}
|
|
94
|
+
</ol>
|
|
95
|
+
</nav>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Panel.tsx — Bordered card surface for the Bizar design system (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* The workhorse container for grouped content. Renders an optional
|
|
5
|
+
* header (title + description + actions) with a hairline separator from
|
|
6
|
+
* the body, then any children inside a padded region. Two surface tones
|
|
7
|
+
* — `outlined` (default, surface-1) and `filled` (surface-2 + stronger
|
|
8
|
+
* border) — handle the two densities found across the dashboard. Padding
|
|
9
|
+
* accepts a 0..5 scale that maps to the `--space-N` tokens (default 4).
|
|
10
|
+
*
|
|
11
|
+
* The header is only rendered when at least one of `title`, `description`,
|
|
12
|
+
* `actions` is set, so an empty Panel renders just the body.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { ReactNode } from 'react';
|
|
16
|
+
import { cx } from '../utils/cx';
|
|
17
|
+
|
|
18
|
+
export type PanelPadding = 0 | 1 | 2 | 3 | 4 | 5;
|
|
19
|
+
export type PanelVariant = 'outlined' | 'filled';
|
|
20
|
+
|
|
21
|
+
export type PanelProps = {
|
|
22
|
+
title?: ReactNode;
|
|
23
|
+
description?: ReactNode;
|
|
24
|
+
actions?: ReactNode;
|
|
25
|
+
children?: ReactNode;
|
|
26
|
+
padding?: PanelPadding;
|
|
27
|
+
variant?: PanelVariant;
|
|
28
|
+
className?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function Panel({
|
|
32
|
+
title,
|
|
33
|
+
description,
|
|
34
|
+
actions,
|
|
35
|
+
children,
|
|
36
|
+
padding = 4,
|
|
37
|
+
variant = 'outlined',
|
|
38
|
+
className,
|
|
39
|
+
}: PanelProps): React.JSX.Element {
|
|
40
|
+
const hasHeader =
|
|
41
|
+
title !== undefined || description !== undefined || actions !== undefined;
|
|
42
|
+
return (
|
|
43
|
+
<section
|
|
44
|
+
className={cx(
|
|
45
|
+
'bizar-panel',
|
|
46
|
+
variant === 'filled' && 'bizar-panel--filled',
|
|
47
|
+
className,
|
|
48
|
+
)}
|
|
49
|
+
>
|
|
50
|
+
{hasHeader && (
|
|
51
|
+
<div className="bizar-panel__header">
|
|
52
|
+
{(title || description) && (
|
|
53
|
+
<div className="bizar-panel__header-text">
|
|
54
|
+
{title && <h3 className="bizar-panel__title">{title}</h3>}
|
|
55
|
+
{description && (
|
|
56
|
+
<p className="bizar-panel__description">{description}</p>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
)}
|
|
60
|
+
{actions && <div className="bizar-panel__actions">{actions}</div>}
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
<div
|
|
64
|
+
className={cx(
|
|
65
|
+
'bizar-panel__body',
|
|
66
|
+
`bizar-panel__padding--${padding}`,
|
|
67
|
+
)}
|
|
68
|
+
>
|
|
69
|
+
{children}
|
|
70
|
+
</div>
|
|
71
|
+
</section>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* PanelHeader.tsx — Standalone header block for use inside a Panel (Wave 2C).
|
|
3
|
+
*
|
|
4
|
+
* Splits a header into three regions (text on the left, actions on the
|
|
5
|
+
* right, optional custom children prepended above all). The bottom border
|
|
6
|
+
* that separates header from body is owned by Panel; this component only
|
|
7
|
+
* renders the inner layout. Use `<Panel>` for the standard header shape
|
|
8
|
+
* — drop down to `<PanelHeader>` only when you need a non-trivial header
|
|
9
|
+
* (e.g. tab strip + filter chips stacked above the title).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { ReactNode } from 'react';
|
|
13
|
+
|
|
14
|
+
export type PanelHeaderProps = {
|
|
15
|
+
title?: ReactNode;
|
|
16
|
+
description?: ReactNode;
|
|
17
|
+
actions?: ReactNode;
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function PanelHeader({
|
|
22
|
+
title,
|
|
23
|
+
description,
|
|
24
|
+
actions,
|
|
25
|
+
children,
|
|
26
|
+
}: PanelHeaderProps): React.JSX.Element {
|
|
27
|
+
return (
|
|
28
|
+
<div className="bizar-panel__header">
|
|
29
|
+
<div className="bizar-panel__header-text">
|
|
30
|
+
{children}
|
|
31
|
+
{title && <h3 className="bizar-panel__title">{title}</h3>}
|
|
32
|
+
{description && (
|
|
33
|
+
<p className="bizar-panel__description">{description}</p>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
{actions && <div className="bizar-panel__actions">{actions}</div>}
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|