UNPKG

@rjsf/antd

Version:

Ant Design theme, fields and widgets for react-jsonschema-form

62 lines 3.99 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useMemo, useState } from 'react'; import { ariaDescribedByIds, enumOptionSelectedValue, enumOptionValueDecoder, enumOptionValueEncoder, getOptionValueFormat, } from '@rjsf/utils'; import { Select } from 'antd'; import isString from 'lodash-es/isString.js'; const SELECT_STYLE = { width: '100%', }; /** The `SelectWidget` is a widget for rendering dropdowns. * It is typically used with string properties constrained with enum options. * * @param props - The `WidgetProps` for this component */ export default function SelectWidget({ autofocus, disabled, registry, id, htmlName, multiple, onBlur, onChange, onFocus, options, placeholder, readonly, value, schema, }) { const [open, setOpen] = useState(false); const { formContext } = registry; const { readonlyAsDisabled = true } = formContext; const { enumOptions, enumDisabled, emptyValue } = options; const optionValueFormat = getOptionValueFormat(options); const handleChange = (nextValue) => onChange(enumOptionValueDecoder(nextValue, enumOptions, optionValueFormat, emptyValue)); const handleBlur = () => onBlur(id, enumOptionValueDecoder(value, enumOptions, optionValueFormat, emptyValue)); const handleFocus = () => onFocus(id, enumOptionValueDecoder(value, enumOptions, optionValueFormat, emptyValue)); const filterOption = (input, option) => { if (option && isString(option.label)) { // labels are strings in this context return option.label.toLowerCase().includes(input.toLowerCase()); } return false; }; const getPopupContainer = SelectWidget.getPopupContainerCallback(); const selectValue = enumOptionSelectedValue(value, enumOptions, !!multiple, optionValueFormat, emptyValue); // Antd's typescript definitions do not contain the following props that are actually necessary and, if provided, // they are used, so hacking them in via by spreading `extraProps` on the component to avoid typescript errors const extraProps = { name: htmlName || id, }; const showPlaceholderOption = !multiple && schema.default === undefined; const selectOptions = useMemo(() => { if (Array.isArray(enumOptions)) { const enumOptionsList = enumOptions.map(({ value: optionValue, label: optionLabel }, index) => ({ disabled: Array.isArray(enumDisabled) && enumDisabled.includes(optionValue), key: String(index), value: enumOptionValueEncoder(optionValue, index, optionValueFormat), label: optionLabel, })); if (showPlaceholderOption) { enumOptionsList.unshift({ value: '', label: placeholder || '' }); } return enumOptionsList; } return undefined; }, [enumDisabled, enumOptions, placeholder, showPlaceholderOption, optionValueFormat]); return (_jsx(Select, { open: open, autoFocus: autofocus, disabled: disabled || (readonlyAsDisabled && readonly), getPopupContainer: getPopupContainer, id: id, mode: multiple ? 'multiple' : undefined, onBlur: !readonly ? handleBlur : undefined, onChange: !readonly ? handleChange : undefined, onFocus: !readonly ? handleFocus : undefined, placeholder: placeholder, style: SELECT_STYLE, value: selectValue, ...extraProps, // When the open change is called, set the open state, needed so that the select opens properly in the playground onOpenChange: setOpen, showSearch: { filterOption }, "aria-describedby": ariaDescribedByIds(id), options: selectOptions })); } /** Give the playground a place to hook into the `getPopupContainer` callback generation function so that it can be * disabled while in the playground. Since the callback is a simple function, it can be returned by this static * "generator" function. */ SelectWidget.getPopupContainerCallback = () => (node) => node.parentElement; //# sourceMappingURL=index.js.map