Files
calendar/packages/features/timezone-buddy/store.ts
T
luzpazandGitHub 197a7ba6e9 fix: typos in packages/features (#19220)
Found via `codespell -q 3 -S "*.svg,./apps/web/public/static/locales,./packages/app-store/stripepayment/lib/currencyOptions.ts,./packages/lib/freeEmailDomainCheck/freeEmailDomains.ts" -L afterall,atleast,datea,fo,incase,ist,nam,notin,optionel,perview,reccuring`

Closes #19219
2025-02-21 05:14:57 -03:00

95 lines
2.9 KiB
TypeScript

import { createContext } from "react";
import { createStore } from "zustand";
export interface Timezone {
name: string;
offset: number;
isdst?: boolean;
abbr?: string;
city?: string;
location?: string;
}
export interface TimezoneBuddyProps {
browsingDate: Date;
timeMode?: "12h" | "24h";
containerRef?: React.RefObject<HTMLElement>;
x: number;
height: number;
y: number;
isHover?: boolean;
}
type TimezoneBuddyState = TimezoneBuddyProps & {
addToDate: (amount: number) => void;
subtractFromDate: (amount: number) => void;
setBrowseDate: (date: Date) => void;
setContainerRef: (ref: React.RefObject<HTMLElement>) => void;
emitCellPosition: (x: number) => void;
updateDimensions: () => void;
};
export type TimezoneBuddyStore = ReturnType<typeof createTimezoneBuddyStore>;
/**
* Different type of zustand store compared to what we are used to
* This is a function that returns a store instead of a hook. This allows us to properly set the initial state of the store
* from the props passed in to the component.
*/
export const createTimezoneBuddyStore = (initProps?: Partial<TimezoneBuddyProps>) => {
const DEFAULT_PROPS: TimezoneBuddyProps = {
timeMode: "24h",
browsingDate: new Date(),
x: 0,
y: 0,
height: 0,
};
return createStore<TimezoneBuddyState>()((set, get) => ({
...DEFAULT_PROPS,
...initProps,
addToDate: (amount?: number) => {
const date = get().browsingDate;
date.setDate(date.getDate() + (amount || 1));
set({ browsingDate: date });
},
subtractFromDate: (amount?: number) => {
const date = get().browsingDate;
date.setDate(date.getDate() - (amount || 1));
set({ browsingDate: date });
},
setBrowseDate: (date: Date) => {
set({ browsingDate: date });
},
setContainerRef: (ref: React.RefObject<HTMLElement>) => {
set({ containerRef: ref });
},
emitCellPosition: (x: number) => {
const container = get().containerRef?.current;
if (x < 0) {
// If x is less than 0, we are outside the container
set({ isHover: false });
} else if (container) {
const containerRect = container.getBoundingClientRect();
set({ x: x - containerRect.left, isHover: true });
}
},
updateDimensions: () => {
const container = get().containerRef?.current;
let x = get().x;
if (container) {
const containerRect = container.getBoundingClientRect();
const timeDials = container.querySelectorAll("[data-time-dial]>div");
const height =
timeDials[timeDials.length - 1]?.getBoundingClientRect().bottom -
timeDials[0]?.getBoundingClientRect().top;
const y = timeDials[0]?.getBoundingClientRect().top - containerRect.top;
x = x ? x : timeDials[0]?.getBoundingClientRect().left - containerRect.left;
set({ height, y, x });
}
},
}));
};
export const TBContext = createContext<TimezoneBuddyStore | null>(null);