Repository: h2oai/wave
File: ui/src/time_picker.tsx (TypeScript)

Code before:
      { hour_format = '12', label, disabled, min, max, placeholder, required, minutes_step = 1 } = m,
      [value, setValue] = React.useState(m.value ? parseTimeStringToDate(m.value) : null),
      [isDialogOpen, setIsDialogOpen] = React.useState(false),
      textInputRef = React.useRef<HTMLDivElement | null>(null),
      popperRef = React.useRef<HTMLDivElement | null>(null),
      minTime = React.useMemo(() => parseTimeStringToDate(min || '00:00'), [min]),
      maxTime = React.useMemo(() => parseTimeStringToDate(max || '24:00'), [max]),
      switchAmPm = () => {
        setValue((prevValue) => {
          if (prevValue && canSwitchAmPm(prevValue, minTime, maxTime)) {
            const date = new Date(prevValue!)
            date.setTime(date.getTime() + 12 * 60 * 60 * 1000)
            const newValue = formatDateToTimeString(date, '24')
            m.value = newValue
            wave.args[m.name] = newValue
            return date
          }
          return prevValue
        })
      },
      onChangeTime = (time: unknown) => {
        const date = time instanceof Date && new Date(normalize(formatDateToTimeString(time, '24')))
        if (date && !isOutOfBounds(date, minTime, maxTime)) {
          const newValue = formatDateToTimeString(time, '24')
          m.value = newValue
          wave.args[m.name] = newValue
          setValue(time)
        }
      },
      onSelectTime = () => { if (m.trigger) wave.push() },
      // HACK: https://stackoverflow.com/questions/70106353/material-ui-date-time-picker-safari-browser-issue
      onOpen = () => setTimeout(() => (document.activeElement as HTMLElement)?.blur()),
      onBlur = (ev: React.FocusEvent) => {
        // Close the popover if the side panel or dialog opens.
        // TODO: Investigate why MUI dismiss on outer click handling doesn't work in this case.
        if (!ev.relatedTarget || !Fluent.elementContains(popperRef.current, ev.relatedTarget as HTMLElement)) setIsDialogOpen(false)
      },
      { palette: fluentPalette } = Fluent.useTheme(),
      themeObj = {
        palette: {
          background: {
            paper: cssVar('$card'),
          },
          primary: {
            main: fluentPalette.themePrimary,
            contrastText: cssVar('$neutralLight')
          },
          text: {
            primary: fluentPalette.neutralPrimary,
            secondary: cssVar('$neutralSecondary'),
            disabled: cssVar('$neutralTertiaryAlt'),

Review comment (suggestion):
```suggestion
        if (!(time instanceof Date)) return
        const newValue = formatDateToTimeString(time, '24')
        const date = new Date(normalize(newValue))
        if (isOutOfBounds(date, minTime, maxTime)) return

        m.value = newValue
        wave.args[m.name] = newValue
        setValue(time)
```

Code after:
        m.value = newValue
        wave.args[m.name] = newValue
        setValue(time)
      },
      onSelectTime = () => { if (m.trigger) wave.push() },
      // HACK: https://stackoverflow.com/questions/70106353/material-ui-date-time-picker-safari-browser-issue
      onOpen = () => setTimeout(() => (document.activeElement as HTMLElement)?.blur()),
      onBlur = (ev: React.FocusEvent) => {
        // Close the popover if the side panel or dialog opens.
        // TODO: Investigate why MUI dismiss on outer click handling doesn't work in this case.
        if (!ev.relatedTarget || !Fluent.elementContains(popperRef.current, ev.relatedTarget as HTMLElement)) setIsDialogOpen(false)
      },
      { palette: fluentPalette } = Fluent.useTheme(),
      themeObj = {
        palette: {
          background: {
            paper: cssVar('$card'),
          },
          primary: {
            main: fluentPalette.themePrimary,
            contrastText: cssVar('$neutralLight')
          },
          text: {
            primary: fluentPalette.neutralPrimary,
            secondary: cssVar('$neutralSecondary'),
            disabled: cssVar('$neutralTertiaryAlt'),
          },
          action: {
            active: fluentPalette.themePrimary,
            disabled: cssVar('$neutralLight'),
            hover: cssVar('$neutralLight'),
            hoverOpacity: 0.04
          }
        },
      },
      { format, AdapterDateFns, theme } = useTime(themeObj),
      formatDateToTimeString = React.useCallback((date: D, hour_format: S) => format ? format(date, hour_format === '12' ? 'hh:mm aa' : 'HH:mm') : '', [format])

    React.useEffect(() => {
      const time = m.value ? parseTimeStringToDate(m.value) : null
      const newTime = time && isBelowMin(time, minTime) ? minTime : time && isOverMax(time, maxTime) ? maxTime : time
      if (format) wave.args[m.name] = newTime ? formatDateToTimeString(newTime, '24') : null
      setValue(newTime)
    }, [format, formatDateToTimeString, m.name, m.value, maxTime, minTime])

    // TODO: Remove once CSS vars are fully supported - https://github.com/mui/material-ui/issues/27651
    React.useEffect(() => {
      if (theme) {
        theme.palette.primary.main = fluentPalette.themePrimary
        theme.palette.text.primary = fluentPalette.neutralPrimary
        theme.palette.action.active = fluentPalette.themePrimary