fix: Theme class names for embed elements (#21275)
* refactor(embed-core): update theme class names for consistency Standardize theme class names to use 'cal-element-embed-dark' and 'cal-element-embed-light' to improve maintainability and clarity. * refactor(embed-core): replace theme class strings with constants * fix theme not changing --------- Co-authored-by: Tushar Bhatt <95581504+TusharBhatt1@users.noreply.github.com> Co-authored-by: Hariom <hariombalhara@gmail.com>
This commit is contained in:
co-authored by
Tushar Bhatt
Hariom
parent
c215dc5864
commit
e22d9a551c
@@ -6,6 +6,7 @@ import type { Mock } from "vitest";
|
||||
|
||||
import { EmbedElement } from "./EmbedElement";
|
||||
import inlineHTML from "./Inline/inlineHtml";
|
||||
import { EMBED_DARK_THEME_CLASS, EMBED_LIGHT_THEME_CLASS } from "./constants";
|
||||
import { getColorSchemeDarkQuery } from "./ui-utils";
|
||||
|
||||
(function defineEmbedTestElement() {
|
||||
@@ -269,8 +270,8 @@ describe("EmbedElement", () => {
|
||||
},
|
||||
getSkeletonData: vi.fn(),
|
||||
});
|
||||
expect(element.classList.contains("dark")).toBe(true);
|
||||
expect(element.classList.contains("light")).toBe(false);
|
||||
expect(element.classList.contains(EMBED_DARK_THEME_CLASS)).toBe(true);
|
||||
expect(element.classList.contains(EMBED_LIGHT_THEME_CLASS)).toBe(false);
|
||||
});
|
||||
|
||||
it("should update theme class when system preference changes as long as embed theme is not set", () => {
|
||||
@@ -279,8 +280,8 @@ describe("EmbedElement", () => {
|
||||
});
|
||||
getColorSchemeDarkQuery().dispatchEvent(buildMediaQueryListEvent({ type: "change", matches: true }));
|
||||
|
||||
expect(element.classList.contains("dark")).toBe(true);
|
||||
expect(element.classList.contains("light")).toBe(false);
|
||||
expect(element.classList.contains(EMBED_DARK_THEME_CLASS)).toBe(true);
|
||||
expect(element.classList.contains(EMBED_LIGHT_THEME_CLASS)).toBe(false);
|
||||
});
|
||||
|
||||
it("should not update theme on system color scheme change when embed theme is set", () => {
|
||||
@@ -291,7 +292,7 @@ describe("EmbedElement", () => {
|
||||
getSkeletonData: vi.fn(),
|
||||
});
|
||||
getColorSchemeDarkQuery().dispatchEvent(buildMediaQueryListEvent({ type: "change", matches: true }));
|
||||
expect(element.classList.contains("light")).toBe(true);
|
||||
expect(element.classList.contains(EMBED_LIGHT_THEME_CLASS)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EMBED_DARK_THEME_CLASS, EMBED_LIGHT_THEME_CLASS } from "./constants";
|
||||
import type { EmbedThemeConfig, AllPossibleLayouts, BookerLayouts, EmbedPageType } from "./types";
|
||||
import {
|
||||
getThemeClassForEmbed,
|
||||
@@ -157,9 +158,7 @@ export class EmbedElement extends HTMLElement {
|
||||
this.isModal = data.isModal;
|
||||
this.layout = this.getLayout();
|
||||
this.theme = this.dataset.theme as EmbedThemeConfig | null;
|
||||
this.themeClass = getThemeClassForEmbed({ theme: this.theme });
|
||||
this.classList.add(this.themeClass);
|
||||
|
||||
this.setTheme(this.theme);
|
||||
this.getSkeletonData = data.getSkeletonData;
|
||||
this.boundResizeHandler = this.resizeHandler.bind(this);
|
||||
this.boundPrefersDarkThemeChangedHandler = this.prefersDarkThemeChangedHandler.bind(this);
|
||||
@@ -197,20 +196,26 @@ export class EmbedElement extends HTMLElement {
|
||||
skeletonEl.innerHTML = skeletonContent;
|
||||
}
|
||||
|
||||
public setTheme(theme: EmbedThemeConfig | null) {
|
||||
const allPossibleThemeClasses = [EMBED_DARK_THEME_CLASS, EMBED_LIGHT_THEME_CLASS];
|
||||
|
||||
const newThemeClass = getThemeClassForEmbed({ theme });
|
||||
|
||||
if (newThemeClass === this.themeClass) {
|
||||
return;
|
||||
}
|
||||
this.themeClass = newThemeClass;
|
||||
this.classList.remove(...allPossibleThemeClasses);
|
||||
this.classList.add(this.themeClass);
|
||||
}
|
||||
|
||||
public prefersDarkThemeChangedHandler(e: MediaQueryListEvent) {
|
||||
const isDarkPreferred = e.matches;
|
||||
const allPossibleThemeClasses = ["dark", "light"];
|
||||
if (isThemePreferenceProvided(this.theme)) {
|
||||
// User has provided a theme preference, so we stick to that and don't react to system theme change
|
||||
return;
|
||||
}
|
||||
const newThemeClass = getThemeClassForEmbed({
|
||||
theme: isDarkPreferred ? "dark" : "light",
|
||||
});
|
||||
if (newThemeClass !== this.themeClass) {
|
||||
this.classList.remove(...allPossibleThemeClasses);
|
||||
this.classList.add(newThemeClass);
|
||||
}
|
||||
this.setTheme(isDarkPreferred ? "dark" : "light");
|
||||
}
|
||||
connectedCallback() {
|
||||
// Make sure to show the loader initially.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { EMBED_DARK_THEME_CLASS } from "./constants";
|
||||
|
||||
export const addAppCssVars = () => {
|
||||
const calElements = ["cal-floating-button", "cal-modal-box", "cal-inline"];
|
||||
try {
|
||||
@@ -148,7 +150,7 @@ export const addAppCssVars = () => {
|
||||
--cal-brand-text: hsla(0, 0%, 100%, 1); /* white */
|
||||
}
|
||||
|
||||
${calElements.map((element) => `${element}.dark`).join(",")} {
|
||||
${calElements.map((element) => `${element}.${EMBED_DARK_THEME_CLASS}`).join(",")} {
|
||||
/* Background Standard */
|
||||
--cal-bg-emphasis: hsla(0, 0%, 25%, 1); /* stone-700 */
|
||||
--cal-bg: hsla(0, 0%, 6%, 1); /* stone-950 */
|
||||
|
||||
@@ -10,3 +10,8 @@ if (EMBED_MODAL_IFRAME_SLOT_STALE_TIME > EMBED_MODAL_IFRAME_FORCE_RELOAD_THRESHO
|
||||
"EMBED_MODAL_IFRAME_SLOT_STALE_TIME must be less than EMBED_MODAL_IFRAME_FORCE_RELOAD_THRESHOLD_MS"
|
||||
);
|
||||
}
|
||||
|
||||
// These classes are applied to Embed Elements and thus are in the same scope as the embedding webpage.
|
||||
// So, these classes need to be unique to us, to avoid accidental override
|
||||
export const EMBED_LIGHT_THEME_CLASS = "cal-element-embed-light";
|
||||
export const EMBED_DARK_THEME_CLASS = "cal-element-embed-dark";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { EMBED_DARK_THEME_CLASS, EMBED_LIGHT_THEME_CLASS } from "./constants";
|
||||
import type { AllPossibleLayouts, EmbedThemeConfig } from "./types";
|
||||
|
||||
export function getMaxHeightForModal() {
|
||||
@@ -32,7 +33,7 @@ function detectColorScheme() {
|
||||
}
|
||||
|
||||
function getClassBasedOnTheme(theme: EmbedThemeConfig | undefined | null) {
|
||||
return theme ?? "light";
|
||||
return theme === "dark" ? EMBED_DARK_THEME_CLASS : EMBED_LIGHT_THEME_CLASS;
|
||||
}
|
||||
|
||||
export function isThemePreferenceProvided(theme: EmbedThemeConfig | undefined | null) {
|
||||
|
||||
Reference in New Issue
Block a user