@redocly/theme 0.70.0-next.3 → 0.70.0-next.5

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 (123) hide show
  1. package/lib/components/Catalog/Catalog.js +1 -1
  2. package/lib/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy.d.ts +1 -1
  3. package/lib/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.js +2 -2
  4. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -1
  5. package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +30 -11
  6. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.js +1 -1
  7. package/lib/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.js +2 -2
  8. package/lib/components/Dropdown/Dropdown.js +3 -1
  9. package/lib/components/Dropdown/DropdownMenu.d.ts +1 -0
  10. package/lib/components/Dropdown/DropdownMenu.js +1 -1
  11. package/lib/components/Feedback/Reasons.js +3 -2
  12. package/lib/components/Filter/FilterCheckboxes.js +30 -11
  13. package/lib/components/Image/Image.js +24 -4
  14. package/lib/components/Markdown/Markdown.js +3 -2
  15. package/lib/components/Menu/Menu.js +4 -0
  16. package/lib/components/Menu/MenuSelect.d.ts +7 -0
  17. package/lib/components/Menu/MenuSelect.js +129 -0
  18. package/lib/components/Menu/variables.js +43 -4
  19. package/lib/components/Navbar/Navbar.js +44 -5
  20. package/lib/components/Navbar/variables.js +3 -0
  21. package/lib/components/NavigationTabs/NavigationTab.d.ts +7 -0
  22. package/lib/components/NavigationTabs/NavigationTab.js +93 -0
  23. package/lib/components/NavigationTabs/NavigationTabContent.d.ts +7 -0
  24. package/lib/components/NavigationTabs/NavigationTabContent.js +50 -0
  25. package/lib/components/NavigationTabs/NavigationTabMenu.d.ts +7 -0
  26. package/lib/components/NavigationTabs/NavigationTabMenu.js +18 -0
  27. package/lib/components/NavigationTabs/NavigationTabs.d.ts +7 -0
  28. package/lib/components/NavigationTabs/NavigationTabs.js +97 -0
  29. package/lib/components/NavigationTabs/variables.d.ts +1 -0
  30. package/lib/components/NavigationTabs/variables.js +37 -0
  31. package/lib/components/Search/SearchTrigger.js +8 -2
  32. package/lib/components/Segmented/Segmented.js +23 -3
  33. package/lib/components/Select/Select.js +10 -3
  34. package/lib/components/Select/SelectInput.d.ts +1 -0
  35. package/lib/components/Select/SelectInput.js +3 -3
  36. package/lib/components/Sidebar/Sidebar.js +2 -2
  37. package/lib/components/TableOfContent/TableOfContent.js +2 -2
  38. package/lib/core/constants/common.d.ts +1 -0
  39. package/lib/core/constants/common.js +1 -0
  40. package/lib/core/hooks/index.d.ts +2 -0
  41. package/lib/core/hooks/index.js +2 -0
  42. package/lib/core/hooks/menu/use-mobile-menu-items.js +75 -51
  43. package/lib/core/hooks/menu/use-mobile-menu-levels.js +12 -7
  44. package/lib/core/hooks/use-scroll-item-into-view.d.ts +2 -0
  45. package/lib/core/hooks/use-scroll-item-into-view.js +16 -0
  46. package/lib/core/hooks/use-tab-list.d.ts +31 -0
  47. package/lib/core/hooks/use-tab-list.js +49 -0
  48. package/lib/core/hooks/use-theme-hooks.js +2 -0
  49. package/lib/core/styles/global.js +12 -2
  50. package/lib/core/types/hooks.d.ts +5 -0
  51. package/lib/core/types/index.d.ts +1 -0
  52. package/lib/core/types/l10n.d.ts +1 -1
  53. package/lib/core/types/navigation-tabs.d.ts +49 -0
  54. package/lib/core/types/navigation-tabs.js +3 -0
  55. package/lib/core/utils/Dynamic.d.ts +8 -1
  56. package/lib/core/utils/Dynamic.js +34 -3
  57. package/lib/core/utils/index.d.ts +1 -0
  58. package/lib/core/utils/index.js +1 -0
  59. package/lib/core/utils/menu.d.ts +4 -0
  60. package/lib/core/utils/menu.js +42 -3
  61. package/lib/core/utils/navigation-tabs.d.ts +8 -0
  62. package/lib/core/utils/navigation-tabs.js +71 -0
  63. package/lib/index.d.ts +5 -0
  64. package/lib/index.js +7 -1
  65. package/lib/layouts/PageLayout.js +1 -1
  66. package/lib/layouts/RootLayout.js +2 -2
  67. package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +1 -1
  68. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +3 -3
  69. package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
  70. package/package.json +3 -3
  71. package/src/components/Catalog/Catalog.tsx +1 -1
  72. package/src/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar.tsx +2 -2
  73. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -1
  74. package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +37 -22
  75. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanel.tsx +1 -1
  76. package/src/components/Catalog/CatalogMobileFiltersPanel/CatalogMobileFiltersPanelOverlay.tsx +2 -2
  77. package/src/components/Dropdown/Dropdown.tsx +4 -1
  78. package/src/components/Dropdown/DropdownMenu.tsx +7 -1
  79. package/src/components/Feedback/Reasons.tsx +3 -2
  80. package/src/components/Filter/FilterCheckboxes.tsx +33 -18
  81. package/src/components/Image/Image.tsx +26 -5
  82. package/src/components/Markdown/Markdown.tsx +3 -2
  83. package/src/components/Menu/Menu.tsx +5 -0
  84. package/src/components/Menu/MenuSelect.tsx +198 -0
  85. package/src/components/Menu/variables.ts +43 -4
  86. package/src/components/Navbar/Navbar.tsx +22 -5
  87. package/src/components/Navbar/variables.ts +3 -0
  88. package/src/components/NavigationTabs/NavigationTab.tsx +148 -0
  89. package/src/components/NavigationTabs/NavigationTabContent.tsx +66 -0
  90. package/src/components/NavigationTabs/NavigationTabMenu.tsx +40 -0
  91. package/src/components/NavigationTabs/NavigationTabs.tsx +83 -0
  92. package/src/components/NavigationTabs/variables.ts +34 -0
  93. package/src/components/Search/SearchTrigger.tsx +11 -2
  94. package/src/components/Segmented/Segmented.tsx +25 -16
  95. package/src/components/Select/Select.tsx +12 -6
  96. package/src/components/Select/SelectInput.tsx +8 -10
  97. package/src/components/Sidebar/Sidebar.tsx +2 -2
  98. package/src/components/TableOfContent/TableOfContent.tsx +2 -2
  99. package/src/core/constants/common.ts +1 -0
  100. package/src/core/hooks/__mocks__/use-theme-hooks.ts +3 -0
  101. package/src/core/hooks/index.ts +2 -0
  102. package/src/core/hooks/menu/use-mobile-menu-items.ts +91 -56
  103. package/src/core/hooks/menu/use-mobile-menu-levels.ts +14 -6
  104. package/src/core/hooks/use-scroll-item-into-view.ts +18 -0
  105. package/src/core/hooks/use-tab-list.ts +63 -0
  106. package/src/core/hooks/use-theme-hooks.ts +2 -0
  107. package/src/core/styles/global.ts +12 -2
  108. package/src/core/types/hooks.ts +5 -0
  109. package/src/core/types/index.ts +1 -0
  110. package/src/core/types/l10n.ts +3 -0
  111. package/src/core/types/navigation-tabs.ts +54 -0
  112. package/src/core/utils/Dynamic.tsx +67 -35
  113. package/src/core/utils/index.ts +1 -0
  114. package/src/core/utils/menu.ts +49 -3
  115. package/src/core/utils/navigation-tabs.ts +99 -0
  116. package/src/icons/CheckboxIcon/CheckboxIcon.tsx +1 -0
  117. package/src/icons/ChevronSortIcon/ChevronSortIcon.tsx +1 -0
  118. package/src/index.ts +6 -0
  119. package/src/layouts/PageLayout.tsx +1 -1
  120. package/src/layouts/RootLayout.tsx +2 -2
  121. package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +1 -1
  122. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +3 -3
  123. package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +1 -1
