@redocly/theme 0.56.0-next.7 → 0.56.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 (31) hide show
  1. package/lib/components/Breadcrumbs/Breadcrumbs.js +1 -1
  2. package/lib/components/Button/Button.js +1 -0
  3. package/lib/components/Catalog/CatalogEntityTypeTag.js +1 -1
  4. package/lib/components/Catalog/CatalogPageDescription.js +1 -1
  5. package/lib/components/Catalog/CatalogSortButton.js +6 -6
  6. package/lib/components/Catalog/CatalogTableView/CatalogEntityCell.js +1 -1
  7. package/lib/components/Catalog/CatalogTableView/CatalogTableViewRow.js +1 -1
  8. package/lib/components/CodeBlock/CodeBlock.js +1 -0
  9. package/lib/components/CodeBlock/CodeBlockControls.js +30 -6
  10. package/lib/components/Feedback/Feedback.js +1 -1
  11. package/lib/components/Filter/FilterCheckboxes.js +5 -2
  12. package/lib/components/Search/SearchDialog.js +2 -2
  13. package/lib/core/types/catalog.d.ts +4 -0
  14. package/lib/core/types/l10n.d.ts +1 -1
  15. package/lib/core/types/telemetry.d.ts +5 -20
  16. package/package.json +2 -2
  17. package/src/components/Breadcrumbs/Breadcrumbs.tsx +1 -1
  18. package/src/components/Button/Button.tsx +1 -0
  19. package/src/components/Catalog/CatalogEntityTypeTag.tsx +4 -1
  20. package/src/components/Catalog/CatalogPageDescription.tsx +1 -1
  21. package/src/components/Catalog/CatalogSortButton.tsx +19 -20
  22. package/src/components/Catalog/CatalogTableView/CatalogEntityCell.tsx +1 -1
  23. package/src/components/Catalog/CatalogTableView/CatalogTableViewRow.tsx +1 -0
  24. package/src/components/CodeBlock/CodeBlock.tsx +1 -0
  25. package/src/components/CodeBlock/CodeBlockControls.tsx +56 -23
  26. package/src/components/Feedback/Feedback.tsx +1 -1
  27. package/src/components/Filter/FilterCheckboxes.tsx +9 -2
  28. package/src/components/Search/SearchDialog.tsx +2 -2
  29. package/src/core/types/catalog.ts +4 -0
  30. package/src/core/types/l10n.ts +2 -0
  31. package/src/core/types/telemetry.ts +5 -13
@@ -25,7 +25,7 @@ function Breadcrumbs(props) {
25
25
  payload: {
26
26
  link: breadcrumb.link,
27
27
  position: idx + 1,
28
- total_breadcrumbs: breadcrumbs.length,
28
+ totalBreadcrumbs: breadcrumbs.length,
29
29
  },
30
30
  });
31
31
  } }),
