@redocly/theme 0.69.0-next.7 → 0.69.0-next.9

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.
Files changed (45) hide show
  1. package/lib/components/Accordion/Accordion.js +5 -1
  2. package/lib/components/Admonition/Admonition.d.ts +1 -1
  3. package/lib/components/Admonition/Admonition.js +1 -1
  4. package/lib/components/Admonition/variables.dark.js +2 -2
  5. package/lib/components/Admonition/variables.js +9 -9
  6. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.js +5 -3
  7. package/lib/components/Catalog/CatalogViewModeToggle.d.ts +1 -1
  8. package/lib/components/Catalog/CatalogViewModeToggle.js +2 -43
  9. package/lib/components/Filter/FilterInput.js +4 -2
  10. package/lib/components/JsonViewer/Helpers.js +12 -42
  11. package/lib/components/Panel/Panel.js +5 -1
  12. package/lib/components/Search/FilterFields/SearchFilterFieldSelect.js +22 -32
  13. package/lib/components/Search/SearchItem.js +5 -3
  14. package/lib/components/Search/variables.js +1 -0
  15. package/lib/components/Select/Select.js +10 -5
  16. package/lib/components/Sidebar/Sidebar.js +2 -38
  17. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +5 -17
  18. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +1 -0
  19. package/lib/core/hooks/menu/use-menu-item-expanded.js +1 -0
  20. package/lib/core/hooks/use-local-state.js +1 -0
  21. package/lib/core/hooks/use-mobile-menu.js +10 -2
  22. package/lib/core/types/l10n.d.ts +1 -1
  23. package/lib/markdoc/tags/admonition.js +1 -1
  24. package/package.json +3 -3
  25. package/src/components/Accordion/Accordion.tsx +7 -3
  26. package/src/components/Admonition/Admonition.tsx +2 -2
  27. package/src/components/Admonition/variables.dark.ts +2 -2
  28. package/src/components/Admonition/variables.ts +9 -9
  29. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.tsx +6 -4
  30. package/src/components/Catalog/CatalogViewModeToggle.tsx +2 -17
  31. package/src/components/Filter/FilterInput.tsx +5 -3
  32. package/src/components/JsonViewer/Helpers.tsx +13 -9
  33. package/src/components/Panel/Panel.tsx +7 -3
  34. package/src/components/Search/FilterFields/SearchFilterFieldSelect.tsx +32 -40
  35. package/src/components/Search/SearchItem.tsx +6 -1
  36. package/src/components/Search/variables.ts +1 -0
  37. package/src/components/Select/Select.tsx +12 -6
  38. package/src/components/Sidebar/Sidebar.tsx +2 -6
  39. package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +6 -20
  40. package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +1 -0
  41. package/src/core/hooks/menu/use-menu-item-expanded.ts +1 -0
  42. package/src/core/hooks/use-local-state.ts +1 -0
  43. package/src/core/hooks/use-mobile-menu.ts +11 -3
  44. package/src/core/types/l10n.ts +4 -0
  45. package/src/markdoc/tags/admonition.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  import type { TOptions } from 'i18next';