@@ -151,7 +151,7 @@ const CatalogDescription = styled_components_1.default.p `
151
151
  const CatalogPageWrapper = styled_components_1.default.div `
152
152
  --sidebar-width: var(--catalog-sidebar-width);
153
153
 
154
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
154
+ height: calc(100vh - var(--navbar-offset));
155
155
  display: flex;
156
156
  flex-direction: column;
157
157
  overflow: hidden;
@@ -1,2 +1,2 @@
1
1
  import type { CatalogEntityRelationsGraphProps } from '../../../../components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph';
2
- export declare const CatalogEntityRelationsGraph: import("react").ComponentType<CatalogEntityRelationsGraphProps>;
2
+ export declare const CatalogEntityRelationsGraph: import("../../../../core/utils").DynamicComponent<CatalogEntityRelationsGraphProps>;
@@ -142,10 +142,10 @@ function CatalogEntityHistorySidebar({ entityKey, revision, version, className,
142
142
  }
143
143
  const SidebarOverlay = styled_components_1.default.div `
144
144
  position: fixed;
145
- top: calc(var(--navbar-height) + var(--banner-height));
145
+ top: var(--navbar-offset);
146
146
  left: 0;
147
147
  width: var(--sidebar-width);
148
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
148
+ height: calc(100vh - var(--navbar-offset));
149
149
  padding: var(--catalog-history-sidebar-padding);
150
150
  background-color: var(--catalog-history-sidebar-bg-color);
151
151
  border-right: 1px solid var(--catalog-history-sidebar-border-color);
@@ -98,7 +98,7 @@ const SplitViewWrapper = styled_components_1.default.div `
98
98
  const SchemaSampleWrapper = styled_components_1.default.div `
99
99
  flex: 1;
100
100
  position: sticky;
101
- top: calc(var(--navbar-height) + var(--banner-height) + var(--spacing-md));
101
+ top: calc(var(--navbar-offset) + var(--spacing-md));
102
102
  align-self: flex-start;
103
103
  padding-top: var(--spacing-sm);
104
104
  `;
@@ -101,17 +101,20 @@ function CatalogFilterCheckboxes({ filter, filterValuesCasing, showCounter = tru
101
101
  react_1.default.createElement(FilterInput_1.FilterInput, { value: searchTerm, onChange: setSearchTerm })),
102
102
  react_1.default.createElement(FilterOptions_1.FilterOptions, null, filteredOptions.map(({ value, count }) => {
103
103
  const id = 'filter--' + filter.property + '--' + value;
104
- return (react_1.default.createElement(FilterCheckboxOption, { key: id, role: "link", onClick: () => {
105
- filter.toggleOption(value);
106
- telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
107
- Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('catalogEntitiesFilterCheckboxId', 'checkbox')), { category: filter.property, value: value }),
108
- ]);
109
- } },
110
- react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: filter.selectedOptions instanceof Set
111
- ? filter.selectedOptions.has(value) ||
112
- filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase())
113
- : false }),
114
- react_1.default.createElement(FilterOptionLabel_1.FilterOptionLabel, { "data-translation-key": value }, highlightText((0, utils_1.changeTextCasing)(translate(value), filterValuesCasing) || '')),
104
+ const checked = filter.selectedOptions instanceof Set
105
+ ? filter.selectedOptions.has(value) ||
106
+ filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase())
107
+ : false;
108
+ return (react_1.default.createElement(FilterCheckboxOption, { key: id },
109
+ react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: checked }),
110
+ react_1.default.createElement(FilterOptionLabel_1.FilterOptionLabel, { "data-translation-key": value },
111
+ react_1.default.createElement(FilterCheckboxInput, { checked: checked, onChange: () => {
112
+ filter.toggleOption(value);
113
+ telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage([
114
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('catalogEntitiesFilterCheckboxId', 'checkbox')), { category: filter.property, value: value }),
115
+ ]);
116
+ } }),
117
+ highlightText((0, utils_1.changeTextCasing)(translate(value), filterValuesCasing) || '')),
115
118
  showCounter && react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, count)));
