@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
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SocialRow — a quiet utility row of company-profile icon buttons.
|
|
3
|
+
* Same borderless `.btn-icon` grammar as the NavShell GitHub slot: radius 0,
|
|
4
|
+
* no fill, ink-mute → ink, phosphor (`--accent`) only on :focus-visible.
|
|
5
|
+
* Not a marketing share bar. The primitive carries no Discord (that network
|
|
6
|
+
* does not exist for the company); default `DIGITHINGS_SOCIALS` is the live
|
|
7
|
+
* GitHub / X / LinkedIn set. Pass `profiles` to retarget; the row never
|
|
8
|
+
* invents networks.
|
|
9
|
+
*
|
|
10
|
+
* Dress lives in styles/nav-shell.css (already imported wherever NavShell
|
|
11
|
+
* is), so a contact band or footer can reuse the buttons without a second
|
|
12
|
+
* sheet.
|
|
13
|
+
*/
|
|
14
|
+
import type { ReactNode } from "react";
|
|
15
|
+
|
|
16
|
+
import { GitHubGlyph, LinkedInGlyph, XGlyph } from "./icons";
|
|
17
|
+
|
|
18
|
+
export type SocialNetwork = "github" | "x" | "linkedin";
|
|
19
|
+
|
|
20
|
+
export type SocialProfile = {
|
|
21
|
+
network: SocialNetwork;
|
|
22
|
+
href: string;
|
|
23
|
+
label: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Live company profiles only. Do not add networks we do not run. */
|
|
27
|
+
export const DIGITHINGS_SOCIALS: readonly SocialProfile[] = [
|
|
28
|
+
{
|
|
29
|
+
network: "github",
|
|
30
|
+
href: "https://github.com/digithings-ai/digithings",
|
|
31
|
+
label: "digithings on GitHub",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
network: "x",
|
|
35
|
+
href: "https://x.com/digithingsai",
|
|
36
|
+
label: "digithings on X",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
network: "linkedin",
|
|
40
|
+
href: "https://www.linkedin.com/company/digithingsai/",
|
|
41
|
+
label: "digithings on LinkedIn",
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
export type SocialRowProps = {
|
|
46
|
+
profiles?: readonly SocialProfile[];
|
|
47
|
+
"aria-label"?: string;
|
|
48
|
+
className?: string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function SocialGlyph({ network }: { network: SocialNetwork }): ReactNode {
|
|
52
|
+
switch (network) {
|
|
53
|
+
case "github":
|
|
54
|
+
return <GitHubGlyph />;
|
|
55
|
+
case "x":
|
|
56
|
+
return <XGlyph />;
|
|
57
|
+
case "linkedin":
|
|
58
|
+
return <LinkedInGlyph />;
|
|
59
|
+
default: {
|
|
60
|
+
const _exhaustive: never = network;
|
|
61
|
+
return _exhaustive;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function SocialRow({
|
|
67
|
+
profiles = DIGITHINGS_SOCIALS,
|
|
68
|
+
"aria-label": ariaLabel = "Company profiles",
|
|
69
|
+
className,
|
|
70
|
+
}: SocialRowProps) {
|
|
71
|
+
return (
|
|
72
|
+
<nav className={className ? `social-row ${className}` : "social-row"} aria-label={ariaLabel}>
|
|
73
|
+
{profiles.map((profile) => (
|
|
74
|
+
<a
|
|
75
|
+
key={profile.network}
|
|
76
|
+
className="btn-icon"
|
|
77
|
+
href={profile.href}
|
|
78
|
+
target="_blank"
|
|
79
|
+
rel="noopener noreferrer"
|
|
80
|
+
aria-label={profile.label}
|
|
81
|
+
>
|
|
82
|
+
<SocialGlyph network={profile.network} />
|
|
83
|
+
</a>
|
|
84
|
+
))}
|
|
85
|
+
</nav>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { cn } from "../lib/utils";
|
|
2
|
+
|
|
3
|
+
export type SpinnerProps = {
|
|
4
|
+
/** Extra utilities (size overrides, margins, colours) merged after the base. */
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Spinner — the canonical inline loading glyph. The wave-3 shared replacement
|
|
10
|
+
* for the hand-rolled `<span className="size-[11px] … animate-spin
|
|
11
|
+
* rounded-full border-2 border-current/30 border-t-current" />` idiom that had
|
|
12
|
+
* been copied into three reference specimens (task-1b review, Minor 3).
|
|
13
|
+
*
|
|
14
|
+
* `currentColor`-based, so it inherits the button/label tone; motion-reduce
|
|
15
|
+
* disables the rotation. Import from `@digithings-ai/ui`.
|
|
16
|
+
*/
|
|
17
|
+
export function Spinner({ className }: SpinnerProps) {
|
|
18
|
+
return (
|
|
19
|
+
<span
|
|
20
|
+
aria-hidden="true"
|
|
21
|
+
className={cn(
|
|
22
|
+
"size-[11px] shrink-0 animate-spin rounded-full border-2 border-current/30 border-t-current motion-reduce:animate-none",
|
|
23
|
+
className
|
|
24
|
+
)}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StackLogo — renders a real vendor mark (Simple Icons, MIT data) tinted to
|
|
3
|
+
* --ink-soft, brand colour on hover; or a monogram chip when no mark exists.
|
|
4
|
+
* Icons resolved by slug via a namespace lookup so an unknown/typo'd slug
|
|
5
|
+
* degrades to a monogram rather than breaking the build.
|
|
6
|
+
*
|
|
7
|
+
* Brand marks are trademarks of their owners; Simple Icons provides the icon
|
|
8
|
+
* data under MIT. We render monochrome by default out of respect for brand use.
|
|
9
|
+
*/
|
|
10
|
+
"use client";
|
|
11
|
+
import { ICONS } from "./logos";
|
|
12
|
+
import { type StackItem } from "../data/modules";
|
|
13
|
+
|
|
14
|
+
export function StackLogo({ item }: { item: StackItem }) {
|
|
15
|
+
const icon = item.icon ? ICONS[item.icon] ?? null : null;
|
|
16
|
+
if (icon) {
|
|
17
|
+
return (
|
|
18
|
+
<span className="stack-chip" title={item.name}>
|
|
19
|
+
<svg viewBox="0 0 24 24" width="15" height="15" className="stack-ico" style={{ ["--brand" as string]: `#${icon.hex}` }} aria-hidden="true">
|
|
20
|
+
<path d={icon.path} fill="currentColor" />
|
|
21
|
+
</svg>
|
|
22
|
+
<span className="stack-name">{item.name}</span>
|
|
23
|
+
</span>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return (
|
|
27
|
+
<span className="stack-chip" title={item.name}>
|
|
28
|
+
<span className="stack-mono" aria-hidden="true">{item.mono ?? item.name.slice(0, 2)}</span>
|
|
29
|
+
<span className="stack-name">{item.name}</span>
|
|
30
|
+
</span>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function StackRow({ items, className }: { items: StackItem[]; className?: string }) {
|
|
35
|
+
return (
|
|
36
|
+
<div className={className ?? "stack-row"}>
|
|
37
|
+
{items.map((it) => <StackLogo key={it.name} item={it} />)}
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/** Typed terminal playback — the hero signature. Renders line-by-line with a
|
|
3
|
+
* blinking cursor; instant under reduced-motion. Content is component-authored. */
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { useMotionSafe } from "../motion/primitives";
|
|
6
|
+
|
|
7
|
+
export type TermLine =
|
|
8
|
+
| { kind: "cmd" | "out" | "install" | "arrow"; text: string }
|
|
9
|
+
| { kind: "ok" | "mod"; name: string; text: string }
|
|
10
|
+
| { kind: "gap" };
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The column the `ok`/`mod` text starts at — one past the longest name in the
|
|
14
|
+
* list.
|
|
15
|
+
*
|
|
16
|
+
* This used to be a hard-coded `padEnd(15)`, which looks like it guarantees a
|
|
17
|
+
* gap and does not: once a name reaches 15 characters `padEnd` returns it
|
|
18
|
+
* unchanged and the text runs straight into it. `otel-collector` (v13) and
|
|
19
|
+
* `digi-digisearch` (v15) were both glued to the word after them, and both were
|
|
20
|
+
* worked around by renaming the service rather than by fixing the padding.
|
|
21
|
+
*
|
|
22
|
+
* Deriving the column from the lines in hand is what actually holds it: every
|
|
23
|
+
* list aligns to its own longest name, and no name can outgrow it.
|
|
24
|
+
*/
|
|
25
|
+
function nameColumn(lines: TermLine[]): number {
|
|
26
|
+
let longest = 0;
|
|
27
|
+
for (const l of lines) if ("name" in l) longest = Math.max(longest, l.name.length);
|
|
28
|
+
return longest + 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function Line({ l, col }: { l: TermLine; col: number }) {
|
|
32
|
+
switch (l.kind) {
|
|
33
|
+
case "gap": return <br />;
|
|
34
|
+
case "cmd": return <span className="tl-cmd">{l.text}</span>;
|
|
35
|
+
case "out": return <span className="tl-out">{l.text}</span>;
|
|
36
|
+
case "install": return <span className="tl-install">{l.text}</span>;
|
|
37
|
+
case "arrow": return <span className="tl-arrow">{l.text}</span>;
|
|
38
|
+
case "ok": return <span className="tl-ok"><b>{l.name.padEnd(col)}</b>{l.text}</span>;
|
|
39
|
+
case "mod": return <span className="tl-mod"><b>{l.name.padEnd(col)}</b>{l.text} →</span>;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function Terminal({
|
|
44
|
+
title,
|
|
45
|
+
lines,
|
|
46
|
+
size = "default",
|
|
47
|
+
fill = false,
|
|
48
|
+
className,
|
|
49
|
+
}: {
|
|
50
|
+
title: string;
|
|
51
|
+
lines: TermLine[];
|
|
52
|
+
/** `compact` is the smaller register — tighter body type and window bar. */
|
|
53
|
+
size?: "default" | "compact";
|
|
54
|
+
/**
|
|
55
|
+
* Stretch `.term` to its wrapper's height instead of sizing to the text, so
|
|
56
|
+
* a scripted playback never grows the box as lines type in. Pair with a
|
|
57
|
+
* fixed-height wrapper; the body clips rather than expanding.
|
|
58
|
+
*/
|
|
59
|
+
fill?: boolean;
|
|
60
|
+
className?: string;
|
|
61
|
+
}) {
|
|
62
|
+
const safe = useMotionSafe();
|
|
63
|
+
const [n, setN] = useState(safe ? 0 : lines.length);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
// useMotionSafe resolves after mount (hydration-safe): reduced-motion
|
|
67
|
+
// users reach here with safe=false on the second pass — show everything
|
|
68
|
+
// instantly.
|
|
69
|
+
if (!safe) {
|
|
70
|
+
setN(lines.length);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// The lead-in and the inter-line waits are chained timeouts, so the whole
|
|
74
|
+
// chain is tracked and cleared together on cleanup. A first-render effect
|
|
75
|
+
// pass is guaranteed (useMotionSafe flips `mounted` one tick after mount),
|
|
76
|
+
// which re-runs this effect; every pending timer must be cancelled and the
|
|
77
|
+
// chain restarted from zero, or the re-run would leave the body empty.
|
|
78
|
+
let i = 0;
|
|
79
|
+
let timer: ReturnType<typeof setTimeout>;
|
|
80
|
+
const tick = () => {
|
|
81
|
+
i += 1;
|
|
82
|
+
setN(i);
|
|
83
|
+
if (i < lines.length) {
|
|
84
|
+
const prev = lines[i - 1];
|
|
85
|
+
timer = setTimeout(tick, prev.kind === "gap" ? 90 : prev.kind === "cmd" ? 420 : 200);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
timer = setTimeout(tick, 420);
|
|
89
|
+
return () => clearTimeout(timer);
|
|
90
|
+
}, [safe, lines]);
|
|
91
|
+
|
|
92
|
+
const root = ["term", size === "compact" ? "term--compact" : "", fill ? "term--fill" : "", className]
|
|
93
|
+
.filter(Boolean)
|
|
94
|
+
.join(" ");
|
|
95
|
+
const col = nameColumn(lines);
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div className={root}>
|
|
99
|
+
<div className="term-bar"><i /><i /><i /><span className="term-title">{title}</span></div>
|
|
100
|
+
<pre className="term-body">
|
|
101
|
+
{lines.slice(0, n).map((l, k) => (
|
|
102
|
+
<span key={k}>
|
|
103
|
+
<Line l={l} col={col} />{l.kind !== "gap" ? "\n" : ""}
|
|
104
|
+
</span>
|
|
105
|
+
))}
|
|
106
|
+
{n >= lines.length && <span className="term-cursor" />}
|
|
107
|
+
</pre>
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* Terminal manifest — the `cli ps` process pane behind digithings-web's
|
|
4
|
+
* ModuleManifest (#1415): a prompt head line, selectable rows (status dot,
|
|
5
|
+
* two-tone mono name, optional port, blurb), and an output panel where the
|
|
6
|
+
* selected row's detail types out at a blinking cursor. Rows arrive as props;
|
|
7
|
+
* selection is uncontrolled by default or controlled via `selectedId`.
|
|
8
|
+
* Row-appear stagger and the type-out both degrade under reduced motion.
|
|
9
|
+
* Pane surface, row states, keyframes, and the container-query column
|
|
10
|
+
* collapse live in styles/terminal-manifest.css (import it once app-wide).
|
|
11
|
+
* The pane deliberately wears the manifest chrome (prompt head line), not
|
|
12
|
+
* the <Terminal> window bar — its frame is page CSS and its body is a
|
|
13
|
+
* scripted playback; compose the two side by side when both are wanted.
|
|
14
|
+
*/
|
|
15
|
+
import { useEffect, useState, type ReactNode } from "react";
|
|
16
|
+
import { useMotionSafe } from "../motion/primitives";
|
|
17
|
+
|
|
18
|
+
export type TerminalManifestStatus = "online" | "roadmap";
|
|
19
|
+
|
|
20
|
+
export type TerminalManifestRow = {
|
|
21
|
+
id: string;
|
|
22
|
+
/** Lowercase process name; `namePrefix` splits it into ink + accent. */
|
|
23
|
+
name: string;
|
|
24
|
+
/** Optional port column — rendered only when at least one row carries one. */
|
|
25
|
+
port?: string | number;
|
|
26
|
+
status: TerminalManifestStatus;
|
|
27
|
+
/** Row summary column; also the typed output when `detail` is absent. */
|
|
28
|
+
blurb: string;
|
|
29
|
+
/** Output typed at the cursor when the row is selected. */
|
|
30
|
+
detail?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type TerminalManifestProps = {
|
|
34
|
+
/** Head line, e.g. `modules`. Pair a non-shell `prompt` with a non-shell
|
|
35
|
+
* label: with the default `$` mark this reads as a command the visitor can
|
|
36
|
+
* type, so it must name one that exists. */
|
|
37
|
+
command: string;
|
|
38
|
+
rows: TerminalManifestRow[];
|
|
39
|
+
/** Head-line prompt mark. */
|
|
40
|
+
prompt?: string;
|
|
41
|
+
/** Trailing head-line annotation, e.g. `· 7 online · 3 on the roadmap`. */
|
|
42
|
+
meta?: string;
|
|
43
|
+
/** Idle output line shown before any row is selected. */
|
|
44
|
+
hint?: string;
|
|
45
|
+
/** Two-tone name split: this leading fragment renders ink, the rest accent. */
|
|
46
|
+
namePrefix?: string;
|
|
47
|
+
/** Staggered row-appear animation (CSS keyframe; off under reduced motion). */
|
|
48
|
+
animateRows?: boolean;
|
|
49
|
+
/** Controlled selection; omit to let the pane own it. */
|
|
50
|
+
selectedId?: string | null;
|
|
51
|
+
defaultSelectedId?: string | null;
|
|
52
|
+
onSelect?: (id: string | null) => void;
|
|
53
|
+
/** Rendered under the output panel — e.g. a hand-off button. */
|
|
54
|
+
footer?: ReactNode;
|
|
55
|
+
className?: string;
|
|
56
|
+
"aria-label"?: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function RowName({ name, prefix }: { name: string; prefix?: string }) {
|
|
60
|
+
if (prefix && name.startsWith(prefix) && name.length > prefix.length) {
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<span className="text-ink">{prefix}</span>
|
|
64
|
+
<span className="text-accent">{name.slice(prefix.length)}</span>
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return <span className="text-ink">{name}</span>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function TerminalManifest({
|
|
72
|
+
command,
|
|
73
|
+
rows,
|
|
74
|
+
prompt = "$",
|
|
75
|
+
meta,
|
|
76
|
+
hint = "select a module",
|
|
77
|
+
namePrefix,
|
|
78
|
+
animateRows = true,
|
|
79
|
+
selectedId,
|
|
80
|
+
defaultSelectedId = null,
|
|
81
|
+
onSelect,
|
|
82
|
+
footer,
|
|
83
|
+
className,
|
|
84
|
+
"aria-label": ariaLabel,
|
|
85
|
+
}: TerminalManifestProps) {
|
|
86
|
+
const safe = useMotionSafe();
|
|
87
|
+
const [ownSel, setOwnSel] = useState<string | null>(defaultSelectedId);
|
|
88
|
+
const sel = selectedId !== undefined ? selectedId : ownSel;
|
|
89
|
+
const selRow = sel ? (rows.find((r) => r.id === sel) ?? null) : null;
|
|
90
|
+
const out = selRow ? (selRow.detail ?? selRow.blurb) : "";
|
|
91
|
+
const open = selRow !== null;
|
|
92
|
+
|
|
93
|
+
const [shown, setShown] = useState(0);
|
|
94
|
+
|
|
95
|
+
// The detail types out in ~1.5s regardless of length: this effect resets and
|
|
96
|
+
// then drives `shown` as an animation, so synchronous setState in the effect
|
|
97
|
+
// body is intentional (same pattern as digithings-web's ModuleManifest).
|
|
98
|
+
/* eslint-disable react-hooks/set-state-in-effect */
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (!open) {
|
|
101
|
+
setShown(0);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (!safe) {
|
|
105
|
+
setShown(out.length);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
setShown(0);
|
|
109
|
+
let i = 0;
|
|
110
|
+
const step = Math.max(2, Math.ceil(out.length / 90));
|
|
111
|
+
const id = window.setInterval(() => {
|
|
112
|
+
i += step;
|
|
113
|
+
if (i >= out.length) {
|
|
114
|
+
i = out.length;
|
|
115
|
+
window.clearInterval(id);
|
|
116
|
+
}
|
|
117
|
+
setShown(i);
|
|
118
|
+
}, 16);
|
|
119
|
+
return () => window.clearInterval(id);
|
|
120
|
+
}, [open, out, safe]);
|
|
121
|
+
/* eslint-enable react-hooks/set-state-in-effect */
|
|
122
|
+
|
|
123
|
+
const select = (id: string) => {
|
|
124
|
+
const next = sel === id ? null : id;
|
|
125
|
+
if (selectedId === undefined) setOwnSel(next);
|
|
126
|
+
onSelect?.(next);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const hasPorts = rows.some((r) => r.port !== undefined);
|
|
130
|
+
const anim = animateRows && safe;
|
|
131
|
+
const shell = ["tm", hasPorts ? "has-ports" : "", anim ? "" : "no-anim", className ?? ""]
|
|
132
|
+
.filter(Boolean)
|
|
133
|
+
.join(" ");
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<div className={shell} aria-label={ariaLabel}>
|
|
137
|
+
<div className="tm-pane flex flex-col rounded-none border border-hair px-[clamp(1rem,2.4vw,1.6rem)] py-[clamp(1rem,2.4vw,1.5rem)] font-mono">
|
|
138
|
+
<div className="mb-[0.7rem] flex-none text-[0.8rem] tracking-[0.02em] text-ink-mute">
|
|
139
|
+
<span className="text-accent">{prompt}</span> {command}
|
|
140
|
+
{meta ? <span> {meta}</span> : null}
|
|
141
|
+
</div>
|
|
142
|
+
<div className="tm-body">
|
|
143
|
+
<ol className="tm-rows">
|
|
144
|
+
{rows.map((r, i) => {
|
|
145
|
+
const off = r.status === "roadmap";
|
|
146
|
+
const isSel = sel === r.id;
|
|
147
|
+
return (
|
|
148
|
+
<li
|
|
149
|
+
key={r.id}
|
|
150
|
+
className={`tm-row${off ? " is-off" : ""}${isSel ? " is-sel" : ""}`}
|
|
151
|
+
style={anim ? { animationDelay: `${i * 55}ms` } : undefined}
|
|
152
|
+
>
|
|
153
|
+
<button
|
|
154
|
+
type="button"
|
|
155
|
+
className="tm-row-link"
|
|
156
|
+
// Toggle buttons feeding one shared output pane: clicking a
|
|
157
|
+
// row selects it (re-clicking deselects), so aria-pressed —
|
|
158
|
+
// the selected state — is the accurate model. (aria-selected
|
|
159
|
+
// is invalid on role=button; a listbox would need arrow-key
|
|
160
|
+
// nav these rows don't implement.) The output pane always
|
|
161
|
+
// renders (hint vs detail — content swaps, nothing
|
|
162
|
+
// collapses), so this is selection, not disclosure. (#1434)
|
|
163
|
+
aria-pressed={isSel}
|
|
164
|
+
onClick={() => select(r.id)}
|
|
165
|
+
>
|
|
166
|
+
<span className={`tm-dot${off ? " off" : ""}`} aria-hidden="true" />
|
|
167
|
+
{/* The dot is the only running/roadmap signal (color +
|
|
168
|
+
glow), aria-hidden with no text equivalent elsewhere
|
|
169
|
+
in the row — a screen-reader user got zero indication
|
|
170
|
+
of which services are live. .tm-sr (terminal-manifest.css),
|
|
171
|
+
not Tailwind's .sr-only: this is a shared component and
|
|
172
|
+
that utility only exists in an app whose own source
|
|
173
|
+
happens to use the class (see .tl-sr's comment,
|
|
174
|
+
terminal-loaders.css, for the bug that already caused
|
|
175
|
+
once). */}
|
|
176
|
+
<span className="tm-sr">{off ? "On the roadmap" : "Online"}</span>
|
|
177
|
+
<span className="tm-name text-[0.92rem] font-medium">
|
|
178
|
+
<RowName name={r.name} prefix={namePrefix} />
|
|
179
|
+
</span>
|
|
180
|
+
{hasPorts ? (
|
|
181
|
+
<span className="tm-port text-[0.78rem] text-ink-mute">{r.port ?? ""}</span>
|
|
182
|
+
) : null}
|
|
183
|
+
<span className="tm-blurb truncate text-[0.84rem] text-ink-soft">{r.blurb}</span>
|
|
184
|
+
</button>
|
|
185
|
+
</li>
|
|
186
|
+
);
|
|
187
|
+
})}
|
|
188
|
+
</ol>
|
|
189
|
+
<div className="tm-out">
|
|
190
|
+
<div className="tm-out-show pb-[0.2rem]" aria-live="polite">
|
|
191
|
+
{selRow ? (
|
|
192
|
+
<pre className="tm-out-body m-0 whitespace-pre-wrap break-words font-mono text-[0.84rem] leading-[1.6] text-ink-soft">
|
|
193
|
+
{out.slice(0, shown)}
|
|
194
|
+
<span className="tm-cursor" aria-hidden="true" />
|
|
195
|
+
</pre>
|
|
196
|
+
) : (
|
|
197
|
+
<p className="m-0 text-[0.84rem] text-ink-mute">
|
|
198
|
+
{hint}
|
|
199
|
+
<span className="tm-cursor" aria-hidden="true" />
|
|
200
|
+
</p>
|
|
201
|
+
)}
|
|
202
|
+
</div>
|
|
203
|
+
{/* Fragment keeps the slot element out of this children array: an
|
|
204
|
+
element prop arriving across an RSC boundary trips React 19's
|
|
205
|
+
missing-key check when reconciled as a direct array member. */}
|
|
206
|
+
<>{footer}</>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
);
|
|
212
|
+
}
|