@digithings-ai/ui 0.0.0-stage → 0.1.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/README.md +48 -2
- package/package.json +143 -4
- package/src/components/NavShell.tsx +776 -0
- package/src/components/SocialRow.tsx +87 -0
- package/src/components/Spinner.tsx +27 -0
- package/src/components/StackLogo.tsx +40 -0
- package/src/components/Terminal.tsx +110 -0
- package/src/components/TerminalManifest.tsx +212 -0
- package/src/components/ThemeProvider.tsx +271 -0
- package/src/components/account/AuthCard.tsx +309 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.aui.tsx +63 -0
- package/src/components/assistant-ui/elements/mermaid-diagram.tsx +340 -0
- package/src/components/brand/BrandWordmark.tsx +32 -0
- package/src/components/changelog/ReleaseRail.tsx +81 -0
- package/src/components/changelog/index.ts +1 -0
- package/src/components/chat/ChatCodeBlock.tsx +67 -0
- package/src/components/chat/ChatMarkdown.tsx +66 -0
- package/src/components/chat/ChatMarkdownSource.tsx +203 -0
- package/src/components/chat/ChatMermaidBlock.tsx +202 -0
- package/src/components/chat/ChatMessage.tsx +77 -0
- package/src/components/chat/ChatPlayback.tsx +422 -0
- package/src/components/chat/ChatStreamCursor.tsx +25 -0
- package/src/components/chat/ChatThinking.tsx +113 -0
- package/src/components/chat/ChatToolCall.tsx +190 -0
- package/src/components/chat/ChatTranscript.tsx +60 -0
- package/src/components/chat/ChatWidgetFrame.tsx +107 -0
- package/src/components/chat/DigichatBootLoader.tsx +683 -0
- package/src/components/chat/DigichatLauncher.tsx +361 -0
- package/src/components/chat/DigichatThread.tsx +118 -0
- package/src/components/chat/DigichatThreadList.tsx +54 -0
- package/src/components/chat/DigichatWordmark.tsx +24 -0
- package/src/components/chat/DotMatrix.tsx +650 -0
- package/src/components/chat/boot-lab.tsx +766 -0
- package/src/components/chat/boot-signal.ts +144 -0
- package/src/components/chat/chat-surfaces.ts +52 -0
- package/src/components/chat/connection-status.ts +40 -0
- package/src/components/chat/digichat-wordmark.ts +355 -0
- package/src/components/chat/disclosure-chevron.tsx +49 -0
- package/src/components/chat/followable-href.ts +9 -0
- package/src/components/chat/gallery-thread/action-icons.tsx +25 -0
- package/src/components/chat/gallery-thread/attachment.aui.tsx +262 -0
- package/src/components/chat/gallery-thread/block-caret.tsx +439 -0
- package/src/components/chat/gallery-thread/cn.ts +1 -0
- package/src/components/chat/gallery-thread/composer-keyboard.ts +106 -0
- package/src/components/chat/gallery-thread/composer-trigger-popover.aui.tsx +235 -0
- package/src/components/chat/gallery-thread/css.d.ts +6 -0
- package/src/components/chat/gallery-thread/file.tsx +238 -0
- package/src/components/chat/gallery-thread/follow-up-suggestions.aui.tsx +92 -0
- package/src/components/chat/gallery-thread/format-json-dump.ts +112 -0
- package/src/components/chat/gallery-thread/hooks/use-attachment-src.ts +46 -0
- package/src/components/chat/gallery-thread/hooks/use-copy-to-clipboard.ts +9 -0
- package/src/components/chat/gallery-thread/image.tsx +519 -0
- package/src/components/chat/gallery-thread/markdown-text.tsx +278 -0
- package/src/components/chat/gallery-thread/message-error.aui.tsx +105 -0
- package/src/components/chat/gallery-thread/message-timing.aui.tsx +143 -0
- package/src/components/chat/gallery-thread/private-work-step.tsx +188 -0
- package/src/components/chat/gallery-thread/reasoning.tsx +332 -0
- package/src/components/chat/gallery-thread/scroll-mode.ts +174 -0
- package/src/components/chat/gallery-thread/source.tsx +76 -0
- package/src/components/chat/gallery-thread/thread.aui.tsx +1619 -0
- package/src/components/chat/gallery-thread/tooltip-icon-button.tsx +53 -0
- package/src/components/chat/gallery-thread/typed-welcome-copy.tsx +18 -0
- package/src/components/chat/gallery-thread/ui/tooltip.tsx +22 -0
- package/src/components/chat/gallery-thread/work-chain-summary.tsx +48 -0
- package/src/components/chat/gallery-thread/work-chain.tsx +110 -0
- package/src/components/chat/gallery-thread/work-status.ts +66 -0
- package/src/components/chat/overlay-scrollbar.tsx +86 -0
- package/src/components/chat/sanitize-mermaid-svg.ts +38 -0
- package/src/components/chat/skins/SOURCE.md +36 -0
- package/src/components/chat/skins/base/attachment.aui.tsx +287 -0
- package/src/components/chat/skins/base/aui-default/README.md +45 -0
- package/src/components/chat/skins/base/aui-default/collapsible-root.tsx +19 -0
- package/src/components/chat/skins/base/aui-default/collapsible.tsx +21 -0
- package/src/components/chat/skins/base/aui-default/reasoning.aui.tsx +120 -0
- package/src/components/chat/skins/base/aui-default/reasoning.tsx +331 -0
- package/src/components/chat/skins/base/aui-default/surfaces.ts +7 -0
- package/src/components/chat/skins/base/aui-default/tool-fallback.aui.tsx +772 -0
- package/src/components/chat/skins/base/aui-default/tool-group.aui.tsx +241 -0
- package/src/components/chat/skins/base/docs-model-options.ts +6 -0
- package/src/components/chat/skins/base/elements/assistant-trace.aui.tsx +169 -0
- package/src/components/chat/skins/base/elements/composer-trigger-popover.aui.tsx +271 -0
- package/src/components/chat/skins/base/elements/directive-text.aui.tsx +29 -0
- package/src/components/chat/skins/base/elements/directive-text.tsx +76 -0
- package/src/components/chat/skins/base/elements/message-timing.aui.tsx +104 -0
- package/src/components/chat/skins/base/elements/model-selector.aui.tsx +140 -0
- package/src/components/chat/skins/base/elements/model-selector.tsx +720 -0
- package/src/components/chat/skins/base/elements/quote.aui.tsx +290 -0
- package/src/components/chat/skins/base/elements/work-chain.tsx +100 -0
- package/src/components/chat/skins/base/markdown-text.tsx +294 -0
- package/src/components/chat/skins/base/model.ts +1 -0
- package/src/components/chat/skins/base/thread.tsx +1050 -0
- package/src/components/chat/skins/base/tooltip-icon-button.tsx +56 -0
- package/src/components/chat/skins/base/ui/avatar.tsx +115 -0
- package/src/components/chat/skins/base/ui/badge.tsx +51 -0
- package/src/components/chat/skins/base/ui/button.tsx +67 -0
- package/src/components/chat/skins/base/ui/command.tsx +185 -0
- package/src/components/chat/skins/base/ui/dialog.tsx +168 -0
- package/src/components/chat/skins/base/ui/dot-matrix.tsx +267 -0
- package/src/components/chat/skins/base/ui/popover.tsx +97 -0
- package/src/components/chat/skins/base/ui/skeleton.tsx +20 -0
- package/src/components/chat/skins/base/ui/textarea.tsx +24 -0
- package/src/components/chat/skins/base/ui/tooltip.tsx +73 -0
- package/src/components/chat/skins/base-assistant-ui/config-provider.tsx +90 -0
- package/src/components/chat/skins/base-assistant-ui/defaults.ts +419 -0
- package/src/components/chat/skins/base-assistant-ui/index.tsx +44 -0
- package/src/components/chat/skins/chatgpt.tsx +448 -0
- package/src/components/chat/skins/claude.tsx +380 -0
- package/src/components/chat/skins/digichat-composer-toolbar.tsx +151 -0
- package/src/components/chat/skins/digichat-context-meter-shares.ts +158 -0
- package/src/components/chat/skins/digichat-context-meter.tsx +243 -0
- package/src/components/chat/skins/digichat-meter-tone.ts +26 -0
- package/src/components/chat/skins/digichat-usage-meter.tsx +103 -0
- package/src/components/chat/skins/digichat.tsx +144 -0
- package/src/components/chat/skins/expo-react-native.tsx +29 -0
- package/src/components/chat/skins/gemini.tsx +322 -0
- package/src/components/chat/skins/grok-icon.tsx +34 -0
- package/src/components/chat/skins/grok.tsx +369 -0
- package/src/components/chat/skins/index.ts +46 -0
- package/src/components/chat/skins/perplexity.tsx +462 -0
- package/src/components/chat/skins/product-page-assistant/assistant-modal.tsx +73 -0
- package/src/components/chat/skins/product-page-assistant/index.tsx +19 -0
- package/src/components/chat/skins/product-page-assistant/product-dashboard.tsx +164 -0
- package/src/components/chat/skins/react-ink.tsx +97 -0
- package/src/components/chat/skins/thread-skin-host-contract.ts +102 -0
- package/src/components/chat/skins/thread-skin-view.tsx +156 -0
- package/src/components/chat/skins/thread-skins.ts +143 -0
- package/src/components/chat/skins/tooltip-icon-button.tsx +35 -0
- package/src/components/chat/skins/ui/dropdown-menu.tsx +272 -0
- package/src/components/chat/skins/webpage-assistant/assistant-config.ts +238 -0
- package/src/components/chat/skins/webpage-assistant/assistant-modal.tsx +78 -0
- package/src/components/chat/skins/webpage-assistant/config-provider.tsx +132 -0
- package/src/components/chat/skins/webpage-assistant/docs-app.tsx +106 -0
- package/src/components/chat/skins/webpage-assistant/docs-article.tsx +109 -0
- package/src/components/chat/skins/webpage-assistant/docs-assistant.tsx +73 -0
- package/src/components/chat/skins/webpage-assistant/docs-nav.tsx +81 -0
- package/src/components/chat/skins/webpage-assistant/host-ui.ts +79 -0
- package/src/components/chat/skins/webpage-assistant/index.tsx +12 -0
- package/src/components/chat/skins/webpage-assistant/markdown-page.tsx +11 -0
- package/src/components/chat/skins/webpage-assistant/pages.ts +9 -0
- package/src/components/chat/skins/webpage-assistant/types.ts +178 -0
- package/src/components/chat/skins/webpage-assistant/use-mobile.ts +19 -0
- package/src/components/chat/stock/SOURCE.md +90 -0
- package/src/components/chat/stock/artifacts-panel.tsx +305 -0
- package/src/components/chat/stock/attachment.aui.tsx +280 -0
- package/src/components/chat/stock/chat-notice.tsx +143 -0
- package/src/components/chat/stock/chat-private-mode.tsx +64 -0
- package/src/components/chat/stock/deploy-ui-context.tsx +89 -0
- package/src/components/chat/stock/embed-chat-prefs.tsx +471 -0
- package/src/components/chat/stock/file.tsx +265 -0
- package/src/components/chat/stock/follow-up-suggestions.aui.tsx +83 -0
- package/src/components/chat/stock/image.tsx +531 -0
- package/src/components/chat/stock/index.ts +129 -0
- package/src/components/chat/stock/json-view.tsx +140 -0
- package/src/components/chat/stock/markdown-text.tsx +319 -0
- package/src/components/chat/stock/message-error.aui.tsx +96 -0
- package/src/components/chat/stock/message-export-menu.tsx +156 -0
- package/src/components/chat/stock/palette-row-preview.tsx +26 -0
- package/src/components/chat/stock/reasoning.aui.tsx +120 -0
- package/src/components/chat/stock/reasoning.tsx +335 -0
- package/src/components/chat/stock/skin-chrome.tsx +81 -0
- package/src/components/chat/stock/skin-credit.tsx +63 -0
- package/src/components/chat/stock/skin-palette-bridge.tsx +235 -0
- package/src/components/chat/stock/skin-palette-context.ts +16 -0
- package/src/components/chat/stock/skin-runtime.tsx +52 -0
- package/src/components/chat/stock/skin-slash-palette.tsx +393 -0
- package/src/components/chat/stock/skin-types.ts +217 -0
- package/src/components/chat/stock/stock-chat-prefs-host.tsx +501 -0
- package/src/components/chat/stock/stock-send-gate.tsx +94 -0
- package/src/components/chat/stock/stock-shape.tsx +39 -0
- package/src/components/chat/stock/thread.aui.tsx +645 -0
- package/src/components/chat/stock/tool-display.ts +6 -0
- package/src/components/chat/stock/tool-fallback.aui.tsx +866 -0
- package/src/components/chat/stock/tool-group.aui.tsx +244 -0
- package/src/components/chat/stock/tool-surface.ts +120 -0
- package/src/components/chat/stock/tooltip-icon-button.tsx +49 -0
- package/src/components/chat/stock/ui/avatar.tsx +108 -0
- package/src/components/chat/stock/ui/button.tsx +81 -0
- package/src/components/chat/stock/ui/collapsible.tsx +21 -0
- package/src/components/chat/stock/ui/dialog.tsx +163 -0
- package/src/components/chat/stock/ui/skeleton.tsx +13 -0
- package/src/components/chat/stock/ui/textarea.tsx +20 -0
- package/src/components/chat/stock/ui/tooltip.tsx +68 -0
- package/src/components/chat/stock/use-attachment-src.ts +42 -0
- package/src/components/chat/stock/use-copy-to-clipboard.ts +29 -0
- package/src/components/chat/strip-model-boilerplate.ts +42 -0
- package/src/components/chat/suggestion-cycle.tsx +230 -0
- package/src/components/chat/suggestion-scroll-row.tsx +81 -0
- package/src/components/chat/trace-grouping/chain-group-by.ts +44 -0
- package/src/components/chat/trace-grouping/chain-state.ts +141 -0
- package/src/components/chat/trace-grouping/index.ts +32 -0
- package/src/components/chat/trace-grouping/tool-row.ts +74 -0
- package/src/components/chat/trace-grouping/use-deploy-work-disclosure.ts +35 -0
- package/src/components/chat/trace-grouping/use-work-chain.ts +103 -0
- package/src/components/chat/trace-i18n/core.ts +48 -0
- package/src/components/chat/trace-i18n/index.tsx +23 -0
- package/src/components/chat/trace-i18n/locales/en.ts +24 -0
- package/src/components/chat/trace-i18n/locales/fr.ts +28 -0
- package/src/components/chat/trace-i18n/types.ts +35 -0
- package/src/components/chat/trace-spacing.ts +249 -0
- package/src/components/chat/transcript/activity-view.ts +375 -0
- package/src/components/chat/transcript/chat-export.ts +133 -0
- package/src/components/chat/transcript/index.ts +10 -0
- package/src/components/chat/transcript/save-file.ts +209 -0
- package/src/components/chat/transcript/transcript-markdown.ts +428 -0
- package/src/components/chat/transcript/types.ts +81 -0
- package/src/components/chat/turn-outcome.ts +52 -0
- package/src/components/chat/use-warmup-phase.ts +18 -0
- package/src/components/chat/work-status-lead.tsx +49 -0
- package/src/components/chrome.tsx +264 -0
- package/src/components/command-palette/CommandPalette.tsx +404 -0
- package/src/components/command-palette/index.ts +6 -0
- package/src/components/contact/ContactMailto.tsx +112 -0
- package/src/components/contact/index.ts +5 -0
- package/src/components/conviction/ConvictionMeter.tsx +40 -0
- package/src/components/conviction/SignedConvictionBadge.tsx +26 -0
- package/src/components/conviction/index.ts +7 -0
- package/src/components/data-layout/BentoGrid.tsx +52 -0
- package/src/components/data-layout/CardRail.tsx +150 -0
- package/src/components/data-layout/DotMatrixStat.tsx +65 -0
- package/src/components/data-layout/FeatureCell.tsx +80 -0
- package/src/components/data-layout/MediaFrame.tsx +125 -0
- package/src/components/data-layout/ModuleGrid.tsx +735 -0
- package/src/components/data-layout/Odometer.tsx +149 -0
- package/src/components/data-layout/ProductFrame.tsx +79 -0
- package/src/components/data-layout/TestimonialWall.tsx +139 -0
- package/src/components/data-layout/index.ts +19 -0
- package/src/components/data-layout/treemap.ts +368 -0
- package/src/components/deck/DeckStack.tsx +243 -0
- package/src/components/desk/DataTable.tsx +373 -0
- package/src/components/desk/KpiGrid.tsx +80 -0
- package/src/components/desk/Sparkline.tsx +63 -0
- package/src/components/desk/StateBlock.tsx +132 -0
- package/src/components/desk/index.ts +18 -0
- package/src/components/diagrams/ArchitectureDiagram.tsx +350 -0
- package/src/components/diagrams/ArchitectureTour.tsx +912 -0
- package/src/components/diagrams/TerminalSchematic.tsx +192 -0
- package/src/components/diagrams/architecture-svg.tsx +384 -0
- package/src/components/diagrams/index.ts +30 -0
- package/src/components/diagrams/mermaid-theme.ts +115 -0
- package/src/components/diagrams/tour-camera.ts +171 -0
- package/src/components/docs/CodeTabs.tsx +90 -0
- package/src/components/docs/CopyCommand.tsx +151 -0
- package/src/components/docs/DocsLayout.tsx +197 -0
- package/src/components/docs/DocsSearch.tsx +97 -0
- package/src/components/docs/Endpoint.tsx +135 -0
- package/src/components/document/DocumentFrame.tsx +43 -0
- package/src/components/document/GlyphList.tsx +51 -0
- package/src/components/document/PageTitle.tsx +44 -0
- package/src/components/document/Prose.tsx +38 -0
- package/src/components/document/Section.tsx +55 -0
- package/src/components/document/index.ts +13 -0
- package/src/components/effects-chrome/AnnouncementBar.tsx +88 -0
- package/src/components/effects-chrome/HorizontalScrollTrack.tsx +461 -0
- package/src/components/effects-chrome/Pipeline.tsx +226 -0
- package/src/components/effects-chrome/RotatingPrompts.tsx +116 -0
- package/src/components/effects-chrome/StackingPanels.tsx +101 -0
- package/src/components/effects-chrome/TabStrip.tsx +232 -0
- package/src/components/effects-chrome/ToastStack.tsx +201 -0
- package/src/components/effects-chrome/horizontal-track-core.ts +70 -0
- package/src/components/effects-chrome/index.ts +35 -0
- package/src/components/emblems.tsx +188 -0
- package/src/components/faviconTheme.ts +23 -0
- package/src/components/figure/Figure.tsx +38 -0
- package/src/components/figure/index.ts +2 -0
- package/src/components/finance-charts/DrawdownPlot.tsx +76 -0
- package/src/components/finance-charts/EquityCurve.tsx +71 -0
- package/src/components/finance-charts/PriceChart.tsx +119 -0
- package/src/components/finance-charts/chart-host.tsx +236 -0
- package/src/components/finance-charts/chart-scale.ts +93 -0
- package/src/components/finance-charts/demo-data.ts +88 -0
- package/src/components/finance-charts/index.ts +46 -0
- package/src/components/finance-charts/lw-chart.tsx +292 -0
- package/src/components/finance-composites/MarketBar.tsx +243 -0
- package/src/components/finance-composites/OrderBook.tsx +133 -0
- package/src/components/finance-composites/PerformanceDashboard.tsx +185 -0
- package/src/components/finance-composites/SortableTable.tsx +144 -0
- package/src/components/finance-composites/StockTicker.tsx +65 -0
- package/src/components/finance-composites/SyncedTearsheet.tsx +226 -0
- package/src/components/finance-composites/index.ts +28 -0
- package/src/components/finance-tearsheet/KpiStrip.tsx +49 -0
- package/src/components/finance-tearsheet/LiveBadge.tsx +29 -0
- package/src/components/finance-tearsheet/ReturnsMatrix.tsx +321 -0
- package/src/components/finance-tearsheet/StrategyTearsheet.tsx +99 -0
- package/src/components/finance-tearsheet/TearsheetCard.tsx +54 -0
- package/src/components/finance-tearsheet/TradeLogTable.tsx +73 -0
- package/src/components/finance-tearsheet/charts.tsx +2624 -0
- package/src/components/finance-tearsheet/demo-data.ts +177 -0
- package/src/components/finance-tearsheet/format.ts +41 -0
- package/src/components/finance-tearsheet/index.ts +120 -0
- package/src/components/finance-tearsheet/print.ts +52 -0
- package/src/components/finance-tearsheet/risk-bands.ts +48 -0
- package/src/components/finance-tearsheet/stats.ts +35 -0
- package/src/components/finance-tearsheet/strategy-sheet-model.ts +238 -0
- package/src/components/finance-tearsheet/types.ts +58 -0
- package/src/components/footer/FooterCells.tsx +109 -0
- package/src/components/footer/index.ts +6 -0
- package/src/components/graph.tsx +158 -0
- package/src/components/icons.tsx +98 -0
- package/src/components/landing/PixelWordmark.tsx +36 -0
- package/src/components/logos.ts +39 -0
- package/src/components/marquee/Marquee.tsx +204 -0
- package/src/components/metrics/PerfMetrics.tsx +68 -0
- package/src/components/metrics/StatCounter.tsx +104 -0
- package/src/components/page-geometry.tsx +177 -0
- package/src/components/pricing/Pricing.tsx +174 -0
- package/src/components/pricing/PricingMatrix.tsx +219 -0
- package/src/components/prose/index.ts +2 -0
- package/src/components/prose/prose.tsx +86 -0
- package/src/components/repo-activity/RepoActivity.tsx +599 -0
- package/src/components/repo-activity/RepoHeatmap.tsx +225 -0
- package/src/components/repo-activity/demo.ts +201 -0
- package/src/components/repo-activity/fetch.ts +211 -0
- package/src/components/repo-activity/heatmap.ts +123 -0
- package/src/components/repo-activity/index.ts +28 -0
- package/src/components/repo-activity/types.ts +99 -0
- package/src/components/stages/NumberedStages.tsx +116 -0
- package/src/components/symbols/marks.tsx +116 -0
- package/src/components/symbols/terminal-lockup.tsx +136 -0
- package/src/components/symbols/terminal-marks.tsx +226 -0
- package/src/components/terminal/ChatResponseLoader.tsx +67 -0
- package/src/components/terminal/ContainerBootLoader.tsx +82 -0
- package/src/components/terminal/TerminalStepCaret.tsx +202 -0
- package/src/components/themeInit.ts +24 -0
- package/src/components/typography/MotionReveal.tsx +108 -0
- package/src/components/typography/TypewriterReveal.tsx +101 -0
- package/src/components/typography/WordReveal.tsx +143 -0
- package/src/data/modules.ts +378 -0
- package/src/data/subsystems.ts +101 -0
- package/src/index.ts +587 -0
- package/src/lib/base-path.ts +60 -0
- package/src/lib/cx.ts +25 -0
- package/src/lib/gloomberb.ts +69 -0
- package/src/lib/record.ts +19 -0
- package/src/lib/stub-payload.ts +183 -0
- package/src/lib/useBodyScrollLock.ts +44 -0
- package/src/lib/utils.ts +6 -0
- package/src/motion/primitives.tsx +105 -0
- package/src/motion/scroll-glide.ts +62 -0
- package/src/motion/scrolly-core.ts +38 -0
- package/src/motion/scrolly.tsx +95 -0
- package/src/navigation/HashScrollManager.tsx +167 -0
- package/src/navigation/hashScroll.ts +78 -0
- package/src/replay/browser.ts +280 -0
- package/src/replay/chat-export-run.ts +121 -0
- package/src/replay/export-format.ts +25 -0
- package/src/replay/export-mount.ts +32 -0
- package/src/replay/filename.ts +54 -0
- package/src/replay/index.ts +21 -0
- package/src/replay/redact-dom.ts +178 -0
- package/src/replay/redact.ts +113 -0
- package/src/replay/snapshot.ts +659 -0
- package/src/styles/account-auth.css +339 -0
- package/src/styles/brand-wordmark.css +11 -0
- package/src/styles/card-rail.css +120 -0
- package/src/styles/chat-aui.css +1143 -0
- package/src/styles/chat-core.css +469 -0
- package/src/styles/chat-digichat.css +2531 -0
- package/src/styles/chat-math.css +70 -0
- package/src/styles/chat-skin-palette.css +138 -0
- package/src/styles/chat-stock-menu.css +37 -0
- package/src/styles/chat-widgets.css +190 -0
- package/src/styles/command-palette.css +372 -0
- package/src/styles/controls-core.css +2261 -0
- package/src/styles/controls-overlay.css +603 -0
- package/src/styles/data-layout.css +288 -0
- package/src/styles/deck.css +141 -0
- package/src/styles/diagrams.css +1860 -0
- package/src/styles/digichat-app-theme.css +250 -0
- package/src/styles/digichat-boot-loader.css +487 -0
- package/src/styles/digichat-launcher.css +377 -0
- package/src/styles/docs.css +165 -0
- package/src/styles/effects-chrome.css +888 -0
- package/src/styles/finance-composites.css +214 -0
- package/src/styles/finance-tearsheet-overlay.css +90 -0
- package/src/styles/finance-tearsheet.css +945 -0
- package/src/styles/marquee.css +168 -0
- package/src/styles/metrics.css +82 -0
- package/src/styles/nav-shell.css +551 -0
- package/src/styles/pricing.css +79 -0
- package/src/styles/repo-activity.css +575 -0
- package/src/styles/stages.css +69 -0
- package/src/styles/terminal-loaders.css +122 -0
- package/src/styles/terminal-manifest.css +228 -0
- package/src/styles/web-theme.css +1007 -0
- package/src/styles/word-reveal.css +204 -0
- package/src/theme/apply-theme.ts +214 -0
- package/src/theme/index.ts +27 -0
- package/src/theme/palette-registry.ts +855 -0
- package/src/theme/tui-prefs.ts +64 -0
- package/src/ui/alert.tsx +78 -0
- package/src/ui/avatar.tsx +104 -0
- package/src/ui/badge.tsx +75 -0
- package/src/ui/breadcrumb.tsx +61 -0
- package/src/ui/button.tsx +67 -0
- package/src/ui/card.tsx +139 -0
- package/src/ui/checkbox.tsx +27 -0
- package/src/ui/collapsible.tsx +32 -0
- package/src/ui/date-pager.tsx +325 -0
- package/src/ui/dialog.tsx +157 -0
- package/src/ui/dropdown-menu.tsx +267 -0
- package/src/ui/empty-state.tsx +165 -0
- package/src/ui/field.tsx +104 -0
- package/src/ui/form.tsx +36 -0
- package/src/ui/icon-button.tsx +36 -0
- package/src/ui/index.ts +34 -0
- package/src/ui/input.tsx +33 -0
- package/src/ui/kbd.tsx +30 -0
- package/src/ui/label.tsx +32 -0
- package/src/ui/pager.tsx +119 -0
- package/src/ui/pagination.tsx +126 -0
- package/src/ui/radio-group.tsx +51 -0
- package/src/ui/search-bar.tsx +85 -0
- package/src/ui/segmented-control.tsx +76 -0
- package/src/ui/select.tsx +257 -0
- package/src/ui/separator.tsx +24 -0
- package/src/ui/sheet.tsx +141 -0
- package/src/ui/skeleton.tsx +76 -0
- package/src/ui/slider.tsx +76 -0
- package/src/ui/switch.tsx +31 -0
- package/src/ui/table.tsx +179 -0
- package/src/ui/tabs.tsx +89 -0
- package/src/ui/tags-input.tsx +168 -0
- package/src/ui/textarea.tsx +17 -0
- package/src/ui/tooltip.tsx +71 -0
package/src/ui/kbd.tsx
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Kbd — the keycap chip. Promoted from the old reference gallery's global
|
|
6
|
+
* `.kbd`, which was reference-only: an app that wanted a keycap had no
|
|
7
|
+
* canonical part to reach for and would have tripped the family census.
|
|
8
|
+
*
|
|
9
|
+
* The keycap look: hairline box, a heavier bottom border so it reads as a
|
|
10
|
+
* physical key, the ink-wash fill, mono at the micro size. Token utilities
|
|
11
|
+
* only — no app-local class family. Renders a real `<kbd>`, so the phase-id /
|
|
12
|
+
* shortcut chips it dresses keep their semantic.
|
|
13
|
+
*/
|
|
14
|
+
export type KbdProps = HTMLAttributes<HTMLElement>
|
|
15
|
+
|
|
16
|
+
function Kbd({ className, children, ...props }: KbdProps) {
|
|
17
|
+
return (
|
|
18
|
+
<kbd
|
|
19
|
+
className={cn(
|
|
20
|
+
"inline-flex h-[1.15rem] min-w-[1.15rem] items-center justify-center rounded-none border border-hair border-b-2 bg-ink/5 px-[0.3rem] align-middle font-mono text-[0.62rem] leading-none text-ink-soft",
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
>
|
|
25
|
+
{children}
|
|
26
|
+
</kbd>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { Kbd }
|
package/src/ui/label.tsx
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "../lib/utils"
|
|
5
|
+
|
|
6
|
+
export type LabelDress = "default" | "chat";
|
|
7
|
+
|
|
8
|
+
function Label({
|
|
9
|
+
className,
|
|
10
|
+
dress = "default",
|
|
11
|
+
...props
|
|
12
|
+
}: React.ComponentProps<"label"> & { dress?: LabelDress }) {
|
|
13
|
+
// dress="chat" emits the digichat chat-dress class (styles/controls-core.css)
|
|
14
|
+
// instead of the kit utilities, keeping digichat's rendered look exact.
|
|
15
|
+
const classes =
|
|
16
|
+
dress === "chat"
|
|
17
|
+
? cn("ctl-label-chat", className)
|
|
18
|
+
: cn(
|
|
19
|
+
"flex items-center gap-2 text-xs leading-none select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
20
|
+
className
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<label
|
|
25
|
+
data-slot="label"
|
|
26
|
+
className={classes}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { Label }
|
package/src/ui/pager.tsx
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pager — the prev/next wayfinding control with a fixed middle slot
|
|
5
|
+
* (`PagerPage` cells, a page count, a date), promoted from the controls layer
|
|
6
|
+
* into the kit (#4306, batch K3). Disabled edges around a middle column that
|
|
7
|
+
* stays put while its label width changes. Two dresses: "reference" (default,
|
|
8
|
+
* per-cell hairline) and "capsule" (dashboard's shipped one-capsule look —
|
|
9
|
+
* borderless chevrons pinned at the ends). The `.nb-pager*` / `.nb-page*`
|
|
10
|
+
* dress is translated into token utilities here, so the controls CSS can
|
|
11
|
+
* retire. This is distinct from {@link Pagination}, the numbered page trail.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { ComponentPropsWithoutRef, HTMLAttributes, ReactNode } from "react"
|
|
15
|
+
|
|
16
|
+
import { cn } from "../lib/utils"
|
|
17
|
+
|
|
18
|
+
const BASE_ITEM =
|
|
19
|
+
"min-w-[2rem] h-[2rem] px-[0.6rem] border border-hair bg-surface font-mono text-[0.72rem] text-ink-soft transition-colors"
|
|
20
|
+
|
|
21
|
+
const BASE_EDGE = cn(
|
|
22
|
+
BASE_ITEM,
|
|
23
|
+
"cursor-pointer enabled:hover:text-ink enabled:hover:border-[color-mix(in_srgb,var(--accent)_45%,var(--hair))] disabled:cursor-not-allowed disabled:opacity-40",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
const CAPSULE_EDGE =
|
|
27
|
+
"min-w-0 cursor-pointer border-0 bg-transparent p-0 text-ink-mute transition-colors duration-150 enabled:hover:text-ink disabled:cursor-not-allowed disabled:opacity-30"
|
|
28
|
+
|
|
29
|
+
export type PagerProps = HTMLAttributes<HTMLDivElement> & {
|
|
30
|
+
onPrev?: () => void
|
|
31
|
+
onNext?: () => void
|
|
32
|
+
prevDisabled?: boolean
|
|
33
|
+
nextDisabled?: boolean
|
|
34
|
+
prevLabel?: ReactNode
|
|
35
|
+
nextLabel?: ReactNode
|
|
36
|
+
/** Set these when the edge labels are bare glyphs (chevrons). */
|
|
37
|
+
prevAriaLabel?: string
|
|
38
|
+
nextAriaLabel?: string
|
|
39
|
+
/** Middle slot — PagerPage cells, or any label (a date, "3 / 12", …). */
|
|
40
|
+
children?: ReactNode
|
|
41
|
+
/** Visual dress — "reference" (default) or dashboard's "capsule". */
|
|
42
|
+
dress?: "reference" | "capsule"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function Pager({
|
|
46
|
+
onPrev,
|
|
47
|
+
onNext,
|
|
48
|
+
prevDisabled,
|
|
49
|
+
nextDisabled,
|
|
50
|
+
prevLabel = "‹ prev",
|
|
51
|
+
nextLabel = "next ›",
|
|
52
|
+
prevAriaLabel,
|
|
53
|
+
nextAriaLabel,
|
|
54
|
+
children,
|
|
55
|
+
className,
|
|
56
|
+
dress = "reference",
|
|
57
|
+
...props
|
|
58
|
+
}: PagerProps) {
|
|
59
|
+
const edge = dress === "capsule" ? CAPSULE_EDGE : BASE_EDGE
|
|
60
|
+
return (
|
|
61
|
+
<div
|
|
62
|
+
data-slot="pager"
|
|
63
|
+
data-dress={dress}
|
|
64
|
+
className={cn(
|
|
65
|
+
"inline-grid grid-cols-[auto_minmax(0,max-content)_auto] items-center gap-[0.3rem]",
|
|
66
|
+
dress === "capsule" &&
|
|
67
|
+
"grid-cols-[auto_1fr_auto] gap-[0.5rem] border border-hair bg-term-bg px-[0.625rem] py-[0.375rem] font-mono text-[12.5px] tabular-nums",
|
|
68
|
+
className,
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
>
|
|
72
|
+
<button
|
|
73
|
+
type="button"
|
|
74
|
+
className={edge}
|
|
75
|
+
disabled={prevDisabled}
|
|
76
|
+
aria-label={prevAriaLabel}
|
|
77
|
+
onClick={onPrev}
|
|
78
|
+
>
|
|
79
|
+
{prevLabel}
|
|
80
|
+
</button>
|
|
81
|
+
{/* Fixed middle column so capsule arrows stay pinned at the ends while
|
|
82
|
+
the label width varies (date strings, page counts, …). */}
|
|
83
|
+
<div className="flex min-w-0 items-center justify-center">{children}</div>
|
|
84
|
+
<button
|
|
85
|
+
type="button"
|
|
86
|
+
className={edge}
|
|
87
|
+
disabled={nextDisabled}
|
|
88
|
+
aria-label={nextAriaLabel}
|
|
89
|
+
onClick={onNext}
|
|
90
|
+
>
|
|
91
|
+
{nextLabel}
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type PagerPageProps = ComponentPropsWithoutRef<"button"> & {
|
|
98
|
+
/** The current page — wears the accent fill and aria-current="page". */
|
|
99
|
+
current?: boolean
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function PagerPage({ current, className, ...props }: PagerPageProps) {
|
|
103
|
+
return (
|
|
104
|
+
<button
|
|
105
|
+
type="button"
|
|
106
|
+
data-slot="pager-page"
|
|
107
|
+
aria-current={current ? "page" : undefined}
|
|
108
|
+
className={cn(
|
|
109
|
+
BASE_ITEM,
|
|
110
|
+
"cursor-pointer",
|
|
111
|
+
current
|
|
112
|
+
? "text-on-accent bg-accent border-accent"
|
|
113
|
+
: "hover:text-ink hover:border-[color-mix(in_srgb,var(--accent)_45%,var(--hair))]",
|
|
114
|
+
className,
|
|
115
|
+
)}
|
|
116
|
+
{...props}
|
|
117
|
+
/>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pagination — the numbered page trail (`nav[aria-label]`), promoted from the
|
|
3
|
+
* controls layer into the kit (#4306, batch K2). Controlled: `page` (1-based)
|
|
4
|
+
* + `pageCount`, with either `hrefForPage` (links) or `onPageChange` (buttons).
|
|
5
|
+
* The window shows first / last with an ellipsis around the current page;
|
|
6
|
+
* prev/next disable at the edges. The current page is the one loud control
|
|
7
|
+
* (ink fill); siblings are hairline ghosts.
|
|
8
|
+
*
|
|
9
|
+
* The `.ctl-pagination*` dress is translated into token utilities here, so the
|
|
10
|
+
* controls CSS can retire. Direction glyphs mirror under RTL via `rtl:`.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { cn } from "../lib/utils"
|
|
14
|
+
|
|
15
|
+
export type PaginationProps = {
|
|
16
|
+
page: number
|
|
17
|
+
pageCount: number
|
|
18
|
+
onPageChange?: (page: number) => void
|
|
19
|
+
hrefForPage?: (page: number) => string
|
|
20
|
+
ariaLabel?: string
|
|
21
|
+
className?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 1-based page window: first, last, and ±1 around current, ellipsis-filled. */
|
|
25
|
+
export function paginationWindow(page: number, pageCount: number): (number | "…")[] {
|
|
26
|
+
const pages = new Set<number>([1, pageCount, page - 1, page, page + 1])
|
|
27
|
+
const sorted = [...pages].filter((p) => p >= 1 && p <= pageCount).sort((a, b) => a - b)
|
|
28
|
+
const out: (number | "…")[] = []
|
|
29
|
+
for (const p of sorted) {
|
|
30
|
+
if (out.length > 0 && p - (out[out.length - 1] as number) > 1) out.push("…")
|
|
31
|
+
out.push(p)
|
|
32
|
+
}
|
|
33
|
+
return out
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const ITEM =
|
|
37
|
+
"inline-flex h-[2rem] min-w-[2rem] items-center justify-center border border-hair bg-transparent px-[0.5rem] text-ink-soft no-underline transition-colors [font:inherit] hover:border-hair-2 hover:text-ink focus-visible:border-hair-2 focus-visible:ring-[3px] focus-visible:ring-accent/30 focus-visible:outline-none"
|
|
38
|
+
|
|
39
|
+
export function Pagination({
|
|
40
|
+
page,
|
|
41
|
+
pageCount,
|
|
42
|
+
onPageChange,
|
|
43
|
+
hrefForPage,
|
|
44
|
+
ariaLabel = "Pagination",
|
|
45
|
+
className,
|
|
46
|
+
}: PaginationProps) {
|
|
47
|
+
if (pageCount < 1) return null
|
|
48
|
+
const current = Math.max(1, Math.min(pageCount, Math.floor(page)))
|
|
49
|
+
const go = (p: number) => onPageChange?.(Math.max(1, Math.min(pageCount, p)))
|
|
50
|
+
|
|
51
|
+
const item = (p: number) => {
|
|
52
|
+
const isCurrent = p === current
|
|
53
|
+
const cls = cn(ITEM, isCurrent && "cursor-default border-ink bg-ink font-semibold text-bg")
|
|
54
|
+
const inner = String(p)
|
|
55
|
+
if (isCurrent) {
|
|
56
|
+
return (
|
|
57
|
+
<span key={p} aria-current="page" className={cls}>
|
|
58
|
+
{inner}
|
|
59
|
+
</span>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
if (hrefForPage) {
|
|
63
|
+
return (
|
|
64
|
+
<a key={p} href={hrefForPage(p)} className={cn(ITEM, "cursor-pointer")}>
|
|
65
|
+
{inner}
|
|
66
|
+
</a>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
return (
|
|
70
|
+
<button key={p} type="button" className={cn(ITEM, "cursor-pointer")} onClick={() => go(p)}>
|
|
71
|
+
{inner}
|
|
72
|
+
</button>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const step = (dir: -1 | 1) => {
|
|
77
|
+
const target = current + dir
|
|
78
|
+
const disabled = dir === -1 ? current <= 1 : current >= pageCount
|
|
79
|
+
const label = dir === -1 ? "Previous page" : "Next page"
|
|
80
|
+
const glyph = dir === -1 ? "←" : "→"
|
|
81
|
+
const cls = cn(ITEM, "cursor-pointer disabled:cursor-not-allowed disabled:opacity-40")
|
|
82
|
+
if (hrefForPage && !disabled) {
|
|
83
|
+
return (
|
|
84
|
+
<a key={dir} href={hrefForPage(target)} aria-label={label} className={cls}>
|
|
85
|
+
<span aria-hidden="true" className="inline-block rtl:scale-x-[-1]">
|
|
86
|
+
{glyph}
|
|
87
|
+
</span>
|
|
88
|
+
</a>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
return (
|
|
92
|
+
<button
|
|
93
|
+
key={dir}
|
|
94
|
+
type="button"
|
|
95
|
+
aria-label={label}
|
|
96
|
+
className={cls}
|
|
97
|
+
disabled={disabled}
|
|
98
|
+
onClick={() => go(target)}
|
|
99
|
+
>
|
|
100
|
+
<span aria-hidden="true" className="inline-block rtl:scale-x-[-1]">
|
|
101
|
+
{glyph}
|
|
102
|
+
</span>
|
|
103
|
+
</button>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<nav
|
|
109
|
+
aria-label={ariaLabel}
|
|
110
|
+
data-slot="pagination"
|
|
111
|
+
className={cn("flex items-center gap-[0.4rem] font-mono text-[0.8rem]", className)}
|
|
112
|
+
>
|
|
113
|
+
{step(-1)}
|
|
114
|
+
{paginationWindow(current, pageCount).map((p, i) =>
|
|
115
|
+
p === "…" ? (
|
|
116
|
+
<span key={`gap-${i}`} aria-hidden="true" className="px-[0.1rem] text-ink-mute">
|
|
117
|
+
…
|
|
118
|
+
</span>
|
|
119
|
+
) : (
|
|
120
|
+
item(p)
|
|
121
|
+
),
|
|
122
|
+
)}
|
|
123
|
+
{step(1)}
|
|
124
|
+
</nav>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RadioGroup / Radio — the shared selection control (#1548), promoted from the
|
|
5
|
+
* controls layer into the kit (#4306, batch K1). Behavior comes from
|
|
6
|
+
* `@base-ui/react`'s Radio / RadioGroup primitives (roving focus, keyboard
|
|
7
|
+
* toggle, `data-checked` / `data-disabled` state); this file skins them to the
|
|
8
|
+
* form-fields grammar — a 16px circle, hairline, accent dot, accent focus ring
|
|
9
|
+
* — re-expressed in kit token utilities so `.ctl-radio*` can retire.
|
|
10
|
+
*
|
|
11
|
+
* Pair with a plain `<label>` (wrapping or `htmlFor`) — the control owns no
|
|
12
|
+
* label of its own, same as the native inputs it replaces. `Checkbox` and
|
|
13
|
+
* `Switch` remain on the controls layer for now; the kit already owns both, so
|
|
14
|
+
* they have no live main-barrel consumer to repoint.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { Radio as RadioPrimitive } from "@base-ui/react/radio"
|
|
18
|
+
import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group"
|
|
19
|
+
|
|
20
|
+
import { cn } from "../lib/utils"
|
|
21
|
+
|
|
22
|
+
export type RadioGroupProps = RadioGroupPrimitive.Props
|
|
23
|
+
export type RadioProps = RadioPrimitive.Root.Props
|
|
24
|
+
|
|
25
|
+
export function RadioGroup({ className, ...props }: RadioGroupProps) {
|
|
26
|
+
return (
|
|
27
|
+
<RadioGroupPrimitive
|
|
28
|
+
data-slot="radio-group"
|
|
29
|
+
className={cn("flex flex-col gap-2", className)}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function Radio({ className, ...props }: RadioProps) {
|
|
36
|
+
return (
|
|
37
|
+
<RadioPrimitive.Root
|
|
38
|
+
data-slot="radio"
|
|
39
|
+
className={cn(
|
|
40
|
+
"relative inline-flex size-4 shrink-0 cursor-pointer appearance-none items-center justify-center rounded-full border border-hair bg-surface p-0 transition-colors outline-none after:absolute after:-inset-3 focus-visible:ring-[3px] focus-visible:ring-ring/30 data-checked:border-accent data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
41
|
+
className,
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
<RadioPrimitive.Indicator
|
|
46
|
+
data-slot="radio-indicator"
|
|
47
|
+
className="absolute inset-[3px] rounded-full bg-accent"
|
|
48
|
+
/>
|
|
49
|
+
</RadioPrimitive.Root>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
/**
|
|
3
|
+
* SearchBar — a search field with a leading glyph, a clear affordance that
|
|
4
|
+
* appears once there's input, and an optional trailing `hint` slot shown
|
|
5
|
+
* while empty (the reference wears a `/` keycap), promoted from the controls
|
|
6
|
+
* layer into the kit (#4306, batch K2). Controlled — the results pane stays
|
|
7
|
+
* with the caller; the bar only owns the query.
|
|
8
|
+
*
|
|
9
|
+
* The `.ctl-search` / `.sb-*` dress is translated into token utilities here;
|
|
10
|
+
* focus-within lights the accent ring, and the native WebKit search-cancel
|
|
11
|
+
* affordance is suppressed in favour of the clear button.
|
|
12
|
+
*/
|
|
13
|
+
import type { InputHTMLAttributes, ReactNode } from "react"
|
|
14
|
+
|
|
15
|
+
import { cn } from "../lib/utils"
|
|
16
|
+
|
|
17
|
+
export type SearchBarProps = Omit<
|
|
18
|
+
InputHTMLAttributes<HTMLInputElement>,
|
|
19
|
+
"value" | "onChange" | "type" | "className"
|
|
20
|
+
> & {
|
|
21
|
+
value: string
|
|
22
|
+
onChange: (query: string) => void
|
|
23
|
+
/** Clears the query — defaults to onChange(""). */
|
|
24
|
+
onClear?: () => void
|
|
25
|
+
clearAriaLabel?: string
|
|
26
|
+
/** Trailing slot shown while the query is empty (keycap hint etc.). */
|
|
27
|
+
hint?: ReactNode
|
|
28
|
+
/** Replaces the leading magnifier glyph. */
|
|
29
|
+
glyph?: ReactNode
|
|
30
|
+
/** Lands on the field wrapper, not the input. */
|
|
31
|
+
className?: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const MAGNIFIER = (
|
|
35
|
+
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6">
|
|
36
|
+
<circle cx="11" cy="11" r="7" />
|
|
37
|
+
<path d="M20 20l-3.5-3.5" strokeLinecap="round" />
|
|
38
|
+
</svg>
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
export function SearchBar({
|
|
42
|
+
value,
|
|
43
|
+
onChange,
|
|
44
|
+
onClear,
|
|
45
|
+
clearAriaLabel = "Clear search",
|
|
46
|
+
hint,
|
|
47
|
+
glyph,
|
|
48
|
+
className,
|
|
49
|
+
"aria-label": ariaLabel = "Search",
|
|
50
|
+
...inputProps
|
|
51
|
+
}: SearchBarProps) {
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
data-slot="search-bar"
|
|
55
|
+
className={cn(
|
|
56
|
+
"flex w-[min(100%,26rem)] items-center gap-[0.55rem] border border-hair bg-surface px-[0.7rem] py-[0.55rem] transition-[border-color,box-shadow] duration-200 focus-within:border-[color-mix(in_srgb,var(--accent)_55%,var(--hair))] focus-within:shadow-[0_0_0_3px_color-mix(in_srgb,var(--accent)_22%,transparent)]",
|
|
57
|
+
className,
|
|
58
|
+
)}
|
|
59
|
+
>
|
|
60
|
+
<span className="inline-flex text-ink-mute" aria-hidden="true">
|
|
61
|
+
{glyph ?? MAGNIFIER}
|
|
62
|
+
</span>
|
|
63
|
+
<input
|
|
64
|
+
className="flex-1 border-none bg-transparent font-mono text-[0.82rem] text-ink outline-none placeholder:text-ink-mute [&::-webkit-search-cancel-button]:hidden"
|
|
65
|
+
type="search"
|
|
66
|
+
value={value}
|
|
67
|
+
aria-label={ariaLabel}
|
|
68
|
+
onChange={(e) => onChange(e.target.value)}
|
|
69
|
+
{...inputProps}
|
|
70
|
+
/>
|
|
71
|
+
{value ? (
|
|
72
|
+
<button
|
|
73
|
+
type="button"
|
|
74
|
+
className="cursor-pointer border-none bg-transparent px-[0.2rem] py-[0.1rem] text-[0.7rem] text-ink-mute transition-colors hover:text-ink"
|
|
75
|
+
aria-label={clearAriaLabel}
|
|
76
|
+
onClick={onClear ?? (() => onChange(""))}
|
|
77
|
+
>
|
|
78
|
+
✕
|
|
79
|
+
</button>
|
|
80
|
+
) : (
|
|
81
|
+
(hint ?? null)
|
|
82
|
+
)}
|
|
83
|
+
</div>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SegmentedControl — the range switch (#1548), promoted from the controls
|
|
5
|
+
* layer into the kit (#4306, batch K1). Plain buttons wearing `aria-pressed`
|
|
6
|
+
* inside a `role="group"` — deliberately NOT a tablist (the segments switch a
|
|
7
|
+
* data range on the same view, they don't own tab panels). Two dresses:
|
|
8
|
+
* "reference" (default, mono cells on surface / accent-weak selection) and
|
|
9
|
+
* "accent" (dashboard's shipped look — sans font-medium cells, transparent
|
|
10
|
+
* track, accent/20 wash + accent text on the selection). Token utilities only,
|
|
11
|
+
* so `.nb-seg*` can retire.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { HTMLAttributes, ReactNode } from "react"
|
|
15
|
+
|
|
16
|
+
import { cn } from "../lib/utils"
|
|
17
|
+
|
|
18
|
+
export type SegmentedOption<T extends string = string> = {
|
|
19
|
+
value: T
|
|
20
|
+
/** Defaults to the value itself. */
|
|
21
|
+
label?: ReactNode
|
|
22
|
+
disabled?: boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type SegmentedControlProps<T extends string = string> = Omit<
|
|
26
|
+
HTMLAttributes<HTMLDivElement>,
|
|
27
|
+
"onChange"
|
|
28
|
+
> & {
|
|
29
|
+
options: ReadonlyArray<T | SegmentedOption<T>>
|
|
30
|
+
value: T
|
|
31
|
+
onChange?: (value: T) => void
|
|
32
|
+
/** Visual dress — "reference" (default) or dashboard's "accent". */
|
|
33
|
+
dress?: "reference" | "accent"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function SegmentedControl<T extends string = string>({
|
|
37
|
+
options,
|
|
38
|
+
value,
|
|
39
|
+
onChange,
|
|
40
|
+
className,
|
|
41
|
+
dress = "reference",
|
|
42
|
+
...props
|
|
43
|
+
}: SegmentedControlProps<T>) {
|
|
44
|
+
const accent = dress === "accent"
|
|
45
|
+
return (
|
|
46
|
+
<div
|
|
47
|
+
data-slot="segmented"
|
|
48
|
+
role="group"
|
|
49
|
+
className={cn(
|
|
50
|
+
"inline-flex overflow-hidden rounded-none border border-hair",
|
|
51
|
+
className,
|
|
52
|
+
)}
|
|
53
|
+
{...props}
|
|
54
|
+
>
|
|
55
|
+
{options.map((option) => {
|
|
56
|
+
const opt = typeof option === "string" ? { value: option } : option
|
|
57
|
+
return (
|
|
58
|
+
<button
|
|
59
|
+
key={opt.value}
|
|
60
|
+
type="button"
|
|
61
|
+
className={cn(
|
|
62
|
+
"inline-flex cursor-pointer items-center justify-center rounded-none bg-surface px-[0.85rem] py-[0.4rem] font-mono text-[0.72rem] text-ink-mute transition-colors [border-inline-start:1px_solid_var(--hair)] first:[border-inline-start:0] hover:text-ink-soft aria-pressed:bg-accent-weak aria-pressed:text-ink disabled:cursor-not-allowed",
|
|
63
|
+
accent &&
|
|
64
|
+
"bg-transparent px-3 py-[0.375rem] font-sans text-xs font-medium text-ink-mute hover:bg-ink/4 hover:text-ink aria-pressed:bg-accent/20 aria-pressed:text-accent",
|
|
65
|
+
)}
|
|
66
|
+
aria-pressed={opt.value === value}
|
|
67
|
+
disabled={opt.disabled}
|
|
68
|
+
onClick={() => onChange?.(opt.value)}
|
|
69
|
+
>
|
|
70
|
+
{opt.label ?? opt.value}
|
|
71
|
+
</button>
|
|
72
|
+
)
|
|
73
|
+
})}
|
|
74
|
+
</div>
|
|
75
|
+
)
|
|
76
|
+
}
|