ぼざクリタグ広場 https://hub.nizika.monster
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

47 lines
1.1 KiB

  1. import { useEffect, useState } from 'react'
  2. import { cn } from '@/lib/utils'
  3. import type { FC, FocusEvent } from 'react'
  4. const pad = (n: number): string => n.toString ().padStart (2, '0')
  5. const toDateTimeLocalValue = (d: Date) => {
  6. const y = d.getFullYear ()
  7. const m = pad (d.getMonth () + 1)
  8. const day = pad (d.getDate ())
  9. const h = pad (d.getHours ())
  10. const min = pad (d.getMinutes ())
  11. return `${ y }-${ m }-${ day }T${ h }:${ min }:00`
  12. }
  13. type Props = {
  14. value?: string
  15. onChange?: (isoUTC: string | null) => void
  16. className?: string
  17. onBlur?: (ev: FocusEvent<HTMLInputElement>) => void }
  18. export default (({ value, onChange, className, onBlur }: Props) => {
  19. const [local, setLocal] = useState ('')
  20. useEffect (() => {
  21. setLocal (value ? toDateTimeLocalValue (new Date (value)) : '')
  22. }, [value])
  23. return (
  24. <input
  25. className={cn ('border rounded p-2', className)}
  26. type="datetime-local"
  27. value={local}
  28. onChange={ev => {
  29. const v = ev.target.value
  30. setLocal (v)
  31. onChange?.(v ? (new Date (v)).toISOString () : null)
  32. }}
  33. onBlur={onBlur}/>)
  34. }) satisfies FC<Props>