Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to overwrite the default theme with a custom theme #228

Open
shinokada opened this issue Nov 29, 2024 · 0 comments
Open

Question: How to overwrite the default theme with a custom theme #228

shinokada opened this issue Nov 29, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@shinokada
Copy link

shinokada commented Nov 29, 2024

Describe the bug
I'm trying to overwrite the default theme with a custom theme. I can't find any documentation, so I apologize in advance to create an issue.
My code works, but I get some type errors. It will be great if you can provide some examples.

To Reproduce

I have the following default tailwind-variants:

import { tv } from "tailwind-variants";

export const breadcrumb = tv({
  slots: {
    nav: "flex",
    list: "inline-flex items-center space-x-1 rtl:space-x-reverse md:space-x-3 rtl:space-x-reverse",
    item: "inline-flex items-center",
    icon: "h-6 w-6 text-gray-400 rtl:-scale-x-100"
  },
  variants: {
    solid: {
      true: {
        nav: "px-5 py-3 text-gray-700 border border-gray-200 rounded-lg bg-gray-50 dark:bg-gray-800 dark:border-gray-700"
      },
      false: ""
    },
    home: {
      true: "",
      false: ""
    },
    hasHref: {
      true: "",
      false: ""
    }
  },
  compoundVariants: [
    {
      home: true,
      class: {
        item: "inline-flex items-center text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white",
        icon: "me-2 h-4 w-4"
      }
    },
    {
      home: false,
      hasHref: true,
      class: {
        item: "ms-1 text-sm font-medium text-gray-700 hover:text-gray-900 md:ms-2 dark:text-gray-400 dark:hover:text-white"
      }
    },
    {
      home: false,
      hasHref: false,
      class: {
        item: "ms-1 text-sm font-medium text-gray-500 md:ms-2 dark:text-gray-400"
      }
    }
  ],
  defaultVariants: {
    solid: false
  }
});

My library has many components and all component has similar theme.

In order to a user can overwrite this, I am making a new component.

types.ts

import { tv } from 'tailwind-variants';

export interface ThemeType {
  [key: string]: ReturnType<typeof tv>;

And merging function in the following code using deepmerge package.

<script lang="ts">
  import { setContext, type Snippet } from "svelte";
  import { tv } from "tailwind-variants";
  import deepmerge from "deepmerge";
  import {
    accordion,
    accordionitem,
    alert,
  // more lines
  } from "$lib";
  import type { ThemeType } from "$lib/types";

  interface Props {
    children: Snippet;
    theme?: Record<string, any>;
  }

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

  // Function to merge theme configurations
  function mergeThemes(baseThemes: ThemeType, customTheme?: ThemeType) {
    const mergedTheme: ThemeType = {};

    // Merge each component's theme
    for (const [componentName, baseTheme] of Object.entries(baseThemes)) {
      const customComponentTheme = customTheme?.[componentName] || {};

      // Deep merge base theme with custom theme
      mergedTheme[componentName] = tv(
        deepmerge(
          {
            slots: baseTheme.slots,
            variants: baseTheme.variants,
            compoundVariants: baseTheme.compoundVariants,
            defaultVariants: baseTheme.defaultVariants
          },
          {
            slots: customComponentTheme.slots || {},
            variants: customComponentTheme.variants || {},
            compoundVariants: customComponentTheme.compoundVariants || [],
            defaultVariants: customComponentTheme.defaultVariants || {}
          }
        )
      );
    }

    return mergedTheme;
  }

  const baseThemes = {
    accordion,
    accordionitem,
    alert,
    // more line
  };

  const mergedThemes = mergeThemes(baseThemes, theme);

  setContext("themeConfig", mergedThemes);
</script>

{@render children()}

An example of theme.

import { tv } from "tailwind-variants";

export const themeConfig = {
  breadcrumb: tv({
    slots: {
      list: "inline-flex items-center space-x-8 rtl:space-x-reverse rtl:space-x-reverse"
    }
  }),
  accordionitem: tv({
    compoundVariants: [
      {
        flush: true,
        open: true,
        class: {
          button: "text-red-900 dark:text-red-300"
        }
      },
      {
        flush: true,
        open: false,
        class: {
          button: "text-green-500 dark:text-green-300"
        }
      }
    ]
  })
};

Screenshots
N/A

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]
System:
    OS: macOS 15.1.1
    CPU: (10) arm64 Apple M2 Pro
    Memory: 371.58 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.11.0 - ~/.nvm/versions/node/v22.11.0/bin/node
    npm: 10.9.0 - ~/.nvm/versions/node/v22.11.0/bin/npm
    pnpm: 9.14.2 - /opt/homebrew/bin/pnpm
    bun: 1.1.8 - ~/.bun/bin/bun
  Browsers:
    Chrome: 131.0.6778.86
    Edge: 131.0.2903.70
    Safari: 18.1.1
  npmPackages:
    @sveltejs/kit: ^2.8.4 => 2.8.4 
    svelte: 5.2.8 => 5.2.8 
    tailwind-variants: ^0.3.0 => 0.3.0 
    vite: ^5.4.11 => 5.4.11 

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]
@shinokada shinokada added the bug Something isn't working label Nov 29, 2024
@shinokada shinokada changed the title [Question: ]How to overwrite the default theme with a custom theme Question: How to overwrite the default theme with a custom theme Nov 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant