@redocly/theme 0.55.0-next.4 → 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.
@@ -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-blue-4);
45
+ --dropdown-menu-item-border-color-focused: var(--button-border-color-focused);
46
46
  // @tokens End
47
47
  `;
48
48
  //# sourceMappingURL=variables.js.map
@@ -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;
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import type { SelectOption } from '../../core/types/select';
3
3
  type SelectInputProps<T> = {
4
4
  id?: string;
5
+ listboxId?: string;
5
6
  selectedOptions: SelectOption<T>[];
6
7
  searchValue: any;
7
8
  stickyValue: any;
@@ -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.4",
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.1",
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-blue-4);
43
+ --dropdown-menu-item-border-color-focused: var(--button-border-color-focused);
44
44
  // @tokens End
45
45
  `;
@@ -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 {...props} id={id} onFocus={onFocusHandler} onClick={onClickHandler}>
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 data-component-name="VersionPicker/VersionPicker">
39
- <VersionPickerLabel data-translation-key="versionPicker.label">
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
  `;