import { type ReactElement, type ReactNode } from 'react' import { Calendar, ChevronDown, ChevronUp, X } from 'lucide-react' import Block from '../../Primitives/Block/Block' import PrimitiveButton from '../../Primitives/PrimitiveButton/PrimitiveButton' import { ButtonV2, ButtonV2Size, ButtonV2Type } from '../../ButtonV2' import { FOUNDATION_THEME } from '../../../tokens' import type { ThemeType } from '../../../tokens' import type { CalendarTokenType } from '../../DateRangePicker/dateRangePicker.tokens' import type { DateRange, TriggerConfig, DateRangePickerSize, } from '../../DateRangePicker/types' /** * The trigger surface shared by every date/time picker in the library. * * This was lifted verbatim out of `DateRangePicker`'s inline `renderTrigger` * closure so `SingleDatePicker` and `TimePicker` present an identical control * instead of forking 230 lines of markup, token wiring and `data-*` hooks. * * The four render branches and their precedence are unchanged: * 1. `triggerConfig.renderTrigger` — caller owns the markup entirely * 2. `triggerConfig.element` / `triggerElement` — caller supplies a node * 3. mobile drawer — a plain secondary button * 4. the default token-styled button * * Everything added for the newer components (`hasError`, `onClear`, * `defaultIcon`) is optional and inert when omitted, so DateRangePicker's * output is byte-identical to before the extraction. */ export type PickerTriggerProps = { /** Text for the default desktop trigger. Caller does the formatting. */ displayText: string /** Text for the mobile drawer button. Caller does the formatting. */ mobileText?: string /** Passed straight through to `triggerConfig.renderTrigger`. */ displayRange: DateRange | undefined isOpen: boolean isDisabled: boolean size: DateRangePickerSize calendarToken: CalendarTokenType /** Foundation palette used for legacy fallback styles. */ foundationTokens?: ThemeType /** Squares off the left edge when a quick-range selector sits beside it. */ hasQuickSelector?: boolean triggerConfig?: TriggerConfig triggerElement?: ReactNode /** Render branch 3 (the drawer button) instead of the default button. */ isMobileDrawer?: boolean onToggle: () => void onMobileOpen?: () => void ariaLabel: string /** Value of the `data-date-picker` attribute used by E2E selectors. */ dataDatePicker: string /** Icon used when `triggerConfig.icon` is not supplied. */ defaultIcon?: ReactNode /** Applies the error border token instead of the default border. */ hasError?: boolean /** * Reserves room at the right edge for a `PickerClearButton` overlay. * The button itself must be rendered by the caller as a DOM sibling — * see the note in the render body. */ showClearSpacer?: boolean } export type PickerClearButtonProps = { onClear: () => void calendarToken: CalendarTokenType label?: string } /** * The inline "clear" affordance. Rendered as a sibling of the trigger and * absolutely positioned over its right edge, because a button nested inside * the trigger button would be invalid ARIA and unreachable by keyboard. */ export const PickerClearButton = ({ onClear, calendarToken, label = 'Clear selection', }: PickerClearButtonProps) => { const dateInputToken = calendarToken?.trigger?.dateInput const iconSize = dateInputToken?.iconSize return ( ) } const Chevron = ({ isOpen, size, gap, }: { isOpen: boolean size?: string | number gap?: string | number }) => { const Icon = isOpen ? ChevronUp : ChevronDown return