2
- export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.create.app.dialog.callbackUrls' | 'dev.create.app.dialog.callbackUrls.placeholder' | 'dev.create.app.dialog.callbackUrls.hint' | 'dev.app.callbackUrls.title' | 'dev.edit.callbackUrls.dialog.title' | 'dev.edit.callbackUrls.dialog.placeholder' | 'dev.edit.callbackUrls.dialog.hint' | 'dev.edit.callbackUrls.dialog.save' | 'dev.edit.callbackUrls.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.error.title' | 'search.error.button' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.toolCall.executed' | 'search.ai.toolCall.executing' | 'search.ai.toolCall.withArgs' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.mcpNotAllowed.title' | 'page.mcpNotAllowed.description' | 'page.mcpNotAllowed.publicNote' | 'page.mcpNotAllowed.publicEndpointHint' | 'page.mcpNotAllowed.mainEndpointHint' | 'page.mcpNotAllowed.snippets.terminal.hint' | 'page.mcpNotAllowed.snippets.claudeCode.headline' | 'page.mcpNotAllowed.snippets.claudeDesktop.headline' | 'page.mcpNotAllowed.snippets.claudeDesktop.instruction' | 'page.mcpNotAllowed.snippets.chatgptApp.headline' | 'page.mcpNotAllowed.snippets.chatgptApp.instruction' | 'page.mcpNotAllowed.snippets.codexCli.headline' | 'page.mcpNotAllowed.snippets.prompt.headline' | 'page.mcpNotAllowed.snippets.prompt.hint' | 'page.mcpNotAllowed.snippets.json.hint' | 'page.mcpNotAllowed.tabs.claude' | 'page.mcpNotAllowed.tabs.chatgpt' | 'page.mcpNotAllowed.tabs.json' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.notConnected' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.filters.close' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.maxLength' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'jsonViewer.showMore' | 'jsonViewer.showLess' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.claudeCode' | 'page.actions.connectMcp.claudeCodeDescription' | 'page.actions.connectMcp.codex' | 'page.actions.connectMcp.codexDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'page.actions.connectMcp.moreOptions' | 'page.actions.moreActions' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'graphql.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.languages.moreButton.tooltipText' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.schemas' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.querystring' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.property' | 'openapi.properties' | 'openapi.details' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.noRequestData' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'openapi.mcp.exampleTitle' | 'openapi.mcp.argumentsExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'asyncapi.info.contact.url' | 'asyncapi.info.contact.name' | 'asyncapi.info.license' | 'asyncapi.info.termsOfService' | 'asyncapi.key' | 'asyncapi.value' | 'asyncapi.variables' | 'asyncapi.required' | 'asyncapi.requiredScopes' | 'asyncapi.viewSecurityDetails' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.actions.show' | 'graphql.actions.hide' | 'graphql.actions.more' | 'graphql.fields' | 'graphql.inputFields' | 'graphql.values' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.implementedBy' | 'graphql.nonNull' | 'graphql.required' | 'asyncapi.badges.deprecated' | 'graphql.badges.deprecated' | 'asyncapi.actions.show' | 'asyncapi.actions.hide' | 'asyncapi.actions.more' | 'asyncapi.payload' | 'asyncapi.parameters' | 'asyncapi.messages' | 'asyncapi.contentType' | 'asyncapi.moreDetails' | 'asyncapi.property' | 'asyncapi.properties' | 'asyncapi.details' | 'asyncapi.reply' | 'asyncapi.servers.title' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'button.download.tooltipText' | 'button.externalLink.tooltipText' | 'button.email.tooltipText' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to' | 'diagram.openFullscreen' | 'diagram.zoomIn' | 'diagram.zoomOut' | 'diagram.reset' | 'diagram.close' | 'diagram.viewer';
2
+ export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.create.app.dialog.callbackUrls' | 'dev.create.app.dialog.callbackUrls.placeholder' | 'dev.create.app.dialog.callbackUrls.hint' | 'dev.app.callbackUrls.title' | 'dev.edit.callbackUrls.dialog.title' | 'dev.edit.callbackUrls.dialog.placeholder' | 'dev.edit.callbackUrls.dialog.hint' | 'dev.edit.callbackUrls.dialog.save' | 'dev.edit.callbackUrls.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.error.title' | 'search.error.button' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.toolCall.executed' | 'search.ai.toolCall.executing' | 'search.ai.toolCall.withArgs' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.apiNotFound.title' | 'page.apiNotFound.description' | 'page.apiNotFound.hint' | 'page.apiNotFound.backButton' | 'page.mcpNotAllowed.title' | 'page.mcpNotAllowed.description' | 'page.mcpNotAllowed.publicNote' | 'page.mcpNotAllowed.publicEndpointHint' | 'page.mcpNotAllowed.mainEndpointHint' | 'page.mcpNotAllowed.snippets.terminal.hint' | 'page.mcpNotAllowed.snippets.claudeCode.headline' | 'page.mcpNotAllowed.snippets.claudeDesktop.headline' | 'page.mcpNotAllowed.snippets.claudeDesktop.instruction' | 'page.mcpNotAllowed.snippets.chatgptApp.headline' | 'page.mcpNotAllowed.snippets.chatgptApp.instruction' | 'page.mcpNotAllowed.snippets.codexCli.headline' | 'page.mcpNotAllowed.snippets.prompt.headline' | 'page.mcpNotAllowed.snippets.prompt.hint' | 'page.mcpNotAllowed.snippets.json.hint' | 'page.mcpNotAllowed.tabs.claude' | 'page.mcpNotAllowed.tabs.chatgpt' | 'page.mcpNotAllowed.tabs.json' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.notConnected' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.filters.close' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.maxLength' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'jsonViewer.showMore' | 'jsonViewer.showLess' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.claudeCode' | 'page.actions.connectMcp.claudeCodeDescription' | 'page.actions.connectMcp.codex' | 'page.actions.connectMcp.codexDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'page.actions.connectMcp.moreOptions' | 'page.actions.moreActions' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'graphql.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.languages.moreButton.tooltipText' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.schemas' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.querystring' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.property' | 'openapi.properties' | 'openapi.details' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.noRequestData' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'openapi.mcp.exampleTitle' | 'openapi.mcp.argumentsExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'asyncapi.info.contact.url' | 'asyncapi.info.contact.name' | 'asyncapi.info.license' | 'asyncapi.info.termsOfService' | 'asyncapi.key' | 'asyncapi.value' | 'asyncapi.variables' | 'asyncapi.required' | 'asyncapi.requiredScopes' | 'asyncapi.viewSecurityDetails' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.actions.show' | 'graphql.actions.hide' | 'graphql.actions.more' | 'graphql.fields' | 'graphql.inputFields' | 'graphql.values' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.implementedBy' | 'graphql.nonNull' | 'graphql.required' | 'asyncapi.badges.deprecated' | 'graphql.badges.deprecated' | 'asyncapi.actions.show' | 'asyncapi.actions.hide' | 'asyncapi.actions.more' | 'asyncapi.payload' | 'asyncapi.parameters' | 'asyncapi.messages' | 'asyncapi.contentType' | 'asyncapi.moreDetails' | 'asyncapi.property' | 'asyncapi.properties' | 'asyncapi.details' | 'asyncapi.reply' | 'asyncapi.servers.title' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'button.download.tooltipText' | 'button.externalLink.tooltipText' | 'button.email.tooltipText' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to' | 'diagram.openFullscreen' | 'diagram.zoomIn' | 'diagram.zoomOut' | 'diagram.reset' | 'diagram.close' | 'diagram.viewer';
3
3
  export type Locale = {
4
4
  code: string;
5
5
  name: string;
@@ -8,7 +8,7 @@ exports.admonition = {
8
8
  type: String,
9
9
  required: true,
10
10
  default: 'info',
11
- matches: ['warning', 'info', 'danger', 'success', 'default'],
11
+ matches: ['warning', 'info', 'danger', 'success', 'idea'],
12
12
  },
13
13
  name: { type: String },
14
14
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.69.0-next.7",
3
+ "version": "0.69.0-next.9",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -71,7 +71,7 @@
71
71
  "webpack": "5.105.2"
72
72
  },
