{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "time-picker",
  "title": "Time Picker",
  "description": "Time picker: a 24-hour field with hour/minute segments in the style of Input, standalone segment inputs, and a visual popover variant.",
  "dependencies": [
    "lucide-react@^1.48.0"
  ],
  "registryDependencies": [
    "https://rdf.dev.360online.com/r/button.json",
    "https://rdf.dev.360online.com/r/popover.json",
    "https://rdf.dev.360online.com/r/scroll-area.json"
  ],
  "files": [
    {
      "path": "registry/rapid/ui/time-picker/index.ts",
      "content": "export * from './time-picker'\nexport * from './visual-time-picker'\n",
      "type": "registry:ui",
      "target": "components/ui/time-picker/index.ts"
    },
    {
      "path": "registry/rapid/ui/time-picker/time-picker-utils.ts",
      "content": "/**\n * regular expression to check for valid hour format (01-23)\n */\nexport function isValidHour(value: string) {\n\treturn /^(0[0-9]|1[0-9]|2[0-3])$/.test(value)\n}\n\n/**\n * regular expression to check for valid 12 hour format (01-12)\n */\nexport function isValid12Hour(value: string) {\n\treturn /^(0[1-9]|1[0-2])$/.test(value)\n}\n\n/**\n * regular expression to check for valid minute format (00-59)\n */\nexport function isValidMinuteOrSecond(value: string) {\n\treturn /^[0-5][0-9]$/.test(value)\n}\n\ntype GetValidNumberConfig = { max: number; min?: number; loop?: boolean }\n\nexport function getValidNumber(value: string, { max, min = 0, loop = false }: GetValidNumberConfig) {\n\tlet numericValue = Number.parseInt(value, 10)\n\n\tif (!Number.isNaN(numericValue)) {\n\t\tif (!loop) {\n\t\t\tif (numericValue > max) numericValue = max\n\t\t\tif (numericValue < min) numericValue = min\n\t\t} else {\n\t\t\tif (numericValue > max) numericValue = min\n\t\t\tif (numericValue < min) numericValue = max\n\t\t}\n\t\treturn numericValue.toString().padStart(2, '0')\n\t}\n\n\treturn '00'\n}\n\nexport function getValidHour(value: string) {\n\tif (isValidHour(value)) return value\n\treturn getValidNumber(value, { max: 23 })\n}\n\nexport function getValid12Hour(value: string) {\n\tif (isValid12Hour(value)) return value\n\treturn getValidNumber(value, { min: 1, max: 12 })\n}\n\nexport function getValidMinuteOrSecond(value: string) {\n\tif (isValidMinuteOrSecond(value)) return value\n\treturn getValidNumber(value, { max: 59 })\n}\n\ntype GetValidArrowNumberConfig = {\n\tmin: number\n\tmax: number\n\tstep: number\n}\n\nexport function getValidArrowNumber(value: string, { min, max, step }: GetValidArrowNumberConfig) {\n\tlet numericValue = Number.parseInt(value, 10)\n\tif (!Number.isNaN(numericValue)) {\n\t\tnumericValue += step\n\t\treturn getValidNumber(String(numericValue), { min, max, loop: true })\n\t}\n\treturn '00'\n}\n\nexport function getValidArrowHour(value: string, step: number) {\n\treturn getValidArrowNumber(value, { min: 0, max: 23, step })\n}\n\nexport function getValidArrow12Hour(value: string, step: number) {\n\treturn getValidArrowNumber(value, { min: 1, max: 12, step })\n}\n\nexport function getValidArrowMinuteOrSecond(value: string, step: number) {\n\treturn getValidArrowNumber(value, { min: 0, max: 59, step })\n}\n\nexport function setMinutes(date: Date, value: string) {\n\tconst minutes = getValidMinuteOrSecond(value)\n\tdate.setMinutes(Number.parseInt(minutes, 10))\n\treturn date\n}\n\nexport function setSeconds(date: Date, value: string) {\n\tconst seconds = getValidMinuteOrSecond(value)\n\tdate.setSeconds(Number.parseInt(seconds, 10))\n\treturn date\n}\n\nexport function setHours(date: Date, value: string) {\n\tconst hours = getValidHour(value)\n\tdate.setHours(Number.parseInt(hours, 10))\n\treturn date\n}\n\nexport function set12Hours(date: Date, value: string, period: Period) {\n\tconst hours = Number.parseInt(getValid12Hour(value), 10)\n\tconst convertedHours = convert12HourTo24Hour(hours, period)\n\tdate.setHours(convertedHours)\n\treturn date\n}\n\nexport type TimePickerType = 'minutes' | 'seconds' | 'hours' | '12hours'\nexport type Period = 'AM' | 'PM'\n\nexport function setDateByType(date: Date, value: string, type: TimePickerType, period?: Period) {\n\tswitch (type) {\n\t\tcase 'minutes':\n\t\t\treturn setMinutes(date, value)\n\t\tcase 'seconds':\n\t\t\treturn setSeconds(date, value)\n\t\tcase 'hours':\n\t\t\treturn setHours(date, value)\n\t\tcase '12hours': {\n\t\t\tif (!period) return date\n\t\t\treturn set12Hours(date, value, period)\n\t\t}\n\t\tdefault:\n\t\t\treturn date\n\t}\n}\n\nexport function getDateByType(date: Date, type: TimePickerType) {\n\tswitch (type) {\n\t\tcase 'minutes':\n\t\t\treturn getValidMinuteOrSecond(String(date.getMinutes()))\n\t\tcase 'seconds':\n\t\t\treturn getValidMinuteOrSecond(String(date.getSeconds()))\n\t\tcase 'hours':\n\t\t\treturn getValidHour(String(date.getHours()))\n\t\tcase '12hours': {\n\t\t\tconst hours = display12HourValue(date.getHours())\n\t\t\treturn getValid12Hour(String(hours))\n\t\t}\n\t\tdefault:\n\t\t\treturn '00'\n\t}\n}\n\nexport function getArrowByType(value: string, step: number, type: TimePickerType) {\n\tswitch (type) {\n\t\tcase 'minutes':\n\t\t\treturn getValidArrowMinuteOrSecond(value, step)\n\t\tcase 'seconds':\n\t\t\treturn getValidArrowMinuteOrSecond(value, step)\n\t\tcase 'hours':\n\t\t\treturn getValidArrowHour(value, step)\n\t\tcase '12hours':\n\t\t\treturn getValidArrow12Hour(value, step)\n\t\tdefault:\n\t\t\treturn '00'\n\t}\n}\n\n/**\n * handles value change of 12-hour input\n * 12:00 PM is 12:00\n * 12:00 AM is 00:00\n */\nexport function convert12HourTo24Hour(hour: number, period: Period) {\n\tif (period === 'PM') {\n\t\tif (hour <= 11) {\n\t\t\treturn hour + 12\n\t\t}\n\t\treturn hour\n\t}\n\tif (period === 'AM') {\n\t\tif (hour === 12) return 0\n\t\treturn hour\n\t}\n\treturn hour\n}\n\n/**\n * time is stored in the 24-hour form,\n * but needs to be displayed to the user\n * in its 12-hour representation\n */\nexport function display12HourValue(hours: number) {\n\tif (hours === 0 || hours === 12) return '12'\n\tif (hours >= 22) return `${hours - 12}`\n\tif (hours % 12 > 9) return `${hours}`\n\treturn `0${hours % 12}`\n}\n",
      "type": "registry:ui",
      "target": "components/ui/time-picker/time-picker-utils.ts"
    },
    {
      "path": "registry/rapid/ui/time-picker/time-picker.tsx",
      "content": "'use client'\n\nimport { ClockIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { cn } from '@/lib/utils'\nimport { getArrowByType, getDateByType, type Period, setDateByType, type TimePickerType } from './time-picker-utils'\n\nexport interface TimePickerInputProps extends Omit<React.ComponentProps<'input'>, 'type'> {\n\tpicker: TimePickerType\n\tdate: Date | undefined\n\tsetDate: (date: Date | undefined) => void\n\tperiod?: Period\n\tonRightFocus?: () => void\n\tonLeftFocus?: () => void\n\t/** `default` is a standalone field; `segment` is borderless, for use inside `TimePicker` or your own field */\n\tvariant?: 'default' | 'segment'\n}\n\nconst inputVariants = {\n\tdefault:\n\t\t'h-10 w-12 rounded-lg border border-input bg-background px-1 text-sm transition-colors hover:border-primary/90 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 disabled:pointer-events-none disabled:opacity-50 read-only:cursor-default read-only:border-dashed read-only:bg-muted/50 read-only:hover:border-input',\n\tsegment: 'h-6 w-7 rounded-sm bg-transparent p-0 text-sm disabled:pointer-events-none read-only:cursor-default',\n}\n\n/** One time segment (hours, minutes, seconds or 12-hour hours). Type digits or use the arrow keys. */\nfunction TimePickerInput({\n\tclassName,\n\tvariant = 'default',\n\tvalue,\n\tdate = new Date(new Date().setHours(0, 0, 0, 0)),\n\tsetDate,\n\tonChange,\n\tonKeyDown,\n\tpicker,\n\tperiod,\n\tonLeftFocus,\n\tonRightFocus,\n\treadOnly,\n\t...props\n}: Readonly<TimePickerInputProps>) {\n\tconst [flag, setFlag] = React.useState(false)\n\tconst [prevIntKey, setPrevIntKey] = React.useState('0')\n\n\t// Allow the second digit within two seconds, otherwise start again with the first digit\n\tReact.useEffect(() => {\n\t\tif (!flag) return\n\t\tconst timer = setTimeout(() => setFlag(false), 2000)\n\t\treturn () => clearTimeout(timer)\n\t}, [flag])\n\n\tconst calculatedValue = React.useMemo(() => getDateByType(date, picker), [date, picker])\n\n\tconst calculateNewValue = (key: string) => {\n\t\t// In 12-hour mode a leading 0 makes the next digit 1–9; a following digit gives 10–12\n\t\tif (picker === '12hours' && flag && calculatedValue.slice(1, 2) === '1' && prevIntKey === '0') return `0${key}`\n\t\treturn !flag ? `0${key}` : `${calculatedValue.slice(1, 2)}${key}`\n\t}\n\n\tconst handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key === 'Tab') return\n\t\tevent.preventDefault()\n\t\tif (event.key === 'ArrowRight') onRightFocus?.()\n\t\tif (event.key === 'ArrowLeft') onLeftFocus?.()\n\t\tif (readOnly) return\n\t\tif (event.key === 'ArrowUp' || event.key === 'ArrowDown') {\n\t\t\tconst newValue = getArrowByType(calculatedValue, event.key === 'ArrowUp' ? 1 : -1, picker)\n\t\t\tif (flag) setFlag(false)\n\t\t\tsetDate(setDateByType(new Date(date), newValue, picker, period))\n\t\t}\n\t\tif (event.key >= '0' && event.key <= '9') {\n\t\t\tif (picker === '12hours') setPrevIntKey(event.key)\n\t\t\tconst newValue = calculateNewValue(event.key)\n\t\t\tif (flag) onRightFocus?.()\n\t\t\tsetFlag((prev) => !prev)\n\t\t\tsetDate(setDateByType(new Date(date), newValue, picker, period))\n\t\t}\n\t}\n\n\treturn (\n\t\t<input\n\t\t\tdata-slot=\"time-picker-input\"\n\t\t\ttype=\"text\"\n\t\t\tinputMode=\"numeric\"\n\t\t\tautoComplete=\"off\"\n\t\t\tspellCheck={false}\n\t\t\treadOnly={readOnly}\n\t\t\tclassName={cn(\n\t\t\t\t'text-center tabular-nums text-foreground caret-transparent outline-none selection:bg-transparent focus:bg-accent focus:text-accent-foreground',\n\t\t\t\tinputVariants[variant],\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tvalue={value ?? calculatedValue}\n\t\t\tonChange={(event) => {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tonChange?.(event)\n\t\t\t}}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tonKeyDown?.(event)\n\t\t\t\thandleKeyDown(event)\n\t\t\t}}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nexport interface TimePickerProps {\n\t/** Controlled value. The date part is kept; only the time changes. */\n\tvalue?: Date\n\tdefaultValue?: Date\n\tonValueChange?: (date: Date | undefined) => void\n\t/** Show a seconds segment */\n\twithSeconds?: boolean\n\tdisabled?: boolean\n\treadOnly?: boolean\n\t/** id of the hours segment, so a `<Label htmlFor>` focuses the field */\n\tid?: string\n\tclassName?: string\n\t/** Screen reader names for the segments */\n\tlabels?: { hours?: string; minutes?: string; seconds?: string }\n\t'aria-label'?: string\n\t'aria-labelledby'?: string\n\t'aria-describedby'?: string\n\t'aria-invalid'?: React.AriaAttributes['aria-invalid']\n}\n\n/** A 24-hour time field in the style of `Input`: `HH : MM` (optionally `: SS`) segments in one box. */\nfunction TimePicker({\n\tvalue,\n\tdefaultValue,\n\tonValueChange,\n\twithSeconds = false,\n\tdisabled,\n\treadOnly,\n\tid,\n\tclassName,\n\tlabels,\n\t'aria-invalid': ariaInvalid,\n\t...groupProps\n}: Readonly<TimePickerProps>) {\n\tconst [uncontrolled, setUncontrolled] = React.useState<Date | undefined>(defaultValue)\n\tconst date = value ?? uncontrolled\n\tconst setDate = (next: Date | undefined) => {\n\t\tif (value === undefined) setUncontrolled(next)\n\t\tonValueChange?.(next)\n\t}\n\n\tconst hourRef = React.useRef<HTMLInputElement>(null)\n\tconst minuteRef = React.useRef<HTMLInputElement>(null)\n\tconst secondRef = React.useRef<HTMLInputElement>(null)\n\n\tconst segment = {\n\t\tvariant: 'segment' as const,\n\t\tdate,\n\t\tsetDate,\n\t\tdisabled,\n\t\treadOnly,\n\t\t'aria-invalid': ariaInvalid,\n\t}\n\n\treturn (\n\t\t// biome-ignore lint/a11y/useSemanticElements: a <fieldset> can't centre its flex content vertically in Chrome\n\t\t<div\n\t\t\trole=\"group\"\n\t\t\tdata-slot=\"time-picker\"\n\t\t\tdata-disabled={disabled || undefined}\n\t\t\tdata-read-only={readOnly || undefined}\n\t\t\tdata-invalid={ariaInvalid && ariaInvalid !== 'false' ? '' : undefined}\n\t\t\t{...groupProps}\n\t\t\tclassName={cn(\n\t\t\t\t'inline-flex h-10 w-fit min-w-0 items-center gap-0.5 rounded-lg border border-input bg-background pr-1.5 pl-2.5 text-sm transition-colors hover:border-primary/90 has-focus-visible:border-ring has-focus-visible:ring-3 has-focus-visible:ring-ring data-invalid:border-destructive data-invalid:ring-3 data-invalid:ring-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 data-read-only:border-dashed data-read-only:bg-muted/50 data-read-only:hover:border-input',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<ClockIcon aria-hidden=\"true\" className=\"mr-1 size-4 shrink-0 text-muted-foreground\" />\n\t\t\t<TimePickerInput\n\t\t\t\t{...segment}\n\t\t\t\tref={hourRef}\n\t\t\t\tid={id}\n\t\t\t\tpicker=\"hours\"\n\t\t\t\taria-label={labels?.hours ?? 'Hours'}\n\t\t\t\tonRightFocus={() => minuteRef.current?.focus()}\n\t\t\t/>\n\t\t\t<span aria-hidden=\"true\" className=\"text-muted-foreground\">\n\t\t\t\t:\n\t\t\t</span>\n\t\t\t<TimePickerInput\n\t\t\t\t{...segment}\n\t\t\t\tref={minuteRef}\n\t\t\t\tpicker=\"minutes\"\n\t\t\t\taria-label={labels?.minutes ?? 'Minutes'}\n\t\t\t\tonLeftFocus={() => hourRef.current?.focus()}\n\t\t\t\tonRightFocus={() => secondRef.current?.focus()}\n\t\t\t/>\n\t\t\t{withSeconds ? (\n\t\t\t\t<>\n\t\t\t\t\t<span aria-hidden=\"true\" className=\"text-muted-foreground\">\n\t\t\t\t\t\t:\n\t\t\t\t\t</span>\n\t\t\t\t\t<TimePickerInput\n\t\t\t\t\t\t{...segment}\n\t\t\t\t\t\tref={secondRef}\n\t\t\t\t\t\tpicker=\"seconds\"\n\t\t\t\t\t\taria-label={labels?.seconds ?? 'Seconds'}\n\t\t\t\t\t\tonLeftFocus={() => minuteRef.current?.focus()}\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t</div>\n\t)\n}\n\nexport { TimePicker, TimePickerInput }\n",
      "type": "registry:ui",
      "target": "components/ui/time-picker/time-picker.tsx"
    },
    {
      "path": "registry/rapid/ui/time-picker/visual-time-picker.tsx",
      "content": "'use client'\n\nimport { ClockIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { Button } from '@/components/ui/button'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { ScrollArea, ScrollBar } from '@/components/ui/scroll-area'\nimport { cn } from '@/lib/utils'\n\nexport interface VisualTimePickerProps {\n\tdate?: Date\n\tsetDate: (date: Date | undefined) => void\n\tclassName?: string\n\tdisabled?: boolean\n\tplaceholder?: string\n\treadOnly?: boolean\n\tlabels?: {\n\t\thours: string\n\t\tminutes: string\n\t}\n\t/** marks the trigger as invalid (destructive border + ring) */\n\t'aria-invalid'?: React.AriaAttributes['aria-invalid']\n\t/** id for the trigger button (e.g. to pair with a `<Label htmlFor>`) */\n\tid?: string\n\t/** accessible name when there is no visible `<Label htmlFor={id}>` */\n\t'aria-label'?: string\n\t/**\n\t * Ids of the elements that name the picker, usually the field's label. The button adds\n\t * itself, so the name ends with the chosen value (or the placeholder): \"Date of birth,\n\t * required, 15 Oct 2026\". Takes precedence over `aria-label`.\n\t */\n\t'aria-labelledby'?: string\n\t/** Ids of the help text and error message, passed on to the button */\n\t'aria-describedby'?: string\n}\n\nexport function VisualTimePicker({\n\tdate,\n\tsetDate,\n\tclassName,\n\tdisabled,\n\tplaceholder,\n\treadOnly,\n\tlabels,\n\tid,\n\t'aria-invalid': ariaInvalid,\n\t'aria-label': ariaLabel,\n\t'aria-labelledby': ariaLabelledby,\n\t'aria-describedby': ariaDescribedby,\n}: Readonly<VisualTimePickerProps>) {\n\tconst [isOpen, setIsOpen] = React.useState(false)\n\tconst generatedId = React.useId()\n\tconst buttonId = id ?? generatedId\n\n\t// Create arrays for hours (0-23) and minutes (every 5th minute)\n\tconst hours = Array.from({ length: 24 }, (_, i) => i)\n\tconst minutes = Array.from({ length: 12 }, (_, i) => i * 5)\n\n\tconst handleTimeChange = (type: 'hour' | 'minute', value: number) => {\n\t\t// If no date is set, start from now but reset the time first for a clean start\n\t\tconst newDate = date ? new Date(date) : new Date()\n\n\t\tif (!date) {\n\t\t\tnewDate.setHours(0, 0, 0, 0)\n\t\t}\n\n\t\tif (type === 'hour') {\n\t\t\tnewDate.setHours(value)\n\t\t} else {\n\t\t\tnewDate.setMinutes(value)\n\t\t}\n\n\t\tsetDate(newDate)\n\t}\n\n\treturn (\n\t\t<Popover open={isOpen && !readOnly} onOpenChange={setIsOpen}>\n\t\t\t<PopoverTrigger\n\t\t\t\tdisabled={disabled}\n\t\t\t\trender={\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tdata-read-only={readOnly || undefined}\n\t\t\t\t\t\tdata-empty={!date || undefined}\n\t\t\t\t\t\taria-invalid={ariaInvalid}\n\t\t\t\t\t\tid={buttonId}\n\t\t\t\t\t\taria-label={ariaLabelledby ? undefined : ariaLabel}\n\t\t\t\t\t\taria-labelledby={ariaLabelledby ? `${ariaLabelledby} ${buttonId}` : undefined}\n\t\t\t\t\t\taria-describedby={ariaDescribedby}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'w-full justify-between font-normal hover:border-primary hover:bg-transparent hover:text-foreground data-empty:text-muted-foreground data-read-only:pointer-events-none data-read-only:cursor-default data-read-only:border-dashed data-read-only:border-input data-read-only:bg-muted/50 data-read-only:text-foreground data-read-only:hover:border-input data-read-only:hover:bg-muted/50',\n\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t>\n\t\t\t\t{date ? (\n\t\t\t\t\t<span>\n\t\t\t\t\t\t{date.getHours().toString().padStart(2, '0')}:{date.getMinutes().toString().padStart(2, '0')}\n\t\t\t\t\t</span>\n\t\t\t\t) : (\n\t\t\t\t\t<span>{placeholder}</span>\n\t\t\t\t)}\n\t\t\t\t<ClockIcon data-icon=\"inline-end\" className=\"text-muted-foreground\" />\n\t\t\t</PopoverTrigger>\n\t\t\t<PopoverContent\n\t\t\t\tclassName=\"max-h-(--available-height) w-auto overflow-y-auto p-0\"\n\t\t\t\talign=\"start\"\n\t\t\t\t// Named after the field, so the list is not announced as just \"dialog\"\n\t\t\t\taria-labelledby={ariaLabelledby}\n\t\t\t\taria-label={ariaLabelledby ? undefined : ariaLabel}\n\t\t\t>\n\t\t\t\t<div className=\"flex h-[300px] divide-x\">\n\t\t\t\t\t{/* Hours */}\n\t\t\t\t\t<ScrollArea className=\"h-full w-20\">\n\t\t\t\t\t\t<div className=\"flex flex-col p-2\">\n\t\t\t\t\t\t\t<div className=\"mb-2 text-xs font-medium text-center text-muted-foreground\">{labels?.hours}</div>\n\t\t\t\t\t\t\t{hours.map((hour) => (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tkey={hour}\n\t\t\t\t\t\t\t\t\tvariant={date && date.getHours() === hour ? 'default' : 'ghost'}\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tclassName=\"my-0.5 shrink-0 justify-center\"\n\t\t\t\t\t\t\t\t\tonClick={() => handleTimeChange('hour', hour)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{hour.toString().padStart(2, '0')}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<ScrollBar orientation=\"vertical\" />\n\t\t\t\t\t</ScrollArea>\n\n\t\t\t\t\t{/* Minutes */}\n\t\t\t\t\t<ScrollArea className=\"h-full w-20\">\n\t\t\t\t\t\t<div className=\"flex flex-col p-2\">\n\t\t\t\t\t\t\t<div className=\"mb-2 text-xs font-medium text-center text-muted-foreground\">{labels?.minutes}</div>\n\t\t\t\t\t\t\t{minutes.map((minute) => (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tkey={minute}\n\t\t\t\t\t\t\t\t\tvariant={date && date.getMinutes() === minute ? 'default' : 'ghost'}\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tclassName=\"my-0.5 shrink-0 justify-center\"\n\t\t\t\t\t\t\t\t\tonClick={() => handleTimeChange('minute', minute)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{minute.toString().padStart(2, '0')}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<ScrollBar orientation=\"vertical\" />\n\t\t\t\t\t</ScrollArea>\n\t\t\t\t</div>\n\t\t\t</PopoverContent>\n\t\t</Popover>\n\t)\n}\n",
      "type": "registry:ui",
      "target": "components/ui/time-picker/visual-time-picker.tsx"
    }
  ],
  "type": "registry:ui"
}