{"version":3,"file":"qualcomm-ui-angular-theme.mjs","sources":["../../src/theme/qds-theme-providers.ts","../../src/theme/qds-theme.service.ts","../../src/theme/qualcomm-ui-angular-theme.ts"],"sourcesContent":["// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.\n// SPDX-License-Identifier: BSD-3-Clause-Clear\n\nimport {inject, InjectionToken, type Provider, REQUEST} from \"@angular/core\"\n\nimport type {Brand, QdsThemeProviderOptions, Theme} from \"./qds-theme.types\"\n\nexport const THEME_COOKIE_NAME = \"app-qds-theme\"\nexport const BRAND_COOKIE_NAME = \"app-qds-brand\"\n\n/**\n * Concrete values are provided at bootstrap, but we attach a\n * factory so injection works even if the caller forgets to register them,\n * falling back to the light theme / first brand.\n */\nexport const THEME_COOKIE = new InjectionToken<Theme>(\"THEME_COOKIE\")\n\nexport const BRAND_COOKIE = new InjectionToken<Brand>(\"BRAND_COOKIE\")\n\n/**\n * Reads the cookie in both the browser (document.cookie) and during SSR\n * (Fetch Request.headers) and makes it available through THEME_COOKIE.\n */\nfunction provideThemeCookie(opts?: QdsThemeProviderOptions): Provider {\n  return {\n    provide: THEME_COOKIE,\n    useFactory: () => {\n      return (\n        opts?.themeOverride ||\n        readCookie<Theme>(THEME_COOKIE_NAME) ||\n        opts?.defaultTheme ||\n        \"dark\"\n      )\n    },\n  }\n}\n\n/**\n * Same helper for the brand cookie.\n */\nfunction provideBrandCookie(opts?: QdsThemeProviderOptions): Provider {\n  return {\n    provide: BRAND_COOKIE,\n    useFactory: () => {\n      return (\n        opts?.brandOverride ||\n        readCookie<Brand>(BRAND_COOKIE_NAME) ||\n        opts?.defaultBrand ||\n        \"qualcomm\"\n      )\n    },\n  }\n}\n\nexport const QDS_THEME_OPTIONS = new InjectionToken<\n  Partial<QdsThemeProviderOptions>\n>(\"QDS_THEME_OPTIONS\")\n\nfunction provideQdsThemeOptions(opts?: QdsThemeProviderOptions): Provider {\n  return {\n    provide: QDS_THEME_OPTIONS,\n    useValue: opts || {\n      skipAttributes: false,\n    },\n  }\n}\n\nexport function provideQdsTheme(opts?: QdsThemeProviderOptions) {\n  return [\n    provideQdsThemeOptions(opts),\n    provideThemeCookie(opts),\n    provideBrandCookie(opts),\n  ]\n}\n\nexport function readCookie<T extends string>(name: string): string | undefined {\n  // Browser path\n  // eslint-disable-next-line no-restricted-globals\n  if (typeof document !== \"undefined\") {\n    // eslint-disable-next-line no-restricted-globals\n    const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`))\n    return match?.[1] || undefined\n  }\n\n  // Server path – Fetch Request is registered in the injector\n  const request = inject(REQUEST, {optional: true})\n  if (request) {\n    const cookieHeader = request.headers.get(\"cookie\") ?? \"\"\n    const match = cookieHeader.match(new RegExp(`(?:^|; )${name}=([^;]*)`))\n    return match?.[1] as T | undefined\n  }\n\n  return undefined\n}\n","// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.\n// SPDX-License-Identifier: BSD-3-Clause-Clear\n\nimport {DOCUMENT} from \"@angular/common\"\nimport {\n  effect,\n  inject,\n  Injectable,\n  Renderer2,\n  signal,\n  type WritableSignal,\n} from \"@angular/core\"\n\nimport {useCsrCheck} from \"@qualcomm-ui/angular-core/common\"\n\nimport {\n  BRAND_COOKIE,\n  BRAND_COOKIE_NAME,\n  QDS_THEME_OPTIONS,\n  readCookie,\n  THEME_COOKIE,\n  THEME_COOKIE_NAME,\n} from \"./qds-theme-providers\"\nimport type {Brand, QdsThemeProviderOptions, Theme} from \"./qds-theme.types\"\n\n/**\n * A service that provides access to the current theme and brand, and ensures that\n * the application's root element is in sync with the selected brand/theme.\n */\n@Injectable({providedIn: \"root\"})\nexport class QdsThemeService {\n  private readonly document = inject(DOCUMENT)\n  private readonly response = inject(Response, {optional: true})\n  private readonly renderer = inject(Renderer2, {optional: true})\n  protected readonly isCsr = useCsrCheck()\n\n  readonly theme: WritableSignal<Theme> = signal(inject(THEME_COOKIE))\n  readonly brand: WritableSignal<Brand> = signal(inject(BRAND_COOKIE))\n\n  private readonly themeOpts: QdsThemeProviderOptions =\n    inject(QDS_THEME_OPTIONS)\n\n  get themeOptions(): Required<\n    Omit<\n      QdsThemeProviderOptions,\n      \"brandOverride\" | \"themeOverride\" | \"defaultTheme\" | \"defaultBrand\"\n    >\n  > {\n    const opts = this.themeOpts\n    const rootElement = opts.rootElement || this.document.documentElement\n    return {\n      rootElement,\n      skipAttributes:\n        typeof opts.skipAttributes === \"object\"\n          ? {\n              brand: opts.skipAttributes.brand || false,\n              theme: opts.skipAttributes.theme || false,\n            }\n          : opts.skipAttributes || false,\n      skipColorSchemeStyle: opts.skipColorSchemeStyle || false,\n    }\n  }\n\n  get rootElement(): HTMLElement {\n    const elementOrFn = this.themeOptions.rootElement\n    return typeof elementOrFn === \"function\" ? elementOrFn() : elementOrFn\n  }\n\n  get skipBrandAttribute(): boolean {\n    const skipAttributes = this.themeOptions.skipAttributes\n    return typeof skipAttributes === \"object\"\n      ? skipAttributes.brand || false\n      : skipAttributes || false\n  }\n\n  get skipThemeAttribute(): boolean {\n    const skipAttributes = this.themeOptions.skipAttributes\n    return typeof skipAttributes === \"object\"\n      ? skipAttributes.theme || false\n      : skipAttributes || false\n  }\n\n  constructor() {\n    effect(() => {\n      const theme = this.theme()\n      const brand = this.brand()\n      this.syncAttributes(theme, brand)\n      this.syncCookie(theme, brand)\n    })\n\n    const theme = readCookie(THEME_COOKIE_NAME) || this.themeOpts?.defaultTheme\n    if (theme === \"dark\" || theme === \"light\") {\n      this.theme.set(theme)\n      this.syncAttributes(theme, this.brand())\n    }\n  }\n\n  toggleTheme(): void {\n    this.theme.update((theme) => (theme === \"dark\" ? \"light\" : \"dark\"))\n  }\n\n  private syncAttributes(theme: Theme, brand: Brand): void {\n    if (!this.skipBrandAttribute) {\n      this.updateAttribute(\"data-brand\", brand)\n    }\n    if (!this.skipThemeAttribute) {\n      this.updateAttribute(\"data-theme\", theme)\n    }\n    if (!this.themeOptions.skipColorSchemeStyle) {\n      this.updateColorScheme(theme)\n    }\n  }\n\n  private syncCookie(theme: Theme, brand: Brand): void {\n    if (this.isCsr()) {\n      const maxAge = 60 * 60 * 24 * 365 // 1 year\n\n      this.document.cookie = `${THEME_COOKIE_NAME}=${theme}; Path=/; Max-Age=${maxAge}; SameSite=Lax`\n      this.document.cookie = `${BRAND_COOKIE_NAME}=${brand}; Path=/; Max-Age=${maxAge}; SameSite=Lax`\n    } else if (this.response) {\n      // Persist cookies by appending headers to the Fetch Response\n      this.appendSetCookieHeader(THEME_COOKIE_NAME, theme)\n      this.appendSetCookieHeader(BRAND_COOKIE_NAME, brand)\n    }\n  }\n\n  private updateAttribute(name: string, value: string): void {\n    if (this.renderer) {\n      this.renderer.setAttribute(this.rootElement, name, value)\n    } else {\n      this.rootElement?.setAttribute?.(name, value)\n    }\n  }\n\n  private updateColorScheme(theme: Theme): void {\n    if (this.renderer) {\n      this.renderer.setStyle(this.rootElement, \"color-scheme\", theme)\n    } else {\n      this.rootElement?.style?.setProperty?.(\"color-scheme\", theme)\n    }\n  }\n\n  private appendSetCookieHeader(name: string, value: string): void {\n    this.response!.headers.append(\n      \"Set-Cookie\",\n      `${name}=${value}; Path=/; Max-Age=${60 * 60 * 24 * 365}; SameSite=Lax`,\n    )\n  }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}