Files
calendar/packages/embeds/embed-core/src/ui-utils.ts
T
9bc703a437 feat: Embed - Show skeleton loader when pageType is provided (#20646)
* mvp done

* wip

* fix ts errors and other code improvements

* fix ts errors

* ensure mobile layout support

* Make skeleton responsive on screen resize

* refactor

* Add test for EmbedElement

* make skeleton closer to pixel perfect

* Address PR feedback

* Remove PR_TODO

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: amrit <iamamrit27@gmail.com>
2025-04-16 13:40:51 +00:00

67 lines
2.4 KiB
TypeScript

import type { AllPossibleLayouts, EmbedThemeConfig } from "./types";
export function getMaxHeightForModal() {
const spacingTopPlusBottom = 2 * 50; // 50 is the padding we want to keep to show close button comfortably. Make it same as top for bottom.
// It ensures that if the iframe is so tall that it can't fit in the parent window without scroll. Then force the scroll by restricting the max-height to innerHeight
// This case is reproducible when viewing in ModalBox on Mobile.
return window.innerHeight - spacingTopPlusBottom;
}
function matchesMediaQuery(query: string) {
return window.matchMedia(query).matches;
}
export function getTrueLayout({ layout }: { layout: AllPossibleLayouts | null }) {
const isMobile = matchesMediaQuery("(max-width: 768px)");
if (isMobile) {
return "mobile";
}
const defaultLayout = "month_view";
// If layout is mobile and isMobile false, then we need to reset to defaultLayout
if (layout === "mobile") {
return defaultLayout;
}
return layout ?? defaultLayout;
}
function detectColorScheme() {
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
return "dark";
}
return "light";
}
function getClassBasedOnTheme(theme: EmbedThemeConfig | undefined | null) {
return theme ?? "light";
}
export function isThemePreferenceProvided(theme: EmbedThemeConfig | undefined | null) {
return theme === "dark" || theme === "light";
}
export function getThemeClassForEmbed({ theme }: { theme: EmbedThemeConfig | undefined | null }) {
const systemTheme = detectColorScheme();
if (isThemePreferenceProvided(theme)) {
return getClassBasedOnTheme(theme);
}
// NOTE: We don't support App configured theme as we can't fetch those details here. User has to explicitly set the theme in the embed snippet or use system theme
return getClassBasedOnTheme(systemTheme);
}
let colorSchemeDarkQuery: MediaQueryList | null = null;
export function getColorSchemeDarkQuery() {
if (!colorSchemeDarkQuery) {
colorSchemeDarkQuery = window.matchMedia("(prefers-color-scheme: dark)");
}
return colorSchemeDarkQuery;
}
export function addDarkColorSchemeChangeListener(listener: (e: MediaQueryListEvent) => void) {
getColorSchemeDarkQuery().addEventListener("change", listener);
}
export function removeDarkColorSchemeChangeListener(listener: (e: MediaQueryListEvent) => void) {
getColorSchemeDarkQuery()?.removeEventListener("change", listener);
}