'use client' import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react' import * as React from 'react' import { ChevronDownIcon, ChevronUpIcon, isBezierIcon, } from '@channel.io/bezier-icons' import classNames from 'classnames' import { getFormFieldSizeClassName } from '~/src/types/props-helpers' import { isEmpty } from '~/src/utils/type' import { BaseButton } from '~/src/components/BaseButton' import { useFormFieldProps } from '~/src/components/FormControl' import { Icon } from '~/src/components/Icon' import { Overlay } from '~/src/components/Overlay' import { Text } from '~/src/components/Text' import { type SelectProps, type SelectRef } from './Select.types' import styles from './Select.module.scss' export const SELECT_DROPDOWN_TEST_ID = 'bezier-select-dropdown' export const Select = forwardRef(function Select( { children, style, className, size: sizeProps, defaultFocus = false, placeholder = '', leftContent, rightContent, iconColor = 'text-neutral-lighter', text, textColor = 'text-neutral', withoutChevron = false, dropdownStyle, dropdownClassName, dropdownContainer, dropdownMarginX, dropdownMarginY = 6, dropdownZIndex = 'overlay', dropdownPosition = 'bottom-left', dropdownKeepInContainer = false, onClickTrigger, onHideDropdown, ...rest }, forwardedRef ) { const { disabled, readOnly, hasError, size: formFieldSize, ...ownProps } = useFormFieldProps(rest) const containerRef = useRef(null) const triggerRef = useRef(null) const size = sizeProps ?? formFieldSize ?? 'm' const [isDropdownOpened, setIsDropdownOpened] = useState(false) const handleClickTrigger = useCallback( (event: React.MouseEvent) => { if (!disabled && !readOnly) { setIsDropdownOpened((prevState) => !prevState) onClickTrigger?.(event) } }, [disabled, readOnly, onClickTrigger] ) const handleHideDropdown = useCallback(() => { setIsDropdownOpened(false) onHideDropdown?.() }, [onHideDropdown]) const getDOMNode = useCallback(() => triggerRef.current, []) const handle = useMemo( (): SelectRef => ({ handleClickTrigger, handleHideDropdown, getDOMNode, }), [handleClickTrigger, handleHideDropdown, getDOMNode] ) useEffect( function handleDefaultFocus() { if (defaultFocus && !disabled && !readOnly) { setIsDropdownOpened(true) } }, [defaultFocus, disabled, readOnly] ) useImperativeHandle(forwardedRef, () => handle) const hasContent = !isEmpty(text) const Content = (() => { if (!hasContent) { return ( {placeholder} ) } if (typeof text === 'string') { return ( {text} ) } return text })() return (
{isBezierIcon(leftContent) ? ( ) : ( leftContent )} {Content} {isBezierIcon(rightContent) ? ( ) : ( rightContent )}
{!withoutChevron && ( )}
{children}
) })