import * as React from 'react'; import { TextControl, tailwind } from '@tesseract-design/web-base'; import { useFallbackId } from '@modal-sh/react-utils'; import { PluginCreator } from 'tailwindcss/types/config'; const { tw } = tailwind; const MenuSelectDerivedElementComponent = 'select' as const; /** * Derived HTML element of the {@link MenuSelect} component. */ export type MenuSelectDerivedElement = HTMLElementTagNameMap[ typeof MenuSelectDerivedElementComponent ]; /** * Props of the {@link MenuSelect} component. */ export interface MenuSelectProps extends Omit, 'size' | 'style' | 'label' | 'multiple'> { /** * Short textual description indicating the nature of the component's value. */ label?: React.ReactNode, /** * Short textual description as guidelines for valid input values. */ hint?: React.ReactNode, /** * Size of the component. */ size?: TextControl.Size, /** * Additional description, usually graphical, indicating the nature of the component's value. */ indicator?: React.ReactNode, /** * Should the component display a border? */ border?: boolean, /** * Should the component occupy the whole width of its parent? */ block?: boolean, /** * Style of the component. */ variant?: TextControl.Variant, /** * Is the label hidden? */ hiddenLabel?: boolean, /** * Starting height of the component. */ startingHeight?: number | string, } export const menuSelectPlugin: PluginCreator = ({ addComponents }) => { addComponents({ '.menu-select': { '& optgroup': { 'color': 'rgb(var(--color-positive) / 50%)', 'text-transform': 'uppercase', 'font-size': '0.75em', 'margin-top': '0.5rem', 'user-select': 'none', }, '& optgroup > option': { 'color': 'rgb(var(--color-positive))', 'text-transform': 'none', 'font-size': '1.333333em', }, '& option': { 'user-select': 'none', }, }, }); }; /** * Component for selecting a single value from a menu. */ export const MenuSelect = React.forwardRef(( { label, hint, indicator, size = 'medium' as const, border = false, block = false, variant = 'default' as const, hiddenLabel = false, className, startingHeight = '15rem', id: idProp, ...etcProps }: MenuSelectProps, forwardedRef, ) => { const labelId = React.useId(); const id = useFallbackId(idProp); return (
{label && ( <> {' '} )} {hint && (
{hint}
)} {indicator && (
{indicator}
)} {border && ( )}
); }); MenuSelect.displayName = 'MenuSelect' as const; MenuSelect.defaultProps = { label: undefined, hint: undefined, indicator: undefined, size: 'medium' as const, border: false as const, block: false as const, variant: 'default' as const, hiddenLabel: false as const, startingHeight: '15rem' as const, };