@redocly/theme 0.70.0-next.1 → 0.70.0-next.11
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/lib/components/Buttons/ConnectMCPButton.js +19 -14
- package/lib/components/Buttons/variables.d.ts +1 -0
- package/lib/components/Buttons/variables.js +4 -1
- package/lib/components/Catalog/Catalog.js +3 -3
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.d.ts +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.js +1 -1
- package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +2 -2
- package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -1
- package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +30 -11
- package/lib/components/Catalog/CatalogFilter/CatalogFilterDateRange.js +2 -1
- package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.js +1 -1
- package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.js +2 -2
- package/lib/components/CodeBlock/CodeBlockControls.js +3 -5
- package/lib/components/Consent/Consent.d.ts +2 -0
- package/lib/components/Consent/Consent.js +17 -0
- package/lib/components/Consent/ConsentBanner.d.ts +2 -0
- package/lib/components/Consent/ConsentBanner.js +120 -0
- package/lib/components/Consent/ConsentDialog.d.ts +2 -0
- package/lib/components/Consent/ConsentDialog.js +128 -0
- package/lib/components/Consent/ConsentSettingsLink.d.ts +2 -0
- package/lib/components/Consent/ConsentSettingsLink.js +35 -0
- package/lib/components/Consent/variables.d.ts +1 -0
- package/lib/components/Consent/variables.js +31 -0
- package/lib/components/Dropdown/Dropdown.d.ts +4 -2
- package/lib/components/Dropdown/Dropdown.js +31 -9
- package/lib/components/Dropdown/DropdownMenu.d.ts +1 -0
- package/lib/components/Dropdown/DropdownMenu.js +1 -1
- package/lib/components/Feedback/Reasons.js +3 -2
- package/lib/components/Filter/FilterCheckboxes.js +30 -11
- package/lib/components/Filter/FilterDateRange.js +36 -2
- package/lib/components/Footer/Footer.js +4 -1
- package/lib/components/Image/Image.js +24 -4
- package/lib/components/JsonViewer/Helpers.d.ts +10 -2
- package/lib/components/JsonViewer/Helpers.js +32 -36
- package/lib/components/JsonViewer/JsonViewer.js +15 -18
- package/lib/components/LoadProgressBar/LoadProgressBar.d.ts +8 -0
- package/lib/components/LoadProgressBar/LoadProgressBar.js +122 -0
- package/lib/components/MCP/McpConnectionTabs.js +9 -2
- package/lib/components/Markdown/Markdown.js +3 -2
- package/lib/components/Markdown/styles/base-table.js +14 -1
- package/lib/components/Markdown/variables.js +1 -0
- package/lib/components/Menu/Menu.js +4 -0
- package/lib/components/Menu/MenuSelect.d.ts +7 -0
- package/lib/components/Menu/MenuSelect.js +129 -0
- package/lib/components/Menu/variables.js +43 -4
- package/lib/components/Navbar/Navbar.js +44 -5
- package/lib/components/Navbar/variables.js +3 -0
- package/lib/components/NavigationTabs/NavigationTab.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTab.js +93 -0
- package/lib/components/NavigationTabs/NavigationTabContent.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTabContent.js +50 -0
- package/lib/components/NavigationTabs/NavigationTabMenu.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTabMenu.js +18 -0
- package/lib/components/NavigationTabs/NavigationTabs.d.ts +7 -0
- package/lib/components/NavigationTabs/NavigationTabs.js +97 -0
- package/lib/components/NavigationTabs/variables.d.ts +1 -0
- package/lib/components/NavigationTabs/variables.js +37 -0
- package/lib/components/Portal/Portal.js +37 -5
- package/lib/components/Product/utils.js +1 -1
- package/lib/components/Search/SearchAiActionButtons.js +8 -3
- package/lib/components/Search/SearchAiActivity.d.ts +10 -0
- package/lib/components/Search/SearchAiActivity.js +278 -0
- package/lib/components/Search/SearchAiConversationInput.js +10 -6
- package/lib/components/Search/SearchAiDialog.js +13 -2
- package/lib/components/Search/SearchAiMessage.d.ts +2 -1
- package/lib/components/Search/SearchAiMessage.js +21 -109
- package/lib/components/Search/SearchAiResponse.js +1 -0
- package/lib/components/Search/SearchDialog.js +10 -0
- package/lib/components/Search/SearchItem.js +11 -10
- package/lib/components/Search/SearchTrigger.js +37 -6
- package/lib/components/Search/variables.js +17 -2
- package/lib/components/Segmented/Segmented.js +23 -3
- package/lib/components/Select/Select.js +10 -3
- package/lib/components/Select/SelectInput.d.ts +1 -0
- package/lib/components/Select/SelectInput.js +5 -11
- package/lib/components/Sidebar/Sidebar.js +2 -2
- package/lib/components/SplitButton/SplitButton.js +37 -3
- package/lib/components/TableOfContent/TableOfContent.js +2 -2
- package/lib/core/constants/common.d.ts +1 -0
- package/lib/core/constants/common.js +1 -0
- package/lib/core/constants/consent.d.ts +2 -0
- package/lib/core/constants/consent.js +30 -0
- package/lib/core/constants/index.d.ts +2 -0
- package/lib/core/constants/index.js +2 -0
- package/lib/core/constants/mcp.d.ts +2 -2
- package/lib/core/constants/mcp.js +3 -8
- package/lib/core/constants/prompt.d.ts +9 -0
- package/lib/core/constants/prompt.js +33 -0
- package/lib/core/constants/search.d.ts +1 -1
- package/lib/core/constants/search.js +6 -2
- package/lib/core/contexts/PortalContainerContext.d.ts +2 -0
- package/lib/core/contexts/PortalContainerContext.js +7 -0
- package/lib/core/hooks/code-walkthrough/use-code-panel.d.ts +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.d.ts +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough.d.ts +1 -2
- package/lib/core/hooks/code-walkthrough/use-renderable-files.d.ts +1 -1
- package/lib/core/hooks/index.d.ts +9 -0
- package/lib/core/hooks/index.js +9 -0
- package/lib/core/hooks/menu/use-collapse.js +1 -1
- package/lib/core/hooks/menu/use-mobile-menu-items.js +75 -51
- package/lib/core/hooks/menu/use-mobile-menu-levels.js +12 -7
- package/lib/core/hooks/prompt/use-prompt-actions.d.ts +7 -0
- package/lib/core/hooks/prompt/use-prompt-actions.js +19 -0
- package/lib/core/hooks/prompt/use-prompt-text-limit.d.ts +19 -0
- package/lib/core/hooks/prompt/use-prompt-text-limit.js +35 -0
- package/lib/core/hooks/search/use-persisted-quick-filter.d.ts +21 -0
- package/lib/core/hooks/search/use-persisted-quick-filter.js +92 -0
- package/lib/core/hooks/search/use-search-ai-activity.d.ts +11 -0
- package/lib/core/hooks/search/use-search-ai-activity.js +15 -0
- package/lib/core/hooks/use-connect-mcp-button.js +3 -1
- package/lib/core/hooks/use-consent-dialog.d.ts +12 -0
- package/lib/core/hooks/use-consent-dialog.js +36 -0
- package/lib/core/hooks/use-consent-telemetry.d.ts +1 -0
- package/lib/core/hooks/use-consent-telemetry.js +42 -0
- package/lib/core/hooks/use-dialog-hotkeys.js +4 -2
- package/lib/core/hooks/use-full-height.d.ts +1 -1
- package/lib/core/hooks/use-full-height.js +8 -8
- package/lib/core/hooks/use-page-actions.d.ts +1 -1
- package/lib/core/hooks/use-page-actions.js +10 -8
- package/lib/core/hooks/use-pointer-border-highlight.d.ts +7 -0
- package/lib/core/hooks/use-pointer-border-highlight.js +29 -0
- package/lib/core/hooks/use-scroll-item-into-view.d.ts +2 -0
- package/lib/core/hooks/use-scroll-item-into-view.js +16 -0
- package/lib/core/hooks/use-tab-list.d.ts +31 -0
- package/lib/core/hooks/use-tab-list.js +49 -0
- package/lib/core/hooks/use-telemetry-fallback.d.ts +2 -0
- package/lib/core/hooks/use-telemetry-fallback.js +2 -0
- package/lib/core/hooks/use-theme-hooks.js +16 -0
- package/lib/core/styles/dark.js +14 -12
- package/lib/core/styles/global.d.ts +2 -0
- package/lib/core/styles/global.js +115 -136
- package/lib/core/styles/index.d.ts +1 -0
- package/lib/core/styles/index.js +3 -1
- package/lib/core/styles/search-ai-appear.d.ts +1 -0
- package/lib/core/styles/search-ai-appear.js +18 -0
- package/lib/core/types/code-walkthrough.d.ts +84 -0
- package/lib/core/types/consent.d.ts +54 -0
- package/lib/core/types/consent.js +3 -0
- package/lib/core/types/dropdown.d.ts +1 -0
- package/lib/core/types/dropdown.js +3 -0
- package/lib/core/types/hooks.d.ts +8 -1
- package/lib/core/types/index.d.ts +4 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/types/mcp.d.ts +3 -2
- package/lib/core/types/navigation-tabs.d.ts +49 -0
- package/lib/core/types/navigation-tabs.js +3 -0
- package/lib/core/types/prompt.d.ts +9 -0
- package/lib/core/types/prompt.js +3 -0
- package/lib/core/types/search.d.ts +25 -0
- package/lib/core/utils/Dynamic.d.ts +8 -1
- package/lib/core/utils/Dynamic.js +34 -3
- package/lib/core/utils/assign-ref.d.ts +2 -0
- package/lib/core/utils/assign-ref.js +12 -0
- package/lib/core/utils/consent-settings-link-placement.d.ts +3 -0
- package/lib/core/utils/consent-settings-link-placement.js +15 -0
- package/lib/core/utils/content-segments.d.ts +12 -1
- package/lib/core/utils/content-segments.js +90 -5
- package/lib/core/utils/download-code-walkthrough.d.ts +1 -1
- package/lib/core/utils/dropdown.d.ts +2 -0
- package/lib/core/utils/dropdown.js +12 -0
- package/lib/core/utils/get-ai-prompt-link.d.ts +15 -0
- package/lib/core/utils/get-ai-prompt-link.js +29 -0
- package/lib/core/utils/get-code-walkthrough-file-text.d.ts +1 -1
- package/lib/core/utils/index.d.ts +5 -0
- package/lib/core/utils/index.js +5 -0
- package/lib/core/utils/match-code-walkthrough-conditions.d.ts +1 -1
- package/lib/core/utils/mcp.d.ts +2 -1
- package/lib/core/utils/mcp.js +13 -3
- package/lib/core/utils/menu.d.ts +4 -0
- package/lib/core/utils/menu.js +48 -8
- package/lib/core/utils/navigation-tabs.d.ts +8 -0
- package/lib/core/utils/navigation-tabs.js +71 -0
- package/lib/core/utils/search-ai-activity.d.ts +4 -0
- package/lib/core/utils/search-ai-activity.js +83 -0
- package/lib/core/utils/urls.js +3 -1
- package/lib/core/utils/with-load-progress.d.ts +3 -0
- package/lib/core/utils/with-load-progress.js +24 -19
- package/lib/ext/configure.d.ts +1 -1
- package/lib/ext/configure.js +0 -1
- package/lib/icons/ExpandCollapseIcon/ExpandCollapseIcon.d.ts +29 -0
- package/lib/icons/ExpandCollapseIcon/ExpandCollapseIcon.js +81 -0
- package/lib/icons/LinkIcon/LinkIconSymbol.d.ts +12 -0
- package/lib/icons/LinkIcon/LinkIconSymbol.js +41 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +9 -1
- package/lib/layouts/PageLayout.js +1 -1
- package/lib/layouts/RootLayout.js +2 -2
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanel.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +3 -3
- package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeStep.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.d.ts +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
- package/lib/markdoc/components/Prompt/Prompt.d.ts +15 -0
- package/lib/markdoc/components/Prompt/Prompt.js +163 -0
- package/lib/markdoc/components/Prompt/PromptActions.d.ts +13 -0
- package/lib/markdoc/components/Prompt/PromptActions.js +43 -0
- package/lib/markdoc/components/Prompt/PromptBody.d.ts +14 -0
- package/lib/markdoc/components/Prompt/PromptBody.js +99 -0
- package/lib/markdoc/components/Prompt/PromptCopyButton.d.ts +10 -0
- package/lib/markdoc/components/Prompt/PromptCopyButton.js +28 -0
- package/lib/markdoc/components/Prompt/PromptHeader.d.ts +9 -0
- package/lib/markdoc/components/Prompt/PromptHeader.js +57 -0
- package/lib/markdoc/components/Prompt/PromptShowHideButton.d.ts +7 -0
- package/lib/markdoc/components/Prompt/PromptShowHideButton.js +21 -0
- package/lib/markdoc/components/Prompt/PromptToggleLabel.d.ts +7 -0
- package/lib/markdoc/components/Prompt/PromptToggleLabel.js +28 -0
- package/lib/markdoc/components/Prompt/variables.d.ts +1 -0
- package/lib/markdoc/components/Prompt/variables.dark.d.ts +1 -0
- package/lib/markdoc/components/Prompt/variables.dark.js +8 -0
- package/lib/markdoc/components/Prompt/variables.js +44 -0
- package/lib/markdoc/components/Tabs/TabList.js +8 -6
- package/lib/markdoc/components/default.d.ts +1 -0
- package/lib/markdoc/components/default.js +1 -0
- package/lib/markdoc/default.d.ts +2 -0
- package/lib/markdoc/default.js +2 -0
- package/lib/markdoc/tags/code-walkthrough.d.ts +1 -1
- package/lib/markdoc/tags/connect-mcp.js +15 -0
- package/lib/markdoc/tags/prompt.d.ts +2 -0
- package/lib/markdoc/tags/prompt.js +56 -0
- package/package.json +4 -8
- package/src/components/Buttons/ConnectMCPButton.tsx +21 -16
- package/src/components/Buttons/variables.ts +4 -0
- package/src/components/Catalog/Catalog.tsx +6 -4
- package/src/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.tsx +3 -1
- package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +2 -2
- package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -1
- package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +37 -22
- package/src/components/Catalog/CatalogFilter/CatalogFilterDateRange.tsx +3 -2
- package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.tsx +1 -1
- package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.tsx +2 -2
- package/src/components/CodeBlock/CodeBlockControls.tsx +4 -7
- package/src/components/Consent/Consent.tsx +18 -0
- package/src/components/Consent/ConsentBanner.tsx +110 -0
- package/src/components/Consent/ConsentDialog.tsx +210 -0
- package/src/components/Consent/ConsentSettingsLink.tsx +44 -0
- package/src/components/Consent/variables.ts +28 -0
- package/src/components/Dropdown/Dropdown.tsx +32 -7
- package/src/components/Dropdown/DropdownMenu.tsx +7 -1
- package/src/components/Feedback/Reasons.tsx +3 -2
- package/src/components/Filter/FilterCheckboxes.tsx +33 -18
- package/src/components/Filter/FilterDateRange.tsx +3 -2
- package/src/components/Footer/Footer.tsx +2 -0
- package/src/components/Image/Image.tsx +26 -5
- package/src/components/JsonViewer/Helpers.tsx +51 -54
- package/src/components/JsonViewer/JsonViewer.tsx +23 -25
- package/src/components/LoadProgressBar/LoadProgressBar.tsx +113 -0
- package/src/components/MCP/McpConnectionTabs.tsx +22 -5
- package/src/components/Markdown/Markdown.tsx +3 -2
- package/src/components/Markdown/styles/base-table.ts +14 -1
- package/src/components/Markdown/variables.ts +1 -0
- package/src/components/Menu/Menu.tsx +5 -0
- package/src/components/Menu/MenuSelect.tsx +198 -0
- package/src/components/Menu/variables.ts +43 -4
- package/src/components/Navbar/Navbar.tsx +22 -5
- package/src/components/Navbar/variables.ts +3 -0
- package/src/components/NavigationTabs/NavigationTab.tsx +148 -0
- package/src/components/NavigationTabs/NavigationTabContent.tsx +66 -0
- package/src/components/NavigationTabs/NavigationTabMenu.tsx +40 -0
- package/src/components/NavigationTabs/NavigationTabs.tsx +83 -0
- package/src/components/NavigationTabs/variables.ts +34 -0
- package/src/components/Portal/Portal.tsx +4 -2
- package/src/components/Product/utils.ts +1 -1
- package/src/components/Search/SearchAiActionButtons.tsx +31 -19
- package/src/components/Search/SearchAiActivity.tsx +318 -0
- package/src/components/Search/SearchAiConversationInput.tsx +13 -7
- package/src/components/Search/SearchAiDialog.tsx +20 -4
- package/src/components/Search/SearchAiMessage.tsx +28 -136
- package/src/components/Search/SearchAiResponse.tsx +1 -0
- package/src/components/Search/SearchDialog.tsx +11 -0
- package/src/components/Search/SearchItem.tsx +19 -10
- package/src/components/Search/SearchTrigger.tsx +47 -3
- package/src/components/Search/variables.ts +17 -2
- package/src/components/Segmented/Segmented.tsx +25 -16
- package/src/components/Select/Select.tsx +12 -6
- package/src/components/Select/SelectInput.tsx +10 -18
- package/src/components/Sidebar/Sidebar.tsx +2 -2
- package/src/components/SplitButton/SplitButton.tsx +8 -2
- package/src/components/TableOfContent/TableOfContent.tsx +2 -2
- package/src/core/constants/common.ts +1 -0
- package/src/core/constants/consent.ts +29 -0
- package/src/core/constants/index.ts +2 -0
- package/src/core/constants/mcp.ts +3 -9
- package/src/core/constants/prompt.ts +34 -0
- package/src/core/constants/search.ts +6 -2
- package/src/core/contexts/PortalContainerContext.tsx +4 -0
- package/src/core/hooks/__mocks__/index.ts +5 -0
- package/src/core/hooks/__mocks__/use-theme-hooks.ts +20 -0
- package/src/core/hooks/code-walkthrough/__mocks__/MockIntersectionObserver.ts +1 -2
- package/src/core/hooks/code-walkthrough/__mocks__/mock-intersection-observer.ts +1 -2
- package/src/core/hooks/code-walkthrough/use-code-panel.ts +1 -1
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +2 -2
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +1 -1
- package/src/core/hooks/code-walkthrough/use-code-walkthrough.ts +3 -3
- package/src/core/hooks/code-walkthrough/use-renderable-files.ts +1 -1
- package/src/core/hooks/index.ts +9 -0
- package/src/core/hooks/menu/use-collapse.ts +1 -1
- package/src/core/hooks/menu/use-mobile-menu-items.ts +91 -56
- package/src/core/hooks/menu/use-mobile-menu-levels.ts +14 -6
- package/src/core/hooks/prompt/use-prompt-actions.ts +28 -0
- package/src/core/hooks/prompt/use-prompt-text-limit.ts +59 -0
- package/src/core/hooks/search/use-persisted-quick-filter.ts +125 -0
- package/src/core/hooks/search/use-search-ai-activity.ts +31 -0
- package/src/core/hooks/use-connect-mcp-button.ts +13 -2
- package/src/core/hooks/use-consent-dialog.ts +51 -0
- package/src/core/hooks/use-consent-telemetry.ts +56 -0
- package/src/core/hooks/use-dialog-hotkeys.ts +11 -5
- package/src/core/hooks/use-full-height.ts +8 -8
- package/src/core/hooks/use-page-actions.ts +21 -9
- package/src/core/hooks/use-pointer-border-highlight.ts +46 -0
- package/src/core/hooks/use-scroll-item-into-view.ts +18 -0
- package/src/core/hooks/use-tab-list.ts +63 -0
- package/src/core/hooks/use-telemetry-fallback.ts +2 -0
- package/src/core/hooks/use-theme-hooks.ts +16 -0
- package/src/core/styles/dark.ts +2 -0
- package/src/core/styles/global.ts +96 -116
- package/src/core/styles/index.ts +2 -1
- package/src/core/styles/search-ai-appear.ts +16 -0
- package/src/core/types/code-walkthrough.ts +103 -0
- package/src/core/types/consent.ts +51 -0
- package/src/core/types/dropdown.ts +1 -0
- package/src/core/types/hooks.ts +8 -0
- package/src/core/types/index.ts +4 -0
- package/src/core/types/l10n.ts +46 -2
- package/src/core/types/mcp.ts +4 -2
- package/src/core/types/navigation-tabs.ts +54 -0
- package/src/core/types/prompt.ts +11 -0
- package/src/core/types/search.ts +23 -0
- package/src/core/utils/Dynamic.tsx +67 -35
- package/src/core/utils/assign-ref.ts +9 -0
- package/src/core/utils/consent-settings-link-placement.ts +18 -0
- package/src/core/utils/content-segments.ts +98 -6
- package/src/core/utils/download-code-walkthrough.ts +1 -1
- package/src/core/utils/dropdown.ts +14 -0
- package/src/core/utils/get-ai-prompt-link.ts +30 -0
- package/src/core/utils/get-code-walkthrough-file-text.ts +1 -1
- package/src/core/utils/index.ts +5 -0
- package/src/core/utils/match-code-walkthrough-conditions.ts +1 -1
- package/src/core/utils/mcp.ts +16 -4
- package/src/core/utils/menu.ts +54 -9
- package/src/core/utils/navigation-tabs.ts +99 -0
- package/src/core/utils/search-ai-activity.ts +110 -0
- package/src/core/utils/urls.ts +3 -1
- package/src/core/utils/with-load-progress.ts +23 -18
- package/src/ext/configure.ts +1 -1
- package/src/icons/CheckboxIcon/CheckboxIcon.tsx +1 -0
- package/src/icons/ChevronSortIcon/ChevronSortIcon.tsx +1 -0
- package/src/icons/ExpandCollapseIcon/ExpandCollapseIcon.tsx +56 -0
- package/src/icons/LinkIcon/LinkIconSymbol.tsx +51 -0
- package/src/index.ts +8 -0
- package/src/layouts/PageLayout.tsx +1 -1
- package/src/layouts/RootLayout.tsx +2 -2
- package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +2 -2
- package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +4 -4
- package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodePanelToolbar.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +2 -2
- package/src/markdoc/components/Prompt/Prompt.tsx +219 -0
- package/src/markdoc/components/Prompt/PromptActions.tsx +104 -0
- package/src/markdoc/components/Prompt/PromptBody.tsx +107 -0
- package/src/markdoc/components/Prompt/PromptCopyButton.tsx +73 -0
- package/src/markdoc/components/Prompt/PromptHeader.tsx +81 -0
- package/src/markdoc/components/Prompt/PromptShowHideButton.tsx +43 -0
- package/src/markdoc/components/Prompt/PromptToggleLabel.tsx +41 -0
- package/src/markdoc/components/Prompt/variables.dark.ts +5 -0
- package/src/markdoc/components/Prompt/variables.ts +41 -0
- package/src/markdoc/components/Tabs/TabList.tsx +9 -12
- package/src/markdoc/components/default.ts +1 -0
- package/src/markdoc/default.ts +2 -0
- package/src/markdoc/tags/code-walkthrough.ts +1 -1
- package/src/markdoc/tags/connect-mcp.ts +16 -1
- package/src/markdoc/tags/prompt.ts +58 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { JSX } from 'react';
|
|
5
|
+
|
|
6
|
+
import { Button } from '@redocly/theme/components/Button/Button';
|
|
7
|
+
import { useThemeConfig, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
8
|
+
import { resolveSettingsLinkPlacement } from '@redocly/theme/core/utils';
|
|
9
|
+
|
|
10
|
+
export function ConsentSettingsLink(): JSX.Element | null {
|
|
11
|
+
const { useConsent, useTranslate } = useThemeHooks();
|
|
12
|
+
const { consent: consentConfig, footer } = useThemeConfig() || {};
|
|
13
|
+
const consent = useConsent();
|
|
14
|
+
const { translate } = useTranslate();
|
|
15
|
+
|
|
16
|
+
if (!consent.enabled || resolveSettingsLinkPlacement(consentConfig, footer) !== 'footer') {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<SettingsLinkButton
|
|
22
|
+
variant="link"
|
|
23
|
+
size="small"
|
|
24
|
+
data-component-name="Consent/ConsentSettingsLink"
|
|
25
|
+
onClick={consent.openDialog}
|
|
26
|
+
>
|
|
27
|
+
{translate('consent.settingsLink', 'Cookie preferences')}
|
|
28
|
+
</SettingsLinkButton>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const SettingsLinkButton = styled(Button)`
|
|
33
|
+
margin: var(--footer-link-padding-vertical) 0 var(--footer-link-padding-vertical) var(--spacing-sm);
|
|
34
|
+
padding: 0;
|
|
35
|
+
color: var(--footer-link-text-color);
|
|
36
|
+
font: inherit;
|
|
37
|
+
line-height: inherit;
|
|
38
|
+
|
|
39
|
+
&:hover,
|
|
40
|
+
&:focus-visible {
|
|
41
|
+
color: var(--footer-link-color-hover);
|
|
42
|
+
background: none;
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { css } from 'styled-components';
|
|
2
|
+
|
|
3
|
+
export const consent = css`
|
|
4
|
+
/**
|
|
5
|
+
* @tokens Consent
|
|
6
|
+
*/
|
|
7
|
+
--consent-banner-width: 380px;
|
|
8
|
+
--consent-banner-offset: var(--spacing-base); // @presenter Spacing
|
|
9
|
+
--consent-banner-bg-color: var(--bg-color); // @presenter Color
|
|
10
|
+
--consent-banner-text-color: var(--text-color-primary); // @presenter Color
|
|
11
|
+
--consent-banner-border-color: var(--border-color-primary); // @presenter Color
|
|
12
|
+
--consent-banner-border-radius: var(--border-radius-lg);
|
|
13
|
+
--consent-banner-box-shadow: var(--bg-raised-shadow);
|
|
14
|
+
--consent-banner-padding: var(--spacing-base); // @presenter Spacing
|
|
15
|
+
--consent-banner-gap: var(--spacing-sm); // @presenter Spacing
|
|
16
|
+
--consent-banner-title-font-size: var(--font-size-base);
|
|
17
|
+
--consent-banner-font-size: var(--font-size-sm);
|
|
18
|
+
--consent-banner-z-index: var(--z-index-overlay);
|
|
19
|
+
|
|
20
|
+
--consent-dialog-width: 560px;
|
|
21
|
+
--consent-dialog-max-width: calc(100vw - 2 * var(--spacing-base));
|
|
22
|
+
--consent-dialog-padding: var(--spacing-lg); // @presenter Spacing
|
|
23
|
+
--consent-dialog-border-radius: var(--border-radius-lg);
|
|
24
|
+
--consent-dialog-bg-color: var(--modal-bg-color); // @presenter Color
|
|
25
|
+
--consent-dialog-box-shadow: var(--modal-box-shadow);
|
|
26
|
+
--consent-dialog-row-border-color: var(--border-color-primary); // @presenter Color
|
|
27
|
+
--consent-dialog-description-color: var(--text-color-secondary); // @presenter Color
|
|
28
|
+
`;
|
|
@@ -11,9 +11,10 @@ import { createPortal } from 'react-dom';
|
|
|
11
11
|
import styled, { css } from 'styled-components';
|
|
12
12
|
|
|
13
13
|
import type { CSSProperties, ReactElement } from 'react';
|
|
14
|
-
import type { RenderableChildren } from '@redocly/theme/core/types';
|
|
14
|
+
import type { DropdownAlignment, RenderableChildren } from '@redocly/theme/core/types';
|
|
15
15
|
|
|
16
16
|
import { useOutsideClick, useControlledState } from '@redocly/theme/core/hooks';
|
|
17
|
+
import { fitDropdownAlignment } from '@redocly/theme/core/utils';
|
|
17
18
|
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
|
|
18
19
|
import { ChevronUpIcon } from '@redocly/theme/icons/ChevronUpIcon/ChevronUpIcon';
|
|
19
20
|
|
|
@@ -37,7 +38,7 @@ export type DropdownProps = {
|
|
|
37
38
|
children: RenderableChildren<DropdownMenuContext>;
|
|
38
39
|
triggerEvent?: 'click' | 'hover';
|
|
39
40
|
placement?: 'top' | 'bottom';
|
|
40
|
-
alignment?:
|
|
41
|
+
alignment?: DropdownAlignment;
|
|
41
42
|
|
|
42
43
|
active?: boolean;
|
|
43
44
|
closeOnClick?: boolean;
|
|
@@ -46,6 +47,8 @@ export type DropdownProps = {
|
|
|
46
47
|
className?: string;
|
|
47
48
|
withArrow?: boolean;
|
|
48
49
|
portalled?: boolean;
|
|
50
|
+
/** Element the menu lines up with when it is not the dropdown itself, e.g. a whole split button. */
|
|
51
|
+
alignmentAnchorRef?: React.RefObject<HTMLElement | null>;
|
|
49
52
|
|
|
50
53
|
onClick?: (event: React.UIEvent) => void;
|
|
51
54
|
onClose?: () => void;
|
|
@@ -66,6 +69,7 @@ export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
|
|
|
66
69
|
placement,
|
|
67
70
|
alignment,
|
|
68
71
|
portalled = false,
|
|
72
|
+
alignmentAnchorRef,
|
|
69
73
|
onClick,
|
|
70
74
|
onClose,
|
|
71
75
|
onOpen,
|
|
@@ -76,6 +80,7 @@ export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
|
|
|
76
80
|
const menuRef = useRef<HTMLDivElement | null>(null);
|
|
77
81
|
const [isOpen, setIsOpen] = useControlledState<boolean>(false, active);
|
|
78
82
|
const [menuStyle, setMenuStyle] = useState<CSSProperties>({});
|
|
83
|
+
const [fittedAlignment, setFittedAlignment] = useState(alignment);
|
|
79
84
|
|
|
80
85
|
const wrapperRef = (ref as React.RefObject<HTMLDivElement | null>) || dropdownRef;
|
|
81
86
|
|
|
@@ -115,7 +120,7 @@ export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
|
|
|
115
120
|
const updateMenuPosition = useCallback(() => {
|
|
116
121
|
const wrapper = wrapperRef.current;
|
|
117
122
|
if (!wrapper) return;
|
|
118
|
-
const rect = wrapper.getBoundingClientRect();
|
|
123
|
+
const rect = (alignmentAnchorRef?.current ?? wrapper).getBoundingClientRect();
|
|
119
124
|
const menuHeight = menuRef.current?.offsetHeight ?? 0;
|
|
120
125
|
const fitsBelow = rect.bottom + menuHeight <= window.innerHeight;
|
|
121
126
|
const fitsAbove = rect.top - menuHeight >= 0;
|
|
@@ -126,7 +131,7 @@ export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
|
|
|
126
131
|
} else {
|
|
127
132
|
style.top = rect.bottom;
|
|
128
133
|
}
|
|
129
|
-
if (alignment === 'end') {
|
|
134
|
+
if (fitDropdownAlignment(rect, menuRef.current?.offsetWidth ?? 0, alignment) === 'end') {
|
|
130
135
|
style.right = window.innerWidth - rect.right;
|
|
131
136
|
} else {
|
|
132
137
|
style.left = rect.left;
|
|
@@ -136,7 +141,24 @@ export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
|
|
|
136
141
|
style.zIndex = zIndex;
|
|
137
142
|
}
|
|
138
143
|
setMenuStyle(style);
|
|
139
|
-
}, [placement, alignment, wrapperRef]);
|
|
144
|
+
}, [placement, alignment, wrapperRef, alignmentAnchorRef]);
|
|
145
|
+
|
|
146
|
+
/* The absolute-positioned menu is placed by CSS, so the side is measured once it is
|
|
147
|
+
shown and again on resize; a side that runs off the viewport flips to the other one. */
|
|
148
|
+
const updateFittedAlignment = useCallback(() => {
|
|
149
|
+
const wrapper = wrapperRef.current;
|
|
150
|
+
const menu = menuRef.current;
|
|
151
|
+
if (!wrapper || !menu) return;
|
|
152
|
+
const rect = (alignmentAnchorRef?.current ?? wrapper).getBoundingClientRect();
|
|
153
|
+
setFittedAlignment(fitDropdownAlignment(rect, menu.offsetWidth, alignment));
|
|
154
|
+
}, [alignment, wrapperRef, alignmentAnchorRef]);
|
|
155
|
+
|
|
156
|
+
useIsomorphicLayoutEffect(() => {
|
|
157
|
+
if (portalled || !isOpen) return;
|
|
158
|
+
updateFittedAlignment();
|
|
159
|
+
window.addEventListener('resize', updateFittedAlignment);
|
|
160
|
+
return () => window.removeEventListener('resize', updateFittedAlignment);
|
|
161
|
+
}, [portalled, isOpen, updateFittedAlignment]);
|
|
140
162
|
|
|
141
163
|
useIsomorphicLayoutEffect(() => {
|
|
142
164
|
if (!portalled || !isOpen) return;
|
|
@@ -156,20 +178,23 @@ export const Dropdown = forwardRef<HTMLDivElement, DropdownProps>(
|
|
|
156
178
|
|
|
157
179
|
const triggerChild = React.Children.only(trigger) as ReactElement<TriggerProps>;
|
|
158
180
|
|
|
181
|
+
const isLinkTrigger = Boolean(triggerChild.props?.to || triggerChild.props?.href);
|
|
182
|
+
|
|
159
183
|
const dropdownTrigger = cloneElement(triggerChild, {
|
|
160
184
|
onClick: triggerEvent === 'click' ? handleToggle : undefined,
|
|
185
|
+
'aria-haspopup': 'menu',
|
|
161
186
|
'aria-expanded': isOpen,
|
|
162
187
|
icon: withArrow ? isOpen ? <ChevronUpIcon /> : <ChevronDownIcon /> : undefined,
|
|
163
188
|
...(withArrow ? { iconPosition: 'right' } : {}),
|
|
164
189
|
...triggerChild.props,
|
|
165
|
-
onKeyDown: triggerEvent === 'click' ? handleKeyDown : undefined,
|
|
190
|
+
onKeyDown: triggerEvent === 'click' || !isLinkTrigger ? handleKeyDown : undefined,
|
|
166
191
|
});
|
|
167
192
|
|
|
168
193
|
const menu = (
|
|
169
194
|
<ChildrenWrapper
|
|
170
195
|
ref={menuRef}
|
|
171
196
|
$placement={placement}
|
|
172
|
-
$alignment={
|
|
197
|
+
$alignment={fittedAlignment}
|
|
173
198
|
$isOpen={isOpen}
|
|
174
199
|
$portalled={portalled}
|
|
175
200
|
style={portalled ? menuStyle : undefined}
|
|
@@ -6,7 +6,12 @@ import type { DropdownMenuItemProps } from '@redocly/theme/components/Dropdown/D
|
|
|
6
6
|
|
|
7
7
|
import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
|
|
8
8
|
|
|
9
|
-
export type DropdownMenuProps = {
|
|
9
|
+
export type DropdownMenuProps = {
|
|
10
|
+
id?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
role?: string;
|
|
13
|
+
footer?: React.ReactNode;
|
|
14
|
+
} & (
|
|
10
15
|
| {
|
|
11
16
|
items: DropdownMenuItemProps[];
|
|
12
17
|
}
|
|
@@ -32,6 +37,7 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
|
|
|
32
37
|
<DropdownMenuWrapper
|
|
33
38
|
data-component-name="Dropdown/DropdownMenu"
|
|
34
39
|
data-testid="dropdown-menu"
|
|
40
|
+
id={props.id}
|
|
35
41
|
className={props.className}
|
|
36
42
|
role={props.role || 'menu'}
|
|
37
43
|
>
|
|
@@ -18,6 +18,7 @@ export type ReasonsProps = {
|
|
|
18
18
|
export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.Element | null {
|
|
19
19
|
const { label, component = 'checkbox', items = [] } = settings;
|
|
20
20
|
const [checkedState, setCheckedState] = React.useState(new Array(items.length).fill(false));
|
|
21
|
+
const idPrefix = React.useId();
|
|
21
22
|
const { useTranslate } = useThemeHooks();
|
|
22
23
|
const { translate } = useTranslate();
|
|
23
24
|
|
|
@@ -51,6 +52,7 @@ export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.El
|
|
|
51
52
|
{items.map((reason, idx) => (
|
|
52
53
|
<OptionWrapper key={reason}>
|
|
53
54
|
<input
|
|
55
|
+
id={`${idPrefix}-${idx}`}
|
|
54
56
|
type={component}
|
|
55
57
|
value={reason}
|
|
56
58
|
checked={checkedState[idx]}
|
|
@@ -59,8 +61,7 @@ export function Reasons({ settings, onChange, className }: ReasonsProps): JSX.El
|
|
|
59
61
|
/>
|
|
60
62
|
<label
|
|
61
63
|
data-translation-key={`feedback.settings.reasons.items.${idx + 1}`}
|
|
62
|
-
|
|
63
|
-
onClick={() => handleOptionChange(idx)}
|
|
64
|
+
htmlFor={`${idPrefix}-${idx}`}
|
|
64
65
|
>
|
|
65
66
|
{translate(`feedback.settings.reasons.items.${idx + 1}`, reason)}
|
|
66
67
|
</label>
|
|
@@ -30,26 +30,24 @@ export function FilterCheckboxes({
|
|
|
30
30
|
<FilterOptions>
|
|
31
31
|
{(filter.filteredOptions || filter.options).map(({ value, count }) => {
|
|
32
32
|
const id = 'filter--' + filter.property + '--' + value;
|
|
33
|
+
const checked =
|
|
34
|
+
filter.selectedOptions instanceof Set
|
|
35
|
+
? filter.selectedOptions.has(value) ||
|
|
36
|
+
filter.selectedOptions.has(value?.toLowerCase())
|
|
37
|
+
: false;
|
|
33
38
|
return (
|
|
34
|
-
<FilterCheckboxOption
|
|
35
|
-
|
|
36
|
-
role="link"
|
|
37
|
-
onClick={() => {
|
|
38
|
-
filter.toggleOption(value);
|
|
39
|
-
telemetry.sendFilterCheckboxToggledMessage([
|
|
40
|
-
getBaseDataAttributes('filterId', 'checkbox'),
|
|
41
|
-
]);
|
|
42
|
-
}}
|
|
43
|
-
>
|
|
44
|
-
<CheckboxIcon
|
|
45
|
-
checked={
|
|
46
|
-
filter.selectedOptions instanceof Set
|
|
47
|
-
? filter.selectedOptions.has(value) ||
|
|
48
|
-
filter.selectedOptions.has(value?.toLowerCase())
|
|
49
|
-
: false
|
|
50
|
-
}
|
|
51
|
-
/>
|
|
39
|
+
<FilterCheckboxOption key={id}>
|
|
40
|
+
<CheckboxIcon checked={checked} />
|
|
52
41
|
<FilterOptionLabel data-translation-key={value}>
|
|
42
|
+
<FilterCheckboxInput
|
|
43
|
+
checked={checked}
|
|
44
|
+
onChange={() => {
|
|
45
|
+
filter.toggleOption(value);
|
|
46
|
+
telemetry.sendFilterCheckboxToggledMessage([
|
|
47
|
+
getBaseDataAttributes('filterId', 'checkbox'),
|
|
48
|
+
]);
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
53
51
|
{changeTextCasing(translate(value), filterValuesCasing)}
|
|
54
52
|
</FilterOptionLabel>
|
|
55
53
|
{showCounter && <CounterTag borderless>{count}</CounterTag>}
|
|
@@ -63,6 +61,23 @@ export function FilterCheckboxes({
|
|
|
63
61
|
|
|
64
62
|
const FilterCheckboxOption = styled(FilterOption)`
|
|
65
63
|
padding-left: var(--filter-option-checkbox-padding-left);
|
|
64
|
+
|
|
65
|
+
&:has(input:focus-visible) {
|
|
66
|
+
outline: 1px solid var(--button-border-color-focused);
|
|
67
|
+
outline-offset: -1px;
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
const FilterCheckboxInput = styled.input.attrs({ type: 'checkbox' })`
|
|
72
|
+
position: absolute;
|
|
73
|
+
width: 1px;
|
|
74
|
+
height: 1px;
|
|
75
|
+
margin: -1px;
|
|
76
|
+
padding: 0;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
clip: rect(0 0 0 0);
|
|
79
|
+
white-space: nowrap;
|
|
80
|
+
border: 0;
|
|
66
81
|
`;
|
|
67
82
|
|
|
68
83
|
const FilterCheckboxesWrapper = styled.div`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
4
|
import type { JSX } from 'react';
|
|
@@ -11,6 +11,7 @@ import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
|
11
11
|
import { formatDateWithoutTimeZone } from '@redocly/theme/core/utils';
|
|
12
12
|
|
|
13
13
|
export function FilterDateRange({ filter }: FilterProps): JSX.Element {
|
|
14
|
+
const [today] = useState(() => new Date());
|
|
14
15
|
const { useTranslate } = useThemeHooks();
|
|
15
16
|
const { translate } = useTranslate();
|
|
16
17
|
|
|
@@ -33,7 +34,7 @@ export function FilterDateRange({ filter }: FilterProps): JSX.Element {
|
|
|
33
34
|
monthPlaceholder="MM"
|
|
34
35
|
yearPlaceholder="YYYY"
|
|
35
36
|
value={from}
|
|
36
|
-
maxDate={
|
|
37
|
+
maxDate={today}
|
|
37
38
|
onChange={(from) => {
|
|
38
39
|
if (Array.isArray(from)) return;
|
|
39
40
|
filter.selectOption({
|
|
@@ -9,6 +9,7 @@ import { breakpoints, isEmptyArray } from '@redocly/theme/core/utils';
|
|
|
9
9
|
import { useThemeConfig } from '@redocly/theme/core/hooks';
|
|
10
10
|
import { FooterCopyright } from '@redocly/theme/components/Footer/FooterCopyright';
|
|
11
11
|
import { FooterColumn } from '@redocly/theme/components/Footer/FooterColumn';
|
|
12
|
+
import { ConsentSettingsLink } from '@redocly/theme/components/Consent/ConsentSettingsLink';
|
|
12
13
|
|
|
13
14
|
export type FooterProps = {
|
|
14
15
|
className?: string;
|
|
@@ -43,6 +44,7 @@ export function Footer({ className }: FooterProps): JSX.Element | null {
|
|
|
43
44
|
)}
|
|
44
45
|
<FooterCopyrightWrapper>
|
|
45
46
|
{copyrightText && <FooterCopyright copyrightText={copyrightText} />}
|
|
47
|
+
<ConsentSettingsLink />
|
|
46
48
|
</FooterCopyrightWrapper>
|
|
47
49
|
</FooterWrapper>
|
|
48
50
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import type { KeyboardEvent, JSX } from 'react';
|
|
4
|
+
import type { KeyboardEvent, JSX, MouseEvent } from 'react';
|
|
5
5
|
|
|
6
6
|
import { parseSrcSet, parseStyleString } from '@redocly/theme/core/utils';
|
|
7
7
|
import { useModalScrollLock } from '@redocly/theme/core/hooks';
|
|
@@ -42,6 +42,7 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
42
42
|
} = props;
|
|
43
43
|
|
|
44
44
|
const lightboxContainerRef = useRef<HTMLDivElement>(null);
|
|
45
|
+
const lightboxTriggerRef = useRef<HTMLElement | null>(null);
|
|
45
46
|
const [lightboxImage, setLightboxImage] = useState<string | undefined>(undefined);
|
|
46
47
|
const parsedSourceSetMap = useMemo(() => {
|
|
47
48
|
return srcSet ? parseSrcSet(srcSet) : new Map();
|
|
@@ -55,15 +56,32 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
55
56
|
}, []);
|
|
56
57
|
|
|
57
58
|
const handleImageClick = useCallback(
|
|
58
|
-
(src: string) => {
|
|
59
|
+
(src: string, trigger: HTMLElement) => {
|
|
59
60
|
if (!withLightbox || lightboxImage) {
|
|
60
61
|
return;
|
|
61
62
|
}
|
|
63
|
+
lightboxTriggerRef.current = trigger;
|
|
62
64
|
setLightboxImage(src);
|
|
63
65
|
},
|
|
64
66
|
[withLightbox, lightboxImage],
|
|
65
67
|
);
|
|
66
68
|
|
|
69
|
+
const getLightboxTriggerProps = (imageSrc: string) =>
|
|
70
|
+
withLightbox
|
|
71
|
+
? {
|
|
72
|
+
role: 'button',
|
|
73
|
+
tabIndex: 0,
|
|
74
|
+
'aria-label': alt ? undefined : 'Open image',
|
|
75
|
+
onClick: (e: MouseEvent<HTMLElement>) => handleImageClick(imageSrc, e.currentTarget),
|
|
76
|
+
onKeyDown: (e: KeyboardEvent<HTMLElement>) => {
|
|
77
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
78
|
+
e.preventDefault();
|
|
79
|
+
handleImageClick(imageSrc, e.currentTarget);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
: {};
|
|
84
|
+
|
|
67
85
|
const handleCloseLightbox = useCallback(() => {
|
|
68
86
|
setLightboxImage(undefined);
|
|
69
87
|
}, []);
|
|
@@ -72,6 +90,9 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
72
90
|
useEffect(() => {
|
|
73
91
|
if (lightboxImage) {
|
|
74
92
|
lightboxContainerRef.current?.focus();
|
|
93
|
+
} else {
|
|
94
|
+
lightboxTriggerRef.current?.focus();
|
|
95
|
+
lightboxTriggerRef.current = null;
|
|
75
96
|
}
|
|
76
97
|
}, [lightboxImage]);
|
|
77
98
|
|
|
@@ -92,7 +113,7 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
92
113
|
width={width}
|
|
93
114
|
height={height}
|
|
94
115
|
style={combinedStyles}
|
|
95
|
-
|
|
116
|
+
{...getLightboxTriggerProps(src)}
|
|
96
117
|
/>
|
|
97
118
|
) : (
|
|
98
119
|
Array.from(parsedSourceSetMap).map(([key, value]) => (
|
|
@@ -106,7 +127,7 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
106
127
|
height={height}
|
|
107
128
|
$withLightbox={withLightbox}
|
|
108
129
|
style={combinedStyles}
|
|
109
|
-
|
|
130
|
+
{...getLightboxTriggerProps(value)}
|
|
110
131
|
/>
|
|
111
132
|
))
|
|
112
133
|
);
|
|
@@ -122,7 +143,7 @@ export function Image(props: ImageProps): JSX.Element {
|
|
|
122
143
|
src={galleryImageSrc}
|
|
123
144
|
alt={alt}
|
|
124
145
|
style={withLightbox ? { cursor: 'pointer' } : undefined}
|
|
125
|
-
|
|
146
|
+
{...getLightboxTriggerProps(galleryImageSrc)}
|
|
126
147
|
/>
|
|
127
148
|
))}
|
|
128
149
|
</GalleryRow>
|
|
@@ -7,40 +7,50 @@ import { Button } from '@redocly/theme/components/Button/Button';
|
|
|
7
7
|
import { ShowMoreToggleButton } from '@redocly/theme/components/Button/ShowMoreToggleButton';
|
|
8
8
|
import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
|
|
9
9
|
|
|
10
|
+
export type JsonFold = {
|
|
11
|
+
isExpanded: (path: string, level: number) => boolean;
|
|
12
|
+
setExpanded: (path: string, expanded: boolean) => void;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type Foldable = [path: string, level: number];
|
|
16
|
+
|
|
17
|
+
export function isFoldable(value: unknown): value is Record<string, unknown> {
|
|
18
|
+
return (
|
|
19
|
+
typeof value === 'object' &&
|
|
20
|
+
value !== null &&
|
|
21
|
+
Object.values(value).some((item) => item !== undefined)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function collectFoldables(value: unknown, path = '', level = 1): Foldable[] {
|
|
26
|
+
if (!isFoldable(value)) return [];
|
|
27
|
+
return Object.entries(value).flatMap(([key, child]): Foldable[] => {
|
|
28
|
+
const childPath = `${path}/${key}`;
|
|
29
|
+
return isFoldable(child)
|
|
30
|
+
? [[childPath, level], ...collectFoldables(child, childPath, level + 1)]
|
|
31
|
+
: [];
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
10
35
|
export function JsonValue(props: {
|
|
11
36
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
12
37
|
value: any;
|
|
13
38
|
level: number;
|
|
39
|
+
path: string;
|
|
14
40
|
standalone?: boolean; // if true, will render the opening and closing punctuation (when it's an item inside array or top-level)
|
|
15
|
-
|
|
16
|
-
expandAllSignal: boolean | undefined;
|
|
41
|
+
fold: JsonFold;
|
|
17
42
|
maxStringLength?: number;
|
|
18
43
|
}): React.ReactNode {
|
|
19
|
-
const { standalone,
|
|
44
|
+
const { standalone, fold, level, path, value, maxStringLength } = props;
|
|
20
45
|
const indent = ' '.repeat(level * 2);
|
|
21
|
-
|
|
22
|
-
const [isExpandedState, setExpanded] = React.useState(
|
|
23
|
-
expandAllSignal ?? level < defaultExpandLevel,
|
|
24
|
-
);
|
|
25
|
-
const isExpanded = expandAllSignal !== undefined && level > 0 ? expandAllSignal : isExpandedState;
|
|
26
|
-
const [prevExpandAllSignal, setPrevExpandAllSignal] = React.useState(expandAllSignal);
|
|
27
|
-
const [prevLevel, setPrevLevel] = React.useState(level);
|
|
28
|
-
|
|
29
|
-
if (prevExpandAllSignal !== expandAllSignal || prevLevel !== level) {
|
|
30
|
-
setPrevExpandAllSignal(expandAllSignal);
|
|
31
|
-
setPrevLevel(level);
|
|
32
|
-
if (expandAllSignal !== undefined && !(expandAllSignal === false && level === 0)) {
|
|
33
|
-
setExpanded(expandAllSignal);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
46
|
+
const isExpanded = fold.isExpanded(path, level);
|
|
36
47
|
|
|
37
48
|
const keys: string[] =
|
|
38
49
|
(value && Object.keys(value).filter((key) => value[key] !== undefined)) || []; // filter out undefined properties
|
|
39
50
|
|
|
40
51
|
const valueType = typeof value;
|
|
41
|
-
const isPrimitive = (valueType !== 'object' && value !== null) || keys.length === 0;
|
|
42
52
|
|
|
43
|
-
if (
|
|
53
|
+
if (!isFoldable(value)) {
|
|
44
54
|
const isOversizedString =
|
|
45
55
|
typeof value === 'string' && maxStringLength !== undefined && value.length > maxStringLength;
|
|
46
56
|
return (
|
|
@@ -64,12 +74,12 @@ export function JsonValue(props: {
|
|
|
64
74
|
<JsonValue
|
|
65
75
|
value={item}
|
|
66
76
|
level={level + 1}
|
|
77
|
+
path={`${path}/${index}`}
|
|
67
78
|
standalone={true}
|
|
68
|
-
|
|
69
|
-
expandAllSignal={expandAllSignal}
|
|
79
|
+
fold={fold}
|
|
70
80
|
maxStringLength={maxStringLength}
|
|
71
81
|
/>
|
|
72
|
-
{index < value.length - 1 ? ',\n' : null}
|
|
82
|
+
{index < value.length - 1 ? <span>{',\n'}</span> : null}
|
|
73
83
|
</React.Fragment>
|
|
74
84
|
))
|
|
75
85
|
: keys.map((key, index) => (
|
|
@@ -78,11 +88,11 @@ export function JsonValue(props: {
|
|
|
78
88
|
name={key}
|
|
79
89
|
value={value[key]}
|
|
80
90
|
level={level + 1}
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
path={`${path}/${key}`}
|
|
92
|
+
fold={fold}
|
|
83
93
|
maxStringLength={maxStringLength}
|
|
84
94
|
/>
|
|
85
|
-
{index < keys.length - 1 ? ',\n' : null}
|
|
95
|
+
{index < keys.length - 1 ? <span>{',\n'}</span> : null}
|
|
86
96
|
</React.Fragment>
|
|
87
97
|
));
|
|
88
98
|
|
|
@@ -90,7 +100,7 @@ export function JsonValue(props: {
|
|
|
90
100
|
<>
|
|
91
101
|
{indent}
|
|
92
102
|
{level > 0 ? (
|
|
93
|
-
<ExpandIcon onClick={() => setExpanded(
|
|
103
|
+
<ExpandIcon onClick={() => fold.setExpanded(path, !isExpanded)} isExpanded={isExpanded} />
|
|
94
104
|
) : null}
|
|
95
105
|
{openingPunctuation}
|
|
96
106
|
{isExpanded ? '\n' : null}
|
|
@@ -119,33 +129,18 @@ function JsonKeyValue(props: {
|
|
|
119
129
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
120
130
|
value: any;
|
|
121
131
|
level: number;
|
|
122
|
-
|
|
123
|
-
|
|
132
|
+
path: string;
|
|
133
|
+
fold: JsonFold;
|
|
124
134
|
maxStringLength?: number;
|
|
125
135
|
}): React.ReactNode {
|
|
126
|
-
const {
|
|
136
|
+
const { fold, level, name, path, value, maxStringLength } = props;
|
|
127
137
|
const indent = ' '.repeat(level * 2);
|
|
128
|
-
const
|
|
129
|
-
(value && Object.keys(value).filter((key) => value[key] !== undefined)) || []; // filter out undefined properties
|
|
130
|
-
|
|
131
|
-
const isCollapsible = typeof value === 'object' && value !== null && keys.length > 0;
|
|
132
|
-
const [isExpandedState, setExpanded] = React.useState(
|
|
133
|
-
expandAllSignal ?? level < defaultExpandLevel,
|
|
134
|
-
);
|
|
135
|
-
const isExpanded = expandAllSignal !== undefined ? expandAllSignal : isExpandedState;
|
|
136
|
-
const [prevExpandAllSignal, setPrevExpandAllSignal] = React.useState(expandAllSignal);
|
|
137
|
-
|
|
138
|
-
if (prevExpandAllSignal !== expandAllSignal) {
|
|
139
|
-
setPrevExpandAllSignal(expandAllSignal);
|
|
140
|
-
if (expandAllSignal !== undefined) {
|
|
141
|
-
setExpanded(expandAllSignal);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
138
|
+
const isExpanded = fold.isExpanded(path, level);
|
|
144
139
|
|
|
145
140
|
const openingPunctuation = Array.isArray(value) ? '[' : '{';
|
|
146
141
|
const closingPunctuation = Array.isArray(value) ? ']' : '}';
|
|
147
142
|
|
|
148
|
-
const valueElement =
|
|
143
|
+
const valueElement = isFoldable(value) ? (
|
|
149
144
|
<>
|
|
150
145
|
{openingPunctuation}
|
|
151
146
|
{isExpanded ? (
|
|
@@ -154,8 +149,8 @@ function JsonKeyValue(props: {
|
|
|
154
149
|
<JsonValue
|
|
155
150
|
value={value}
|
|
156
151
|
level={level}
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
path={path}
|
|
153
|
+
fold={fold}
|
|
159
154
|
maxStringLength={maxStringLength}
|
|
160
155
|
/>
|
|
161
156
|
{'\n'}
|
|
@@ -170,8 +165,8 @@ function JsonKeyValue(props: {
|
|
|
170
165
|
<JsonValue
|
|
171
166
|
value={value}
|
|
172
167
|
level={level}
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
path={path}
|
|
169
|
+
fold={fold}
|
|
175
170
|
maxStringLength={maxStringLength}
|
|
176
171
|
/>
|
|
177
172
|
);
|
|
@@ -179,10 +174,12 @@ function JsonKeyValue(props: {
|
|
|
179
174
|
return (
|
|
180
175
|
<>
|
|
181
176
|
{indent}
|
|
182
|
-
{
|
|
183
|
-
<ExpandIcon onClick={() => setExpanded(
|
|
177
|
+
{isFoldable(value) ? (
|
|
178
|
+
<ExpandIcon onClick={() => fold.setExpanded(path, !isExpanded)} isExpanded={isExpanded} />
|
|
184
179
|
) : null}
|
|
185
|
-
<span className="property token string">{`"${name}"`}</span
|
|
180
|
+
<span className="property token string">{`"${name}"`}</span>
|
|
181
|
+
<span>{': '}</span>
|
|
182
|
+
{valueElement}
|
|
186
183
|
</>
|
|
187
184
|
);
|
|
188
185
|
}
|