首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nuxt和Windi,我能在windi.config.ts中得到当前的主题吗?

Nuxt和Windi,我能在windi.config.ts中得到当前的主题吗?
EN

Stack Overflow用户
提问于 2022-10-20 14:41:49
回答 2查看 53关注 0票数 0

我创建了一个theme.ts,其中我使用主机名(基于可怕的初学者nuxt3库 versoin)来判断站点的“品牌”,如下所示:

utils/theme.ts

代码语言:javascript
复制
export type IThemeSettingOptions = 'light' | 'system' | 'foo' | 'bar'

export type ITheme = 'light' | 'foo' | 'bar'

export const availableThemes: {
  key: IThemeSettingOptions
  text: string
}[] = [
    { key: 'light', text: 'Light' },
    { key: 'system', text: 'System' },
    { key: 'foo', text: 'Foo' },
    { key: 'bar', text: 'Bar' },
  ]

export function ThemeManager() {
  // composable
  const themeUserSetting = useCookie<IThemeSettingOptions>('theme')

  // methods
  const getUserSetting = (): IThemeSettingOptions => {
    return themeUserSetting.value || 'system'
  }

  const getSiteTheme = (): ITheme => {
    try {
      const host = location.hostname
      const sites = {
        'foo.whitelabel.com': 'foo',
        'bar.whitelabel.com': 'bar'
      }

      if (sites[host]) {
        return sites[host]
      }
    } catch (e) {
      return 'light' // This means generic styles, no customizable brand
    }
  }

  // state
  const themeSetting = useState<IThemeSettingOptions>('theme.setting', () =>
    getSiteTheme()
  )

  const themeCurrent = useState<ITheme>('theme.current', () =>
    process.client ? getSiteTheme() : 'light'
  )

  // init theme
  const init = () => {
    themeSetting.value = getSiteTheme()
  }

  // lifecycle
  onBeforeMount(() => init())

  onMounted(() => {
    themeCurrent.value = getSiteTheme()
  })

  return {
    themeSetting,
    themeCurrent,
    getUserSetting,
    getSiteTheme
  }
}

我知道nuxt提供的色彩模式。但是在使用报时时,我希望为每个主题/品牌设置一个不同的配置文件/对象。

我在windi.config.ts里试过像这样

代码语言:javascript
复制
import { defineConfig } from 'windicss/helpers';
import type { Plugin } from 'windicss/types/interfaces';
import { ThemeManager } from './utils/theme';

console.log(ThemeManager().themeCurrent)
// etc..

但是这不会在控制台上记录任何东西

这个可以定位吗?如果不是,类似的解决办法?(也许是尾风车)

我想这样做,所以primary的颜色对于foobar品牌来说是不同的,让我们这样说:

windi.config.ts

代码语言:javascript
复制
const MyThemes = {
  light: {
    colors: {
      green: {
        DEFAULT: '#3BA670'
      },
      blue: {
        DEFAULT: '#0096F0'
      }
    }
  },
  foo: {
    colors: {
      green: {
        DEFAULT: '#3BA675'
      },
      blue: {
        DEFAULT: '#0096F5'
      }
    }
  },
  bar: {
    colors: {
      green: {
        DEFAULT: '#3BA67F'
      },
      blue: {
        DEFAULT: '#0096FF'
      }
    }
  }
}

const MyTheme = MyThemes['foo'] // or 'bar' or 'light'


export default defineConfig({
  // etc..
  theme: {
    extend: {
      colors: {
        primary: MyTheme.colors.green,
        // etc.. 
      }
    },
  }
  // etc..
})
EN

回答 2

Stack Overflow用户

发布于 2022-10-20 16:48:21

  1. 如果希望在Tailwind中获取特定令牌的JS中的实际值,可以使用如下所示的这个答案
代码语言:javascript
复制
import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from '@/tailwind.config.js'
const twFullConfig = resolveConfig(tailwindConfig)

...
mounted() {
  console.log('tw', twFullConfig.theme.colors['primary-500'])
}
  1. 如果您想要动态地依赖于一个特定的变量,您需要将它映射到一个对象,然后将您的类作为在这里显示。如果您在使用基于实用程序的CSS框架和适当的设计系统时想要动态的东西,这是非常方便的。
  2. 顺风不允许动态类的性能原因,因此,这种映射是一个必要的邪恶。

UnoCSS可能是我所知道的最灵活的解决方案,但它仍然没有适应于解决这样的问题。使用某些CSS变量并动态覆盖它们也是如此,因为设计系统的基础远远不止是颜色或大小。

TLDR:主题化很难,需要一些手工制作的映射才能有效地完成。我已经在客户端尝试过这种方法,而且它很早就很复杂,特别是如果您想出一种动态的方法来做到这一点。

我试过就是那个[医]孪生垫片。在运行时使用它是可行的(如果需要的话),但确实很棘手。

票数 0
EN

Stack Overflow用户

发布于 2022-11-23 21:50:57

如果您可以依赖CSS vars (自定义属性) IMHO,您可以简化这一点。

  1. 根据主题在html上设置一个类,例如<html class="dark">...</html><html class="foo">...</html>。您可以在nuxt.config.ts应用程序部分或您提到的颜色模块中完成这一任务。
代码语言:javascript
复制
  app: {
    // https://nuxt.com/docs/api/configuration/nuxt-config#head
    head: {
      htmlAttrs: {
        lang: 'en',
        class: 'foo', // Here you could an environment variable
      },
    },
  },
  1. 在样式表上设置颜色。
代码语言:javascript
复制
// theme.css

:root {
  --color-primary: #3BA670; /* or Whatever value you like, HSL, RGBA, colornames, ecc */
  --color-error: darkred;
}

html.foo {
  --color-primary: #3BA675;
  --color-error: mediumvioletred;
}

html.bar {
  --color-primary: orange;
  --color-error: indianred;
}

最后在你的windi.config.ts中

代码语言:javascript
复制
export default defineConfig({
  // etc..
  theme: {
    extend: {
      colors: {
        primary: 'var(--color-primary)',
        error: 'var(--color-error)',
        // etc.. 
      }
    },
  }
  // etc..
})

此外,如果您有一个坚实的颜色系统,您可以省略扩展颜色,只需覆盖windi调色板并实现您的颜色。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74141792

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档