116
119
  })))));
117
120
  }
@@ -147,6 +150,22 @@ const HighlightedText = styled_components_1.default.span `
147
150
  `;
148
151
  const FilterCheckboxOption = (0, styled_components_1.default)(FilterOption_1.FilterOption) `
149
152
  padding-left: var(--filter-option-checkbox-padding-left);
153
+
154
+ &:has(input:focus-visible) {
155
+ outline: 1px solid var(--button-border-color-focused);
156
+ outline-offset: -1px;
157
+ }
158
+ `;
159
+ const FilterCheckboxInput = styled_components_1.default.input.attrs({ type: 'checkbox' }) `
160
+ position: absolute;
161
+ width: 1px;
162
+ height: 1px;
163
+ margin: -1px;
164
+ padding: 0;
165
+ overflow: hidden;
166
+ clip: rect(0 0 0 0);
167
+ white-space: nowrap;
168
+ border: 0;
150
169
  `;
151
170
  const FilterSearchWrapper = styled_components_1.default.div `
152
171
  padding-bottom: var(--spacing-xs);
@@ -14,7 +14,7 @@ function CatalogMobileFiltersPanel({ setMobileFiltersPanelOpen, filterContent, }
14
14
  }
15
15
  const CatalogMobileFiltersPanelWrapper = styled_components_1.default.div `
16
16
  width: 100%;
17
- max-height: calc(100vh - var(--navbar-height) - var(--banner-height));
17
+ max-height: calc(100vh - var(--navbar-offset));
18
18
  overflow-y: auto;
19
19
  background: var(--sidebar-bg-color);
20
20
  display: flex;
