@redocly/theme 0.55.0-next.3 → 0.55.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.
- package/lib/components/Dropdown/variables.js +1 -1
- package/lib/components/Menu/MenuItem.d.ts +1 -1
- package/lib/components/Menu/MenuItem.js +7 -3
- package/lib/components/Select/Select.js +19 -3
- package/lib/components/Select/SelectInput.d.ts +1 -0
- package/lib/components/Select/SelectInput.js +7 -3
- package/lib/components/VersionPicker/VersionPicker.js +22 -3
- package/lib/components/VersionPicker/variables.js +1 -0
- package/package.json +2 -2
- package/src/components/Dropdown/variables.ts +1 -1
- package/src/components/Menu/MenuItem.tsx +11 -2
- package/src/components/Select/Select.tsx +24 -1
- package/src/components/Select/SelectInput.tsx +20 -1
- package/src/components/VersionPicker/VersionPicker.tsx +32 -2
- package/src/components/VersionPicker/variables.ts +1 -0
|
@@ -42,7 +42,7 @@ exports.dropdown = (0, styled_components_1.css) `
|
|
|
42
42
|
|
|
43
43
|
--dropdown-menu-item-color-dangerous: var(--color-error-base);
|
|
44
44
|
|
|
45
|
-
--dropdown-menu-item-border-color-focused: var(--color-
|
|
45
|
+
--dropdown-menu-item-border-color-focused: var(--button-border-color-focused);
|
|
46
46
|
// @tokens End
|
|
47
47
|
`;
|
|
48
48
|
//# sourceMappingURL=variables.js.map
|
|
@@ -66,9 +66,14 @@ function MenuItem(props) {
|
|
|
66
66
|
handleExpand();
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
|
+
const handleExpandOnEnter = (event) => {
|
|
70
|
+
if (event.key === 'Enter') {
|
|
71
|
+
handleOnClick();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
69
74
|
const chevron = hasChevron ? (isExpanded ? (react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, { size: "var(--menu-item-label-chevron-size)", color: "--tree-content-color-default" })) : (react_1.default.createElement(ChevronRightIcon_1.ChevronRightIcon, { size: "var(--menu-item-label-chevron-size)", color: "--tree-content-color-default" }))) : null;
|
|
70
75
|
const httpColor = item.deprecated ? 'http-deprecated' : item.httpVerb;
|
|
71
|
-
const label = item.label && (react_1.default.createElement(MenuItemLabelWrapper, { active: item.active, deprecated: item.deprecated, depth: depth, withChevron: hasChevron, isSeparator: isSeparator, onClick: handleOnClick, ref: labelRef, role: item.link ? 'none' : 'link', "data-testid": "menu-item-label" },
|
|
76
|
+
const label = item.label && (react_1.default.createElement(MenuItemLabelWrapper, { active: item.active, deprecated: item.deprecated, depth: depth, withChevron: hasChevron, isSeparator: isSeparator, onClick: handleOnClick, onKeyDown: handleExpandOnEnter, ref: labelRef, role: item.link ? 'none' : 'link', tabIndex: !item.link ? 0 : undefined, "data-testid": "menu-item-label" },
|
|
72
77
|
hasChevron ? react_1.default.createElement(ChevronWrapper, null, chevron) : null,
|
|
73
78
|
item.icon ? react_1.default.createElement(MenuItemIcon, { src: item.icon }) : null,
|
|
74
79
|
react_1.default.createElement(MenuItemLabelTextWrapper, null,
|
|
@@ -80,7 +85,7 @@ function MenuItem(props) {
|
|
|
80
85
|
isDrilldown ? react_1.default.createElement(ArrowRightIcon_1.ArrowRightIcon, { size: "12px" }) : null,
|
|
81
86
|
hasHttpTag ? (react_1.default.createElement(HttpTag_1.HttpTag, { color: httpColor || '' }, item.httpVerb === 'hook' ? 'event' : item.httpVerb)) : null));
|
|
82
87
|
return (react_1.default.createElement(MenuItemWrapper, { "data-component-name": "Menu/MenuItem", className: generateClassName({ type, item, className }) },
|
|
83
|
-
item.link ? (react_1.default.createElement(MenuItemLink, { to: item.link, external: item.external, target: item.target, languageInsensitive: item.languageInsensitive }, label)) : (label),
|
|
88
|
+
item.link ? (react_1.default.createElement(MenuItemLink, { to: item.link, external: item.external, target: item.target, languageInsensitive: item.languageInsensitive, onKeyDown: handleExpandOnEnter }, label)) : (label),
|
|
84
89
|
isNested ? (react_1.default.createElement(MenuItemNestedWrapper, { depth: depth, ref: nestedMenuRef, style: style }, isExpanded || !canUnmount ? props.children : null)) : null,
|
|
85
90
|
item.separatorLine ? (react_1.default.createElement(MenuItemSeparatorLine, { depth: depth, linePosition: item.linePosition })) : null));
|
|
86
91
|
}
|
|
@@ -128,7 +133,6 @@ const MenuItemWrapper = styled_components_1.default.div `
|
|
|
128
133
|
}
|
|
129
134
|
`;
|
|
130
135
|
const MenuItemNestedWrapper = styled_components_1.default.div `
|
|
131
|
-
overflow: hidden;
|
|
132
136
|
order: 1;
|
|
133
137
|
position: relative;
|
|
134
138
|
|
|
@@ -151,11 +151,23 @@ function Select(props) {
|
|
|
151
151
|
return !!selectedOptions.find((selectOption) => selectOption.value === option.value || selectOption.value === option.label);
|
|
152
152
|
};
|
|
153
153
|
const renderDefaultInput = (inputRef) => {
|
|
154
|
-
return (react_1.default.createElement(SelectInput_1.SelectInput, { id: inputId, selectedOptions: selectedOptions, searchValue: searchValue, placeholder: placeholder, stickyValue: stickyInputValue, multiple: multiple, searchable: searchable, clearable: clearable, customIcon: icon, inputRef: inputRef, onlyIcon: onlyIcon, clearHandler: clearHandler, searchHandler: searchHandler, inputBlurHandler: inputBlurHandler, inputFocusHandler: inputFocusHandler, clickHandler: inputClickHandler }));
|
|
154
|
+
return (react_1.default.createElement(SelectInput_1.SelectInput, { id: inputId, listboxId: inputId, selectedOptions: selectedOptions, searchValue: searchValue, placeholder: placeholder, stickyValue: stickyInputValue, multiple: multiple, searchable: searchable, clearable: clearable, customIcon: icon, inputRef: inputRef, onlyIcon: onlyIcon, clearHandler: clearHandler, searchHandler: searchHandler, inputBlurHandler: inputBlurHandler, inputFocusHandler: inputFocusHandler, clickHandler: inputClickHandler }));
|
|
155
155
|
};
|
|
156
|
-
return (react_1.default.createElement(exports.SelectWrapper, Object.assign({ "data-component-name": "Select/Select", ref: selectRef }, dataAttributes, { disabled: disabled, "data-testid": dataTestId, className: className
|
|
156
|
+
return (react_1.default.createElement(exports.SelectWrapper, Object.assign({ "data-component-name": "Select/Select", ref: selectRef }, dataAttributes, { disabled: disabled, "data-testid": dataTestId, className: className, onKeyDown: (e) => {
|
|
157
|
+
if (e.key === 'Enter' && document.activeElement === selectRef.current) {
|
|
158
|
+
e.preventDefault();
|
|
159
|
+
setDropdownActive(!dropdownActive);
|
|
160
|
+
}
|
|
161
|
+
}, tabIndex: 0, "aria-haspopup": "listbox", "aria-expanded": dropdownActive, "aria-label": "Select option", onFocus: (e) => {
|
|
162
|
+
var _a;
|
|
163
|
+
if (e.target === selectRef.current) {
|
|
164
|
+
(_a = selectInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
165
|
+
}
|
|
166
|
+
}, onMouseDown: (e) => {
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
} }),
|
|
157
169
|
react_1.default.createElement(SelectDropdown, { closeOnClick: !multiple, withArrow: withArrow, trigger: renderInput ? renderInput() : renderDefaultInput(selectInputRef), triggerEvent: triggerEvent, placement: placement, alignment: alignment, active: !renderInput ? dropdownActive : undefined },
|
|
158
|
-
react_1.default.createElement(SelectDropdownMenu, { footer: footer }, filteredOptions.length === 0 ? (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { disabled: true }, "No results")) : (filteredOptions.map((option, index) => {
|
|
170
|
+
react_1.default.createElement(SelectDropdownMenu, { role: "listbox", footer: footer }, filteredOptions.length === 0 ? (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { disabled: true }, "No results")) : (filteredOptions.map((option, index) => {
|
|
159
171
|
return (react_1.default.createElement(react_1.Fragment, { key: index },
|
|
160
172
|
react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { onAction: () => selectHandler(option), prefix: !hideCheckmarkIcon &&
|
|
161
173
|
(checkmarkIconPosition ? checkmarkIconPosition === 'start' : false) &&
|
|
@@ -176,6 +188,10 @@ exports.SelectWrapper = styled_components_1.default.div `
|
|
|
176
188
|
color: var(--select-text-color);
|
|
177
189
|
min-width: 0;
|
|
178
190
|
|
|
191
|
+
&:focus-visible {
|
|
192
|
+
outline: 1px solid var(--button-border-color-focused);
|
|
193
|
+
}
|
|
194
|
+
|
|
179
195
|
${({ disabled }) => disabled &&
|
|
180
196
|
`
|
|
181
197
|
opacity: 0.59;
|
|
@@ -34,7 +34,7 @@ const Tag_1 = require("../../components/Tag/Tag");
|
|
|
34
34
|
const CloseIcon_1 = require("../../icons/CloseIcon/CloseIcon");
|
|
35
35
|
const Button_1 = require("../../components/Button/Button");
|
|
36
36
|
function SelectInput(props) {
|
|
37
|
-
const { id, onlyIcon, icon, customIcon, selectedOptions, placeholder, stickyValue, multiple, searchable, clearable, clearHandler, searchHandler, clickHandler, searchValue, inputBlurHandler, inputFocusHandler, } = props;
|
|
37
|
+
const { id, listboxId, onlyIcon, icon, customIcon, selectedOptions, placeholder, stickyValue, multiple, searchable, clearable, clearHandler, searchHandler, clickHandler, searchValue, inputBlurHandler, inputFocusHandler, } = props;
|
|
38
38
|
const inputRef = (0, react_1.useRef)(null);
|
|
39
39
|
const onChangeHandler = (e) => {
|
|
40
40
|
var _a;
|
|
@@ -83,10 +83,14 @@ function SelectInput(props) {
|
|
|
83
83
|
else {
|
|
84
84
|
props.inputRef.current = input;
|
|
85
85
|
}
|
|
86
|
-
}, width: multiple ? (!searchValue && selectedOptions.length ? '10px' : 'auto') : '100%'
|
|
86
|
+
}, width: multiple ? (!searchValue && selectedOptions.length ? '10px' : 'auto') : '100%', tabIndex: 0, onFocus: (e) => {
|
|
87
|
+
e.stopPropagation();
|
|
88
|
+
}, onMouseDown: (e) => {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
} }));
|
|
87
91
|
const simpleValue = selectedOptions.length ? (selectedOptions[0].label || selectedOptions[0].element || selectedOptions[0].value) : (react_1.default.createElement(SelectInternalInputPlaceholder, null, placeholder));
|
|
88
92
|
const multipleValues = selectedOptions.length ? (selectTags) : (react_1.default.createElement(SelectInternalInputPlaceholder, null, placeholder));
|
|
89
|
-
return (react_1.default.createElement(exports.SelectInputWrapper, Object.assign({}, props, { id: id, onFocus: onFocusHandler, onClick: onClickHandler }),
|
|
93
|
+
return (react_1.default.createElement(exports.SelectInputWrapper, Object.assign({}, props, { id: id, onFocus: onFocusHandler, onClick: onClickHandler, role: "button", "aria-haspopup": "listbox", "aria-controls": listboxId, "aria-owns": listboxId, "aria-label": "Select option" }),
|
|
90
94
|
!onlyIcon && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
91
95
|
react_1.default.createElement(SelectInputValue, null, multiple ? (searchable ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
92
96
|
selectTags,
|
|
@@ -54,9 +54,14 @@ function VersionPicker(props) {
|
|
|
54
54
|
};
|
|
55
55
|
if (!options.length && !(versionPicker === null || versionPicker === void 0 ? void 0 : versionPicker.showForUnversioned))
|
|
56
56
|
return null;
|
|
57
|
-
return (React.createElement(VersionsPickerWrapper, { "data-component-name": "VersionPicker/VersionPicker" },
|
|
58
|
-
React.createElement(VersionPickerLabel, { "data-translation-key": "versionPicker.label" }, translate('versionPicker.label', 'Version:')),
|
|
59
|
-
React.createElement(exports.VersionPickerSelect, { placeholder: translate('versionPicker.unversioned', 'All versions'), disabled: !options.length, options: options, value: value, onChange: handleOnChange
|
|
57
|
+
return (React.createElement(VersionsPickerWrapper, { "data-component-name": "VersionPicker/VersionPicker", role: "region", "aria-label": translate('versionPicker.label', 'Version selector') },
|
|
58
|
+
React.createElement(VersionPickerLabel, { "data-translation-key": "versionPicker.label", htmlFor: "version-picker-select" }, translate('versionPicker.label', 'Version:')),
|
|
59
|
+
React.createElement(exports.VersionPickerSelect, { placeholder: translate('versionPicker.unversioned', 'All versions'), disabled: !options.length, options: options, value: value, onChange: handleOnChange, dataAttributes: {
|
|
60
|
+
id: 'version-picker-select',
|
|
61
|
+
'aria-describedby': 'version-picker-description',
|
|
62
|
+
'aria-label': translate('versionPicker.label', 'Select version'),
|
|
63
|
+
} }),
|
|
64
|
+
React.createElement(SrOnly, { id: "version-picker-description" }, "This is version picker select, using it you can select a version of the API.")));
|
|
60
65
|
}
|
|
61
66
|
const VersionPickerLabel = styled_components_1.default.label `
|
|
62
67
|
font-size: var(--version-picker-label-font-size);
|
|
@@ -79,6 +84,10 @@ exports.VersionPickerSelect = (0, styled_components_1.default)(Select_1.Select)
|
|
|
79
84
|
border-radius: var(--version-picker-input-border-radius);
|
|
80
85
|
padding: var(--version-picker-input-padding-vertical)
|
|
81
86
|
var(--version-picker-input-padding-horizontal);
|
|
87
|
+
|
|
88
|
+
&:focus-within {
|
|
89
|
+
outline: 1px solid var(--version-picker-focus-outline-color);
|
|
90
|
+
}
|
|
82
91
|
}
|
|
83
92
|
`;
|
|
84
93
|
const VersionsPickerWrapper = styled_components_1.default.div `
|
|
@@ -89,5 +98,15 @@ const VersionsPickerWrapper = styled_components_1.default.div `
|
|
|
89
98
|
justify-content: space-between;
|
|
90
99
|
padding: var(--version-picker-padding-vertical) var(--version-picker-padding-horizontal);
|
|
91
100
|
border-bottom: var(--version-picker-border-bottom);
|
|
101
|
+
|
|
102
|
+
&:focus-visible {
|
|
103
|
+
outline: 1px solid var(--version-picker-focus-outline-color);
|
|
104
|
+
}
|
|
105
|
+
`;
|
|
106
|
+
const SrOnly = styled_components_1.default.span `
|
|
107
|
+
position: absolute;
|
|
108
|
+
width: 0;
|
|
109
|
+
height: 0;
|
|
110
|
+
overflow: hidden;
|
|
92
111
|
`;
|
|
93
112
|
//# sourceMappingURL=VersionPicker.js.map
|
|
@@ -37,6 +37,7 @@ exports.versionPicker = (0, styled_components_1.css) `
|
|
|
37
37
|
--version-picker-list-item-bg-color-active: var(--select-list-item-bg-color-active); // @presenter Color
|
|
38
38
|
--version-picker-list-item-bg-color-hover: var(--select-list-item-bg-color-hover); // @presenter Color
|
|
39
39
|
|
|
40
|
+
--version-picker-focus-outline-color: var(--button-border-color-focused);
|
|
40
41
|
// @tokens End
|
|
41
42
|
`;
|
|
42
43
|
//# sourceMappingURL=variables.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.55.0-next.
|
|
3
|
+
"version": "0.55.0-next.5",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"nprogress": "0.2.0",
|
|
89
89
|
"react-calendar": "5.1.0",
|
|
90
90
|
"react-date-picker": "11.0.0",
|
|
91
|
-
"@redocly/config": "0.26.
|
|
91
|
+
"@redocly/config": "0.26.2",
|
|
92
92
|
"@redocly/realm-asyncapi-sdk": "0.1.0-next.0"
|
|
93
93
|
},
|
|
94
94
|
"scripts": {
|
|
@@ -40,6 +40,6 @@ export const dropdown = css`
|
|
|
40
40
|
|
|
41
41
|
--dropdown-menu-item-color-dangerous: var(--color-error-base);
|
|
42
42
|
|
|
43
|
-
--dropdown-menu-item-border-color-focused: var(--color-
|
|
43
|
+
--dropdown-menu-item-border-color-focused: var(--button-border-color-focused);
|
|
44
44
|
// @tokens End
|
|
45
45
|
`;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import type { JSX } from 'react';
|
|
5
4
|
import type { ItemState, MenuItemProps } from '@redocly/theme/core/types';
|
|
5
|
+
import type { JSX, KeyboardEvent } from 'react';
|
|
6
6
|
|
|
7
7
|
import { useNestedMenu, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
8
8
|
import { LaunchIcon } from '@redocly/theme/icons/LaunchIcon/LaunchIcon';
|
|
@@ -49,6 +49,12 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
const handleExpandOnEnter = (event: KeyboardEvent) => {
|
|
53
|
+
if (event.key === 'Enter') {
|
|
54
|
+
handleOnClick();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
52
58
|
const chevron = hasChevron ? (
|
|
53
59
|
isExpanded ? (
|
|
54
60
|
<ChevronDownIcon
|
|
@@ -64,6 +70,7 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
64
70
|
) : null;
|
|
65
71
|
|
|
66
72
|
const httpColor = item.deprecated ? 'http-deprecated' : item.httpVerb;
|
|
73
|
+
|
|
67
74
|
const label = item.label && (
|
|
68
75
|
<MenuItemLabelWrapper
|
|
69
76
|
active={item.active}
|
|
@@ -72,8 +79,10 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
72
79
|
withChevron={hasChevron}
|
|
73
80
|
isSeparator={isSeparator}
|
|
74
81
|
onClick={handleOnClick}
|
|
82
|
+
onKeyDown={handleExpandOnEnter}
|
|
75
83
|
ref={labelRef}
|
|
76
84
|
role={item.link ? 'none' : 'link'}
|
|
85
|
+
tabIndex={!item.link ? 0 : undefined}
|
|
77
86
|
data-testid="menu-item-label"
|
|
78
87
|
>
|
|
79
88
|
{hasChevron ? <ChevronWrapper>{chevron}</ChevronWrapper> : null}
|
|
@@ -115,6 +124,7 @@ export function MenuItem(props: React.PropsWithChildren<MenuItemProps>): JSX.Ele
|
|
|
115
124
|
external={item.external}
|
|
116
125
|
target={item.target}
|
|
117
126
|
languageInsensitive={item.languageInsensitive}
|
|
127
|
+
onKeyDown={handleExpandOnEnter}
|
|
118
128
|
>
|
|
119
129
|
{label}
|
|
120
130
|
</MenuItemLink>
|
|
@@ -194,7 +204,6 @@ const MenuItemNestedWrapper = styled.div<{
|
|
|
194
204
|
isExpanded?: boolean;
|
|
195
205
|
depth?: number;
|
|
196
206
|
}>`
|
|
197
|
-
overflow: hidden;
|
|
198
207
|
order: 1;
|
|
199
208
|
position: relative;
|
|
200
209
|
|
|
@@ -172,6 +172,7 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
|
|
|
172
172
|
return (
|
|
173
173
|
<SelectInput
|
|
174
174
|
id={inputId}
|
|
175
|
+
listboxId={inputId}
|
|
175
176
|
selectedOptions={selectedOptions}
|
|
176
177
|
searchValue={searchValue}
|
|
177
178
|
placeholder={placeholder}
|
|
@@ -199,6 +200,24 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
|
|
|
199
200
|
disabled={disabled}
|
|
200
201
|
data-testid={dataTestId}
|
|
201
202
|
className={className}
|
|
203
|
+
onKeyDown={(e) => {
|
|
204
|
+
if (e.key === 'Enter' && document.activeElement === selectRef.current) {
|
|
205
|
+
e.preventDefault();
|
|
206
|
+
setDropdownActive(!dropdownActive);
|
|
207
|
+
}
|
|
208
|
+
}}
|
|
209
|
+
tabIndex={0}
|
|
210
|
+
aria-haspopup="listbox"
|
|
211
|
+
aria-expanded={dropdownActive}
|
|
212
|
+
aria-label="Select option"
|
|
213
|
+
onFocus={(e) => {
|
|
214
|
+
if (e.target === selectRef.current) {
|
|
215
|
+
selectInputRef.current?.focus();
|
|
216
|
+
}
|
|
217
|
+
}}
|
|
218
|
+
onMouseDown={(e) => {
|
|
219
|
+
e.preventDefault();
|
|
220
|
+
}}
|
|
202
221
|
>
|
|
203
222
|
<SelectDropdown
|
|
204
223
|
closeOnClick={!multiple}
|
|
@@ -209,7 +228,7 @@ export function Select<T>(props: SelectProps<T>): JSX.Element {
|
|
|
209
228
|
alignment={alignment}
|
|
210
229
|
active={!renderInput ? dropdownActive : undefined}
|
|
211
230
|
>
|
|
212
|
-
<SelectDropdownMenu footer={footer}>
|
|
231
|
+
<SelectDropdownMenu role="listbox" footer={footer}>
|
|
213
232
|
{filteredOptions.length === 0 ? (
|
|
214
233
|
<DropdownMenuItem disabled>No results</DropdownMenuItem>
|
|
215
234
|
) : (
|
|
@@ -257,6 +276,10 @@ export const SelectWrapper = styled.div<{ disabled?: boolean }>`
|
|
|
257
276
|
color: var(--select-text-color);
|
|
258
277
|
min-width: 0;
|
|
259
278
|
|
|
279
|
+
&:focus-visible {
|
|
280
|
+
outline: 1px solid var(--button-border-color-focused);
|
|
281
|
+
}
|
|
282
|
+
|
|
260
283
|
${({ disabled }) =>
|
|
261
284
|
disabled &&
|
|
262
285
|
`
|
|
@@ -9,6 +9,7 @@ import { Button } from '@redocly/theme/components/Button/Button';
|
|
|
9
9
|
|
|
10
10
|
type SelectInputProps<T> = {
|
|
11
11
|
id?: string;
|
|
12
|
+
listboxId?: string;
|
|
12
13
|
selectedOptions: SelectOption<T>[];
|
|
13
14
|
searchValue: any;
|
|
14
15
|
stickyValue: any;
|
|
@@ -30,6 +31,7 @@ type SelectInputProps<T> = {
|
|
|
30
31
|
export function SelectInput<T>(props: SelectInputProps<T>): React.ReactNode {
|
|
31
32
|
const {
|
|
32
33
|
id,
|
|
34
|
+
listboxId,
|
|
33
35
|
onlyIcon,
|
|
34
36
|
icon,
|
|
35
37
|
customIcon,
|
|
@@ -119,6 +121,13 @@ export function SelectInput<T>(props: SelectInputProps<T>): React.ReactNode {
|
|
|
119
121
|
}
|
|
120
122
|
}}
|
|
121
123
|
width={multiple ? (!searchValue && selectedOptions.length ? '10px' : 'auto') : '100%'}
|
|
124
|
+
tabIndex={0}
|
|
125
|
+
onFocus={(e) => {
|
|
126
|
+
e.stopPropagation();
|
|
127
|
+
}}
|
|
128
|
+
onMouseDown={(e) => {
|
|
129
|
+
e.preventDefault();
|
|
130
|
+
}}
|
|
122
131
|
/>
|
|
123
132
|
);
|
|
124
133
|
|
|
@@ -135,7 +144,17 @@ export function SelectInput<T>(props: SelectInputProps<T>): React.ReactNode {
|
|
|
135
144
|
);
|
|
136
145
|
|
|
137
146
|
return (
|
|
138
|
-
<SelectInputWrapper
|
|
147
|
+
<SelectInputWrapper
|
|
148
|
+
{...props}
|
|
149
|
+
id={id}
|
|
150
|
+
onFocus={onFocusHandler}
|
|
151
|
+
onClick={onClickHandler}
|
|
152
|
+
role="button"
|
|
153
|
+
aria-haspopup="listbox"
|
|
154
|
+
aria-controls={listboxId}
|
|
155
|
+
aria-owns={listboxId}
|
|
156
|
+
aria-label="Select option"
|
|
157
|
+
>
|
|
139
158
|
{!onlyIcon && (
|
|
140
159
|
<>
|
|
141
160
|
<SelectInputValue>
|
|
@@ -35,8 +35,15 @@ export function VersionPicker(props: { versions?: Version[]; onChange: (v: Versi
|
|
|
35
35
|
if (!options.length && !versionPicker?.showForUnversioned) return null;
|
|
36
36
|
|
|
37
37
|
return (
|
|
38
|
-
<VersionsPickerWrapper
|
|
39
|
-
|
|
38
|
+
<VersionsPickerWrapper
|
|
39
|
+
data-component-name="VersionPicker/VersionPicker"
|
|
40
|
+
role="region"
|
|
41
|
+
aria-label={translate('versionPicker.label', 'Version selector')}
|
|
42
|
+
>
|
|
43
|
+
<VersionPickerLabel
|
|
44
|
+
data-translation-key="versionPicker.label"
|
|
45
|
+
htmlFor="version-picker-select"
|
|
46
|
+
>
|
|
40
47
|
{translate('versionPicker.label', 'Version:')}
|
|
41
48
|
</VersionPickerLabel>
|
|
42
49
|
<VersionPickerSelect
|
|
@@ -45,7 +52,15 @@ export function VersionPicker(props: { versions?: Version[]; onChange: (v: Versi
|
|
|
45
52
|
options={options}
|
|
46
53
|
value={value}
|
|
47
54
|
onChange={handleOnChange}
|
|
55
|
+
dataAttributes={{
|
|
56
|
+
id: 'version-picker-select',
|
|
57
|
+
'aria-describedby': 'version-picker-description',
|
|
58
|
+
'aria-label': translate('versionPicker.label', 'Select version'),
|
|
59
|
+
}}
|
|
48
60
|
/>
|
|
61
|
+
<SrOnly id="version-picker-description">
|
|
62
|
+
This is version picker select, using it you can select a version of the API.
|
|
63
|
+
</SrOnly>
|
|
49
64
|
</VersionsPickerWrapper>
|
|
50
65
|
);
|
|
51
66
|
}
|
|
@@ -72,6 +87,10 @@ export const VersionPickerSelect = styled(Select)<SelectProps>`
|
|
|
72
87
|
border-radius: var(--version-picker-input-border-radius);
|
|
73
88
|
padding: var(--version-picker-input-padding-vertical)
|
|
74
89
|
var(--version-picker-input-padding-horizontal);
|
|
90
|
+
|
|
91
|
+
&:focus-within {
|
|
92
|
+
outline: 1px solid var(--version-picker-focus-outline-color);
|
|
93
|
+
}
|
|
75
94
|
}
|
|
76
95
|
`;
|
|
77
96
|
|
|
@@ -83,4 +102,15 @@ const VersionsPickerWrapper = styled.div`
|
|
|
83
102
|
justify-content: space-between;
|
|
84
103
|
padding: var(--version-picker-padding-vertical) var(--version-picker-padding-horizontal);
|
|
85
104
|
border-bottom: var(--version-picker-border-bottom);
|
|
105
|
+
|
|
106
|
+
&:focus-visible {
|
|
107
|
+
outline: 1px solid var(--version-picker-focus-outline-color);
|
|
108
|
+
}
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
const SrOnly = styled.span`
|
|
112
|
+
position: absolute;
|
|
113
|
+
width: 0;
|
|
114
|
+
height: 0;
|
|
115
|
+
overflow: hidden;
|
|
86
116
|
`;
|
|
@@ -35,5 +35,6 @@ export const versionPicker = css`
|
|
|
35
35
|
--version-picker-list-item-bg-color-active: var(--select-list-item-bg-color-active); // @presenter Color
|
|
36
36
|
--version-picker-list-item-bg-color-hover: var(--select-list-item-bg-color-hover); // @presenter Color
|
|
37
37
|
|
|
38
|
+
--version-picker-focus-outline-color: var(--button-border-color-focused);
|
|
38
39
|
// @tokens End
|
|
39
40
|
`;
|