@@ -82,6 +82,7 @@ const StyledButton = styled_components_1.default.button.attrs((props) => ({
82
82
  background-color: var(--button-bg-color);
83
83
  border: var(--button-border-width) var(--button-border-style) var(--button-border-color);
84
84
  box-shadow: var(--button-box-shadow);
85
+ backdrop-filter: var(--button-backdrop-filter, none);
85
86
 
86
87
  font-weight: var(--button-font-weight);
87
88
  font-size: var(--button-font-size);
@@ -27,7 +27,7 @@ const getEntityTagColor = (type) => {
27
27
  };
28
28
  exports.getEntityTagColor = getEntityTagColor;
29
29
  function CatalogEntityTypeTag({ entityType }) {
30
- return (react_1.default.createElement(EntityTypeTagWrapper, { entityType: entityType },
30
+ return (react_1.default.createElement(EntityTypeTagWrapper, { entityType: entityType, "data-component-name": "Catalog/CatalogEntityTypeTag" },
31
31
  react_1.default.createElement(CatalogHighlight_1.CatalogHighlight, null, entityType)));
32
32
  }
33
33
  const EntityTypeTagWrapper = (0, styled_components_1.default)(Tag_1.Tag) `
@@ -11,7 +11,7 @@ const H3_1 = require("../../components/Typography/H3");
11
11
  const Tag_1 = require("../../components/Tag/Tag");
12
12
  function CatalogPageDescription({ title, titleTranslationKey, description, descriptionTranslationKey, tag, }) {
13
13
  return (react_1.default.createElement(CatalogPageDescriptionWrapper, null,
14
- react_1.default.createElement(CatalogTitleWrapper, null,
14
+ react_1.default.createElement(CatalogTitleWrapper, { "data-component-name": "Catalog/CatalogEntityTitle" },
15
15
  react_1.default.createElement(CatalogTitle, { "data-translation-key": titleTranslationKey }, title),
16
16
  react_1.default.createElement(Tag_1.Tag, { borderless: true, textTransform: "none" }, tag)),
17
17
  react_1.default.createElement(CatalogDescription, { "data-translation-key": descriptionTranslationKey }, description)));
@@ -39,13 +39,13 @@ function CatalogSortButton({ onSortChange, currentSort, }) {
39
39
  const newSort = currentSort === `-${field}` ? field : `-${field}`;
40
40
  onSortChange(newSort);
41
41
  }, [currentSort, onSortChange]);
42
- return (react_1.default.createElement(CatalogSortButtonWrapper, { "data-component-name": "Catalog/CatalogSortButton", trigger: react_1.default.createElement(SortTrigger, null,
43
- react_1.default.createElement(SortIconWrapper, null, currentSort === '-title' ? react_1.default.createElement(DescSortIcon_1.DescSortIcon, null) : react_1.default.createElement(AscSortIcon_1.AscSortIcon, null)),
44
- react_1.default.createElement(SortText, null, "Sort")), alignment: "end" },
45
- react_1.default.createElement(DropdownMenu_1.DropdownMenu, null,
46
- react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { onAction: () => toggleSort('title') }, currentSort === '-title' ? 'Title | A → Z' : 'Title | Z → A'))));
42
+ return (react_1.default.createElement("div", { "data-component-name": "Catalog/CatalogSortButton" },
43
+ react_1.default.createElement(Dropdown_1.Dropdown, { trigger: react_1.default.createElement(SortTrigger, null,
44
+ react_1.default.createElement(SortIconWrapper, null, currentSort === '-title' ? react_1.default.createElement(DescSortIcon_1.DescSortIcon, null) : react_1.default.createElement(AscSortIcon_1.AscSortIcon, null)),
45
+ react_1.default.createElement(SortText, null, "Sort")), alignment: "end" },
46
+ react_1.default.createElement(DropdownMenu_1.DropdownMenu, null,
47
+ react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { onAction: () => toggleSort('title') }, currentSort === '-title' ? 'Title | A → Z' : 'Title | Z → A')))));
47
48
  }
48
- const CatalogSortButtonWrapper = (0, styled_components_1.default)(Dropdown_1.Dropdown) ``;
49
49
  const SortTrigger = styled_components_1.default.div `
50
50
  display: flex;
51
51
  align-items: center;
@@ -12,7 +12,7 @@ function CatalogEntityCell({ entity }) {
12
12
  return (react_1.default.createElement(EntityTitleCellWrapper, { "data-component-name": "Catalog/CatalogTableView/CatalogEntityCell" },
13
13
  react_1.default.createElement(CatalogEntityTypeIcon_1.CatalogEntityTypeIcon, { entityType: entity.type, defaultColor: true }),
14
14
  react_1.default.createElement(EntityTitleContent, null,
15
- react_1.default.createElement(EntityTitle, null,
15
+ react_1.default.createElement(EntityTitle, { "data-component-name": "Catalog/CatalogTableView/CatalogEntityTitle" },
16
16
  react_1.default.createElement(CatalogHighlight_1.CatalogHighlight, null, entity.title)),
17
17
  entity.summary && (react_1.default.createElement(EntitySummary, null,
18
18
  react_1.default.createElement(CatalogHighlight_1.CatalogHighlight, null, entity.summary))))));
@@ -67,7 +67,7 @@ const CatalogTableViewRow = ({ entity, entitiesCatalogConfig, catalogConfig, col
67
67
  catalogConfig,
68
68
  entitiesCatalogConfig,
69
69
  });
70
- return (react_1.default.createElement(TableRow, { key: entity.id, "$columnsWidths": columns.map((column) => column.width || '1fr'), "$columnsMinWidths": columns.map((column) => column.minWidth || 'auto'), to: getEntityDetailsLink(), style: { color: 'var(--catalog-page-wrapper-text-color)' } }, columns.map((column) => (react_1.default.createElement(TableCell, { key: column.key, className: column.key === 'entity' ? '' : 'tooltip-cell-container' }, column.render(entity))))));
70
+ return (react_1.default.createElement(TableRow, { key: entity.id, "$columnsWidths": columns.map((column) => column.width || '1fr'), "$columnsMinWidths": columns.map((column) => column.minWidth || 'auto'), to: getEntityDetailsLink(), style: { color: 'var(--catalog-page-wrapper-text-color)' }, "data-component-name": "Catalog/CatalogTableView/CatalogTableViewRow" }, columns.map((column) => (react_1.default.createElement(TableCell, { key: column.key, className: column.key === 'entity' ? '' : 'tooltip-cell-container' }, column.render(entity))))));
71
71
  };
72
72
  exports.CatalogTableViewRow = CatalogTableViewRow;
73
73
  const TableRow = (0, styled_components_1.default)(Link_1.Link) `
@@ -88,6 +88,7 @@ function CodeBlock(_a) {
88
88
  }
89
89
  const ContainerWrapper = styled_components_1.default.div `
90
90
  display: grid; // prevents content to overstretch
91
+ position: relative;
91
92
  `;
92
93
  const CodeBlockWrapper = styled_components_1.default.div `
93
94
  border: 1px solid var(--border-color-secondary);
@@ -30,18 +30,21 @@ function CodeBlockControls({ children, className, title, controls, tabs, }) {
30
30
  deselect: null,
31
31
  report: null,
32
32
  };
33
+ const isEmptyTitle = !title && !tabs;
33
34
  const defaultControls = controls ? (react_1.default.createElement(react_1.default.Fragment, null,
34
35
  title && react_1.default.createElement(Title, null, title),
35
36
  tabs && react_1.default.createElement(CodeBlockTabs_1.CodeBlockTabs, { tabs: tabs }),
36
37
  react_1.default.createElement(ControlsWrapper, null,
37
38
  report && !((_a = report === null || report === void 0 ? void 0 : report.props) === null || _a === void 0 ? void 0 : _a.hide) ? (react_1.default.createElement(TooltipWrapper_1.TooltipWrapper, { tooltipTranslationKey: "codeSnippet.report.tooltipText", placement: "top" },
38
39
  react_1.default.createElement(ControlButton, Object.assign({ variant: "text", size: "small", "data-testid": "report-button", icon: controlsType === 'icon' ? react_1.default.createElement(WarningSquareIcon_1.WarningSquareIcon, { size: "18px" }) : undefined }, report.props), controlsType != 'icon' && (((_b = report.props) === null || _b === void 0 ? void 0 : _b.buttonText) || 'Report')))) : null,
39
- expand && !((_c = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.expand) === null || _c === void 0 ? void 0 : _c.hide) ? (react_1.default.createElement(ControlButton, { variant: "text", size: "small", "data-testid": "expand-all", icon: controlsType === 'icon' ? react_1.default.createElement(MaximizeIcon_1.MaximizeIcon, null) : undefined, onClick: expand === null || expand === void 0 ? void 0 : expand.onClick }, controlsType !== 'icon' && ((expand === null || expand === void 0 ? void 0 : expand.label) || 'Expand all'))) : null,
40
- collapse && !((_d = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.collapse) === null || _d === void 0 ? void 0 : _d.hide) ? (react_1.default.createElement(ControlButton, { variant: "text", size: "small", "data-testid": "collapse-all", icon: controlsType === 'icon' ? react_1.default.createElement(MinimizeIcon_1.MinimizeIcon, null) : undefined, onClick: collapse === null || collapse === void 0 ? void 0 : collapse.onClick }, controlsType !== 'icon' && ((expand === null || expand === void 0 ? void 0 : expand.label) || 'Collapse all'))) : null,
40
+ expand && !((_c = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.expand) === null || _c === void 0 ? void 0 : _c.hide) ? (react_1.default.createElement(TooltipWrapper_1.TooltipWrapper, { tooltipTranslationKey: "codeSnippet.expand.tooltipText", placement: "top" },
41
+ react_1.default.createElement(ControlButton, { variant: "text", size: "small", "data-testid": "expand-all", icon: controlsType === 'icon' ? react_1.default.createElement(MaximizeIcon_1.MaximizeIcon, null) : undefined, onClick: expand === null || expand === void 0 ? void 0 : expand.onClick }, controlsType !== 'icon' && ((expand === null || expand === void 0 ? void 0 : expand.label) || 'Expand all')))) : null,
42
+ collapse && !((_d = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.collapse) === null || _d === void 0 ? void 0 : _d.hide) ? (react_1.default.createElement(TooltipWrapper_1.TooltipWrapper, { tooltipTranslationKey: "codeSnippet.collapse.tooltipText", placement: "top" },
43
+ react_1.default.createElement(ControlButton, { variant: "text", size: "small", "data-testid": "collapse-all", icon: controlsType === 'icon' ? react_1.default.createElement(MinimizeIcon_1.MinimizeIcon, null) : undefined, onClick: collapse === null || collapse === void 0 ? void 0 : collapse.onClick }, controlsType !== 'icon' && ((expand === null || expand === void 0 ? void 0 : expand.label) || 'Collapse all')))) : null,
41
44
  select ? (react_1.default.createElement(ControlButton, { variant: "text", size: "small", "data-testid": "select-all", icon: controlsType === 'icon' ? react_1.default.createElement(SelectIcon_1.SelectIcon, null) : undefined, onClick: select === null || select === void 0 ? void 0 : select.onClick }, controlsType !== 'icon' && (select === null || select === void 0 ? void 0 : select.label) ? select.label : 'Select all')) : null,
42
45
  deselect ? (react_1.default.createElement(ControlButton, { variant: "text", size: "small", "data-testid": "clear-all", icon: controlsType === 'icon' ? react_1.default.createElement(DeselectIcon_1.DeselectIcon, null) : undefined, onClick: deselect === null || deselect === void 0 ? void 0 : deselect.onClick }, controlsType !== 'icon' && (deselect === null || deselect === void 0 ? void 0 : deselect.label) ? deselect.label : 'Clear all')) : null,
43
46
  copy && !((_e = codeSnippet === null || codeSnippet === void 0 ? void 0 : codeSnippet.copy) === null || _e === void 0 ? void 0 : _e.hide) ? (react_1.default.createElement(TooltipWrapper_1.TooltipWrapper, { tooltipTranslationKey: "codeSnippet.copy.tooltipText", placement: "top" },
44
- react_1.default.createElement(CopyButton_1.CopyButton, { data: copy.data, "data-source": copy.dataSource, "data-hash": copy.dataHash, type: controlsType, toasterPlacement: copy.toasterPlacement, toasterDuration: copy.toasterDuration, buttonText: copy.label, onCopyClick: () => {
47
+ react_1.default.createElement(StyledCopyButton, { data: copy.data, "data-source": copy.dataSource, "data-hash": copy.dataHash, type: controlsType, toasterPlacement: copy.toasterPlacement, toasterDuration: copy.toasterDuration, buttonText: copy.label, onCopyClick: () => {
45
48
  var _a;
46
49
  // If there already is a click handler, events should be handled there, cause they pass additional data
47
50
  if (copy === null || copy === void 0 ? void 0 : copy.onClick) {
@@ -50,15 +53,16 @@ function CodeBlockControls({ children, className, title, controls, tabs, }) {
50
53
  else {
51
54
  telemetry.send({
52
55
  type: 'openapi_docs.copy_code_snippet.clicked',
53
- payload: { snippet_type: 'copy' },
56
+ payload: { snippetType: 'copy' },
54
57
  });
55
58
  }
56
59
  } }))) : null))) : null;
57
- return children || controls ? (react_1.default.createElement(ContainerWrapper, { "data-component-name": "CodeBlock/CodeBlockControls", className: className }, children ? children : defaultControls)) : null;
60
+ return children || controls ? (react_1.default.createElement(ContainerWrapper, { "data-component-name": "CodeBlock/CodeBlockControls", className: className, "$isEmptyTitle": isEmptyTitle }, children ? children : defaultControls)) : null;
58
61
  }
59
62
  const ContainerWrapper = styled_components_1.default.div `
60
63
  display: grid;
61
64
  justify-content: end;
65
+ gap: var(--spacing-sm);
62
66
  font-size: var(--code-block-controls-font-size);
63
67
  font-family: var(--code-block-controls-font-family);
64
68
  background-color: var(--code-block-controls-bg-color);
@@ -67,6 +71,18 @@ const ContainerWrapper = styled_components_1.default.div `
67
71
  line-height: var(--line-height-lg);
68
72
  min-height: var(--control-height-base);
69
73
  grid-template-columns: 1fr auto;
74
+ z-index: 1;
75
+ ${({ $isEmptyTitle }) => $isEmptyTitle &&
76
+ `
77
+ grid-template-columns: 1fr;
78
+ padding-left: var(--spacing-xxs);
79
+ position: absolute;
80
+ right: 0;
81
+ width: auto;
82
+ border: none;
83
+ background-color: transparent;
84
+ margin: 0;
85
+ `}
70
86
  `;
71
87
  const Title = styled_components_1.default.span `
72
88
  display: flex;
@@ -81,11 +97,19 @@ const ControlsWrapper = styled_components_1.default.div `
81
97
  align-items: center;
82
98
  gap: var(--spacing-xxs);
83
99
  justify-content: end;
84
- margin-left: var(--spacing-sm);
85
100
  `;
86
101
  const ControlButton = (0, styled_components_1.default)(Button_1.Button) `
102
+ --button-icon-size: 16px; /* increase icon size for code blocks */
103
+ --button-icon-padding: 3px;
104
+ --button-backdrop-filter: blur(8px); /* backdrop filter when there is text under the button */
105
+
87
106
  & + & {
88
107
  margin-left: 0;
89
108
  }
90
109
  `;
110
+ const StyledCopyButton = (0, styled_components_1.default)(CopyButton_1.CopyButton) `
111
+ --button-icon-size: 16px; /* increase icon size for code blocks */
112
+ --button-icon-padding: 3px;
113
+ --button-backdrop-filter: blur(8px);
114
+ `;
91
115
  //# sourceMappingURL=CodeBlockControls.js.map
@@ -64,7 +64,7 @@ function Feedback(props) {
64
64
  return (React.createElement(FeedbackWrapper, { "data-component-name": "Feedback/Feedback" },
65
65
  React.createElement(FeedbackComponent, { settings: settings, onSubmit: (values) => {
66
66
  submitFeedback({ type, values, path });
67
- telemetry.send({ type: 'feedback.sent', payload: { feedback_type: type } });
67
+ telemetry.send({ type: 'feedback.sent', payload: { feedbackType: type } });
68
68
  } })));
69
69
  };
70
70
  return React.createElement(React.Fragment, { key: pathname }, renderFeedbackComponent());
@@ -20,13 +20,16 @@ function FilterCheckboxes({ filter, filterValuesCasing, showCounter = true, }) {
20
20
  const telemetry = useTelemetry();
21
21
  return (react_1.default.createElement(FilterCheckboxesWrapper, { "data-component-name": "Filter/FilterCheckboxes" },
22
22
  react_1.default.createElement(FilterTitle_1.FilterTitle, { "data-translation-key": filter.titleTranslationKey }, translate(filter.titleTranslationKey, filter.title)),
23
- react_1.default.createElement(FilterOptions_1.FilterOptions, null, filter.options.map(({ value, count }) => {
23
+ react_1.default.createElement(FilterOptions_1.FilterOptions, null, (filter.filteredOptions || filter.options).map(({ value, count }) => {
24
24
  const id = 'filter--' + filter.property + '--' + value;
25
25
  return (react_1.default.createElement(FilterCheckboxOption, { key: id, role: "link", onClick: () => {
26
26
  filter.toggleOption(value);
27
27
  telemetry.send({ type: 'filter_checkbox.toggled', payload: { id } });
28
28
  } },
29
- react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase()) }),
29
+ react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: filter.selectedOptions instanceof Set
30
+ ? filter.selectedOptions.has(value) ||
31
+ filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase())
32
+ : false }),
30
33
  react_1.default.createElement(FilterOptionLabel_1.FilterOptionLabel, { "data-translation-key": value }, (0, utils_1.changeTextCasing)(translate(value), filterValuesCasing)),
31
34
  showCounter && react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, count)));
32
35
  }))));
@@ -115,9 +115,9 @@ function SearchDialog({ onClose, className }) {
115
115
  payload: {
116
116
  query,
117
117
  url: item.document.url,
118
- total_results: results.length.toString(),
118
+ totalResults: results.length.toString(),
119
119
  index: index.toString(),
120
- search_engine: mode,
120
+ searchEngine: mode,
121
121
  },
122
122
  });
123
123
  onClose();
@@ -52,6 +52,10 @@ export type ResolvedFilter = Omit<CatalogFilterConfig, 'options'> & {
52
52
  from?: string;
53
53
  to?: string;
54
54
  };
55
+ filteredOptions?: {
56
+ value: string;
57
+ count: number;
58
+ }[];
55
59
  };
56
60
  export type CatalogItem = {
57
61
  title: string;
@@ -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.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.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | '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.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' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | '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' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | '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.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' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | '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' | '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.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | '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.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | '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' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | '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.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | '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';
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.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.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | '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.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' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | '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' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | '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.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' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | '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' | '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.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | '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.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | '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' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | '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.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | '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';
3
3
  export type Locale = {
4
4
  code: string;
5
5
  name: string;
@@ -1,30 +1,15 @@
1
1
  import { AsyncApiRealm } from '@redocly/realm-asyncapi-sdk';
2
2
  type ExtractEventType<T> = T extends {
3
- span?: {
4
- attributes?: {
5
- 'cloudevents.event_type': infer EventType;
6
- };
7
- };
3
+ type: infer EventType;
8
4
  } ? EventType : never;
9
5
  export type EventType = ExtractEventType<AsyncApiRealm.Messages>;
10
6
  type GetMessageForEventType<TEventType extends EventType> = Extract<AsyncApiRealm.Messages, {
11
- span?: {
12
- attributes?: {
13
- 'cloudevents.event_type': TEventType;
14
- };
15
- };
7
+ type: TEventType;
16
8
  }>;
17
9
  type ExtractEventDataForType<TEventType extends EventType> = GetMessageForEventType<TEventType> extends {
18
- span?: {
19
- attributes?: infer Attrs;
20
- };
21
- } ? {
22
- [K in keyof Attrs as K extends `cloudevents.event_data.${string}` ? K : never]: Attrs[K];
23
- } : never;
24
- export type ConvertEventDataToPayload<T> = {
25
- [K in keyof T as K extends `cloudevents.event_data.${infer FieldName}` ? FieldName : never]: T[K];
26
- };
27
- export type EventPayload<TEventType extends EventType> = ConvertEventDataToPayload<ExtractEventDataForType<TEventType>>;
10
+ data: infer Data;
11
+ } ? Data : never;
12
+ export type EventPayload<TEventType extends EventType> = ExtractEventDataForType<TEventType>;
28
13
  export interface SendEventParams<TEventType extends EventType> {
29
14
  type: TEventType;
30
15
  payload?: EventPayload<TEventType>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.56.0-next.7",
3
+ "version": "0.56.0-next.9",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -89,7 +89,7 @@
89
89
  "nprogress": "0.2.0",
90
90
  "react-calendar": "5.1.0",
91
91
  "react-date-picker": "11.0.0",
92
- "@redocly/config": "0.26.4",
92
+ "@redocly/config": "0.27.0",
93
93
  "@redocly/realm-asyncapi-sdk": "0.2.0-next.1"
94
94
  },
95
95
  "scripts": {
@@ -36,7 +36,7 @@ export function Breadcrumbs(props: {
36
36
  payload: {
37
37
  link: breadcrumb.link,
38
38
  position: idx + 1,
39
- total_breadcrumbs: breadcrumbs.length,
39
+ totalBreadcrumbs: breadcrumbs.length,
40
40
  },
41
41
  });
42
42
  }}
@@ -96,6 +96,7 @@ const StyledButton = styled.button.attrs((props: ButtonProps) => ({
96
96
  background-color: var(--button-bg-color);
97
97
  border: var(--button-border-width) var(--button-border-style) var(--button-border-color);
98
98
  box-shadow: var(--button-box-shadow);
99
+ backdrop-filter: var(--button-backdrop-filter, none);
99
100
 
100
101
  font-weight: var(--button-font-weight);
101
102
  font-size: var(--button-font-size);
@@ -31,7 +31,10 @@ export const getEntityTagColor = (type: EntityType): string => {
31
31
 
32
32
  export function CatalogEntityTypeTag({ entityType }: CatalogEntityTypeTagProps): JSX.Element {
33
33
  return (
34
- <EntityTypeTagWrapper entityType={entityType as EntityType}>
34
+ <EntityTypeTagWrapper
35
+ entityType={entityType as EntityType}
36
+ data-component-name="Catalog/CatalogEntityTypeTag"
37
+ >
35
38
  <CatalogHighlight>{entityType}</CatalogHighlight>
36
39
  </EntityTypeTagWrapper>
37
40
  );
@@ -22,7 +22,7 @@ export function CatalogPageDescription({
22
22
  }: CatalogPageDescriptionProps) {
23
23
  return (
24
24
  <CatalogPageDescriptionWrapper>
25
- <CatalogTitleWrapper>
25
+ <CatalogTitleWrapper data-component-name="Catalog/CatalogEntityTitle">
26
26
  <CatalogTitle data-translation-key={titleTranslationKey}>{title}</CatalogTitle>
27
27
  <Tag borderless textTransform="none">
28
28
  {tag}
@@ -29,29 +29,28 @@ export function CatalogSortButton({
29
29
  );
30
30
 
31
31
  return (
32
- <CatalogSortButtonWrapper
33
- data-component-name="Catalog/CatalogSortButton"
34
- trigger={
35
- <SortTrigger>
36
- <SortIconWrapper>
37
- {currentSort === '-title' ? <DescSortIcon /> : <AscSortIcon />}
38
- </SortIconWrapper>
39
- <SortText>Sort</SortText>
40
- </SortTrigger>
41
- }
42
- alignment="end"
43
- >
44
- <DropdownMenu>
45
- <DropdownMenuItem onAction={() => toggleSort('title')}>
46
- {currentSort === '-title' ? 'Title | A → Z' : 'Title | Z → A'}
47
- </DropdownMenuItem>
48
- </DropdownMenu>
49
- </CatalogSortButtonWrapper>
32
+ <div data-component-name="Catalog/CatalogSortButton">
33
+ <Dropdown
34
+ trigger={
35
+ <SortTrigger>
36
+ <SortIconWrapper>
37
+ {currentSort === '-title' ? <DescSortIcon /> : <AscSortIcon />}
38
+ </SortIconWrapper>
39
+ <SortText>Sort</SortText>
40
+ </SortTrigger>
41
+ }
42
+ alignment="end"
43
+ >
44
+ <DropdownMenu>
45
+ <DropdownMenuItem onAction={() => toggleSort('title')}>
46
+ {currentSort === '-title' ? 'Title | A → Z' : 'Title | Z → A'}
47
+ </DropdownMenuItem>
48
+ </DropdownMenu>
49
+ </Dropdown>
50
+ </div>
50
51
  );
51
52
  }
52
53
 
53
- const CatalogSortButtonWrapper = styled(Dropdown)``;
54
-
55
54
  const SortTrigger = styled.div`
56
55
  display: flex;
57
56
  align-items: center;
@@ -15,7 +15,7 @@ export function CatalogEntityCell<T extends Entity>({ entity }: CatalogEntityCel
15
15
  <EntityTitleCellWrapper data-component-name="Catalog/CatalogTableView/CatalogEntityCell">
16
16
  <CatalogEntityTypeIcon entityType={entity.type} defaultColor={true} />
17
17
  <EntityTitleContent>
18
- <EntityTitle>
18
+ <EntityTitle data-component-name="Catalog/CatalogTableView/CatalogEntityTitle">
19
19
  <CatalogHighlight>{entity.title}</CatalogHighlight>
20
20
  </EntityTitle>
21
21
  {entity.summary && (
@@ -103,6 +103,7 @@ export const CatalogTableViewRow = <T extends BaseEntity>({
103
103
  $columnsMinWidths={columns.map((column) => column.minWidth || 'auto')}
104
104
  to={getEntityDetailsLink()}
105
105
  style={{ color: 'var(--catalog-page-wrapper-text-color)' }}
106
+ data-component-name="Catalog/CatalogTableView/CatalogTableViewRow"
106
107
  >
107
108
  {columns.map((column) => (
108
109
  <TableCell
@@ -148,6 +148,7 @@ export function CodeBlock({
148
148
 
149
149
  const ContainerWrapper = styled.div`
150
150
  display: grid; // prevents content to overstretch
151
+ position: relative;
151
152
  `;
152
153
 
153
154
  const CodeBlockWrapper = styled.div`
@@ -72,6 +72,8 @@ export function CodeBlockControls({
72
72
  report: null,
73
73
  };
74
74
 
75
+ const isEmptyTitle = !title && !tabs;
76
+
75
77
  const defaultControls = controls ? (
76
78
  <>
77
79
  {title && <Title>{title}</Title>}
@@ -92,27 +94,31 @@ export function CodeBlockControls({
92
94
  ) : null}
93
95
 
94
96
  {expand && !codeSnippet?.expand?.hide ? (
95
- <ControlButton
96
- variant="text"
97
- size="small"
98
- data-testid="expand-all"
99
- icon={controlsType === 'icon' ? <MaximizeIcon /> : undefined}
100
- onClick={expand?.onClick}
101
- >
102
- {controlsType !== 'icon' && (expand?.label || 'Expand all')}
103
- </ControlButton>
97
+ <TooltipWrapper tooltipTranslationKey="codeSnippet.expand.tooltipText" placement="top">
98
+ <ControlButton
99
+ variant="text"
100
+ size="small"
101
+ data-testid="expand-all"
102
+ icon={controlsType === 'icon' ? <MaximizeIcon /> : undefined}
103
+ onClick={expand?.onClick}
104
+ >
105
+ {controlsType !== 'icon' && (expand?.label || 'Expand all')}
106
+ </ControlButton>
107
+ </TooltipWrapper>
104
108
  ) : null}
105
109
 
106
110
  {collapse && !codeSnippet?.collapse?.hide ? (
107
- <ControlButton
108
- variant="text"
109
- size="small"
110
- data-testid="collapse-all"
111
- icon={controlsType === 'icon' ? <MinimizeIcon /> : undefined}
112
- onClick={collapse?.onClick}
113
- >
114
- {controlsType !== 'icon' && (expand?.label || 'Collapse all')}
115
- </ControlButton>
111
+ <TooltipWrapper tooltipTranslationKey="codeSnippet.collapse.tooltipText" placement="top">
112
+ <ControlButton
113
+ variant="text"
114
+ size="small"
115
+ data-testid="collapse-all"
116
+ icon={controlsType === 'icon' ? <MinimizeIcon /> : undefined}
117
+ onClick={collapse?.onClick}
118
+ >
119
+ {controlsType !== 'icon' && (expand?.label || 'Collapse all')}
120
+ </ControlButton>
121
+ </TooltipWrapper>
116
122
  ) : null}
117
123
 
118
124
  {select ? (
@@ -141,7 +147,7 @@ export function CodeBlockControls({
141
147
 
142
148
  {copy && !codeSnippet?.copy?.hide ? (
143
149
  <TooltipWrapper tooltipTranslationKey="codeSnippet.copy.tooltipText" placement="top">
144
- <CopyButton
150
+ <StyledCopyButton
145
151
  data={copy.data}
146
152
  data-source={copy.dataSource}
147
153
  data-hash={copy.dataHash}
@@ -156,7 +162,7 @@ export function CodeBlockControls({
156
162
  } else {
157
163
  telemetry.send({
158
164
  type: 'openapi_docs.copy_code_snippet.clicked',
159
- payload: { snippet_type: 'copy' },
165
+ payload: { snippetType: 'copy' },
160
166
  });
161
167
  }
162
168
  }}
@@ -168,15 +174,20 @@ export function CodeBlockControls({
168
174
  ) : null;
169
175
 
170
176
  return children || controls ? (
171
- <ContainerWrapper data-component-name="CodeBlock/CodeBlockControls" className={className}>
177
+ <ContainerWrapper
178
+ data-component-name="CodeBlock/CodeBlockControls"
179
+ className={className}
180
+ $isEmptyTitle={isEmptyTitle}
181
+ >
172
182
  {children ? children : defaultControls}
173
183
  </ContainerWrapper>
174
184
  ) : null;
175
185
  }
176
186
 
177
- const ContainerWrapper = styled.div`
187
+ const ContainerWrapper = styled.div<{ $isEmptyTitle: boolean }>`
178
188
  display: grid;
179
189
  justify-content: end;
190
+ gap: var(--spacing-sm);
180
191
  font-size: var(--code-block-controls-font-size);
181
192
  font-family: var(--code-block-controls-font-family);
182
193
  background-color: var(--code-block-controls-bg-color);
@@ -185,6 +196,19 @@ const ContainerWrapper = styled.div`
185
196
  line-height: var(--line-height-lg);
186
197
  min-height: var(--control-height-base);
187
198
  grid-template-columns: 1fr auto;
199
+ z-index: 1;
200
+ ${({ $isEmptyTitle }) =>
201
+ $isEmptyTitle &&
202
+ `
203
+ grid-template-columns: 1fr;
204
+ padding-left: var(--spacing-xxs);
205
+ position: absolute;
206
+ right: 0;
207
+ width: auto;
208
+ border: none;
209
+ background-color: transparent;
210
+ margin: 0;
211
+ `}
188
212
  `;
189
213
 
190
214
  const Title = styled.span`
@@ -201,11 +225,20 @@ const ControlsWrapper = styled.div`
201
225
  align-items: center;
202
226
  gap: var(--spacing-xxs);
203
227
  justify-content: end;
204
- margin-left: var(--spacing-sm);
205
228
  `;
206
229
 
207
230
  const ControlButton = styled(Button)`
231
+ --button-icon-size: 16px; /* increase icon size for code blocks */
232
+ --button-icon-padding: 3px;
233
+ --button-backdrop-filter: blur(8px); /* backdrop filter when there is text under the button */
234
+
208
235
  & + & {
209
236
  margin-left: 0;
210
237
  }
211
238
  `;
239
+
240
+ const StyledCopyButton = styled(CopyButton)`
241
+ --button-icon-size: 16px; /* increase icon size for code blocks */
242
+ --button-icon-padding: 3px;
243
+ --button-backdrop-filter: blur(8px);
244
+ `;
@@ -58,7 +58,7 @@ export function Feedback(props: FeedbackProps & { path?: string }) {
58
58
  settings={settings}
59
59
  onSubmit={(values) => {
60
60
  submitFeedback({ type, values, path });
61
- telemetry.send({ type: 'feedback.sent', payload: { feedback_type: type } });
61
+ telemetry.send({ type: 'feedback.sent', payload: { feedbackType: type } });
62
62
  }}
63
63
  />
64
64
  </FeedbackWrapper>
@@ -28,7 +28,7 @@ export function FilterCheckboxes({
28
28
  {translate(filter.titleTranslationKey, filter.title)}
29
29
  </FilterTitle>
30
30
  <FilterOptions>
31
- {filter.options.map(({ value, count }) => {
31
+ {(filter.filteredOptions || filter.options).map(({ value, count }) => {
32
32
  const id = 'filter--' + filter.property + '--' + value;
33
33
  return (
34
34
  <FilterCheckboxOption
@@ -39,7 +39,14 @@ export function FilterCheckboxes({
39
39
  telemetry.send({ type: 'filter_checkbox.toggled', payload: { id } });
40
40
  }}
41
41
  >
42
- <CheckboxIcon checked={filter.selectedOptions.has(value?.toLowerCase())} />
42
+ <CheckboxIcon
43
+ checked={
44
+ filter.selectedOptions instanceof Set
45
+ ? filter.selectedOptions.has(value) ||
46
+ filter.selectedOptions.has(value?.toLowerCase())
47
+ : false
48
+ }
49
+ />
43
50
  <FilterOptionLabel data-translation-key={value}>
44
51
  {changeTextCasing(translate(value), filterValuesCasing)}
45
52
  </FilterOptionLabel>
@@ -144,9 +144,9 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
144
144
  payload: {
145
145
  query,
146
146
  url: item.document.url,
147
- total_results: results.length.toString(),
147
+ totalResults: results.length.toString(),
148
148
  index: index.toString(),
149
- search_engine: mode,
149
+ searchEngine: mode,
150
150
  },
151
151
  });
152
152
  onClose();
@@ -54,6 +54,10 @@ export type ResolvedFilter = Omit<CatalogFilterConfig, 'options'> & {
54
54
  selectOption: (option: string) => void;
55
55
  parentUsed: boolean;
56
56
  selectedOptions: Set<string> | { from?: string; to?: string };
57
+ filteredOptions?: {
58
+ value: string;
59
+ count: number;
60
+ }[];
57
61
  };
58
62
 
59
63
  export type CatalogItem = {
@@ -179,6 +179,8 @@ export type TranslationKey =
179
179
  | 'codeSnippet.report.buttonText'
180
180
  | 'codeSnippet.report.tooltipText'
181
181
  | 'codeSnippet.report.label'
182
+ | 'codeSnippet.expand.tooltipText'
183
+ | 'codeSnippet.collapse.tooltipText'
182
184
  | 'userMenu.login'
183
185
  | 'userMenu.logout'
184
186
  | 'userMenu.devOnboardingLabel'
@@ -1,7 +1,7 @@
1
1
  import { AsyncApiRealm } from '@redocly/realm-asyncapi-sdk';
2
2
 
3
3
  type ExtractEventType<T> = T extends {
4
- span?: { attributes?: { 'cloudevents.event_type': infer EventType } };
4
+ type: infer EventType;
5
5
  }
6
6
  ? EventType
7
7
  : never;
@@ -10,25 +10,17 @@ export type EventType = ExtractEventType<AsyncApiRealm.Messages>;
10
10
 
11
11
  type GetMessageForEventType<TEventType extends EventType> = Extract<
12
12
  AsyncApiRealm.Messages,
13
- { span?: { attributes?: { 'cloudevents.event_type': TEventType } } }
13
+ { type: TEventType }
14
14
  >;
15
15
 
16
16
  type ExtractEventDataForType<TEventType extends EventType> =
17
17
  GetMessageForEventType<TEventType> extends {
18
- span?: { attributes?: infer Attrs };
18
+ data: infer Data;
19
19
  }
20
- ? {
21
- [K in keyof Attrs as K extends `cloudevents.event_data.${string}` ? K : never]: Attrs[K];
22
- }
20
+ ? Data
23
21
  : never;
24
22
 
25
- export type ConvertEventDataToPayload<T> = {
26
- [K in keyof T as K extends `cloudevents.event_data.${infer FieldName}` ? FieldName : never]: T[K];
27
- };
28
-
29
- export type EventPayload<TEventType extends EventType> = ConvertEventDataToPayload<
30
- ExtractEventDataForType<TEventType>
31
- >;
23
+ export type EventPayload<TEventType extends EventType> = ExtractEventDataForType<TEventType>;
32
24
 
33
25
  export interface SendEventParams<TEventType extends EventType> {
34
26
  type: TEventType;