@@ -15,10 +15,10 @@ function CatalogMobileFiltersPanelOverlay({ setMobileFiltersPanelOpen, filterCon
15
15
  const CatalogMobileFiltersPanelOverlayWrapper = styled_components_1.default.div `
16
16
  display: none;
17
17
  position: fixed;
18
- top: calc(var(--navbar-height) + var(--banner-height));
18
+ top: var(--navbar-offset);
19
19
  left: 0;
20
20
  width: 100%;
21
- height: calc(100vh - var(--navbar-height) - var(--banner-height));
21
+ height: calc(100vh - var(--navbar-offset));
22
22
  z-index: 3;
23
23
  background: var(--bg-color);
24
24
  flex-direction: column;
@@ -42,6 +42,7 @@ const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon")
42
42
  const ChevronUpIcon_1 = require("../../icons/ChevronUpIcon/ChevronUpIcon");
43
43
  const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? react_1.useLayoutEffect : react_1.useEffect;
44
44
  exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigger, triggerEvent = 'click', closeOnClick = true, withArrow, dataAttributes, placement, alignment, portalled = false, onClick, onClose, onOpen, }, ref) => {
45
+ var _a, _b;
45
46
  const dropdownRef = (0, react_1.useRef)(null);
46
47
  const menuRef = (0, react_1.useRef)(null);
47
48
  const [isOpen, setIsOpen] = (0, hooks_1.useControlledState)(false, active);
@@ -120,7 +121,8 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
120
121
  (0, hooks_1.useOutsideClick)(portalled ? [wrapperRef, menuRef] : wrapperRef, handleClose);
121
122
  const menuContent = typeof children === 'function' ? children({ close: handleClose, isOpen }) : children;
122
123
  const triggerChild = react_1.default.Children.only(trigger);
123
- const dropdownTrigger = (0, react_1.cloneElement)(triggerChild, Object.assign(Object.assign(Object.assign({ onClick: triggerEvent === 'click' ? handleToggle : undefined, 'aria-expanded': isOpen, icon: withArrow ? isOpen ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null) : undefined }, (withArrow ? { iconPosition: 'right' } : {})), triggerChild.props), { onKeyDown: triggerEvent === 'click' ? handleKeyDown : undefined }));
124
+ const isLinkTrigger = Boolean(((_a = triggerChild.props) === null || _a === void 0 ? void 0 : _a.to) || ((_b = triggerChild.props) === null || _b === void 0 ? void 0 : _b.href));
125
+ const dropdownTrigger = (0, react_1.cloneElement)(triggerChild, Object.assign(Object.assign(Object.assign({ onClick: triggerEvent === 'click' ? handleToggle : undefined, 'aria-haspopup': 'menu', 'aria-expanded': isOpen, icon: withArrow ? isOpen ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null) : undefined }, (withArrow ? { iconPosition: 'right' } : {})), triggerChild.props), { onKeyDown: triggerEvent === 'click' || !isLinkTrigger ? handleKeyDown : undefined }));
124
126
  const menu = (react_1.default.createElement(ChildrenWrapper, { ref: menuRef, $placement: placement, $alignment: alignment, $isOpen: isOpen, $portalled: portalled, style: portalled ? menuStyle : undefined, onClick: closeOnClick ? handleChildClick : undefined }, menuContent));
125
127
  const portalledMenu = isOpen && typeof document !== 'undefined' ? (0, react_dom_1.createPortal)(menu, document.body) : null;
126
128
  return (react_1.default.createElement(DropdownWrapper, Object.assign({ "data-component-name": "Dropdown/Dropdown", "data-testid": "dropdown" }, dataAttributes, { className: className, ref: wrapperRef, onPointerEnter: triggerEvent === 'hover' ? handleOpen : undefined, onPointerLeave: triggerEvent === 'hover' ? handleClose : undefined, onClick: onClick }),
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import type { ReactNode, JSX } from 'react';
3
3
  import type { DropdownMenuItemProps } from '../../components/Dropdown/DropdownMenuItem';
4
4
  export type DropdownMenuProps = {
5
+ id?: string;
5
6
  className?: string;
6
7
  role?: string;
7
8
  footer?: React.ReactNode;
@@ -15,7 +15,7 @@ function DropdownMenu(props) {
15
15
  if ('items' in props) {
16
16
  content = props.items.map((item, idx) => (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, Object.assign({ key: idx }, item), item.content)));
17
17
  }
18
- return (react_1.default.createElement(DropdownMenuWrapper, { "data-component-name": "Dropdown/DropdownMenu", "data-testid": "dropdown-menu", className: props.className, role: props.role || 'menu' },
18
+ return (react_1.default.createElement(DropdownMenuWrapper, { "data-component-name": "Dropdown/DropdownMenu", "data-testid": "dropdown-menu", id: props.id, className: props.className, role: props.role || 'menu' },
19
19
  content,
20
20
  props.footer || null));
21
21
  }
@@ -43,6 +43,7 @@ const hooks_1 = require("../../core/hooks");
43
43
  function Reasons({ settings, onChange, className }) {
44
44
  const { label, component = 'checkbox', items = [] } = settings;
45
45
  const [checkedState, setCheckedState] = React.useState(new Array(items.length).fill(false));
46
+ const idPrefix = React.useId();
46
47
  const { useTranslate } = (0, hooks_1.useThemeHooks)();
47
48
  const { translate } = useTranslate();
48
49
  if (!items.length) {
@@ -59,8 +60,8 @@ function Reasons({ settings, onChange, className }) {
59
60
  React.createElement(Label, null, label ||
60
61
  translate('feedback.settings.reasons.label', 'Which statement describes your thoughts about this page?')),
61
62
  items.map((reason, idx) => (React.createElement(OptionWrapper, { key: reason },
62
- React.createElement("input", { type: component, value: reason, checked: checkedState[idx], name: "reasons", onChange: () => handleOptionChange(idx) }),
63
- React.createElement("label", { "data-translation-key": `feedback.settings.reasons.items.${idx + 1}`, id: reason, onClick: () => handleOptionChange(idx) }, translate(`feedback.settings.reasons.items.${idx + 1}`, reason)))))));
63
+ React.createElement("input", { id: `${idPrefix}-${idx}`, type: component, value: reason, checked: checkedState[idx], name: "reasons", onChange: () => handleOptionChange(idx) }),
64
+ React.createElement("label", { "data-translation-key": `feedback.settings.reasons.items.${idx + 1}`, htmlFor: `${idPrefix}-${idx}` }, translate(`feedback.settings.reasons.items.${idx + 1}`, reason)))))));
64
65
  }
65
66
  const ReasonsWrapper = styled_components_1.default.div `
66
67
  font-family: var(--feedback-font-family);
@@ -22,22 +22,41 @@ function FilterCheckboxes({ filter, filterValuesCasing, showCounter = true, }) {
22
22
  react_1.default.createElement(FilterTitle_1.FilterTitle, { "data-translation-key": filter.titleTranslationKey }, translate(filter.titleTranslationKey, filter.title)),
23
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
- return (react_1.default.createElement(FilterCheckboxOption, { key: id, role: "link", onClick: () => {
26
- filter.toggleOption(value);
27
- telemetry.sendFilterCheckboxToggledMessage([
28
- (0, utils_1.getBaseDataAttributes)('filterId', 'checkbox'),
29
- ]);
30
- } },
31
- react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: filter.selectedOptions instanceof Set
32
- ? filter.selectedOptions.has(value) ||
33
- filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase())
34
- : false }),
35
- react_1.default.createElement(FilterOptionLabel_1.FilterOptionLabel, { "data-translation-key": value }, (0, utils_1.changeTextCasing)(translate(value), filterValuesCasing)),
25
+ const checked = filter.selectedOptions instanceof Set
26
+ ? filter.selectedOptions.has(value) ||
27
+ filter.selectedOptions.has(value === null || value === void 0 ? void 0 : value.toLowerCase())
28
+ : false;
29
+ return (react_1.default.createElement(FilterCheckboxOption, { key: id },
30
+ react_1.default.createElement(CheckboxIcon_1.CheckboxIcon, { checked: checked }),
31
+ react_1.default.createElement(FilterOptionLabel_1.FilterOptionLabel, { "data-translation-key": value },
32
+ react_1.default.createElement(FilterCheckboxInput, { checked: checked, onChange: () => {
33
+ filter.toggleOption(value);
34
+ telemetry.sendFilterCheckboxToggledMessage([
35
+ (0, utils_1.getBaseDataAttributes)('filterId', 'checkbox'),
36
+ ]);
37
+ } }),
38
+ (0, utils_1.changeTextCasing)(translate(value), filterValuesCasing)),
36
39
  showCounter && react_1.default.createElement(CounterTag_1.CounterTag, { borderless: true }, count)));
37
40
  }))));
