@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,197 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useState, type ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Docs shell: a sticky, scroll-spied sidebar on desktop and a native
|
|
6
|
+
* <details> disclosure on mobile — the sidebar never just vanishes
|
|
7
|
+
* (canon §17). One nav model, rendered twice. Presentation-generic: nav
|
|
8
|
+
* groups, hero, and content arrive as props/children; nothing app-specific
|
|
9
|
+
* is baked in. Structural CSS (grid reveal, sticky offset, disclosure
|
|
10
|
+
* marker, scroll margins) lives in styles/docs.css; consumers with fixed
|
|
11
|
+
* chrome set --docs-nav-h on the shell or an ancestor.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export interface DocsNavItem {
|
|
15
|
+
/** id of the section element this entry links to (`#id`) and scroll-spies. */
|
|
16
|
+
id: string;
|
|
17
|
+
label: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* A page link instead of an in-page section: the entry is not spied and is
|
|
20
|
+
* lit only when `current`. Lets one sidebar span a docs site's pages.
|
|
21
|
+
*/
|
|
22
|
+
href?: string;
|
|
23
|
+
current?: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DocsNavGroup {
|
|
27
|
+
label: ReactNode;
|
|
28
|
+
items: DocsNavItem[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface DocsHero {
|
|
32
|
+
kicker?: ReactNode;
|
|
33
|
+
title: ReactNode;
|
|
34
|
+
lede?: ReactNode;
|
|
35
|
+
actions?: ReactNode;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Scroll-spy: the last of `ids` whose element's top has passed a line a
|
|
40
|
+
* quarter down the viewport. Position rather than intersection, so a section
|
|
41
|
+
* taller than the viewport stays active the whole way through it.
|
|
42
|
+
*/
|
|
43
|
+
function useSpy(ids: string[], fallback: string): string {
|
|
44
|
+
const [active, setActive] = useState(fallback);
|
|
45
|
+
const key = ids.join("\n");
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const list = key ? key.split("\n") : [];
|
|
48
|
+
let frame = 0;
|
|
49
|
+
const read = () => {
|
|
50
|
+
frame = 0;
|
|
51
|
+
const line = window.innerHeight * 0.25;
|
|
52
|
+
let next = list[0] ?? "";
|
|
53
|
+
for (const id of list) {
|
|
54
|
+
const el = document.getElementById(id);
|
|
55
|
+
if (el && el.getBoundingClientRect().top <= line) next = id;
|
|
56
|
+
}
|
|
57
|
+
setActive(next);
|
|
58
|
+
};
|
|
59
|
+
const onScroll = () => {
|
|
60
|
+
if (frame === 0) frame = requestAnimationFrame(read);
|
|
61
|
+
};
|
|
62
|
+
read();
|
|
63
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
64
|
+
window.addEventListener("resize", onScroll);
|
|
65
|
+
return () => {
|
|
66
|
+
cancelAnimationFrame(frame);
|
|
67
|
+
window.removeEventListener("scroll", onScroll);
|
|
68
|
+
window.removeEventListener("resize", onScroll);
|
|
69
|
+
};
|
|
70
|
+
}, [key]);
|
|
71
|
+
return active;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function DocsLayout({
|
|
75
|
+
nav,
|
|
76
|
+
hero,
|
|
77
|
+
children,
|
|
78
|
+
rail,
|
|
79
|
+
railLabel = "on this page",
|
|
80
|
+
search,
|
|
81
|
+
contentsLabel = "contents",
|
|
82
|
+
ariaLabel = "docs",
|
|
83
|
+
className,
|
|
84
|
+
}: {
|
|
85
|
+
nav: DocsNavGroup[];
|
|
86
|
+
hero?: DocsHero;
|
|
87
|
+
children: ReactNode;
|
|
88
|
+
/**
|
|
89
|
+
* On-this-page entries: a second, narrower rail on wide viewports. Either
|
|
90
|
+
* one list for the whole page, or a list per nav entry (keyed by nav item
|
|
91
|
+
* id) so the rail follows the section being read.
|
|
92
|
+
*/
|
|
93
|
+
rail?: DocsNavItem[] | Record<string, DocsNavItem[]>;
|
|
94
|
+
/** Heading above the on-this-page rail. */
|
|
95
|
+
railLabel?: ReactNode;
|
|
96
|
+
/** Search affordance, rendered above the hero. */
|
|
97
|
+
search?: ReactNode;
|
|
98
|
+
/** Label on the collapsed mobile disclosure. */
|
|
99
|
+
contentsLabel?: string;
|
|
100
|
+
/** aria-label shared by both renderings of the nav. */
|
|
101
|
+
ariaLabel?: string;
|
|
102
|
+
/** Extra classes on the shell (e.g. a wider max-width). */
|
|
103
|
+
className?: string;
|
|
104
|
+
}) {
|
|
105
|
+
// Two spies: the sidebar tracks its entries, the rail tracks its own, so a
|
|
106
|
+
// lit sub-section never un-lights the entry it belongs to.
|
|
107
|
+
const navIds = nav.flatMap((g) => g.items.filter((i) => i.href == null).map((i) => i.id));
|
|
108
|
+
const navActive = useSpy(navIds, navIds[0] ?? "");
|
|
109
|
+
const railItems = Array.isArray(rail) ? rail : rail?.[navActive];
|
|
110
|
+
const railIds = (railItems ?? []).map((i) => i.id);
|
|
111
|
+
const railActive = useSpy(railIds, railIds[0] ?? "");
|
|
112
|
+
|
|
113
|
+
const itemLink = (it: DocsNavItem, active: string) => {
|
|
114
|
+
const on = it.href != null ? it.current === true : active === it.id;
|
|
115
|
+
const current = it.href != null ? "page" : "true";
|
|
116
|
+
return (
|
|
117
|
+
<a
|
|
118
|
+
key={it.id}
|
|
119
|
+
href={it.href ?? `#${it.id}`}
|
|
120
|
+
aria-current={on ? current : undefined}
|
|
121
|
+
className={`rounded-none border-s-2 px-[0.6rem] py-[0.28rem] font-mono text-[0.82rem] no-underline transition-colors duration-150 ease-brand ${
|
|
122
|
+
on
|
|
123
|
+
? "border-s-accent bg-accent-weak text-ink"
|
|
124
|
+
: "border-s-transparent text-ink-soft hover:bg-accent-weak hover:text-ink"
|
|
125
|
+
}`}
|
|
126
|
+
>
|
|
127
|
+
{it.label}
|
|
128
|
+
</a>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const sideNav = (
|
|
133
|
+
<nav aria-label={ariaLabel} className="flex flex-col gap-[0.1rem]">
|
|
134
|
+
{nav.map((g, gi) => (
|
|
135
|
+
<div key={gi} className="mt-[0.8rem] flex flex-col gap-[0.1rem]">
|
|
136
|
+
<span className="mb-[0.2rem] px-[0.6rem] font-mono text-[0.68rem] uppercase tracking-[0.12em] text-ink-mute">
|
|
137
|
+
{g.label}
|
|
138
|
+
</span>
|
|
139
|
+
{g.items.map((it) => itemLink(it, navActive))}
|
|
140
|
+
</div>
|
|
141
|
+
))}
|
|
142
|
+
</nav>
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const railNav =
|
|
146
|
+
railItems && railItems.length > 0 ? (
|
|
147
|
+
<nav
|
|
148
|
+
aria-label={typeof railLabel === "string" ? railLabel : "on this page"}
|
|
149
|
+
className="mt-[0.8rem] flex flex-col gap-[0.1rem]"
|
|
150
|
+
>
|
|
151
|
+
<span className="mb-[0.2rem] px-[0.6rem] font-mono text-[0.68rem] uppercase tracking-[0.12em] text-ink-mute">
|
|
152
|
+
{railLabel}
|
|
153
|
+
</span>
|
|
154
|
+
{railItems.map((it) => itemLink(it, railActive))}
|
|
155
|
+
</nav>
|
|
156
|
+
) : null;
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<div className={className ? `docs-shell ${className}` : "docs-shell"}>
|
|
160
|
+
<aside className="docs-side">{sideNav}</aside>
|
|
161
|
+
|
|
162
|
+
<div className="docs-content flex min-w-0 flex-col gap-[clamp(1.6rem,3.5vw,2.6rem)]">
|
|
163
|
+
<details className="docs-side-mobile mb-[1.3rem] rounded-none border border-hair px-[0.85rem] py-[0.55rem]">
|
|
164
|
+
<summary className="cursor-pointer font-mono text-[0.7rem] uppercase tracking-[0.12em] text-ink-mute">
|
|
165
|
+
{contentsLabel}
|
|
166
|
+
</summary>
|
|
167
|
+
{sideNav}
|
|
168
|
+
</details>
|
|
169
|
+
|
|
170
|
+
{search != null && <div className="docs-search">{search}</div>}
|
|
171
|
+
|
|
172
|
+
{hero && (
|
|
173
|
+
<header className="docs-hero">
|
|
174
|
+
{hero.kicker != null && (
|
|
175
|
+
<p className="m-0 font-mono text-[0.68rem] uppercase tracking-[0.14em] text-accent">
|
|
176
|
+
{hero.kicker}
|
|
177
|
+
</p>
|
|
178
|
+
)}
|
|
179
|
+
<h1 className="mb-[0.7rem] mt-[0.5rem] font-display text-[clamp(1.9rem,4vw,2.7rem)] font-normal tracking-[-0.02em] text-ink">
|
|
180
|
+
{hero.title}
|
|
181
|
+
</h1>
|
|
182
|
+
{hero.lede != null && (
|
|
183
|
+
<p className="m-0 max-w-[60ch] leading-[1.6] text-ink-soft">{hero.lede}</p>
|
|
184
|
+
)}
|
|
185
|
+
{hero.actions != null && <div className="mt-[1rem]">{hero.actions}</div>}
|
|
186
|
+
</header>
|
|
187
|
+
)}
|
|
188
|
+
|
|
189
|
+
{children}
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
{/* The column stays whenever a rail is given, so an entry with no
|
|
193
|
+
sub-sections empties it instead of reflowing the page. */}
|
|
194
|
+
{rail != null && <aside className="docs-rail">{railNav}</aside>}
|
|
195
|
+
</div>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils";
|
|
5
|
+
import { Kbd } from "../../ui/kbd";
|
|
6
|
+
import { SearchBar } from "../../ui/search-bar";
|
|
7
|
+
import type { DocsNavItem } from "./DocsLayout";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Docs search — the bordered `⌘K` affordance over a page's own headings.
|
|
11
|
+
* There is no index and no dependency: the caller hands over the same
|
|
12
|
+
* `DocsNavItem[]` the rail renders, and the field filters them on the client.
|
|
13
|
+
* `⌘K` / `Ctrl-K` focuses the field from anywhere on the page (D1, #4429).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Case-insensitive match over an item's label, falling back to its id. */
|
|
17
|
+
export function filterDocsItems(items: DocsNavItem[], query: string): DocsNavItem[] {
|
|
18
|
+
const needle = query.trim().toLowerCase();
|
|
19
|
+
if (needle === "") return [];
|
|
20
|
+
return items.filter((item) =>
|
|
21
|
+
typeof item.label === "string"
|
|
22
|
+
? item.label.toLowerCase().includes(needle)
|
|
23
|
+
: item.id.toLowerCase().includes(needle),
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface DocsSearchProps {
|
|
28
|
+
items: DocsNavItem[];
|
|
29
|
+
/** Accessible name for the field. */
|
|
30
|
+
label?: string;
|
|
31
|
+
placeholder?: string;
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function DocsSearch({
|
|
36
|
+
items,
|
|
37
|
+
label = "Search sections",
|
|
38
|
+
placeholder = "Search",
|
|
39
|
+
className,
|
|
40
|
+
}: DocsSearchProps) {
|
|
41
|
+
const [query, setQuery] = useState("");
|
|
42
|
+
const wrapRef = useRef<HTMLDivElement>(null);
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
46
|
+
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
wrapRef.current?.querySelector("input")?.focus();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
window.addEventListener("keydown", onKeyDown);
|
|
52
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
const matches = filterDocsItems(items, query);
|
|
56
|
+
|
|
57
|
+
/* Results float over the page, anchored under the field: an in-flow list
|
|
58
|
+
would push the hero down with every keystroke. */
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
ref={wrapRef}
|
|
62
|
+
className={cn("relative flex flex-col items-start", className)}
|
|
63
|
+
onKeyDown={(event) => {
|
|
64
|
+
if (event.key === "Escape") setQuery("");
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
<SearchBar
|
|
68
|
+
value={query}
|
|
69
|
+
onChange={setQuery}
|
|
70
|
+
aria-label={label}
|
|
71
|
+
placeholder={placeholder}
|
|
72
|
+
hint={<Kbd>⌘K</Kbd>}
|
|
73
|
+
/>
|
|
74
|
+
{query.trim() !== "" && (
|
|
75
|
+
<ul className="absolute end-0 top-full z-20 m-0 mt-[0.4rem] grid max-h-[min(60vh,24rem)] w-[min(100vw_-_2rem,26rem)] list-none gap-0 overflow-y-auto border border-hair bg-popover p-0 shadow-lg">
|
|
76
|
+
{matches.length > 0 ? (
|
|
77
|
+
matches.map((item) => (
|
|
78
|
+
<li key={item.id}>
|
|
79
|
+
<a
|
|
80
|
+
href={`#${item.id}`}
|
|
81
|
+
onClick={() => setQuery("")}
|
|
82
|
+
className="block px-[0.7rem] py-[0.45rem] font-mono text-[0.82rem] text-ink-soft no-underline transition-colors duration-150 ease-brand hover:bg-accent-weak hover:text-ink"
|
|
83
|
+
>
|
|
84
|
+
{item.label}
|
|
85
|
+
</a>
|
|
86
|
+
</li>
|
|
87
|
+
))
|
|
88
|
+
) : (
|
|
89
|
+
<li className="px-[0.7rem] py-[0.45rem] font-mono text-[0.82rem] text-ink-mute">
|
|
90
|
+
no section matches
|
|
91
|
+
</li>
|
|
92
|
+
)}
|
|
93
|
+
</ul>
|
|
94
|
+
)}
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { CodeTabs, DocsCodeBlock, type CodeSample } from "./CodeTabs";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One HTTP endpoint as doc chrome: method chip + path, summary, metadata
|
|
5
|
+
* badges, request/response field tables, and tabbed code samples.
|
|
6
|
+
* Presentation-generic — the endpoint arrives fully described as props.
|
|
7
|
+
* Method chips consume the theme-aware var(--method-*) custom props defined
|
|
8
|
+
* in styles/docs.css (never raw hex at the use site); the field-table row
|
|
9
|
+
* hairlines live there too.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export type DocsMethod = "GET" | "POST" | "PUT" | "DELETE";
|
|
13
|
+
|
|
14
|
+
export interface DocsField {
|
|
15
|
+
name: string;
|
|
16
|
+
type: string;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
description: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DocsEndpoint {
|
|
22
|
+
method: DocsMethod;
|
|
23
|
+
path: string;
|
|
24
|
+
summary: string;
|
|
25
|
+
/** Auth requirement, e.g. "none", "bearer · orders:write". */
|
|
26
|
+
auth?: string;
|
|
27
|
+
/** Rate limit note, e.g. "10/min/IP". */
|
|
28
|
+
rateLimit?: string;
|
|
29
|
+
/** Flag / gate note — rendered muted, e.g. an env toggle. */
|
|
30
|
+
flag?: string;
|
|
31
|
+
request?: DocsField[];
|
|
32
|
+
responseFields?: DocsField[];
|
|
33
|
+
/** JSON string, when a shape reads clearer than a table. */
|
|
34
|
+
responseExample?: string;
|
|
35
|
+
examples?: CodeSample[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const METHOD_BG: Record<DocsMethod, string> = {
|
|
39
|
+
GET: "bg-(--method-get)",
|
|
40
|
+
POST: "bg-(--method-post)",
|
|
41
|
+
PUT: "bg-(--method-put)",
|
|
42
|
+
DELETE: "bg-(--method-delete)",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** The colored HTTP-method chip, on its own for legends and indexes. */
|
|
46
|
+
export function MethodBadge({ method }: { method: DocsMethod }) {
|
|
47
|
+
return (
|
|
48
|
+
<span
|
|
49
|
+
className={`rounded-none px-[0.45rem] py-[0.15rem] font-mono text-[0.7rem] font-semibold tracking-[0.04em] text-on-accent ${METHOD_BG[method]}`}
|
|
50
|
+
>
|
|
51
|
+
{method}
|
|
52
|
+
</span>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function InlineCode({ children }: { children: React.ReactNode }) {
|
|
57
|
+
return (
|
|
58
|
+
<code className="rounded-none bg-ink/9 px-[0.3rem] py-[0.05rem] font-mono text-[0.82em]">
|
|
59
|
+
{children}
|
|
60
|
+
</code>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function FieldTable({ title, fields }: { title: string; fields: DocsField[] }) {
|
|
65
|
+
return (
|
|
66
|
+
<div className="flex flex-col gap-[0.3rem]">
|
|
67
|
+
<span className="font-mono text-[0.66rem] uppercase tracking-[0.12em] text-ink-mute">
|
|
68
|
+
{title}
|
|
69
|
+
</span>
|
|
70
|
+
<table className="doc-fields w-full border-collapse text-[0.84rem]">
|
|
71
|
+
<tbody>
|
|
72
|
+
{fields.map((f) => (
|
|
73
|
+
<tr key={f.name}>
|
|
74
|
+
<td className="whitespace-nowrap">
|
|
75
|
+
<InlineCode>{f.name}</InlineCode>
|
|
76
|
+
{f.required && (
|
|
77
|
+
<span className="ms-[0.15rem] text-down" title="required">
|
|
78
|
+
*
|
|
79
|
+
</span>
|
|
80
|
+
)}
|
|
81
|
+
</td>
|
|
82
|
+
<td className="whitespace-nowrap font-mono text-[0.78rem] text-ink-mute">{f.type}</td>
|
|
83
|
+
<td className="w-full leading-[1.5] text-ink-soft">{f.description}</td>
|
|
84
|
+
</tr>
|
|
85
|
+
))}
|
|
86
|
+
</tbody>
|
|
87
|
+
</table>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Small bordered metadata chip beside the endpoint head. */
|
|
93
|
+
function DocBadge({ muted, children }: { muted?: boolean; children: React.ReactNode }) {
|
|
94
|
+
return (
|
|
95
|
+
<span
|
|
96
|
+
className={`whitespace-nowrap rounded-none border border-hair px-[0.45rem] py-[0.15rem] font-mono text-[0.68rem] ${
|
|
97
|
+
muted ? "text-ink-mute" : "text-ink-soft"
|
|
98
|
+
}`}
|
|
99
|
+
>
|
|
100
|
+
{children}
|
|
101
|
+
</span>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function EndpointDoc({ ep }: { ep: DocsEndpoint }) {
|
|
106
|
+
return (
|
|
107
|
+
<div className="doc-endpoint flex flex-col gap-[0.55rem] rounded-none border border-hair bg-surface/55 p-[clamp(0.8rem,2vw,1.1rem)]">
|
|
108
|
+
<div className="flex flex-wrap items-center gap-[0.6rem]">
|
|
109
|
+
<MethodBadge method={ep.method} />
|
|
110
|
+
<code className="break-all font-mono text-[0.92rem] text-ink">{ep.path}</code>
|
|
111
|
+
</div>
|
|
112
|
+
<p className="m-0 text-[0.88rem] leading-[1.65] text-ink-soft">{ep.summary}</p>
|
|
113
|
+
{(ep.auth || ep.rateLimit || ep.flag) && (
|
|
114
|
+
<div className="flex flex-wrap gap-[0.35rem]">
|
|
115
|
+
{ep.auth && <DocBadge>auth · {ep.auth}</DocBadge>}
|
|
116
|
+
{ep.rateLimit && <DocBadge>{ep.rateLimit}</DocBadge>}
|
|
117
|
+
{ep.flag && <DocBadge muted>{ep.flag}</DocBadge>}
|
|
118
|
+
</div>
|
|
119
|
+
)}
|
|
120
|
+
{ep.request && ep.request.length > 0 && <FieldTable title="Request" fields={ep.request} />}
|
|
121
|
+
{ep.responseFields && ep.responseFields.length > 0 && (
|
|
122
|
+
<FieldTable title="Response" fields={ep.responseFields} />
|
|
123
|
+
)}
|
|
124
|
+
{ep.responseExample && (
|
|
125
|
+
<div className="flex flex-col gap-[0.3rem]">
|
|
126
|
+
<span className="font-mono text-[0.66rem] uppercase tracking-[0.12em] text-ink-mute">
|
|
127
|
+
Response
|
|
128
|
+
</span>
|
|
129
|
+
<DocsCodeBlock code={ep.responseExample} copyLabel="Copy response example" />
|
|
130
|
+
</div>
|
|
131
|
+
)}
|
|
132
|
+
{ep.examples && ep.examples.length > 0 && <CodeTabs samples={ep.examples} />}
|
|
133
|
+
</div>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
import { LayoutLines } from "../page-geometry";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The framed document column (D1, #4429).
|
|
8
|
+
*
|
|
9
|
+
* Every marketing page sits between the same fixed dashed rails as the
|
|
10
|
+
* landing page (`LayoutLines`), one `--page-pad` outside the content column,
|
|
11
|
+
* so a subpage and the home page read as the same built object. Section
|
|
12
|
+
* hairlines are full-bleed and cross the rails, as the landing bands do; the
|
|
13
|
+
* outer wrapper clips them to the viewport so they never add a horizontal
|
|
14
|
+
* scroll.
|
|
15
|
+
*
|
|
16
|
+
* The frame also resets the counter the section headings number themselves
|
|
17
|
+
* from (`// 01`, `// 02`, …).
|
|
18
|
+
*
|
|
19
|
+
* Utilities only — no site/app CSS class. The column width and inline
|
|
20
|
+
* inset come from `--frame-w` / `--page-pad`.
|
|
21
|
+
*/
|
|
22
|
+
export interface DocumentFrameProps {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function DocumentFrame({ children, className }: DocumentFrameProps) {
|
|
28
|
+
return (
|
|
29
|
+
<>
|
|
30
|
+
<LayoutLines />
|
|
31
|
+
<div className="relative z-10 overflow-x-clip [counter-reset:doc-section]">
|
|
32
|
+
<div
|
|
33
|
+
className={cn(
|
|
34
|
+
"mx-auto w-full max-w-[calc(var(--frame-w)+2*var(--page-pad))]",
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
>
|
|
38
|
+
{children}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The glyph list (D1, #4429).
|
|
7
|
+
*
|
|
8
|
+
* One list grammar for the whole site: a muted `[*]` marker, then a bold
|
|
9
|
+
* lead-in and one unpunctuated clause. No borders, no bullets, no
|
|
10
|
+
* description columns — the list reads as a dense block of statements.
|
|
11
|
+
*
|
|
12
|
+
* Utilities only — no site/app CSS class.
|
|
13
|
+
*/
|
|
14
|
+
export interface GlyphListProps {
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function GlyphList({ children, className }: GlyphListProps) {
|
|
20
|
+
return (
|
|
21
|
+
<ul className={cn("m-0 grid list-none gap-[1rem] p-0", className)}>{children}</ul>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface GlyphRowProps {
|
|
26
|
+
/** The bold lead-in; rendered in ink at medium weight. */
|
|
27
|
+
label?: ReactNode;
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function GlyphRow({ label, children, className }: GlyphRowProps) {
|
|
33
|
+
return (
|
|
34
|
+
<li
|
|
35
|
+
className={cn(
|
|
36
|
+
"flex gap-[0.75rem] text-[length:var(--type-body)] leading-[var(--leading-prose)] text-ink-soft",
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
>
|
|
40
|
+
<span aria-hidden="true" className="shrink-0 font-mono text-ink-mute">
|
|
41
|
+
[*]
|
|
42
|
+
</span>
|
|
43
|
+
<span>
|
|
44
|
+
{label ? (
|
|
45
|
+
<strong className="mr-[0.6rem] font-medium text-ink">{label}</strong>
|
|
46
|
+
) : null}
|
|
47
|
+
{children}
|
|
48
|
+
</span>
|
|
49
|
+
</li>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The page opener (D1, #4429).
|
|
7
|
+
*
|
|
8
|
+
* The landing hero's grammar at page-title size: a muted `~/digithings/<path>`
|
|
9
|
+
* line, the title with a blinking block caret, and a one-sentence lede, staged
|
|
10
|
+
* in with `animate-appear` (the kit drops the entrance under reduced motion).
|
|
11
|
+
*
|
|
12
|
+
* Utilities only — no site/app CSS class.
|
|
13
|
+
*/
|
|
14
|
+
export interface PageTitleProps {
|
|
15
|
+
title: ReactNode;
|
|
16
|
+
/** The page's path under `~/digithings/`, e.g. `services`. */
|
|
17
|
+
path?: string;
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function PageTitle({ title, path, children, className }: PageTitleProps) {
|
|
23
|
+
return (
|
|
24
|
+
<header className={cn("max-w-[var(--measure-prose)]", className)}>
|
|
25
|
+
{path ? (
|
|
26
|
+
<p className="animate-appear m-0 mb-[1.1rem] font-mono text-[0.75rem] tracking-[0.04em] text-ink-mute opacity-0">
|
|
27
|
+
{`~/digithings/${path}`}
|
|
28
|
+
</p>
|
|
29
|
+
) : null}
|
|
30
|
+
<h1 className="animate-appear m-0 font-mono text-[length:var(--type-page-title)] font-medium leading-[1.2] tracking-[-0.02em] text-ink opacity-0 [animation-delay:90ms]">
|
|
31
|
+
{title}
|
|
32
|
+
<span
|
|
33
|
+
aria-hidden="true"
|
|
34
|
+
className="ml-[0.3em] inline-block h-[0.82em] w-[0.5em] bg-accent align-[-0.08em] [animation:chat-cursor-blink_1.1s_steps(1)_infinite] motion-reduce:[animation:none]"
|
|
35
|
+
/>
|
|
36
|
+
</h1>
|
|
37
|
+
{children ? (
|
|
38
|
+
<p className="animate-appear mt-[0.9rem] mb-0 text-[length:var(--type-body)] leading-[var(--leading-prose)] text-ink-soft opacity-0 [animation-delay:200ms]">
|
|
39
|
+
{children}
|
|
40
|
+
</p>
|
|
41
|
+
) : null}
|
|
42
|
+
</header>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Long-form prose wrapper (D1, #4429).
|
|
7
|
+
*
|
|
8
|
+
* Caps the measure and sets the loose reading leading, then styles the
|
|
9
|
+
* common inline elements (paragraph rhythm, links, emphasis, lists) so a
|
|
10
|
+
* prose block needs no per-element classes. Accent is furniture only —
|
|
11
|
+
* links and list markers, never body text.
|
|
12
|
+
*
|
|
13
|
+
* Utilities only — no site/app CSS class.
|
|
14
|
+
*/
|
|
15
|
+
export interface ProseProps {
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function Prose({ children, className }: ProseProps) {
|
|
21
|
+
return (
|
|
22
|
+
<div
|
|
23
|
+
className={cn(
|
|
24
|
+
"max-w-[var(--measure-prose)] text-[length:var(--type-body)] leading-[var(--leading-prose)] text-ink-soft",
|
|
25
|
+
"[&_p]:mt-[1.1em] [&_p:first-child]:mt-0",
|
|
26
|
+
"[&_a]:text-ink [&_a]:underline [&_a]:underline-offset-[3px]",
|
|
27
|
+
"[&_strong]:font-medium [&_strong]:text-ink",
|
|
28
|
+
"[&_em]:italic",
|
|
29
|
+
"[&_ul]:mt-[1.1em] [&_ul]:list-none [&_ul]:p-0 [&_li]:relative [&_li]:pl-[1.4em] [&_li]:leading-[var(--leading-prose)]",
|
|
30
|
+
"[&_li]:before:absolute [&_li]:before:left-0 [&_li]:before:text-ink-mute [&_li]:before:content-['[_*]_']",
|
|
31
|
+
"[&_ol]:mt-[1.1em] [&_ol]:pl-[1.4em] [&_li]:marker:text-ink-mute",
|
|
32
|
+
className,
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
import { Reveal } from "../../motion/primitives";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A document section (D1, #4429).
|
|
8
|
+
*
|
|
9
|
+
* A full-bleed hairline on top — it crosses the page rails, as the landing
|
|
10
|
+
* bands' rules do — then one inline inset (`--page-pad`) and a block step
|
|
11
|
+
* tighter than the landing's `--page-step`, because a document section is a
|
|
12
|
+
* few rows rather than a band. Headings number themselves `// 01`, `// 02`
|
|
13
|
+
* from the frame's counter. The content rises in once when scrolled into view.
|
|
14
|
+
*
|
|
15
|
+
* Utilities only — no site/app CSS class.
|
|
16
|
+
*/
|
|
17
|
+
export interface SectionProps {
|
|
18
|
+
/** Anchor target, when a section is linked to. */
|
|
19
|
+
id?: string;
|
|
20
|
+
/** Section heading; the one h2 at `--type-section`. */
|
|
21
|
+
title?: ReactNode;
|
|
22
|
+
/** One sentence under the heading, at body size and prose leading. */
|
|
23
|
+
lede?: ReactNode;
|
|
24
|
+
children?: ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function Section({ id, title, lede, children, className }: SectionProps) {
|
|
29
|
+
return (
|
|
30
|
+
<section
|
|
31
|
+
id={id}
|
|
32
|
+
className={cn(
|
|
33
|
+
"relative px-[var(--page-pad)] py-[clamp(3rem,6vw,5rem)]",
|
|
34
|
+
"before:pointer-events-none before:absolute before:top-0 before:left-1/2 before:h-px before:w-screen before:-translate-x-1/2 before:bg-hair",
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
>
|
|
38
|
+
<Reveal>
|
|
39
|
+
{title ? (
|
|
40
|
+
<h2 className="m-0 max-w-[var(--measure-prose)] text-[length:var(--type-section)] font-medium leading-[1.35] tracking-[-0.01em] text-ink [counter-increment:doc-section] before:mb-[0.8rem] before:block before:font-mono before:text-[0.72rem] before:font-normal before:tracking-[0.04em] before:text-ink-mute before:content-['//_'_counter(doc-section,decimal-leading-zero)]">
|
|
41
|
+
{title}
|
|
42
|
+
</h2>
|
|
43
|
+
) : null}
|
|
44
|
+
{lede ? (
|
|
45
|
+
<p className="mt-[0.9rem] mb-0 max-w-[var(--measure-prose)] text-[length:var(--type-body)] leading-[var(--leading-prose)] text-ink-soft">
|
|
46
|
+
{lede}
|
|
47
|
+
</p>
|
|
48
|
+
) : null}
|
|
49
|
+
{children ? (
|
|
50
|
+
<div className={cn(title || lede ? "mt-[1.6rem]" : undefined)}>{children}</div>
|
|
51
|
+
) : null}
|
|
52
|
+
</Reveal>
|
|
53
|
+
</section>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export {
|
|
2
|
+
DocumentFrame,
|
|
3
|
+
type DocumentFrameProps,
|
|
4
|
+
} from "./DocumentFrame";
|
|
5
|
+
export { Section, type SectionProps } from "./Section";
|
|
6
|
+
export { PageTitle, type PageTitleProps } from "./PageTitle";
|
|
7
|
+
export { Prose, type ProseProps } from "./Prose";
|
|
8
|
+
export {
|
|
9
|
+
GlyphList,
|
|
10
|
+
GlyphRow,
|
|
11
|
+
type GlyphListProps,
|
|
12
|
+
type GlyphRowProps,
|
|
13
|
+
} from "./GlyphList";
|