UNPKG

@neo4j-ndl/react

Version:

React implementation of Neo4j Design System

120 lines (119 loc) 6.79 kB
/** * * Copyright (c) "Neo4j" * Neo4j Sweden AB [http://neo4j.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useMemo } from 'react'; import ReactSelect from 'react-select'; import AsyncSelect from 'react-select/async'; /** Different types of select components */ import Creatable from 'react-select/creatable'; import { classNames } from '../_common/defaultImports'; import { needleWarningMessage } from '../_common/utils'; import { useIsInsideDialog } from '../dialog/Dialog'; import { forwardRef } from '../helpers'; import { ExclamationCircleIconSolid } from '../icons'; import { CustomClearIndication, CustomControl, CustomIndicatorsContainer, CustomInput, CustomMenu, CustomMenuList, CustomMenuPortal, CustomMultiValue, CustomOption, CustomPlaceholder, CustomSingleValue, CustomValueContainer, DropdownIndicatorCurrying, } from './Overrides'; /** * * * Helpers * * */ const overrideComponents = (props) => ({ DropdownIndicator: DropdownIndicatorCurrying(props), IndicatorSeparator: null, ClearIndicator: CustomClearIndication(props), Placeholder: CustomPlaceholder(props), Option: CustomOption(props), MultiValue: CustomMultiValue(props), Control: CustomControl(props), IndicatorsContainer: CustomIndicatorsContainer(props), ValueContainer: CustomValueContainer(props), Input: CustomInput(props), SingleValue: CustomSingleValue(props), Menu: CustomMenu(props), MenuPortal: CustomMenuPortal(props), MenuList: CustomMenuList(props), }); const customStyles = () => { return { control: () => ({}), menuList: () => ({}), option: () => ({}), valueContainer: (provided) => (Object.assign(Object.assign({}, provided), { padding: '0' })), indicatorsContainer: () => ({}), dropdownIndicator: () => ({}), clearIndicator: () => ({}), input: () => ({}), singleValue: () => ({}), placeholder: () => ({}), menu: (provided) => ({ top: provided.top, bottom: provided.bottom, }), }; }; export const Select = forwardRef(function Select(props, ref) { var _a, _b, _c; const { as, label, helpText, errorText, isFluid = true, size = 'small', type = 'select', 'aria-label': ariaLabel, selectProps = {}, hasBorder = true, isDisabled, htmlAttributes, style, } = props; const isInsideDialog = useIsInsideDialog(); const menuPosition = isInsideDialog ? 'fixed' : 'absolute'; const Component = as !== null && as !== void 0 ? as : 'div'; const ComponentOverrides = useMemo(() => overrideComponents({ errorText, hasBorder, size, }), [errorText, size, hasBorder]); const StyleOverrides = useMemo(() => customStyles(), []); const identifier = useMemo(() => { if (typeof label === 'string') return label; if (selectProps['aria-label'] !== undefined) return selectProps['aria-label']; needleWarningMessage('Consider adding a label or aria-label to the selectProps to make the select more accessible'); // 7 char long pseudo-random string return Math.random().toString(36).slice(2, 9); }, [label, selectProps]); let SelectElement; switch (type) { case 'async': { SelectElement = (_jsx(AsyncSelect, Object.assign({ name: identifier, inputId: identifier, isDisabled: isDisabled || selectProps.isDisabled, menuPlacement: "auto" }, selectProps, { menuPosition: (_a = selectProps.menuPosition) !== null && _a !== void 0 ? _a : menuPosition, hideSelectedOptions: false, closeMenuOnSelect: !selectProps.isMulti, styles: Object.assign(Object.assign({}, StyleOverrides), selectProps.styles), components: Object.assign(Object.assign({}, ComponentOverrides), selectProps.components) }))); break; } case 'creatable': SelectElement = (_jsx(Creatable, Object.assign({ name: identifier, inputId: identifier, isDisabled: isDisabled || selectProps.isDisabled, menuPlacement: "auto" }, selectProps, { menuPosition: (_b = selectProps.menuPosition) !== null && _b !== void 0 ? _b : menuPosition, hideSelectedOptions: false, closeMenuOnSelect: !selectProps.isMulti, styles: Object.assign(Object.assign({}, StyleOverrides), selectProps.styles), components: Object.assign(Object.assign({}, ComponentOverrides), selectProps.components) }))); break; default: SelectElement = (_jsx(ReactSelect, Object.assign({ name: identifier, inputId: identifier, isDisabled: isDisabled || selectProps.isDisabled, menuPlacement: "auto" }, selectProps, { menuPosition: (_c = selectProps.menuPosition) !== null && _c !== void 0 ? _c : menuPosition, hideSelectedOptions: false, closeMenuOnSelect: !selectProps.isMulti, styles: Object.assign(Object.assign({}, StyleOverrides), selectProps.styles), components: Object.assign(Object.assign({}, ComponentOverrides), selectProps.components) }))); } const classes = classNames('ndl-select', props.className, { 'ndl-small': size === 'small', 'ndl-medium': size === 'medium', 'ndl-large': size === 'large', 'ndl-fluid': isFluid, 'ndl-disabled': selectProps.isDisabled, 'ndl-multi': selectProps.isMulti, 'ndl-creatable': type === 'creatable', 'ndl-has-error': !!errorText, }); return (_jsxs(Component, Object.assign({ "aria-label": ariaLabel, ref: ref, className: classes, style: style }, htmlAttributes, { children: [label && _jsx("label", { htmlFor: identifier, children: label }), SelectElement, helpText && !errorText && (_jsx("span", { className: "ndl-sub-text", "aria-disabled": isDisabled || selectProps.isDisabled, children: helpText })), errorText && (_jsxs("div", { className: "n-flex n-flex-row n-gap-token-3 n-items-center", children: [_jsx(ExclamationCircleIconSolid, { className: classNames('ndl-error-icon', classes), role: "img", type: "solid" }), _jsx("span", { className: "ndl-sub-text ndl-error-text", children: errorText })] }))] }))); }); //# sourceMappingURL=Select.js.map