38
41
  }
39
42
  const FilterCheckboxOption = (0, styled_components_1.default)(FilterOption_1.FilterOption) `
40
43
  padding-left: var(--filter-option-checkbox-padding-left);
44
+
45
+ &:has(input:focus-visible) {
46
+ outline: 1px solid var(--button-border-color-focused);
47
+ outline-offset: -1px;
48
+ }
49
+ `;
50
+ const FilterCheckboxInput = styled_components_1.default.input.attrs({ type: 'checkbox' }) `
51
+ position: absolute;
52
+ width: 1px;
53
+ height: 1px;
54
+ margin: -1px;
55
+ padding: 0;
56
+ overflow: hidden;
57
+ clip: rect(0 0 0 0);
58
+ white-space: nowrap;
59
+ border: 0;
41
60
  `;
42
61
  const FilterCheckboxesWrapper = styled_components_1.default.div `
43
62
  display: flex;
@@ -43,6 +43,7 @@ const Button_1 = require("../../components/Button/Button");
43
43
  function Image(props) {
44
44
  const { src, srcSet, images: galleryImages, alt, className, width, height, border, caption, framed, style, withLightbox, lightboxStyle, } = props;
45
45
  const lightboxContainerRef = (0, react_1.useRef)(null);
46
+ const lightboxTriggerRef = (0, react_1.useRef)(null);
46
47
  const [lightboxImage, setLightboxImage] = (0, react_1.useState)(undefined);
47
48
  const parsedSourceSetMap = (0, react_1.useMemo)(() => {
48
49
  return srcSet ? (0, utils_1.parseSrcSet)(srcSet) : new Map();
@@ -53,28 +54,47 @@ function Image(props) {
53
54
  setLightboxImage(undefined);
54
55
  }
55
56
  }, []);
56
- const handleImageClick = (0, react_1.useCallback)((src) => {
57
+ const handleImageClick = (0, react_1.useCallback)((src, trigger) => {
57
58
  if (!withLightbox || lightboxImage) {
58
59
  return;
59
60
  }
61
+ lightboxTriggerRef.current = trigger;
60
62
  setLightboxImage(src);
61
63
  }, [withLightbox, lightboxImage]);
64
+ const getLightboxTriggerProps = (imageSrc) => withLightbox
65
+ ? {
66
+ role: 'button',
67
+ tabIndex: 0,
68
+ 'aria-label': alt ? undefined : 'Open image',
69
+ onClick: (e) => handleImageClick(imageSrc, e.currentTarget),
70
+ onKeyDown: (e) => {
71
+ if (e.key === 'Enter' || e.key === ' ') {
72
+ e.preventDefault();
73
+ handleImageClick(imageSrc, e.currentTarget);
74
+ }
75
+ },
76
+ }
77
+ : {};
62
78
  const handleCloseLightbox = (0, react_1.useCallback)(() => {
63
79
  setLightboxImage(undefined);
64
80
  }, []);
65
81
  (0, hooks_1.useModalScrollLock)(!!lightboxImage);
66
82
  (0, react_1.useEffect)(() => {
67
- var _a;
83
+ var _a, _b;
68
84
  if (lightboxImage) {
69
85
  (_a = lightboxContainerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
70
86
  }
87
+ else {
88
+ (_b = lightboxTriggerRef.current) === null || _b === void 0 ? void 0 : _b.focus();
89
+ lightboxTriggerRef.current = null;
90
+ }
71
91
  }, [lightboxImage]);
72
92
  const combinedStyles = Object.assign(Object.assign(Object.assign({}, (withLightbox && { cursor: 'pointer' })), (border && { border })), (typeof style === 'string' ? (0, utils_1.parseStyleString)(style) : style));
73
93
  const lightboxOverlayStyles = typeof lightboxStyle === 'string' ? (0, utils_1.parseStyleString)(lightboxStyle) : lightboxStyle;
74
- const images = src ? (react_1.default.createElement("img", { src: src, alt: alt, className: className, width: width, height: height, style: combinedStyles, onClick: () => handleImageClick(src) })) : (Array.from(parsedSourceSetMap).map(([key, value]) => (react_1.default.createElement(ColorModeAwareImage, { key: key, $colorMode: key, src: value, alt: alt, className: className, width: width, height: height, $withLightbox: withLightbox, style: combinedStyles, onClick: () => handleImageClick(value) }))));
94
+ const images = src ? (react_1.default.createElement("img", Object.assign({ src: src, alt: alt, className: className, width: width, height: height, style: combinedStyles }, getLightboxTriggerProps(src)))) : (Array.from(parsedSourceSetMap).map(([key, value]) => (react_1.default.createElement(ColorModeAwareImage, Object.assign({ key: key, $colorMode: key, src: value, alt: alt, className: className, width: width, height: height, $withLightbox: withLightbox, style: combinedStyles }, getLightboxTriggerProps(value))))));
75
95
  const hasGallery = Array.isArray(galleryImages) && galleryImages.length > 0;
76
96
  const visibleGalleryImages = hasGallery ? galleryImages.slice(0, 3) : [];
77
- const gallery = hasGallery ? (react_1.default.createElement(GalleryRow, null, visibleGalleryImages.map((galleryImageSrc, index) => (react_1.default.createElement("img", { key: `${galleryImageSrc}-${index}`, src: galleryImageSrc, alt: alt, style: withLightbox ? { cursor: 'pointer' } : undefined, onClick: () => handleImageClick(galleryImageSrc) }))))) : null;
97
+ const gallery = hasGallery ? (react_1.default.createElement(GalleryRow, null, visibleGalleryImages.map((galleryImageSrc, index) => (react_1.default.createElement("img", Object.assign({ key: `${galleryImageSrc}-${index}`, src: galleryImageSrc, alt: alt, style: withLightbox ? { cursor: 'pointer' } : undefined }, getLightboxTriggerProps(galleryImageSrc))))))) : null;
78
98
  const hasCaption = Boolean(caption);
79
99
  const hasWrapper = Boolean(framed || hasCaption || hasGallery);
80
100
  const wrapperContent = hasGallery ? gallery : images;
@@ -82,7 +82,7 @@ exports.Markdown = styled_components_1.default.main
82
82
  ${links_1.markdownLinksCss}
83
83
 
84
84
  a[name], [id] {
85
- scroll-margin-top: calc(var(--navbar-height) + var(--banner-height));
85
+ scroll-margin-top: var(--navbar-offset);
86
86
  }
87
87
 
88
88
  img,
@@ -95,7 +95,7 @@ exports.Markdown = styled_components_1.default.main
95
95
  font-family: var(--heading-font-family);
96
96
  position: relative;
97
97
 
98
- scroll-margin-top: calc(var(--navbar-height) + var(--banner-height));
98
+ scroll-margin-top: var(--navbar-offset);
99
99
  ${(0, heading_anchor_1.headingAnchorCss)(constants_1.ANCHOR_CLASS)};
100
100
 
101
101
  h1,
@@ -306,6 +306,7 @@ exports.Markdown = styled_components_1.default.main
306
306
  font-size: inherit;
307
307
  font-family: inherit;
308
308
  border: none;
309
+ padding: 0;
309
310
  }
310
311
  }
311
312
 
@@ -7,12 +7,16 @@ exports.Menu = Menu;
7
7
  const styled_components_1 = __importDefault(require("styled-components"));
8
8
  const react_1 = __importDefault(require("react"));
9
9
  const MenuItem_1 = require("../../components/Menu/MenuItem");
10
+ const MenuSelect_1 = require("../../components/Menu/MenuSelect");
10
11
  const constants_1 = require("../../core/constants");
11
12
  const utils_1 = require("../../core/utils");
12
13
  function Menu({ depth = 0, items, className, isMobile, onDrilldownOpen, }) {
13
14
  const activeItem = items.find(({ active }) => active);
14
15
  return (react_1.default.createElement(MenuWrapper, { className: className, "data-component-name": "Menu/Menu" }, items.map((item, index) => {
15
16
  var _a;
17
+ if ((0, utils_1.getMenuItemType)(item) === constants_1.MenuItemType.Select) {
18
+ return react_1.default.createElement(MenuSelect_1.MenuSelect, { item: item, key: `${item.label}-${index}` });
19
+ }
16
20
  return (react_1.default.createElement(MenuItem_1.MenuItem, { item: item, key: `${item.link || item.label}-${index}`, activeItem: activeItem, isMobile: isMobile, depth: depth, onClick: () => {
17
21
  if ((0, utils_1.getMenuItemType)(item) === constants_1.MenuItemType.DrillDown) {
18
22
  onDrilldownOpen === null || onDrilldownOpen === void 0 ? void 0 : onDrilldownOpen({ previousLink: activeItem === null || activeItem === void 0 ? void 0 : activeItem.link, item });
@@ -0,0 +1,7 @@
1
+ import type { JSX } from 'react';
2
+ import type { ItemState } from '../../core/types';
3
+ export type MenuSelectProps = {
4
+ item: ItemState;
5
+ className?: string;
6
+ };
7
+ export declare function MenuSelect({ item, className }: MenuSelectProps): JSX.Element;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MenuSelect = MenuSelect;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const utils_1 = require("../../core/utils");
10
+ const hooks_1 = require("../../core/hooks");
11
+ const Dropdown_1 = require("../../components/Dropdown/Dropdown");
12
+ const DropdownMenu_1 = require("../../components/Dropdown/DropdownMenu");
13
+ const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
14
+ const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
15
+ const LaunchIcon_1 = require("../../icons/LaunchIcon/LaunchIcon");
16
+ const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
17
+ const CheckmarkIcon_1 = require("../../icons/CheckmarkIcon/CheckmarkIcon");
18
+ function MenuSelect({ item, className }) {
19
+ const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
20
+ const { translate } = useTranslate();
21
+ const telemetry = useTelemetry();
22
+ return (react_1.default.createElement(MenuSelectWrapper, { "data-component-name": "Menu/MenuSelect", className: className, role: "listitem" },
23
+ react_1.default.createElement(MenuSelectDropdown, { alignment: "start", trigger: react_1.default.createElement(MenuSelectTrigger, { type: "button" },
24
+ react_1.default.createElement(MenuSelectLabel, null, translate(item.labelTranslationKey, item.label)),
25
+ react_1.default.createElement(MenuSelectChevron, { size: "var(--menu-select-icon-size)", color: "--menu-select-icon-color" })) },
26
+ react_1.default.createElement(MenuSelectMenu, null, item.items.map((option, index) => {
27
+ const key = `${option.link || option.label}-${index}`;
28
+ const checkmark = option.active ? (react_1.default.createElement(MenuSelectCheckmark, { size: "var(--menu-select-option-checkmark-size)" })) : null;
29
+ const content = (react_1.default.createElement(MenuSelectOptionContent, { $active: option.active },
30
+ option.icon || option.srcSet ? (react_1.default.createElement(MenuSelectOptionIcon, { icon: option.icon, srcSet: option.srcSet })) : null,
31
+ translate(option.labelTranslationKey, option.label),
32
+ option.external ? (react_1.default.createElement(LaunchIcon_1.LaunchIcon, { size: "var(--menu-select-option-external-icon-size)" })) : null));
33
+ if (!option.link) {
34
+ return (react_1.default.createElement(MenuSelectOption, { key: key, active: option.active, prefix: checkmark, dataAttributes: { 'aria-disabled': 'true' } }, content));
35
+ }
36
+ return (react_1.default.createElement(MenuSelectOption, { key: key, to: option.link, external: option.external, target: option.target === '_blank' ? '_blank' : undefined, active: option.active, "aria-current": option.active ? 'page' : undefined, prefix: checkmark, onAction: () => telemetry.sendSidebarItemClickedMessage([
37
+ Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('sidebarItem', 'sidebar')), { label: option.label, type: 'link' }),
38
+ ]) }, content));
39
+ })))));
40
+ }
41
+ const MenuSelectWrapper = styled_components_1.default.div `
42
+ margin: var(--menu-select-margin);
43
+ `;
44
+ const MenuSelectDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
45
+ --dropdown-menu-padding-top: var(--menu-select-menu-offset);
46
+ --dropdown-menu-padding: var(--menu-select-menu-padding);
47
+ --dropdown-menu-border-radius: var(--menu-select-menu-border-radius);
48
+ --dropdown-menu-item-gap: var(--menu-select-option-gap);
49
+ --dropdown-menu-item-border-radius: var(--menu-select-option-border-radius);
50
+ --dropdown-menu-item-bg-color-active: var(--menu-select-option-bg-color-active);
51
+ --dropdown-menu-item-color-active: var(--menu-select-option-text-color-active);
52
+
53
+ width: 100%;
54
+
55
+ > * {
56
+ min-width: 100%;
57
+ }
58
+ `;
59
+ const MenuSelectChevron = (0, styled_components_1.default)(ChevronDownIcon_1.ChevronDownIcon) `
60
+ transition: var(--menu-select-transition);
61
+ `;
62
+ const MenuSelectTrigger = styled_components_1.default.button `
63
+ display: flex;
64
+ align-items: center;
65
+ gap: var(--menu-select-gap);
66
+ box-sizing: border-box;
67
+ width: 100%;
68
+ height: var(--menu-select-height);
69
+ padding: 0 var(--menu-select-padding-horizontal);
70
+ border: var(--menu-select-border);
71
+ border-radius: var(--menu-select-border-radius);
72
+ background-color: var(--menu-select-bg-color);
73
+ color: var(--menu-select-text-color);
74
+ font-family: inherit;
75
+ font-size: var(--menu-select-font-size);
76
+ line-height: var(--menu-select-line-height);
77
+ text-align: left;
78
+ cursor: pointer;
79
+
80
+ &:focus-visible {
81
+ outline: 1px solid var(--menu-select-border-color-focused);
82
+ }
83
+
84
+ &[aria-expanded='true'] ${MenuSelectChevron} {
85
+ transform: rotate(180deg);
86
+ }
87
+ `;
88
+ const MenuSelectLabel = styled_components_1.default.span `
89
+ flex: 1;
90
+ min-width: 0;
91
+ overflow: hidden;
92
+ text-overflow: ellipsis;
93
+ white-space: nowrap;
94
+ `;
95
+ const MenuSelectMenu = (0, styled_components_1.default)(DropdownMenu_1.DropdownMenu) `
96
+ box-sizing: border-box;
97
+ width: 100%;
98
+ max-width: 100%;
99
+ `;
100
+ const MenuSelectOption = (0, styled_components_1.default)(DropdownMenuItem_1.DropdownMenuItem) `
101
+ position: relative;
102
+ box-sizing: border-box;
103
+ padding: var(--menu-select-option-padding);
104
+
105
+ &[aria-disabled='true'] {
106
+ cursor: default;
107
+ pointer-events: none;
108
+ }
109
+ `;
110
+ const MenuSelectCheckmark = (0, styled_components_1.default)(CheckmarkIcon_1.CheckmarkIcon) `
111
+ position: absolute;
112
+ top: 50%;
113
+ left: var(--menu-select-option-checkmark-offset);
114
+ transform: translateY(-50%);
115
+ `;
116
+ const MenuSelectOptionContent = styled_components_1.default.span `
117
+ display: inline-flex;
118
+ align-items: center;
119
+ gap: var(--menu-select-option-content-gap);
120
+ font-weight: ${({ $active }) => $active
121
+ ? 'var(--menu-select-option-font-weight-active)'
122
+ : 'var(--menu-select-option-font-weight)'};
123
+ `;
124
+ const MenuSelectOptionIcon = (0, styled_components_1.default)(GenericIcon_1.GenericIcon) `
125
+ --icon-width: var(--menu-select-option-icon-size);
126
+ --icon-height: var(--menu-select-option-icon-size);
127
+ flex-shrink: 0;
128
+ `;
129
+ //# sourceMappingURL=MenuSelect.js.map
@@ -104,6 +104,45 @@ exports.menu = (0, styled_components_1.css) `
104
104
  --menu-back-button-gap: var(--spacing-xs);
105
105
  --menu-back-button-icon: none;
106
106
 
107
+ /**
108
+ * @tokens Menu select
109
+ */
110
+ --menu-select-margin-top: 0;
111
+ --menu-select-margin-bottom: var(--spacing-xs);
112
+ --menu-select-margin-horizontal: var(--menu-item-label-margin-horizontal);
113
+ --menu-select-margin: var(--menu-select-margin-top) var(--menu-select-margin-horizontal) var(--menu-select-margin-bottom); // @presenter Spacing
114
+ --menu-select-height: 32px; // @presenter Spacing
115
+ --menu-select-padding-horizontal: calc(var(--spacing-sm) - var(--border-width)); // @presenter Spacing
116
+ --menu-select-gap: var(--spacing-xxs); // @presenter Spacing
117
+ --menu-select-font-size: var(--font-size-base); // @presenter FontSize
118
+ --menu-select-line-height: var(--line-height-base); // @presenter LineHeight
119
+ --menu-select-text-color: var(--input-content-color-active); // @presenter Color
120
+ --menu-select-bg-color: var(--input-bg-color); // @presenter Color
121
+ --menu-select-border: var(--input-border); // @presenter Border
122
+ --menu-select-border-color-focused: var(--input-border-color-focused); // @presenter Color
123
+ --menu-select-border-radius: var(--input-border-radius); // @presenter BorderRadius
124
+ --menu-select-icon-size: 16px;
125
+ --menu-select-icon-color: var(--icon-color-secondary); // @presenter Color
126
+ --menu-select-transition: transform 150ms ease-in-out;
127
+ --menu-select-menu-offset: var(--spacing-xs); // @presenter Spacing
128
+ --menu-select-menu-padding: calc(var(--dropdown-menu-padding) - var(--border-width)); // @presenter Spacing
129
+ --menu-select-menu-border-radius: var(--border-radius-lg); // @presenter BorderRadius
130
+ --menu-select-option-gap: calc(var(--spacing-unit) / 2); // @presenter Spacing
131
+ --menu-select-option-content-gap: var(--spacing-xs); // @presenter Spacing
132
+ --menu-select-option-padding-vertical: var(--dropdown-menu-item-padding-vertical);
133
+ --menu-select-option-padding-left: var(--spacing-md);
134
+ --menu-select-option-padding-right: var(--spacing-sm);
135
+ --menu-select-option-padding: var(--menu-select-option-padding-vertical) var(--menu-select-option-padding-right) var(--menu-select-option-padding-vertical) var(--menu-select-option-padding-left); // @presenter Spacing
136
+ --menu-select-option-border-radius: var(--border-radius-md); // @presenter BorderRadius
137
+ --menu-select-option-font-weight: var(--font-weight-regular); // @presenter FontWeight
138
+ --menu-select-option-font-weight-active: var(--font-weight-medium); // @presenter FontWeight
139
+ --menu-select-option-text-color-active: var(--text-color-primary); // @presenter Color
140
+ --menu-select-option-bg-color-active: transparent; // @presenter Color
141
+ --menu-select-option-icon-size: var(--menu-item-icon-size);
142
+ --menu-select-option-external-icon-size: var(--menu-item-external-icon-size);
143
+ --menu-select-option-checkmark-size: 14px;
144
+ --menu-select-option-checkmark-offset: calc((var(--menu-select-option-padding-left) - var(--menu-select-option-checkmark-size)) / 2);
145
+
107
146
  /**
108
147
  * @tokens Menu items
109
148
  */
@@ -134,18 +173,18 @@ exports.mobileMenu = (0, styled_components_1.css) `
134
173
  * @tokens Mobile Menu
