@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,271 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* Theme + direction controller for the React marketing apps. Sets
|
|
4
|
+
* [data-theme] on <html> and persists the shared `dt-theme` key (also read by
|
|
5
|
+
* dashboard → cross-surface sync on the same origin). Pair with the pre-paint
|
|
6
|
+
* snippet (themeInitScript) inlined in <head> to avoid a flash.
|
|
7
|
+
*
|
|
8
|
+
* Direction is opt-in: `ThemeProvider dir="rtl"` (default `"ltr"`) applies
|
|
9
|
+
* `dir` to <html>, which is all the kit needs — every part is authored with
|
|
10
|
+
* logical properties and `[[dir=rtl]]`-scoped art, so the whole tree mirrors
|
|
11
|
+
* without touching a single page. `DirectionProvider` is the nested form: it
|
|
12
|
+
* wraps a region in its own `dir` (and `root` applies to <html> instead), for
|
|
13
|
+
* side-by-side or per-subtree direction.
|
|
14
|
+
*/
|
|
15
|
+
import {
|
|
16
|
+
createContext,
|
|
17
|
+
useCallback,
|
|
18
|
+
useContext,
|
|
19
|
+
useEffect,
|
|
20
|
+
useMemo,
|
|
21
|
+
useRef,
|
|
22
|
+
useState,
|
|
23
|
+
type ReactNode,
|
|
24
|
+
} from "react";
|
|
25
|
+
import {
|
|
26
|
+
applyDocumentTheme,
|
|
27
|
+
matchThemeStep,
|
|
28
|
+
nextThemeStep,
|
|
29
|
+
readPaintedTheme,
|
|
30
|
+
readThemeState,
|
|
31
|
+
PALETTE_STORAGE_KEY,
|
|
32
|
+
THEME_CHANGE_EVENT,
|
|
33
|
+
THEME_STORAGE_KEY,
|
|
34
|
+
type PaletteName,
|
|
35
|
+
type ResolvedTheme,
|
|
36
|
+
type ThemePreference,
|
|
37
|
+
type ThemeStep,
|
|
38
|
+
} from "../theme/apply-theme";
|
|
39
|
+
import { IconButton } from "../ui/icon-button";
|
|
40
|
+
|
|
41
|
+
/** Text direction. The kit defaults to `"ltr"`; RTL is always opt-in. */
|
|
42
|
+
export type Direction = "ltr" | "rtl";
|
|
43
|
+
|
|
44
|
+
const DirectionCtx = createContext<Direction>("ltr");
|
|
45
|
+
|
|
46
|
+
/** Current text direction of the surrounding `DirectionProvider` (default ltr). */
|
|
47
|
+
export function useDirection(): Direction {
|
|
48
|
+
return useContext(DirectionCtx);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Apply `dir` to a region. By default it renders a wrapper <div dir=…> and
|
|
53
|
+
* provides `useDirection()`; with `root` it applies `dir` to <html> instead
|
|
54
|
+
* (matching `ThemeProvider dir`) and renders children without a wrapper, so a
|
|
55
|
+
* full app or page can flip direction. Either form resets the document to
|
|
56
|
+
* `ltr` on unmount when `root` is used.
|
|
57
|
+
*/
|
|
58
|
+
export function DirectionProvider({
|
|
59
|
+
dir = "ltr",
|
|
60
|
+
root = false,
|
|
61
|
+
className,
|
|
62
|
+
children,
|
|
63
|
+
}: {
|
|
64
|
+
dir?: Direction;
|
|
65
|
+
/** Apply to <html> (whole document) rather than a wrapper element. */
|
|
66
|
+
root?: boolean;
|
|
67
|
+
className?: string;
|
|
68
|
+
children: ReactNode;
|
|
69
|
+
}) {
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (!root) return;
|
|
72
|
+
document.documentElement.setAttribute("dir", dir);
|
|
73
|
+
return () => {
|
|
74
|
+
document.documentElement.setAttribute("dir", "ltr");
|
|
75
|
+
};
|
|
76
|
+
}, [dir, root]);
|
|
77
|
+
|
|
78
|
+
const value = useMemo(() => dir, [dir]);
|
|
79
|
+
if (root) return <DirectionCtx.Provider value={value}>{children}</DirectionCtx.Provider>;
|
|
80
|
+
return (
|
|
81
|
+
<DirectionCtx.Provider value={value}>
|
|
82
|
+
<div dir={dir} className={className}>
|
|
83
|
+
{children}
|
|
84
|
+
</div>
|
|
85
|
+
</DirectionCtx.Provider>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type { PaletteName, ResolvedTheme, ThemePreference };
|
|
90
|
+
|
|
91
|
+
// themeInitScript lives in ./themeInit.ts (a plain module) — see there.
|
|
92
|
+
export { themeInitScript } from "./themeInit";
|
|
93
|
+
|
|
94
|
+
export type ThemeContextValue = {
|
|
95
|
+
/** Resolved light/dark currently painted. Existing callers read this. */
|
|
96
|
+
theme: ResolvedTheme;
|
|
97
|
+
/** Advance one stop: default dark, default light, then each palette. */
|
|
98
|
+
toggle: () => void;
|
|
99
|
+
/** Stored mode. `auto` means `dt-theme` is absent and the OS is followed. */
|
|
100
|
+
preference: ThemePreference;
|
|
101
|
+
setTheme: (preference: ThemePreference) => void;
|
|
102
|
+
/** `default` or one of the 32 DigiVoice palette ids. Stored in `dt-palette`. */
|
|
103
|
+
palette: PaletteName;
|
|
104
|
+
setPalette: (palette: string) => void;
|
|
105
|
+
/** Paint one cycle stop (mode and palette together). */
|
|
106
|
+
applyStep: (step: ThemeStep) => void;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const ThemeCtx = createContext<ThemeContextValue | null>(null);
|
|
110
|
+
|
|
111
|
+
export function useTheme() {
|
|
112
|
+
const ctx = useContext(ThemeCtx);
|
|
113
|
+
if (!ctx) throw new Error("useTheme must be used within ThemeProvider");
|
|
114
|
+
return ctx;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function ThemeProvider({
|
|
118
|
+
children,
|
|
119
|
+
dir = "ltr",
|
|
120
|
+
}: {
|
|
121
|
+
children: ReactNode;
|
|
122
|
+
/** Text direction applied to <html>. Defaults to `"ltr"`; RTL is opt-in. */
|
|
123
|
+
dir?: Direction;
|
|
124
|
+
}) {
|
|
125
|
+
const [theme, setResolved] = useState<ResolvedTheme>("dark");
|
|
126
|
+
const [preference, setPreferenceState] = useState<ThemePreference>("auto");
|
|
127
|
+
const [palette, setPaletteState] = useState<PaletteName>("default");
|
|
128
|
+
const preferenceRef = useRef<ThemePreference>("auto");
|
|
129
|
+
const setPreference = useCallback((next: ThemePreference) => {
|
|
130
|
+
preferenceRef.current = next;
|
|
131
|
+
setPreferenceState(next);
|
|
132
|
+
}, []);
|
|
133
|
+
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
// The document is the source of truth; storage is only where a user's
|
|
136
|
+
// choice is kept. Mount READS what is painted and never paints or writes:
|
|
137
|
+
// themeInitScript has already applied the stored mode and palette on the
|
|
138
|
+
// surfaces that use it, a pinned embed (data-theme-pin) painted its
|
|
139
|
+
// tenant's theme, and digiquant.io paints dark itself with no
|
|
140
|
+
// themeInitScript. Applying storage here flipped such a page to whatever
|
|
141
|
+
// the dashboard last mirrored into `dt-theme` on that origin.
|
|
142
|
+
const sync = () => {
|
|
143
|
+
const painted = readPaintedTheme();
|
|
144
|
+
const stored = readThemeState().preference;
|
|
145
|
+
// A stored mode the page did not paint (a pinned surface) is not this
|
|
146
|
+
// page's preference; the painted mode is.
|
|
147
|
+
setPreference(stored === "auto" || stored === painted.resolved ? stored : painted.resolved);
|
|
148
|
+
setPaletteState(painted.palette);
|
|
149
|
+
setResolved(painted.resolved);
|
|
150
|
+
};
|
|
151
|
+
sync();
|
|
152
|
+
// A pinned embed owns its document: no OS follow there.
|
|
153
|
+
if (document.documentElement.getAttribute("data-theme-pin") === "1") return;
|
|
154
|
+
// Any painter (the /theme command, the picker, this provider) goes through
|
|
155
|
+
// applyDocumentTheme, which announces the change; re-read so the context
|
|
156
|
+
// and the OS guard below never disagree with what is painted.
|
|
157
|
+
window.addEventListener(THEME_CHANGE_EVENT, sync);
|
|
158
|
+
// Another tab (the marketing site, the other chat) writes the same keys.
|
|
159
|
+
// `storage` does not fire in the tab that wrote them; this tab repaints.
|
|
160
|
+
const onStorage = (event: StorageEvent) => {
|
|
161
|
+
if (
|
|
162
|
+
event.key !== null &&
|
|
163
|
+
event.key !== THEME_STORAGE_KEY &&
|
|
164
|
+
event.key !== PALETTE_STORAGE_KEY
|
|
165
|
+
) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const next = readThemeState();
|
|
169
|
+
applyDocumentTheme(next.preference, next.palette, document, { persist: false });
|
|
170
|
+
sync();
|
|
171
|
+
};
|
|
172
|
+
window.addEventListener("storage", onStorage);
|
|
173
|
+
const mq = matchMedia("(prefers-color-scheme: light)");
|
|
174
|
+
const onOS = () => {
|
|
175
|
+
// As before this provider existed: a stored mode means a choice was
|
|
176
|
+
// made, so the OS does not override it.
|
|
177
|
+
if (readThemeState().preference !== "auto") return;
|
|
178
|
+
// Repaint only; the OS changing is not a choice to store.
|
|
179
|
+
setResolved(
|
|
180
|
+
applyDocumentTheme("auto", readPaintedTheme().palette, undefined, { persist: false }),
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
mq.addEventListener("change", onOS);
|
|
184
|
+
return () => {
|
|
185
|
+
window.removeEventListener(THEME_CHANGE_EVENT, sync);
|
|
186
|
+
window.removeEventListener("storage", onStorage);
|
|
187
|
+
mq.removeEventListener("change", onOS);
|
|
188
|
+
};
|
|
189
|
+
}, [setPreference]);
|
|
190
|
+
|
|
191
|
+
const setTheme = useCallback(
|
|
192
|
+
(next: ThemePreference) => {
|
|
193
|
+
setPreference(next);
|
|
194
|
+
setResolved(applyDocumentTheme(next, readPaintedTheme().palette));
|
|
195
|
+
},
|
|
196
|
+
[setPreference],
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
const setPalette = useCallback((next: string) => {
|
|
200
|
+
const resolved = applyDocumentTheme(preferenceRef.current, next);
|
|
201
|
+
setPaletteState(readPaintedTheme().palette);
|
|
202
|
+
setResolved(resolved);
|
|
203
|
+
}, []);
|
|
204
|
+
|
|
205
|
+
const applyStep = useCallback(
|
|
206
|
+
(step: ThemeStep) => {
|
|
207
|
+
const resolved = applyDocumentTheme(step.mode, step.palette);
|
|
208
|
+
setPreference(step.mode);
|
|
209
|
+
setPaletteState(step.palette);
|
|
210
|
+
setResolved(resolved);
|
|
211
|
+
},
|
|
212
|
+
[setPreference],
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const toggle = useCallback(() => {
|
|
216
|
+
const painted = readPaintedTheme();
|
|
217
|
+
applyStep(nextThemeStep("auto", painted.palette, painted.resolved));
|
|
218
|
+
}, [applyStep]);
|
|
219
|
+
|
|
220
|
+
const value = useMemo(
|
|
221
|
+
() => ({ theme, toggle, preference, setTheme, palette, setPalette, applyStep }),
|
|
222
|
+
[theme, toggle, preference, setTheme, palette, setPalette, applyStep],
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<ThemeCtx.Provider value={value}>
|
|
227
|
+
<DirectionProvider root dir={dir}>
|
|
228
|
+
{children}
|
|
229
|
+
</DirectionProvider>
|
|
230
|
+
</ThemeCtx.Provider>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Theme control for the nav tail.
|
|
236
|
+
*
|
|
237
|
+
* One glyph, not two: the control moves through *theme* (default dark, default
|
|
238
|
+
* light, then 32 palettes), so a sun/moon pair only ever described two stops of
|
|
239
|
+
* a longer cycle and read as a mode switch that it is not. The contrast mark —
|
|
240
|
+
* a ring with half of it filled — is the general "appearance" signifier, and it
|
|
241
|
+
* stays put as the cycle advances. `aria-label` is the stable action name the
|
|
242
|
+
* kit test pins; `title` names the next stop.
|
|
243
|
+
*/
|
|
244
|
+
export function ThemeToggle({ className }: { className?: string }) {
|
|
245
|
+
const { theme, preference, palette, toggle } = useTheme();
|
|
246
|
+
const step = matchThemeStep(preference, palette, theme);
|
|
247
|
+
return (
|
|
248
|
+
<IconButton
|
|
249
|
+
type="button"
|
|
250
|
+
onClick={toggle}
|
|
251
|
+
aria-label="Toggle colour theme"
|
|
252
|
+
title={step.label}
|
|
253
|
+
className={className ?? "theme-toggle"}
|
|
254
|
+
>
|
|
255
|
+
<svg
|
|
256
|
+
viewBox="0 0 24 24"
|
|
257
|
+
width="17"
|
|
258
|
+
height="17"
|
|
259
|
+
fill="none"
|
|
260
|
+
stroke="currentColor"
|
|
261
|
+
strokeWidth="1.8"
|
|
262
|
+
aria-hidden="true"
|
|
263
|
+
focusable="false"
|
|
264
|
+
>
|
|
265
|
+
{/* Ring + filled right half: the contrast/appearance glyph. */}
|
|
266
|
+
<circle cx="12" cy="12" r="8.4" />
|
|
267
|
+
<path d="M12 3.6a8.4 8.4 0 0 1 0 16.8z" fill="currentColor" stroke="none" />
|
|
268
|
+
</svg>
|
|
269
|
+
</IconButton>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/** AuthCard — the shared sign-in / create-account card. Layouts `compact`,
|
|
2
|
+
* `icons-first`, and `desk` share one email + password form with Google /
|
|
3
|
+
* GitHub / X OAuth. Dress lives in `./styles/account-auth.css` (`.acct-*`);
|
|
4
|
+
* the sign-up strength meter renders on desk-signup only. Consumers: the
|
|
5
|
+
* dashboard login screen (compact) and the reference account-page specimens.
|
|
6
|
+
*/
|
|
7
|
+
"use client";
|
|
8
|
+
|
|
9
|
+
import { type FormEvent, type ReactNode } from "react";
|
|
10
|
+
import { Button, Input, Label } from "../../ui";
|
|
11
|
+
import { DigiquantMark } from "../symbols/marks";
|
|
12
|
+
import { GitHubGlyph, GoogleGlyph, XGlyph } from "../icons";
|
|
13
|
+
|
|
14
|
+
export type AuthCardLayout = "compact" | "icons-first" | "desk";
|
|
15
|
+
export type AuthCardMode = "signin" | "signup";
|
|
16
|
+
/** Supabase OAuth 2.0 id for X is `x` (not legacy `twitter`). UI copy is X. */
|
|
17
|
+
export type AuthOAuthProvider = "google" | "github" | "x";
|
|
18
|
+
|
|
19
|
+
const STRENGTH_WORDS = ["", "weak", "fair", "good", "strong"] as const;
|
|
20
|
+
const STRENGTH_COLORS = ["", "var(--danger)", "var(--accent)", "var(--accent)", "var(--ink)"] as const;
|
|
21
|
+
|
|
22
|
+
export function passwordStrength(password: string): number {
|
|
23
|
+
if (password.length === 0) return 0;
|
|
24
|
+
let score = 1;
|
|
25
|
+
if (password.length >= 8) score += 1;
|
|
26
|
+
if (/[a-z]/.test(password) && /[A-Z]/.test(password)) score += 1;
|
|
27
|
+
if (/\d/.test(password) || /[^a-zA-Z0-9]/.test(password)) score += 1;
|
|
28
|
+
return Math.min(score, 4);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type AuthCardBrand = {
|
|
32
|
+
/** Short client marker (e.g. "ACME") shown top-right of the card. */
|
|
33
|
+
marker: string;
|
|
34
|
+
/** Optional line under the brand row (e.g. "Purpose-built for the ACME desk"). */
|
|
35
|
+
line?: string | null;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type AuthCardProps = {
|
|
39
|
+
layout: AuthCardLayout;
|
|
40
|
+
mode?: AuthCardMode;
|
|
41
|
+
productName?: string;
|
|
42
|
+
/** Invite branding — wraps sign-in or sign-up so the invitee knows the
|
|
43
|
+
* product was built for their team. Null/undefined renders the default card. */
|
|
44
|
+
brand?: AuthCardBrand | null;
|
|
45
|
+
mark?: ReactNode;
|
|
46
|
+
email?: string;
|
|
47
|
+
password?: string;
|
|
48
|
+
onEmailChange?: (value: string) => void;
|
|
49
|
+
onPasswordChange?: (value: string) => void;
|
|
50
|
+
onSubmit?: (event: FormEvent<HTMLFormElement>) => void;
|
|
51
|
+
onOAuth?: (provider: AuthOAuthProvider) => void;
|
|
52
|
+
onForgotPassword?: () => void;
|
|
53
|
+
pending?: AuthOAuthProvider | "email" | null;
|
|
54
|
+
error?: string | null;
|
|
55
|
+
info?: string | null;
|
|
56
|
+
switchHref?: string;
|
|
57
|
+
idPrefix?: string;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const OAUTH: { provider: AuthOAuthProvider; label: string; testId: string; icon: ReactNode }[] = [
|
|
61
|
+
{ provider: "google", label: "Google", testId: "login-google", icon: <GoogleGlyph /> },
|
|
62
|
+
{ provider: "github", label: "GitHub", testId: "login-github", icon: <GitHubGlyph width={16} height={16} /> },
|
|
63
|
+
{ provider: "x", label: "X", testId: "login-x", icon: <XGlyph /> },
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
function OAuthButtons({
|
|
67
|
+
pending,
|
|
68
|
+
onOAuth,
|
|
69
|
+
stretch,
|
|
70
|
+
}: {
|
|
71
|
+
pending: AuthCardProps["pending"];
|
|
72
|
+
onOAuth?: AuthCardProps["onOAuth"];
|
|
73
|
+
stretch: boolean;
|
|
74
|
+
}) {
|
|
75
|
+
return (
|
|
76
|
+
<>
|
|
77
|
+
{OAUTH.map((item) => (
|
|
78
|
+
<Button
|
|
79
|
+
key={item.provider}
|
|
80
|
+
type="button"
|
|
81
|
+
className="acct-oauth"
|
|
82
|
+
style={stretch ? { flex: 1, width: "auto" } : undefined}
|
|
83
|
+
disabled={pending !== null && pending !== undefined}
|
|
84
|
+
aria-label={item.label}
|
|
85
|
+
title={item.label}
|
|
86
|
+
data-testid={item.testId}
|
|
87
|
+
onClick={() => onOAuth?.(item.provider)}
|
|
88
|
+
>
|
|
89
|
+
{item.icon}
|
|
90
|
+
</Button>
|
|
91
|
+
))}
|
|
92
|
+
</>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function AuthCard({
|
|
97
|
+
layout,
|
|
98
|
+
mode = "signin",
|
|
99
|
+
productName = "digiquant",
|
|
100
|
+
brand = null,
|
|
101
|
+
mark,
|
|
102
|
+
email = "",
|
|
103
|
+
password = "",
|
|
104
|
+
onEmailChange,
|
|
105
|
+
onPasswordChange,
|
|
106
|
+
onSubmit,
|
|
107
|
+
onOAuth,
|
|
108
|
+
onForgotPassword,
|
|
109
|
+
pending = null,
|
|
110
|
+
error = null,
|
|
111
|
+
info = null,
|
|
112
|
+
switchHref,
|
|
113
|
+
idPrefix,
|
|
114
|
+
}: AuthCardProps) {
|
|
115
|
+
const signUp = mode === "signup";
|
|
116
|
+
const prefix = idPrefix ?? `acct-${layout}-${mode}`;
|
|
117
|
+
const emailId = `${prefix}-email`;
|
|
118
|
+
const passwordId = `${prefix}-password`;
|
|
119
|
+
const score = passwordStrength(password);
|
|
120
|
+
const href = switchHref ?? (signUp ? "/login/" : "/signup/");
|
|
121
|
+
const busy = pending !== null;
|
|
122
|
+
|
|
123
|
+
function handleSubmit(event: FormEvent<HTMLFormElement>) {
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
onSubmit?.(event);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const fields = (
|
|
129
|
+
<>
|
|
130
|
+
<div className="acct-auth-field">
|
|
131
|
+
<Label className="acct-auth-label leading-[normal]" htmlFor={emailId}>
|
|
132
|
+
Email
|
|
133
|
+
</Label>
|
|
134
|
+
<Input
|
|
135
|
+
className={
|
|
136
|
+
error ? "acct-auth-input acct-auth-input-error h-auto" : "acct-auth-input h-auto"
|
|
137
|
+
}
|
|
138
|
+
id={emailId}
|
|
139
|
+
name="email"
|
|
140
|
+
type="email"
|
|
141
|
+
autoComplete="username"
|
|
142
|
+
value={email}
|
|
143
|
+
onChange={(event) => onEmailChange?.(event.target.value)}
|
|
144
|
+
placeholder="you@desk.tld"
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
147
|
+
<div className="acct-auth-field">
|
|
148
|
+
<Label className="acct-auth-label leading-[normal]" htmlFor={passwordId}>
|
|
149
|
+
Password
|
|
150
|
+
</Label>
|
|
151
|
+
<Input
|
|
152
|
+
className={
|
|
153
|
+
error ? "acct-auth-input acct-auth-input-error h-auto" : "acct-auth-input h-auto"
|
|
154
|
+
}
|
|
155
|
+
id={passwordId}
|
|
156
|
+
name="password"
|
|
157
|
+
type="password"
|
|
158
|
+
autoComplete={signUp ? "new-password" : "current-password"}
|
|
159
|
+
value={password}
|
|
160
|
+
onChange={(event) => onPasswordChange?.(event.target.value)}
|
|
161
|
+
placeholder={signUp ? "8+ chars, mixed case, a digit" : "••••••••••"}
|
|
162
|
+
aria-describedby={layout === "desk" && signUp ? `${prefix}-strength` : undefined}
|
|
163
|
+
/>
|
|
164
|
+
{layout === "desk" && signUp ? (
|
|
165
|
+
<div className="acct-auth-strength">
|
|
166
|
+
<div className="acct-auth-strength-track" aria-hidden="true">
|
|
167
|
+
{[0, 1, 2, 3].map((index) => (
|
|
168
|
+
<span
|
|
169
|
+
key={index}
|
|
170
|
+
className="acct-auth-strength-seg"
|
|
171
|
+
style={index < score ? { background: STRENGTH_COLORS[score] } : undefined}
|
|
172
|
+
/>
|
|
173
|
+
))}
|
|
174
|
+
</div>
|
|
175
|
+
<span className="acct-auth-strength-word" id={`${prefix}-strength`} role="status">
|
|
176
|
+
{STRENGTH_WORDS[score] || "—"}
|
|
177
|
+
</span>
|
|
178
|
+
</div>
|
|
179
|
+
) : null}
|
|
180
|
+
</div>
|
|
181
|
+
</>
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
const submitLabel = pending === "email" ? (signUp ? "Creating…" : "Signing in…") : signUp ? "Sign up" : "Sign in";
|
|
185
|
+
const markNode = mark ?? <DigiquantMark size={28} />;
|
|
186
|
+
const inviteMarker = brand?.marker?.trim() ? brand.marker.trim() : null;
|
|
187
|
+
const inviteLine = brand?.line?.trim() ? brand.line.trim() : null;
|
|
188
|
+
const brandRow =
|
|
189
|
+
layout === "compact" ? (
|
|
190
|
+
<div className="acct-auth-brand">
|
|
191
|
+
<div className="acct-auth-mark">{markNode}</div>
|
|
192
|
+
<span className="acct-auth-wordmark">{productName}</span>
|
|
193
|
+
{inviteMarker ? <span className="acct-auth-invite-marker">{inviteMarker}</span> : null}
|
|
194
|
+
</div>
|
|
195
|
+
) : (
|
|
196
|
+
<div className="acct-auth-mark">{markNode}</div>
|
|
197
|
+
);
|
|
198
|
+
const inviteBrand =
|
|
199
|
+
inviteMarker && layout !== "compact" ? (
|
|
200
|
+
<div className="acct-auth-invite">
|
|
201
|
+
<span className="acct-auth-invite-marker">{inviteMarker}</span>
|
|
202
|
+
</div>
|
|
203
|
+
) : null;
|
|
204
|
+
|
|
205
|
+
let body: ReactNode;
|
|
206
|
+
switch (layout) {
|
|
207
|
+
case "compact":
|
|
208
|
+
body = (
|
|
209
|
+
<>
|
|
210
|
+
{fields}
|
|
211
|
+
<div className="acct-auth-actions">
|
|
212
|
+
<OAuthButtons pending={pending} onOAuth={onOAuth} stretch={false} />
|
|
213
|
+
<Button
|
|
214
|
+
type="submit"
|
|
215
|
+
className="acct-auth-submit h-auto font-normal"
|
|
216
|
+
disabled={busy}
|
|
217
|
+
data-testid="login-email-submit"
|
|
218
|
+
>
|
|
219
|
+
{submitLabel}
|
|
220
|
+
</Button>
|
|
221
|
+
</div>
|
|
222
|
+
</>
|
|
223
|
+
);
|
|
224
|
+
break;
|
|
225
|
+
case "icons-first":
|
|
226
|
+
body = (
|
|
227
|
+
<>
|
|
228
|
+
<div className="acct-auth-oauth-row">
|
|
229
|
+
<OAuthButtons pending={pending} onOAuth={onOAuth} stretch />
|
|
230
|
+
</div>
|
|
231
|
+
<div className="acct-auth-divider">
|
|
232
|
+
<span>or email</span>
|
|
233
|
+
</div>
|
|
234
|
+
{fields}
|
|
235
|
+
<Button
|
|
236
|
+
type="submit"
|
|
237
|
+
className="acct-auth-submit-block h-auto font-normal"
|
|
238
|
+
disabled={busy}
|
|
239
|
+
data-testid="login-email-submit"
|
|
240
|
+
>
|
|
241
|
+
{submitLabel}
|
|
242
|
+
</Button>
|
|
243
|
+
</>
|
|
244
|
+
);
|
|
245
|
+
break;
|
|
246
|
+
case "desk":
|
|
247
|
+
body = (
|
|
248
|
+
<>
|
|
249
|
+
<p className="acct-auth-kicker">
|
|
250
|
+
{productName}{" "}
|
|
251
|
+
<span className="text-ink-mute">{signUp ? "· create account" : "· sign in"}</span>
|
|
252
|
+
</p>
|
|
253
|
+
<p className="acct-auth-copy">
|
|
254
|
+
{signUp
|
|
255
|
+
? "Google, GitHub, or X to start. Email if you would rather keep a password."
|
|
256
|
+
: "Email and a password, or a provider."}
|
|
257
|
+
</p>
|
|
258
|
+
{fields}
|
|
259
|
+
<div className="acct-auth-actions">
|
|
260
|
+
<OAuthButtons pending={pending} onOAuth={onOAuth} stretch={false} />
|
|
261
|
+
<Button
|
|
262
|
+
type="submit"
|
|
263
|
+
className="acct-auth-submit h-auto font-normal"
|
|
264
|
+
disabled={busy}
|
|
265
|
+
data-testid="login-email-submit"
|
|
266
|
+
>
|
|
267
|
+
{submitLabel}
|
|
268
|
+
</Button>
|
|
269
|
+
</div>
|
|
270
|
+
{!signUp ? (
|
|
271
|
+
<Button
|
|
272
|
+
type="button"
|
|
273
|
+
className="acct-auth-forgot h-auto font-normal"
|
|
274
|
+
onClick={onForgotPassword}
|
|
275
|
+
>
|
|
276
|
+
Forgot password?
|
|
277
|
+
</Button>
|
|
278
|
+
) : null}
|
|
279
|
+
</>
|
|
280
|
+
);
|
|
281
|
+
break;
|
|
282
|
+
default: {
|
|
283
|
+
const _never: never = layout;
|
|
284
|
+
body = _never;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return (
|
|
289
|
+
<form className="acct-auth" data-layout={layout} data-mode={mode} onSubmit={handleSubmit} noValidate>
|
|
290
|
+
{brandRow}
|
|
291
|
+
{inviteBrand}
|
|
292
|
+
{inviteLine ? <p className="acct-auth-invite-line">{inviteLine}</p> : null}
|
|
293
|
+
{body}
|
|
294
|
+
<p className="acct-auth-switch">
|
|
295
|
+
{signUp ? <a href={href}>Sign in</a> : <a href={href}>Create an account</a>}
|
|
296
|
+
</p>
|
|
297
|
+
{error ? (
|
|
298
|
+
<p className="acct-auth-error" role="alert">
|
|
299
|
+
{error}
|
|
300
|
+
</p>
|
|
301
|
+
) : null}
|
|
302
|
+
{info ? (
|
|
303
|
+
<p className="acct-auth-info" role="status">
|
|
304
|
+
{info}
|
|
305
|
+
</p>
|
|
306
|
+
) : null}
|
|
307
|
+
</form>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { memo, type FC } from "react";
|
|
4
|
+
import { useAuiState } from "@assistant-ui/react";
|
|
5
|
+
import type { SyntaxHighlighterProps } from "@assistant-ui/react-markdown";
|
|
6
|
+
import {
|
|
7
|
+
MermaidDiagram as MermaidDiagramBase,
|
|
8
|
+
MermaidZoom,
|
|
9
|
+
} from "./mermaid-diagram";
|
|
10
|
+
|
|
11
|
+
export type MermaidDiagramProps = SyntaxHighlighterProps & {
|
|
12
|
+
className?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Use it by passing to `componentsByLanguage` for mermaid in `markdown-text.tsx`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const MarkdownTextImpl = () => {
|
|
20
|
+
* return (
|
|
21
|
+
* <MarkdownTextPrimitive
|
|
22
|
+
* remarkPlugins={[remarkGfm]}
|
|
23
|
+
* className="aui-md"
|
|
24
|
+
* components={defaultComponents}
|
|
25
|
+
* componentsByLanguage={{
|
|
26
|
+
* mermaid: {
|
|
27
|
+
* SyntaxHighlighter: MermaidDiagram
|
|
28
|
+
* },
|
|
29
|
+
* }}
|
|
30
|
+
* />
|
|
31
|
+
* );
|
|
32
|
+
* };
|
|
33
|
+
*/
|
|
34
|
+
const MermaidDiagramImpl: FC<MermaidDiagramProps> = ({
|
|
35
|
+
code,
|
|
36
|
+
className,
|
|
37
|
+
node: _node,
|
|
38
|
+
components: _components,
|
|
39
|
+
language: _language,
|
|
40
|
+
}) => {
|
|
41
|
+
const isStreaming = useAuiState(
|
|
42
|
+
(s) => s.optional.part?.status.type === "running",
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<MermaidDiagramBase
|
|
47
|
+
code={code}
|
|
48
|
+
{...(className !== undefined ? { className } : {})}
|
|
49
|
+
streaming={isStreaming}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const MermaidDiagram = memo(
|
|
55
|
+
MermaidDiagramImpl,
|
|
56
|
+
) as unknown as FC<MermaidDiagramProps> & {
|
|
57
|
+
Zoom: typeof MermaidZoom;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
MermaidDiagram.displayName = "MermaidDiagram";
|
|
61
|
+
MermaidDiagram.Zoom = MermaidZoom;
|
|
62
|
+
|
|
63
|
+
export { MermaidDiagram, MermaidZoom };
|