73
73
  "dependencies": {
74
- "@redocly/config": "0.55.0",
74
+ "@redocly/config": "0.56.0",
75
75
  "@tanstack/react-query": "5.62.3",
76
76
  "@tanstack/react-virtual": "3.13.0",
77
77
  "@xyflow/react": "12.8.3",
@@ -84,7 +84,7 @@
84
84
  "lodash.debounce": "^4.0.8",
85
85
  "lodash.throttle": "4.1.1",
86
86
  "nprogress": "0.2.0",
87
- "openapi-sampler": "^1.7.2",
87
+ "openapi-sampler": "^1.7.5",
88
88
  "react-calendar": "5.1.0",
89
89
  "react-date-picker": "11.0.0"
90
90
  },
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react';
@@ -32,6 +32,12 @@ export function Accordion({
32
32
  }: PropsWithChildren<AccordionProps>): JSX.Element {
33
33
  const [isExpanded, setExpanded] = useState(expanded);
34
34
  const [animate, setAnimate] = useState(false);
35
+ const [prevExpanded, setPrevExpanded] = useState(expanded);
36
+
37
+ if (prevExpanded !== expanded) {
38
+ setPrevExpanded(expanded);
39
+ setExpanded(expanded);
40
+ }
35
41
 
36
42
  const toggle = ({ target }: BaseSyntheticEvent): void => {
37
43
  if (target instanceof HTMLAnchorElement || !isExpandable) return;
@@ -40,8 +46,6 @@ export function Accordion({
40
46
  onToggle?.(!isExpanded);
41
47
  };
42
48
 
43
- useEffect(() => setExpanded(expanded), [expanded]);
44
-
45
49
  return (
46
50
  <AccordionWrapper
47
51
  className={className}
@@ -10,7 +10,7 @@ import { InformationIcon } from '@redocly/theme/icons/InformationIcon/Informatio
10
10
  import { IdeaIcon } from '@redocly/theme/icons/IdeaIcon/IdeaIcon';
11
11
 
12
12
  type AdmonitionTypeProps = {
13
- type: 'warning' | 'success' | 'danger' | 'info' | 'default';
13
+ type: 'warning' | 'success' | 'danger' | 'info' | 'idea';
14
14
  };
15
15
 
16
16
  export type AdmonitionProps = Partial<AdmonitionTypeProps> & {
@@ -25,7 +25,7 @@ const IconsMap: Record<AdmonitionTypeProps['type'], FC<{ color?: string }>> = {
25
25
  success: CheckmarkOutlineIcon,
26
26
  danger: ErrorIcon,
27
27
  info: InformationIcon,
28
- default: IdeaIcon,
28
+ idea: IdeaIcon,
29
29
  };
30
30
 
31
31
  export function Admonition({
@@ -13,6 +13,6 @@ export const admonitionDarkMode = css`
13
13
  --admonition-success-bg-color: color-mix(in srgb, var(--color-green-1) 40%, transparent); // @presenter Color
14
14
  --admonition-success-border: var(--admonition-border-width) var(--admonition-border-style) color-mix(in srgb, var(--color-green-3) 40%, transparent); // @presenter Border
15
15
 
16
- --admonition-default-bg-color: color-mix(in srgb, var(--color-primary-bg, var(--admonition-default-bg-color-legacy)) 40%, transparent); // @presenter Color
17
- --admonition-default-border: var(--admonition-border-width) var(--admonition-border-style) color-mix(in srgb, var(--color-primary-border, var(--admonition-default-border-color-legacy)) 40%, transparent); // @presenter Border
16
+ --admonition-idea-bg-color: color-mix(in srgb, var(--color-primary-bg, var(--admonition-default-bg-color-legacy)) 40%, transparent); // @presenter Color
17
+ --admonition-idea-border: var(--admonition-border-width) var(--admonition-border-style) color-mix(in srgb, var(--color-primary-border, var(--admonition-default-border-color-legacy)) 40%, transparent); // @presenter Border
18
18
  `;
@@ -90,17 +90,17 @@ export const admonition = css`
90
90
  --admonition-success-border: var(--admonition-success-border-width) var(--admonition-success-border-style) var(--admonition-success-border-color); // @presenter Border
91
91
 
92
92
  /**
93
- * @tokens Admonition type primary
93
+ * @tokens Admonition type idea
94
94
  */
95
95
 
96
- --admonition-default-bg-color: var(--color-primary-bg, var(--admonition-default-bg-color-legacy)); // @presenter Color
97
- --admonition-default-text-color: var(--admonition-heading-text-color); // @presenter Color
98
- --admonition-default-heading-text-color: var(--admonition-heading-text-color); // @presenter Color
99
- --admonition-default-icon-color: var(--color-primary-base, var(--admonition-default-icon-color-legacy)); // @presenter Color
100
- --admonition-default-border-color: var(--color-primary-border, var(--admonition-default-border-color-legacy)); // @presenter Color
101
- --admonition-default-border-style: var(--admonition-border-style); // @presenter Color
102
- --admonition-default-border-width: var(--admonition-border-width); // @presenter Color
103
- --admonition-default-border: var(--admonition-default-border-width) var(--admonition-default-border-style) var(--admonition-default-border-color); // @presenter Border
96
+ --admonition-idea-bg-color: var(--color-primary-bg, var(--admonition-default-bg-color-legacy)); // @presenter Color
97
+ --admonition-idea-text-color: var(--admonition-heading-text-color); // @presenter Color
98
+ --admonition-idea-heading-text-color: var(--admonition-heading-text-color); // @presenter Color
99
+ --admonition-idea-icon-color: var(--color-primary-base, var(--admonition-default-icon-color-legacy)); // @presenter Color
100
+ --admonition-idea-border-color: var(--color-primary-border, var(--admonition-default-border-color-legacy)); // @presenter Color
101
+ --admonition-idea-border-style: var(--admonition-border-style); // @presenter Color
102
+ --admonition-idea-border-width: var(--admonition-border-width); // @presenter Color
103
+ --admonition-idea-border: var(--admonition-idea-border-width) var(--admonition-idea-border-style) var(--admonition-idea-border-color); // @presenter Border
104
104
 
105
105
  // @tokens End
106
106
  `;
@@ -1,4 +1,4 @@
1
- import React, { JSX, useState, useEffect, useMemo } from 'react';
1
+ import React, { JSX, useState, useMemo } from 'react';
2
2
 
3
3
  import type { CatalogEntityConfig, EntitiesCatalogConfig } from '@redocly/config';
4
4
  import type { BffCatalogEntity, BffCatalogRelatedEntityList } from '@redocly/theme/core/types';
@@ -35,10 +35,12 @@ export function CatalogEntityRelations({
35
35
  const { sortOption, setSortOption, handleSortClick, isColumnSorted } = useCatalogSort();
36
36
 
37
37
  const [filter, setFilter] = useState<string | undefined>(ENTITY_DEFAULT_FILTERS[entity.type]);
38
+ const [prevEntityKey, setPrevEntityKey] = useState(entity.key);
38
39
 
39
- useEffect(() => {
40
- setFilter(ENTITY_DEFAULT_FILTERS[entity.key]);
41
- }, [entity.key]);
40
+ if (prevEntityKey !== entity.key) {
41
+ setPrevEntityKey(entity.key);
42
+ setFilter(ENTITY_DEFAULT_FILTERS[entity.type]);
43
+ }
42
44
 
43
45
  const combinedFilter = useMemo(() => {
44
46
  const baseFilter = filter ?? ENTITY_DEFAULT_FILTERS[entity.type];
@@ -1,31 +1,16 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import { TableIcon } from '@redocly/theme/icons/TableIcon/TableIcon';
5
5
  import { CardsIcon } from '@redocly/theme/icons/CardsIcon/CardsIcon';
6
6
  import { CatalogViewMode } from '@redocly/theme/core/types';
7
7
 
8
- function useViewMode(initialViewMode: CatalogViewMode) {
9
- const [viewMode, setViewMode] = useState<CatalogViewMode | null>(null);
10
-
11
- useEffect(() => {
12
- setViewMode(initialViewMode);
13
- }, [initialViewMode]);
14
-
15
- return viewMode;
16
- }
17
-
18
8
  export type CatalogViewModeToggleProps = {
19
9
  viewMode: CatalogViewMode;
20
10
  onViewModeChange: (mode: CatalogViewMode) => void;
21
11
  };
22
12
 
23
- export function CatalogViewModeToggle({
24
- viewMode: initialViewMode,
25
- onViewModeChange,
26
- }: CatalogViewModeToggleProps) {
27
- const viewMode = useViewMode(initialViewMode);
28
-
13
+ export function CatalogViewModeToggle({ viewMode, onViewModeChange }: CatalogViewModeToggleProps) {
29
14
  return (
30
15
  <ViewModeToggleWrapper data-component-name="Catalog/CatalogViewModeToggle">
31
16
  <ViewModeButton
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
@@ -16,10 +16,12 @@ export function FilterInput(props: FilterInputProps): JSX.Element {
16
16
  const { value: initialValue, onChange, dataTestId } = props;
17
17
 
18
18
  const [value, setValue] = useState(initialValue);
19
+ const [prevInitialValue, setPrevInitialValue] = useState(initialValue);
19
20
 
20
- useEffect(() => {
21
+ if (prevInitialValue !== initialValue) {
22
+ setPrevInitialValue(initialValue);
21
23
  setValue(initialValue);
22
- }, [initialValue]);
24
+ }
23
25
 
24
26
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
25
27
  const newValue = e.target.value;
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react';
1
+ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
@@ -23,14 +23,16 @@ export function JsonValue(props: {
23
23
  expandAllSignal ?? level < defaultExpandLevel,
24
24
  );
25
25
  const isExpanded = expandAllSignal !== undefined && level > 0 ? expandAllSignal : isExpandedState;
26
- useEffect(() => {
27
- if (expandAllSignal !== undefined) {
28
- if (expandAllSignal === false && level === 0) {
29
- return;
30
- }
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)) {
31
33
  setExpanded(expandAllSignal);
32
34
  }
33
- }, [expandAllSignal, level]);
35
+ }
34
36
 
35
37
  const keys: string[] =
36
38
  (value && Object.keys(value).filter((key) => value[key] !== undefined)) || []; // filter out undefined properties
@@ -131,12 +133,14 @@ function JsonKeyValue(props: {
131
133
  expandAllSignal ?? level < defaultExpandLevel,
132
134
  );
133
135
  const isExpanded = expandAllSignal !== undefined ? expandAllSignal : isExpandedState;
136
+ const [prevExpandAllSignal, setPrevExpandAllSignal] = React.useState(expandAllSignal);
134
137
 
135
- useEffect(() => {
138
+ if (prevExpandAllSignal !== expandAllSignal) {
139
+ setPrevExpandAllSignal(expandAllSignal);
136
140
  if (expandAllSignal !== undefined) {
137
141
  setExpanded(expandAllSignal);
138
142
  }
139
- }, [expandAllSignal]);
143
+ }
140
144
 
141
145
  const openingPunctuation = Array.isArray(value) ? '[' : '{';
142
146
  const closingPunctuation = Array.isArray(value) ? ']' : '}';
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react';
@@ -34,6 +34,12 @@ export function Panel({
34
34
  }: PropsWithChildren<PanelProps>): JSX.Element {
35
35
  const [isExpanded, setExpanded] = useState(expanded);
36
36
  const [animate, setAnimate] = useState(false);
37
+ const [prevExpanded, setPrevExpanded] = useState(expanded);
38
+
39
+ if (prevExpanded !== expanded) {
40
+ setPrevExpanded(expanded);
41
+ setExpanded(expanded);
42
+ }
37
43
 
38
44
  const toggle = ({ target }: BaseSyntheticEvent): void => {
39
45
  if (target instanceof HTMLAnchorElement || !isExpandable) return;
@@ -42,8 +48,6 @@ export function Panel({
42
48
  onToggle?.(!isExpanded);
43
49
  };
44
50
 
45
- useEffect(() => setExpanded(expanded), [expanded]);
46
-
47
51
  return (
48
52
  <PanelWrapper
49
53
  className={className}
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { SearchFacet, SearchFacetCount, SearchFilterItem } from '@redocly/theme/core/types';
@@ -27,15 +27,8 @@ export function SearchFilterFieldSelect({
27
27
  const { useFacetQuery, useTranslate } = useThemeHooks();
28
28
  const { translate } = useTranslate();
29
29
  const { searchFacet, setSearchFacet, setSearchFacetQuery } = useFacetQuery(facet.field);
30
- /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
31
- const [selectOptions, setSelectOptions] = useState<any[]>([]);
32
30
  const isMultiple = facet.type === 'multi-select';
33
31
 
34
- useEffect(() => {
35
- setSelectOptions(getSelectOptions());
36
- // eslint-disable-next-line react-hooks/exhaustive-deps
37
- }, [searchFacet, facet]);
38
-
39
32
  const onSearch = (value: string | null) => {
40
33
  if (value === null) {
41
34
  setSearchFacet(null);
@@ -49,38 +42,10 @@ export function SearchFilterFieldSelect({
49
42
  }
50
43
  };
51
44
 
52
- const getSelectOptions = () => {
53
- return searchFacet
54
- ? searchFacet.values.map(facetValueToSelectOption)
55
- : facet.values.map(facetValueToSelectOption);
56
- };
57
-
58
- const facetValueToSelectOption = (facetValue?: SearchFacetCount | string) => {
59
- if (!facetValue) {
60
- return { element: null, value: '' };
61
- }
62
- if (typeof facetValue === 'string') {
63
- return {
64
- element: (
65
- <FilterSelectOptionWrapper>
66
- <FilterSelectOptionText>{facetValue}</FilterSelectOptionText>
67
- </FilterSelectOptionWrapper>
68
- ),
69
- value: facetValue,
70
- };
71
- } else {
72
- const { value, count, isCounterVisible } = facetValue as SearchFacetCount;
73
- return {
74
- element: (
75
- <FilterSelectOptionWrapper>
76
- <FilterSelectOptionText>{value}</FilterSelectOptionText>
77
- {isCounterVisible && <CounterTag>{count}</CounterTag>}
78
- </FilterSelectOptionWrapper>
79
- ),
80
- value: value,
81
- };
82
- }
83
- };
45
+ const selectOptions = useMemo(
46
+ () => (searchFacet ? searchFacet.values : facet.values).map(facetValueToSelectOption),
47
+ [searchFacet, facet],
48
+ );
84
49
 
85
50
  return (
86
51
  <Select
@@ -113,6 +78,33 @@ export function SearchFilterFieldSelect({
113
78
  );
114
79
  }
115
80
 
81
+ function facetValueToSelectOption(facetValue?: SearchFacetCount | string) {
82
+ if (!facetValue) {
83
+ return { element: null, value: '' };
84
+ }
85
+ if (typeof facetValue === 'string') {
86
+ return {
87
+ element: (
88
+ <FilterSelectOptionWrapper>
89
+ <FilterSelectOptionText>{facetValue}</FilterSelectOptionText>
90
+ </FilterSelectOptionWrapper>
91
+ ),
92
+ value: facetValue,
93
+ };
94
+ } else {
95
+ const { value, count, isCounterVisible } = facetValue as SearchFacetCount;
96
+ return {
97
+ element: (
98
+ <FilterSelectOptionWrapper>
99
+ <FilterSelectOptionText>{value}</FilterSelectOptionText>
100
+ {isCounterVisible && <CounterTag>{count}</CounterTag>}
101
+ </FilterSelectOptionWrapper>
102
+ ),
103
+ value: value,
104
+ };
105
+ }
106
+ }
107
+
116
108
  const FilterSelectOptionWrapper = styled.div`
117
109
  width: 100%;
118
110
  display: flex;
@@ -114,7 +114,12 @@ export function SearchItem({
114
114
  <div>
115
115
  {searchHighlight(parameter.place)}
116
116
  {` → `}
117
- {parameter.path?.length ? searchHighlight(parameter.path?.join(' → ')) + ' → ' : ''}
117
+ {parameter.path?.length ? (
118
+ <>
119
+ {searchHighlight(parameter.path.join(' → '))}
120
+ {` → `}
121
+ </>
122
+ ) : null}
118
123
  {searchHighlight(parameter.name)}
119
124
  </div>
120
125
  <div>{searchHighlight(parameter.description)}</div>
@@ -97,6 +97,7 @@ export const search = css`
97
97
  --search-message-line-height: var(--line-height-lg); // @presenter LineHeight
98
98
  --search-message-text-color: var(--text-color-secondary); // @presenter Color
99
99
  --search-message-gap: var(--spacing-md);
100
+ --search-message-padding: var(--spacing-md);
100
101
 
101
102
  --search-header-buttons-gap: var(--spacing-sm);
102
103
  --search-header-buttons-padding-left: var(--spacing-sm);
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useEffect, useId, useRef, useState } from 'react';
1
+ import React, { Fragment, useId, useRef, useState } from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
@@ -68,14 +68,20 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
68
68
  setDropdownActive(false);
69
69
  });
70
70
 
71
- useEffect(() => {
71
+ const [prevOptions, setPrevOptions] = useState(options);
72
+ const [prevValue, setPrevValue] = useState(value);
73
+ const [prevMultiple, setPrevMultiple] = useState(multiple);
74
+
75
+ if (prevOptions !== options) {
76
+ setPrevOptions(options);
72
77
  setFilteredOptions(options);
73
- }, [options]);
78
+ }
74
79
 
75
- useEffect(() => {
80
+ if (prevValue !== value || prevMultiple !== multiple) {
81
+ setPrevValue(value);
82
+ setPrevMultiple(multiple);
76
83
  setSelectedOptions(getSelectedOptionsFromPropsValue());
77
- // eslint-disable-next-line react-hooks/exhaustive-deps
78
- }, [multiple, value]);
84
+ }
79
85
 
80
86
  const changeSearchValue = (newSearchValue: string | null) => {
81
87
  if (newSearchValue === searchValue) {
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react';
1
+ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
@@ -36,11 +36,7 @@ export function Sidebar({
36
36
  menuItemsAnimation,
37
37
  }: SidebarProps): JSX.Element | null {
38
38
  const { isOpen } = useMobileMenu();
39
- const [mappedCollapsed, setMappedCollapsed] = React.useState(collapsed);
40
-
41
- useEffect(() => {
42
- setMappedCollapsed(collapsed && !isOpen);
43
- }, [isOpen, collapsed, setMappedCollapsed]);
39
+ const mappedCollapsed = collapsed && !isOpen;
44
40
 
45
41
  const { sidebar } = useThemeConfig();
46
42
 
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, useMemo, useRef } from 'react';
1
+ import { useState, useEffect, useMemo } from 'react';
2
2
  import { useLocation, useNavigate } from 'react-router';
3
3
 
4
4
  import type {
@@ -50,10 +50,6 @@ export function useCodeWalkthroughControls(
50
50
  const navigate = useNavigate();
51
51
  const searchParams = useMemo(() => new URLSearchParams(location.search), [location.search]);
52
52
 
53
- const filtersRef = useRef(filters);
54
- const inputsRef = useRef(inputs);
55
- const togglesRef = useRef(toggles);
56
-
57
53
  const getInitialState = () => {
58
54
  const state: CodeWalkthroughControlsState = {};
59
55
 
@@ -90,20 +86,11 @@ export function useCodeWalkthroughControls(
90
86
 
91
87
  const [controlsState, setControlsState] = useState(getInitialState);
92
88
 
93
- useEffect(() => {
94
- const sameProps = [
95
- JSON.stringify(filters) === JSON.stringify(filtersRef.current),
96
- JSON.stringify(inputs) === JSON.stringify(inputsRef.current),
97
- JSON.stringify(toggles) === JSON.stringify(togglesRef.current),
98
- ];
99
-
100
- if (sameProps.every(Boolean)) {
101
- return;
102
- }
89
+ const controlsKey = JSON.stringify([filters, inputs, toggles]);
90
+ const [prevControlsKey, setPrevControlsKey] = useState(controlsKey);
103
91
 
104
- filtersRef.current = filters;
105
- inputsRef.current = inputs;
106
- togglesRef.current = toggles;
92
+ if (prevControlsKey !== controlsKey) {
93
+ setPrevControlsKey(controlsKey);
107
94
 
108
95
  const newState = getInitialState();
109
96
 
@@ -120,8 +107,7 @@ export function useCodeWalkthroughControls(
120
107
  });
121
108
 
122
109
  setControlsState(newState);
123
- // eslint-disable-next-line react-hooks/exhaustive-deps
124
- }, [filters, inputs, toggles, enableDeepLink]);
110
+ }
125
111
 
126
112
  const changeControlState = (id: string, value: string | boolean) => {
127
113
  setControlsState((prev) => {
@@ -252,6 +252,7 @@ export function useCodeWalkthroughSteps({
252
252
 
253
253
  const rootTopOffset = root.current?.offsetTop ?? 0;
254
254
  if (!activeStep && rootTopOffset <= options.navbarHeight) {
255
+ // oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- seeded from root.current.offsetTop, a post-layout measurement
255
256
  setActiveStep(visibleSteps[0]?.id || null);
256
257
  }
257
258
 
@@ -16,6 +16,7 @@ export function useMenuItemExpanded(item: ItemState): [boolean, Dispatch<SetStat
16
16
  const [controlledValue, setControlledValue] = useState(isItemExpanded(item));
17
17
 
18
18
  useEffect(() => {
19
+ // oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- deferred a commit on purpose so CSS transitions still run
19
20
  setIsExpanded(controlledValue);
20
21
  }, [controlledValue]);
21
22
 
@@ -21,6 +21,7 @@ export function useLocalState<T>(key: string, initialValue: T): [T, (value: T) =
21
21
  // then client loads the actual stored value without hydration mismatch
22
22
  useEffect(() => {
23
23
  if (!isBrowser()) return;
24
+ // oxlint-disable-next-line react-you-might-not-need-an-effect/no-derived-state -- localStorage is read after mount so SSR and client hydrate from the same value
24
25
  setValue(getStoredValue(key, initialValue));
25
26
  // eslint-disable-next-line react-hooks/exhaustive-deps
26
27
  }, [key]);