135
174
  * */
136
175
  /* Fallback for older browsers. dvh accounts for dynamic UI elements like mobile address bars */
137
- --menu-mobile-height: calc(100vh - var(--navbar-height) - var(--banner-height));
138
- --menu-mobile-height: calc(100dvh - var(--navbar-height) - var(--banner-height));
176
+ --menu-mobile-height: calc(100vh - var(--navbar-offset));
177
+ --menu-mobile-height: calc(100dvh - var(--navbar-offset));
139
178
  --menu-mobile-width: 100%;
140
179
  --menu-mobile-z-index: var(--z-index-raised);
141
180
  --menu-mobile-left: 0;
142
- --menu-mobile-top: calc(var(--navbar-height) + var(--banner-height));
181
+ --menu-mobile-top: var(--navbar-offset);
143
182
  --menu-mobile-transition: 0.5s;
144
183
  --menu-mobile-bg: var(--bg-color); // @presenter Color
145
184
  --menu-mobile-margin: var(--menu-mobile-items-margin-top) var(--menu-mobile-margin-horizontal) 0 var(--menu-mobile-margin-horizontal);
146
185
  --menu-mobile-line-height: var(--line-height-base); // @presenter LineHeight
147
186
  --menu-mobile-padding-top: var(--spacing-sm); // @presenter Spacing
148
- --menu-mobile-margin-horizontal: var(--spacing-xs); // @presenter Spacing
187
+ --menu-mobile-margin-horizontal: 0; // @presenter Spacing
149
188
  --menu-mobile-items-margin-top: var(--spacing-xxs); // @presenter Spacing
150
189
 
151
190
  --menu-mobile-profile-bg-color: var(--bg-color); // @presenter Color