import type { Dayjs } from 'dayjs' ; import { useContext } from 'react' ; import type { TimetableContext } from './context' ; import { TimetableContextImpl } from './context' ; const getItemX = ( ctx ) => ( date ) : number => { const { startAt , scale } = ctx ; return date . diff ( startAt , 'minute' ) * scale ; } ; const getItemY = ( ctx ) => ( row ) : number => { const { itemHeight } = ctx ; return itemHeight * row ; } ; export interface SetFocusedAtParam { readonly behavior ? : ScrollBehavior ; readonly preventFocus ? : boolean ; } const setFocusedAt = ( ctx ) => ( date , params = { } ) : void => { const { ref , startAt , scale , setFocusedAtRaw } = ctx ; setFocusedAtRaw ( date ) ; if ( ref . current == null ) return ; const diff = date . diff ( startAt , 'minute' ) * scale ; ref . current . scrollTo ( { top : 0 , left : diff - ref . current . clientWidth / 2 , behavior : params . behavior ?? 'smooth' , } ) ; if ( params . preventFocus != null && params . preventFocus ) return ; const destination = date . minute ( ) <= 30 ? date . clone ( ) . minute ( 0 ) . second ( 0 ) . millisecond ( 0 ) : date . clone ( ) . minute ( 30 ) . second ( 0 ) . millisecond ( 0 ) ; const anchor = document . getElementById ( destination . toISOString ( ) ) ?. firstElementChild ; if ( anchor instanceof HTMLAnchorElement ) { anchor . focus ( { preventScroll : true } ) ; } } ; const getWidth = ( ctx ) => ( ms ) : number => { const { scale } = ctx ; const MINUTE = 60 ; const SECOND = 1000 ; return ( ms / SECOND / MINUTE ) * scale ; } ; export interface UseTimetableResponse extends TimetableContext { readonly getItemX : ( date : Readonly < Dayjs > ) => number ; readonly getItemY : ( row : number ) => number ; readonly getWidth : ( ms : number ) => number ; readonly setFocusedAt : ( date : Readonly < Dayjs > , params ? : SetFocusedAtParam ) => void ; } export const useTimetable = ( ) : UseTimetableResponse => { const ctx = useContext ( TimetableContextImpl ) ; return { ... ctx , getItemX : getItemX ( ctx ) , getItemY : getItemY ( ctx ) , getWidth : getWidth ( ctx ) , setFocusedAt : setFocusedAt ( ctx ) , } ; } ;