@redocly/theme
Version:
Shared UI components lib
223 lines (220 loc) • 11.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelectWrapper = void 0;
exports.Select = Select;
const react_1 = __importStar(require("react"));
const styled_components_1 = __importDefault(require("styled-components"));
const CheckmarkIcon_1 = require("../../icons/CheckmarkIcon/CheckmarkIcon");
const SelectInput_1 = require("../../components/Select/SelectInput");
const Dropdown_1 = require("../../components/Dropdown/Dropdown");
const DropdownMenu_1 = require("../../components/Dropdown/DropdownMenu");
const DropdownMenuItem_1 = require("../../components/Dropdown/DropdownMenuItem");
const hooks_1 = require("../../core/hooks");
function Select(props) {
const { className, value, options, dataAttributes, withArrow = true, triggerEvent = 'click', placement, alignment, icon, onlyIcon, disabled, placeholder, hideCheckmarkIcon, checkmarkIconPosition, dataTestId = 'select', multiple, searchable, clearable, footer, onChange, onSearch, renderInput, renderDivider, } = props;
const { useTranslate } = (0, hooks_1.useThemeHooks)();
const { translate } = useTranslate();
const getSelectedOptionsFromPropsValue = () => {
const values = Array.isArray(value) ? value : [value];
return values
.map((value) => {
const selectedOption = options.find((option) => option.value === value);
return (selectedOption ||
(typeof value === 'string' ? { value } : value));
})
.filter((option) => !!option);
};
const [selectedOptions, setSelectedOptions] = (0, react_1.useState)(getSelectedOptionsFromPropsValue());
const selectRef = (0, react_1.useRef)(null);
const selectInputRef = (0, react_1.useRef)(null);
const [searchValue, setSearchValue] = (0, react_1.useState)(null);
const [dropdownActive, setDropdownActive] = (0, react_1.useState)(false);
const [filteredOptions, setFilteredOptions] = (0, react_1.useState)(options);
const [stickyInputValue, setStickyInputValue] = (0, react_1.useState)(placeholder || '');
const inputId = (0, react_1.useId)();
(0, hooks_1.useOutsideClick)(selectRef, () => {
setDropdownActive(false);
});
(0, react_1.useEffect)(() => {
setFilteredOptions(options);
}, [options]);
(0, react_1.useEffect)(() => {
setSelectedOptions(getSelectedOptionsFromPropsValue());
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [multiple, value]);
(0, react_1.useEffect)(() => {
if (onSearch) {
onSearch === null || onSearch === void 0 ? void 0 : onSearch(searchValue);
}
else {
if (typeof searchValue === 'string') {
const filteredOptions = options.filter((option) => {
var _a, _b;
const valueForSearch = String((_b = (_a = option.label) !== null && _a !== void 0 ? _a : option.value) !== null && _b !== void 0 ? _b : '');
return (!valueForSearch || valueForSearch.toLowerCase().indexOf(searchValue.toLowerCase()) > -1);
});
setFilteredOptions(filteredOptions);
}
else {
setFilteredOptions(options);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchValue]);
const selectHandler = (selectedOption) => {
var _a;
const newSelectedOptions = multiple
? isSelected(selectedOption)
? selectedOptions.filter((option) => option.value !== selectedOption.value)
: [...selectedOptions, selectedOption]
: [selectedOption];
const newSelectedValues = newSelectedOptions.length
? multiple
? newSelectedOptions.map((o) => o.value)
: newSelectedOptions[0].value
: multiple
? []
: '';
setSelectedOptions(newSelectedOptions);
onChange === null || onChange === void 0 ? void 0 : onChange(newSelectedValues);
setSearchValue(null);
setDropdownActive(false);
if (!multiple) {
setStickyInputValue('');
}
(_a = selectInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
};
const searchHandler = (e) => {
const targetValue = e.target.value;
setSearchValue(targetValue);
setDropdownActive(true);
};
const clearHandler = (option) => {
if (option) {
selectHandler(option);
}
else {
if (!multiple) {
setStickyInputValue('');
}
setSelectedOptions([]);
onChange === null || onChange === void 0 ? void 0 : onChange(multiple ? [] : '');
}
};
const inputBlurHandler = (e) => {
var _a, _b;
const relatedTarget = e.relatedTarget;
const isDropdownItem = ((_a = relatedTarget === null || relatedTarget === void 0 ? void 0 : relatedTarget.attributes.getNamedItem('data-component-name')) === null || _a === void 0 ? void 0 : _a.value) ===
'Dropdown/DropdownMenuItem';
if (!isDropdownItem) {
if (!e.relatedTarget || ((_b = e.relatedTarget) === null || _b === void 0 ? void 0 : _b.id) !== inputId) {
setDropdownActive(false);
}
setSearchValue(null);
setStickyInputValue('');
}
};
const inputFocusHandler = () => {
if (!multiple && selectedOptions.length) {
setStickyInputValue(selectedOptions[0].label || selectedOptions[0].value);
}
};
const inputClickHandler = () => {
setDropdownActive(!dropdownActive);
};
const isSelected = (option) => {
return !!selectedOptions.find((selectOption) => selectOption.value === option.value || selectOption.value === option.label);
};
const renderDefaultInput = (inputRef) => {
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 }));
};
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) => {
if (e.key === 'Enter' && document.activeElement === selectRef.current) {
e.preventDefault();
setDropdownActive(!dropdownActive);
}
}, tabIndex: 0, "aria-haspopup": "listbox", "aria-expanded": dropdownActive, "aria-label": "Select option", onFocus: (e) => {
var _a;
if (e.target === selectRef.current) {
(_a = selectInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
}
}, onMouseDown: (e) => {
e.preventDefault();
} }),
react_1.default.createElement(SelectDropdown, { closeOnClick: !multiple, withArrow: withArrow, trigger: renderInput ? renderInput() : renderDefaultInput(selectInputRef), triggerEvent: triggerEvent, placement: placement, alignment: alignment, active: !renderInput ? dropdownActive : undefined },
react_1.default.createElement(SelectDropdownMenu, { role: "listbox", footer: footer }, filteredOptions.length === 0 ? (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { disabled: true }, translate('select.noResults', 'No results'))) : (filteredOptions.map((option, index) => {
return (react_1.default.createElement(react_1.Fragment, { key: index },
react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { onAction: () => selectHandler(option), prefix: !hideCheckmarkIcon &&
(checkmarkIconPosition ? checkmarkIconPosition === 'start' : false) &&
isSelected(option) && react_1.default.createElement(CheckmarkIcon_1.CheckmarkIcon, null), suffix: !hideCheckmarkIcon &&
(checkmarkIconPosition ? checkmarkIconPosition === 'end' : true) &&
isSelected(option) && react_1.default.createElement(CheckmarkIcon_1.CheckmarkIcon, null) }, typeof option.element === 'string' ? (react_1.default.createElement("div", null, option.element)) : (option.element)),
renderDivider && index !== options.length - 1 ? renderDivider() : null));
}) || translate('select.noResults', 'No results'))))));
}
exports.SelectWrapper = styled_components_1.default.div `
display: flex;
position: relative;
font-size: var(--select-font-size);
font-weight: var(--select-font-weight);
line-height: var(--select-line-height);
border-radius: var(--select-border-radius);
border: var(--select-border);
color: var(--select-text-color);
min-width: 0;
&:focus-visible {
outline: 1px solid var(--button-border-color-focused);
}
${({ disabled }) => disabled &&
`
opacity: 0.59;
pointer-events: none;
`}
`;
const SelectDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
width: 100%;
> * {
min-width: 100%;
}
`;
const SelectDropdownMenu = (0, styled_components_1.default)(DropdownMenu_1.DropdownMenu) `
width: 100%;
margin-top: var(--spacing-unit);
`;
//# sourceMappingURL=Select.js.map