<!-- @component `Theme` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-theming-theme--docs) -->
<script module lang="ts">
  import light from './themes/light.js';
  import dark from './themes/dark.js';
  /**
   * Pre-made themes you can import.
   * @type {{ light, dark }}
   */
  export const themes = { light, dark };
</script>

<script lang="ts">
  import type { CustomTheme } from './@types/component';

  type Base = 'light' | 'dark';

  import flatten from './utils/flatten';
  import mergeThemes from './utils/merge';
  interface Props {
    /** Custom theme object. Can be a partial theme with just
     * what you want to change.
     */
    theme?: CustomTheme;
    /**
     * Base theme is one of `light` or `dark` and will be merged
     * with your custom theme to fill in any values you don't
     * explicitly set.
     */
    base?: Base;
    children?: import('svelte').Snippet;
  }

  let { theme = {}, base = 'light', children }: Props = $props();

  /** @type {Theme} */
  let mergedTheme = $derived(
    mergeThemes({}, themes[base] || themes.light, theme)
  );

  let cssVariables = $derived(
    Object.entries(flatten({ theme: mergedTheme }))
      .map(([key, value]) => `--${key}: ${value};`)
      .join(' ')
  );
</script>

<div class="theme" style={cssVariables} style:display="contents">
  <!-- Clients can override the theme above by attaching custom properties to this element. -->
  <div class="theme-client-override" style="display: contents;">
    <!-- Themed content -->
    {@render children?.()}
  </div>
</div>
