import { createElement } from "react"; /** * External dependencies */ import classNames from 'classnames'; /** * WordPress dependencies */ import { useInstanceId } from '@wordpress/compose'; import { useState, forwardRef } from '@wordpress/element'; /** * Internal dependencies */ import BaseControl from '../base-control'; import InputBase from '../input-control/input-base'; import { Select } from './styles/select-control-styles'; import SelectControlChevronDown from './chevron-down'; import { useDeprecated36pxDefaultSizeProp } from '../utils/use-deprecated-props'; const noop = () => {}; function useUniqueId(idProp) { const instanceId = useInstanceId(SelectControl); const id = `inspector-select-control-${instanceId}`; return idProp || id; } function UnforwardedSelectControl(props, ref) { const { className, disabled = false, help, hideLabelFromVision, id: idProp, label, multiple = false, onBlur = noop, onChange, onFocus = noop, options = [], size = 'default', value: valueProp, labelPosition = 'top', children, prefix, suffix, __next40pxDefaultSize = false, __nextHasNoMarginBottom = false, ...restProps } = useDeprecated36pxDefaultSizeProp(props, 'wp.components.SelectControl', '6.4'); const [isFocused, setIsFocused] = useState(false); const id = useUniqueId(idProp); const helpId = help ? `${id}__help` : undefined; // Disable reason: A select with an onchange throws a warning. if (!options?.length && !children) return null; const handleOnBlur = event => { onBlur(event); setIsFocused(false); }; const handleOnFocus = event => { onFocus(event); setIsFocused(true); }; const handleOnChange = event => { if (props.multiple) { const selectedOptions = Array.from(event.target.options).filter(({ selected }) => selected); const newValues = selectedOptions.map(({ value }) => value); props.onChange?.(newValues, { event }); return; } props.onChange?.(event.target.value, { event }); }; const classes = classNames('components-select-control', className); return createElement(BaseControl, { help: help, id: id, __nextHasNoMarginBottom: __nextHasNoMarginBottom }, createElement(InputBase, { className: classes, disabled: disabled, hideLabelFromVision: hideLabelFromVision, id: id, isFocused: isFocused, label: label, size: size, suffix: suffix || !multiple && createElement(SelectControlChevronDown, null), prefix: prefix, labelPosition: labelPosition, __next40pxDefaultSize: __next40pxDefaultSize }, createElement(Select, { ...restProps, __next40pxDefaultSize: __next40pxDefaultSize, "aria-describedby": helpId, className: "components-select-control__input", disabled: disabled, id: id, multiple: multiple, onBlur: handleOnBlur, onChange: handleOnChange, onFocus: handleOnFocus, ref: ref, selectSize: size, value: valueProp }, children || options.map((option, index) => { const key = option.id || `${option.label}-${option.value}-${index}`; return createElement("option", { key: key, value: option.value, disabled: option.disabled, hidden: option.hidden }, option.label); })))); } /** * `SelectControl` allows users to select from a single or multiple option menu. * It functions as a wrapper around the browser's native `