@thiagormoreira/nightwind 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ npm run lint && npm run test
package/CHANGELOG.md CHANGED
@@ -5,19 +5,63 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.1.0] - 2026-02-20
9
+
10
+ ### Added
11
+ - **Hybrid Performance Optimization**: Implemented a hybrid approach combining optimized static generation for standard colors/weights with `matchUtilities` for arbitrary values, ensuring 100% reliability for variants like `hover`, `group-hover`, and `peer-focus`.
12
+ - **Arbitrary Color Support**: Automatic dark mode inversion for arbitrary color values (e.g., `bg-[#ffffff]`, `text-[rgb(0,0,0)]`).
13
+ - **ESLint Browser Support**: Added proper global definitions for `helper.js` in `eslint.config.js`.
14
+
15
+ ### Changed
16
+ - **Performance Pre-calculation**: Optimized the plugin logic to pre-calculate color mappings and rules, significantly reducing PostCSS processing time during Tailwind JIT.
17
+ - **Transition Synchronization**: The plugin now injects `--nightwind-transition-duration` into `:root` (default `400ms`) for perfect sync with the transition helper.
18
+
19
+ ### Fixed
20
+ - **Variant Reliability**: Fixed issues with `matchComponents` shadowing core utilities, restoring correct variant handling in dark mode.
21
+ - **Linting Errors**: Resolved all `no-undef` and `no-unused-vars` errors in `src/index.js` and `helper.js`.
22
+ - **Helper Compatibility**: Restored toggling of the `light` class in `helper.js` for backward compatibility with custom CSS workflows.
23
+
24
+ ## [2.0.2] - 2026-02-20
25
+
26
+ ### Added
27
+ - **Default Variants**: Added out-of-the-box support for `focus`, `active`, `focus-within`, `focus-visible`, and `disabled`.
28
+ - **Selection Prefix**: Added support for `selection` utility inversion.
29
+
30
+ ### Fixed
31
+ - **Variant Selector Precision**: Implemented strict variant matching to prevent false positives in color names (e.g., `hoverred` no longer triggers `:hover`).
32
+ - **Group & Peer Variants**: Resolved issues with `group-*` and `peer-*` variants, ensuring correct selector generation for nested and sibling elements.
33
+
34
+ ## [2.0.1] - 2026-02-20
35
+
36
+ ### Changed
37
+ - **Node.js Requirement**: Minimum Node.js version updated to `v20.12.0` (dropping support for Node 18).
38
+
39
+ ### Fixed
40
+ - **ESLint Compatibility**: Resolved `TypeError: util.styleText is not a function` in ESLint 10 by upgrading the project's runtime requirements.
41
+
8
42
  ## [2.0.0] - 2026-02-20
9
43
 
10
44
  ### Added
11
45
  - **Universal Opacity Support**: Dynamic CSS attribute selectors ([class*=".../"]) now support ANY opacity modifier (including arbitrary values like `bg-red-500/[0.3]`) with zero performance overhead.
12
46
  - **100% Color Utility Coverage**: Added support for `outline-`, `decoration-`, `accent-`, `caret-`, `fill-`, `stroke-`, and `shadow-color` (via `--tw-shadow-color`).
13
47
  - **Enhanced Transitions**: Default transition duration increased to `400ms` with `ease-in-out` for a smoother theme-switching experience.
14
- - **Compatibility**: Verified support for Tailwind CSS v3 and prepared for v4 "CSS-first" configuration.
15
48
 
16
49
  ### Fixed
17
50
  - **PostCSS Performance**: Resolved Out-Of-Memory (OOM) errors and hangs caused by static opacity combinatorial explosion.
18
51
  - **Color Inversion Precision**: Improved `white`/`black` inversion when modifiers are present.
19
52
  - **Utility Conflicts**: Fixed detection logic for overlapping utilities like `ring-` and `ring-offset-`.
20
- - **Selector Robustness**: Improved handling of `::placeholder`, `divide`, and complex pseudo-variants.
53
+
54
+ ## [1.3.0] - 2026-02-20
55
+
56
+ ### Changed
57
+ - **Maintenance**: General refactoring and cleanup of `src/index.js`.
58
+ - **CI/CD**: Improved GitHub Actions workflows and testing environment consistency.
59
+
60
+ ## [1.2.0] - 2026-02-20
61
+
62
+ ### Added
63
+ - **Testing Infrastructure**: Initial setup of the Jest test suite for color inversion logic.
64
+ - **Helper Refinement**: Initial refactor of `helper.js` for better browser compatibility.
21
65
 
22
66
  ## [1.1.13] - 2023-02-21
23
67
 
@@ -0,0 +1,40 @@
1
+ const postcss = require("postcss")
2
+ const tailwindcss = require("tailwindcss")
3
+ const nightwind = require("../src/index.js")
4
+
5
+ async function generateCss(html, config = {}) {
6
+ const result = await postcss([
7
+ tailwindcss({
8
+ content: [{ raw: html }],
9
+ darkMode: "class",
10
+ plugins: [nightwind],
11
+ theme: {
12
+ extend: {}
13
+ },
14
+ ...config,
15
+ }),
16
+ ]).process("@tailwind utilities;", {
17
+ from: undefined,
18
+ })
19
+ return result.css
20
+ }
21
+
22
+ describe("nightwind arbitrary colors", () => {
23
+ it("should invert arbitrary hex background", async () => {
24
+ const css = await generateCss('<div class="bg-[#ffffff]"></div>')
25
+ expect(css).toContain(".dark .bg-\\[\\#ffffff\\]")
26
+ expect(css).toContain("background-color: rgb(0, 0, 0)")
27
+ })
28
+
29
+ it("should invert arbitrary rgb text", async () => {
30
+ const css = await generateCss('<div class="text-[rgb(0,0,0)]"></div>')
31
+ expect(css).toContain(".dark .text-\\[rgb\\(0\\2c 0\\2c 0\\)\\]")
32
+ expect(css).toContain("color: rgb(255, 255, 255)")
33
+ })
34
+
35
+ it("should invert arbitrary hex border", async () => {
36
+ const css = await generateCss('<div class="border-[#00ff00]"></div>')
37
+ expect(css).toContain(".dark .border-\\[\\#00ff00\\]")
38
+ expect(css).toContain("border-color: rgb(255, 0, 255)")
39
+ })
40
+ })
@@ -1,3 +1,4 @@
1
+ /** @jest-environment jsdom */
1
2
  const helper = require("../helper.js")
2
3
 
3
4
  describe("nightwind/helper", () => {
@@ -56,7 +57,7 @@ describe("nightwind/helper", () => {
56
57
  it("should return the initialization script logic", () => {
57
58
  const script = helper.init()
58
59
  expect(typeof script).toBe("string")
59
- expect(script).toContain("getInitialColorMode")
60
+ expect(script).toContain("nightwind-mode")
60
61
  })
61
62
  })
62
63
 
@@ -0,0 +1,66 @@
1
+ const postcss = require("postcss")
2
+ const tailwindcss = require("tailwindcss")
3
+ const nightwind = require("../src/index.js")
4
+
5
+ async function generateCss(html, config = {}) {
6
+ const result = await postcss([
7
+ tailwindcss({
8
+ content: [{ raw: html }],
9
+ darkMode: "class",
10
+ theme: {
11
+ extend: {
12
+ colors: {
13
+ red: {
14
+ 400: "#f87171",
15
+ 600: "#dc2626",
16
+ },
17
+ blue: {
18
+ 500: "#3b82f6",
19
+ },
20
+ hoverred: {
21
+ 400: "#f87171",
22
+ 500: "#ef4444",
23
+ }
24
+ },
25
+ nightwind: {
26
+ variants: ["group-hover", "peer-focus"]
27
+ }
28
+ },
29
+ },
30
+ plugins: [nightwind],
31
+ ...config,
32
+ }),
33
+ ]).process("@tailwind utilities; @tailwind components;", {
34
+ from: undefined,
35
+ })
36
+ return result.css
37
+ }
38
+
39
+ describe("nightwind variants", () => {
40
+ it("should handle hover variant correctly", async () => {
41
+ const css = await generateCss('<div class="hover:bg-red-600"></div>')
42
+ expect(css).toContain(".dark .hover\\:bg-red-600:hover")
43
+ })
44
+
45
+ it("should handle group-hover variant correctly", async () => {
46
+ const css = await generateCss('<div class="group-hover:bg-red-600"></div>')
47
+ expect(css).toContain(".dark .group:hover .group-hover\\:bg-red-600")
48
+ })
49
+
50
+ it("should handle peer-focus variant correctly", async () => {
51
+ const css = await generateCss('<div class="peer-focus:text-blue-500"></div>')
52
+ expect(css).toContain(".dark .peer:focus ~ .peer-focus\\:text-blue-500")
53
+ })
54
+
55
+ it("should NOT trigger hover on a color name containing hover", async () => {
56
+ const css = await generateCss('<div class="bg-hoverred-500"></div>')
57
+ expect(css).toContain(".dark .bg-hoverred-500")
58
+ expect(css).not.toContain(".dark .bg-hoverred-500:hover")
59
+ })
60
+
61
+ it("should support default variants like focus and disabled", async () => {
62
+ const css = await generateCss('<div class="focus:bg-red-600 disabled:opacity-50 disabled:bg-red-400"></div>')
63
+ expect(css).toContain(".dark .focus\\:bg-red-600:focus")
64
+ expect(css).toContain(".dark .disabled\\:bg-red-400:disabled")
65
+ })
66
+ })
package/eslint.config.js CHANGED
@@ -12,7 +12,10 @@ module.exports = [
12
12
  window: true,
13
13
  document: true,
14
14
  console: true,
15
- __dirname: true
15
+ __dirname: true,
16
+ getComputedStyle: true,
17
+ setTimeout: true,
18
+ localStorage: true
16
19
  }
17
20
  },
18
21
  rules: {
package/helper.js CHANGED
@@ -1,62 +1,24 @@
1
1
  module.exports = {
2
- init: () => {
3
- const codeToRunOnClient = `
4
- (function() {
5
- function getInitialColorMode() {
6
- const persistedColorPreference = window.localStorage.getItem('nightwind-mode');
7
- const hasPersistedPreference = typeof persistedColorPreference === 'string';
8
- if (hasPersistedPreference) {
9
- return persistedColorPreference;
10
- }
11
- const mql = window.matchMedia('(prefers-color-scheme: dark)');
12
- const hasMediaQueryPreference = typeof mql.matches === 'boolean';
13
- if (hasMediaQueryPreference) {
14
- return mql.matches ? 'dark' : 'light';
15
- }
16
- return 'light';
17
- }
18
- getInitialColorMode() == 'light' ? document.documentElement.classList.remove('dark') : document.documentElement.classList.add('dark');
19
- })()
20
- `
21
- return codeToRunOnClient
22
- },
2
+ init: () => `(function(){try{var m=localStorage.getItem('nightwind-mode'),d=window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.classList.toggle('dark',m==='dark'||(!m&&d))}catch(e){}})()`,
23
3
 
24
4
  beforeTransition: () => {
25
5
  const doc = document.documentElement
26
- if (!doc.classList.contains("nightwind")) {
27
- doc.classList.add("nightwind")
28
- }
29
- // Use timeout instead of transitionend to avoid premature removal
30
- // when multiple properties transition at different speeds
31
- const duration = parseFloat(
32
- window.getComputedStyle(document.body).getPropertyValue("--nightwind-transition-duration") || "400"
33
- )
34
- window.setTimeout(() => {
35
- doc.classList.remove("nightwind")
36
- }, duration + 100) // Small buffer to ensure all transitions complete
6
+ doc.classList.add("nightwind")
7
+ const duration = parseFloat(getComputedStyle(doc).getPropertyValue("--nightwind-transition-duration")) || 400
8
+ setTimeout(() => doc.classList.remove("nightwind"), duration + 20)
37
9
  },
38
10
 
39
11
  toggle: () => {
40
12
  module.exports.beforeTransition()
41
- if (!document.documentElement.classList.contains("dark")) {
42
- document.documentElement.classList.add("dark")
43
- window.localStorage.setItem("nightwind-mode", "dark")
44
- } else {
45
- document.documentElement.classList.remove("dark")
46
- window.localStorage.setItem("nightwind-mode", "light")
47
- }
13
+ const isDark = document.documentElement.classList.toggle("dark")
14
+ document.documentElement.classList.toggle("light", !isDark)
15
+ localStorage.setItem("nightwind-mode", isDark ? "dark" : "light")
48
16
  },
49
17
 
50
18
  enable: (dark) => {
51
- const mode = dark ? "dark" : "light"
52
- const opposite = dark ? "light" : "dark"
53
-
54
19
  module.exports.beforeTransition()
55
-
56
- if (document.documentElement.classList.contains(opposite)) {
57
- document.documentElement.classList.remove(opposite)
58
- }
59
- document.documentElement.classList.add(mode)
60
- window.localStorage.setItem("nightwind-mode", mode)
20
+ document.documentElement.classList.toggle("dark", dark)
21
+ document.documentElement.classList.toggle("light", !dark)
22
+ localStorage.setItem("nightwind-mode", dark ? "dark" : "light")
61
23
  },
62
24
  }
package/jest.config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  module.exports = {
2
- testEnvironment: "jsdom",
2
+ testEnvironment: "node",
3
3
  clearMocks: true,
4
- collectCoverage: true,
4
+ collectCoverage: false,
5
5
  coverageDirectory: "coverage",
6
6
  coverageProvider: "v8",
7
7
  testMatch: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[tj]s?(x)"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thiagormoreira/nightwind",
3
- "version": "2.0.1",
3
+ "version": "2.1.1",
4
4
  "description": "An automatic, overridable, customisable Tailwind dark mode plugin",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -29,7 +29,10 @@
29
29
  "scripts": {
30
30
  "test": "jest",
31
31
  "lint": "eslint .",
32
- "format": "prettier --write \"**/*.{js,jsx,json,md}\""
32
+ "format": "prettier --write \"**/*.{js,jsx,json,md}\"",
33
+ "prepare": "husky",
34
+ "preversion": "npm run lint && npm run test",
35
+ "postversion": "git push --follow-tags"
33
36
  },
34
37
  "engines": {
35
38
  "node": ">=20.12.0"
@@ -39,6 +42,7 @@
39
42
  "autoprefixer": "^10.4.24",
40
43
  "eslint": "^10.0.0",
41
44
  "eslint-plugin-jest": "^29.15.0",
45
+ "husky": "^9.1.7",
42
46
  "jest": "^30.2.0",
43
47
  "jest-environment-jsdom": "^30.2.0",
44
48
  "postcss": "^8.5.6",
package/src/index.js CHANGED
@@ -1,36 +1,39 @@
1
1
  const plugin = require("tailwindcss/plugin")
2
2
 
3
+ const invertColorValue = (value) => {
4
+ if (!value || typeof value !== "string") return value
5
+ if (value.startsWith("#")) {
6
+ let hex = value.slice(1)
7
+ if (hex.length === 3) hex = hex.split("").map((c) => c + c).join("")
8
+ if (hex.length === 6) {
9
+ const r = 255 - parseInt(hex.slice(0, 2), 16)
10
+ const g = 255 - parseInt(hex.slice(2, 4), 16)
11
+ const b = 255 - parseInt(hex.slice(4, 6), 16)
12
+ return `rgb(${r}, ${g}, ${b})`
13
+ }
14
+ }
15
+ const rgbMatch = value.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/)
16
+ if (rgbMatch) {
17
+ const r = 255 - parseInt(rgbMatch[1])
18
+ const g = 255 - parseInt(rgbMatch[2])
19
+ const b = 255 - parseInt(rgbMatch[3])
20
+ const a = rgbMatch[4]
21
+ return a ? `rgba(${r}, ${g}, ${b}, ${a})` : `rgb(${r}, ${g}, ${b})`
22
+ }
23
+ return value
24
+ }
25
+
3
26
  const nightwind = plugin(
4
- function ({ addBase, addComponents, addUtilities, theme, variants, config }) {
27
+ function ({ addBase, addComponents, matchUtilities, theme, config }) {
5
28
  const darkSelector = ".dark"
6
- const fixedElementClass = `.${theme("nightwind.fixedClass", "nightwind-prevent")}`
7
- const fixedBlockClass = `.${theme("nightwind.fixedBlockClass", "nightwind-prevent-block")}`
29
+ const fixedElementClass = `${theme("nightwind.fixedClass", "nightwind-prevent")}`
30
+ const fixedBlockClass = `${theme("nightwind.fixedBlockClass", "nightwind-prevent-block")}`
8
31
  const transitionConfig = theme("nightwind.transitionClasses", "default")
9
32
  const colors = theme("colors")
10
- const colorClasses = []
11
- const transitionClasses = []
12
- const typographyValues = {}
13
- const typographyClasses = []
14
- const colorVariants = ["hover"]
15
- const prefixes = ["text", "bg", "border", "ring", "ring-offset", "divide", "placeholder", "outline", "decoration", "accent", "caret", "fill", "stroke", "shadow", "from", "via", "to"]
16
33
  const weights = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]
17
34
  let importantSelector = ""
18
35
  let importantProperty = ""
19
36
 
20
- if (variants("nightwind")) {
21
- typeof variants("nightwind") === "object" ? colorVariants.push(...variants("nightwind")) : colorVariants.push(variants("nightwind"))
22
- } else if (variants("nightwind.variants")) {
23
- typeof variants("nightwind.variants") === "object" ? colorVariants.push(...variants("nightwind.variants")) : colorVariants.push(variants("nightwind.variants"))
24
- }
25
-
26
- if (theme("nightwind.colorClasses")) {
27
- typeof theme("nightwind.colorClasses") === "object" ? prefixes.push(...theme("nightwind.colorClasses")) : prefixes.push(theme("nightwind.colorClasses"))
28
- if (theme("nightwind.colorClasses").includes("gradient")) {
29
- // Gradient already handled in default prefixes now, but keeping for compatibility
30
- if (!prefixes.includes("from")) prefixes.push(...["from", "via", "to"])
31
- }
32
- }
33
-
34
37
  if (config("important")) {
35
38
  if (typeof config("important") === "string") {
36
39
  importantSelector = `${config("important")}${theme("nightwind.importantNode") ? "" : " "}`
@@ -42,31 +45,16 @@ const nightwind = plugin(
42
45
 
43
46
  function hexToRGB(h, alpha) {
44
47
  if (!h || h.includes("var(--")) return h
48
+ let r, g, b
45
49
  if (h.length == 4) {
46
50
  let rh = h[1] + h[1], gh = h[2] + h[2], bh = h[3] + h[3]
47
- var r = parseInt(rh, 16), g = parseInt(gh, 16), b = parseInt(bh, 16)
51
+ r = parseInt(rh, 16), g = parseInt(gh, 16), b = parseInt(bh, 16)
48
52
  } else if (h.length == 7) {
49
- var r = parseInt(h.slice(1, 3), 16), g = parseInt(h.slice(3, 5), 16), b = parseInt(h.slice(5, 7), 16)
53
+ r = parseInt(h.slice(1, 3), 16), g = parseInt(h.slice(3, 5), 16), b = parseInt(h.slice(5, 7), 16)
50
54
  } else return h
51
55
  return alpha ? `rgba(${r}, ${g}, ${b}, ${alpha})` : `rgb(${r}, ${g}, ${b})`
52
56
  }
53
57
 
54
- const hexToTailwind = (hex) => {
55
- let colorCode = ""
56
- if (hex != "inherit" && hex != "current" && hex != "transparent") {
57
- Object.keys(colors).forEach((col) => {
58
- if (typeof theme(`colors.${col}`) === "string") {
59
- if (hex === theme(`colors.${col}`)) colorCode = col
60
- } else if (typeof theme(`colors.${col}`) === "object") {
61
- Object.keys(theme(`colors.${col}`)).forEach((wei) => {
62
- if (hex === theme(`colors.${col}.${wei}`)) colorCode = col + "-" + wei
63
- })
64
- }
65
- })
66
- } else colorCode = hex
67
- return colorCode
68
- }
69
-
70
58
  const invertColor = (colorClass) => {
71
59
  if (colorClass.includes("white") || colorClass.includes("black")) {
72
60
  return {
@@ -74,15 +62,17 @@ const nightwind = plugin(
74
62
  defaultColorValue: colorClass.includes("white") ? theme("colors.white") : theme("colors.black"),
75
63
  }
76
64
  }
77
- if (colorClass === "inherit" || colorClass === "transparent" || colorClass === "current") return { colorValue: colorClass, defaultColorValue: colorClass }
65
+ if (["inherit", "transparent", "current"].includes(colorClass)) return { colorValue: colorClass, defaultColorValue: colorClass }
78
66
 
79
67
  const colorValues = colorClass.split("-")
80
68
  const weight = colorValues.pop()
81
- const color = colorValues.pop()
69
+ const color = colorValues.join("-")
82
70
  const defaultValue = theme(`colors.${color}.${weight}`)
83
71
  if (!defaultValue) return { colorValue: null, defaultColorValue: null }
84
72
 
85
- let invertWeightIndex = 9 - weights.indexOf(Number(weight))
73
+ let invertWeightIndex = weights.indexOf(Number(weight))
74
+ if (invertWeightIndex === -1) return { colorValue: null, defaultColorValue: null }
75
+ invertWeightIndex = 9 - invertWeightIndex
86
76
  let invertWeight = String(weights[invertWeightIndex])
87
77
 
88
78
  if (theme("nightwind.colorScale.preset") === "reduced") {
@@ -95,14 +85,13 @@ const nightwind = plugin(
95
85
  if (theme(`nightwind.colors.${color}.${weight}`)) {
96
86
  colorValue = theme(`colors.${theme(`nightwind.colors.${color}.${weight}`)}`) || theme(`nightwind.colors.${color}.${weight}`)
97
87
  } else if (theme(`nightwind.colors.${color}`) && typeof theme(`nightwind.colors.${color}`) === "string") {
98
- const colorMap = theme(`nightwind.colors.${color}`)
99
- colorValue = theme(`colors.${colorMap}.${invertWeight}`) || theme(`colors.${colorMap}`) || theme(`colors.${color}.${invertWeight}`) || colorMap
88
+ const colorMapSetting = theme(`nightwind.colors.${color}`)
89
+ colorValue = theme(`colors.${colorMapSetting}.${invertWeight}`) || theme(`colors.${colorMapSetting}`) || theme(`colors.${color}.${invertWeight}`) || colorMapSetting
100
90
  }
101
91
 
102
92
  return { colorValue, defaultColorValue: defaultValue }
103
93
  }
104
94
 
105
- // Generate transition classes
106
95
  let transitionDurationValue = "400ms"
107
96
  if (theme("nightwind.transitionDuration") === false || theme("transitionDuration.nightwind") === false) {
108
97
  transitionDurationValue = ""
@@ -113,183 +102,102 @@ const nightwind = plugin(
113
102
  }
114
103
 
115
104
  if (transitionDurationValue) {
116
- const transitionPrefixes = []
117
- if (transitionConfig === "full") transitionPrefixes.push(...prefixes)
118
- else if (typeof transitionConfig === "object" || (typeof transitionConfig === "string" && prefixes.includes(transitionConfig))) {
119
- typeof transitionConfig === "object" ? transitionPrefixes.push(...transitionConfig) : transitionPrefixes.push(transitionConfig)
120
- } else transitionPrefixes.push("text", "bg", "border")
105
+ addBase({ ":root": { "--nightwind-transition-duration": transitionDurationValue } })
106
+ }
121
107
 
122
- Object.keys(colors).forEach((color) => {
123
- transitionPrefixes.forEach((prefix) => {
124
- if (prefix === "from" || prefix === "via" || prefix === "to") return
125
- if (color == "transparent" || color == "current" || color == "white" || color == "black") {
126
- const tc = {
127
- [`${config("important") ? importantSelector : ""}.nightwind .${prefix}-${color}`]: { transitionDuration: transitionDurationValue, transitionProperty: theme("transitionProperty.colors"), transitionTimingFunction: "ease-in-out" },
128
- [`${config("important") ? importantSelector : ""}.nightwind .dark\\:${prefix}-${color}`]: { transitionDuration: transitionDurationValue, transitionProperty: theme("transitionProperty.colors"), transitionTimingFunction: "ease-in-out" },
129
- }
130
- transitionClasses.push(tc)
131
- } else {
132
- weights.forEach((weight) => {
133
- const tc = {
134
- [`${config("important") ? importantSelector : ""}.nightwind .${prefix}-${color}-${weight}`]: { transitionDuration: transitionDurationValue, transitionProperty: theme("transitionProperty.colors"), transitionTimingFunction: "ease-in-out" },
135
- [`${config("important") ? importantSelector : ""}.nightwind .dark\\:${prefix}-${color}-${weight}`]: { transitionDuration: transitionDurationValue, transitionProperty: theme("transitionProperty.colors"), transitionTimingFunction: "ease-in-out" },
136
- }
137
- transitionClasses.push(tc)
138
- })
139
- }
140
- })
141
- })
108
+ const prefixes = ["text", "bg", "border", "ring", "ring-offset", "divide", "placeholder", "outline", "decoration", "accent", "caret", "fill", "stroke", "shadow", "from", "via", "to"]
109
+ const variantsList = ["", "hover", "focus", "active", "focus-within", "focus-visible", "disabled", "group-hover", "peer-focus"]
110
+
111
+ const properties = {
112
+ text: { prop: "color", opacity: "--tw-text-opacity" },
113
+ bg: { prop: "backgroundColor", opacity: "--tw-bg-opacity" },
114
+ border: { prop: "borderColor", opacity: "--tw-border-opacity" },
115
+ ring: { prop: "--tw-ring-color", opacity: "--tw-ring-opacity" },
116
+ "ring-offset": { prop: "--tw-ring-offset-color" },
117
+ outline: { prop: "outlineColor" },
118
+ decoration: { prop: "textDecorationColor" },
119
+ accent: { prop: "accentColor" },
120
+ caret: { prop: "caretColor" },
121
+ fill: { prop: "fill" },
122
+ stroke: { prop: "stroke" },
123
+ shadow: { prop: "--tw-shadow-color" },
124
+ divide: { prop: "borderColor", suffix: " > :not([hidden]) ~ :not([hidden])", opacity: "--tw-divide-opacity" },
125
+ placeholder: { prop: "color", suffix: "::placeholder", opacity: "--tw-placeholder-opacity" },
126
+ from: { prop: "--tw-gradient-from", stops: true },
127
+ via: { prop: "--tw-gradient-stops", via: true },
128
+ to: { prop: "--tw-gradient-to" }
142
129
  }
143
130
 
144
- // Compose colors
145
- prefixes.forEach((prefix) => {
146
- Object.keys(colors).forEach((color) => {
147
- if (color == "white" || color == "black") {
148
- colorClasses.push(`${prefix}-${color}`)
149
- colorVariants.forEach(v => colorClasses.push(`${v}\\:${prefix}-${color}`))
150
- } else if (typeof colors[color] === "object") {
151
- weights.forEach((weight) => {
152
- colorClasses.push(`${prefix}-${color}-${weight}`)
153
- colorVariants.forEach(v => colorClasses.push(`${v}\\:${prefix}-${color}-${weight}`))
131
+ const nightwindClasses = {}
132
+
133
+ Object.keys(colors).forEach(c => {
134
+ const isStandard = !["transparent", "current", "inherit", "white", "black"].includes(c)
135
+ const weightsToProcess = isStandard ? weights : ["DEFAULT"]
136
+
137
+ weightsToProcess.forEach(w => {
138
+ const colorClass = isStandard ? `${c}-${w}` : c
139
+ const invertResults = invertColor(colorClass)
140
+ if (!invertResults.colorValue) return
141
+
142
+ prefixes.forEach(p => {
143
+ const config = properties[p]
144
+ if (!config) return
145
+ const val = config.opacity ? hexToRGB(invertResults.colorValue, `var(${config.opacity}, 1)`) : invertResults.colorValue
146
+ const defVal = config.opacity ? hexToRGB(invertResults.defaultColorValue, `var(${config.opacity}, 1)`) : invertResults.defaultColorValue
147
+
148
+ variantsList.forEach(v => {
149
+ const baseClass = `${p}-${colorClass}`
150
+ let selector = ""
151
+ if (v === "") selector = `.${baseClass}`
152
+ else if (v.startsWith("group-")) selector = `.group:${v.replace("group-", "")} .${v}\\:${baseClass}`
153
+ else if (v.startsWith("peer-")) selector = `.peer:${v.replace("peer-", "")} ~ .${v}\\:${baseClass}`
154
+ else selector = `.${v}\\:${baseClass}:${v}`
155
+
156
+ if (config.suffix) selector += config.suffix
157
+
158
+ const s = `${importantSelector}${darkSelector} ${selector}`
159
+ const preventS = `${s}.${fixedElementClass}, ${importantSelector}${darkSelector} .${fixedBlockClass} ${selector}`
160
+
161
+ if (config.stops) {
162
+ nightwindClasses[s] = { "--tw-gradient-from": val + importantProperty, "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(val, "0")})` + importantProperty }
163
+ nightwindClasses[preventS] = { "--tw-gradient-from": defVal + importantProperty, "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(defVal, "0")})` + importantProperty }
164
+ } else if (config.via) {
165
+ nightwindClasses[s] = { "--tw-gradient-stops": `var(--tw-gradient-from), ${val}, var(--tw-gradient-to, ${hexToRGB(val, "0")})` + importantProperty }
166
+ nightwindClasses[preventS] = { "--tw-gradient-stops": `var(--tw-gradient-from), ${defVal}, var(--tw-gradient-to, ${hexToRGB(defVal, "0")})` + importantProperty }
167
+ } else {
168
+ nightwindClasses[s] = { [config.prop]: val + importantProperty }
169
+ nightwindClasses[preventS] = { [config.prop]: defVal + importantProperty }
170
+ }
171
+
172
+ // Transition classes
173
+ if (v === "" && transitionDurationValue && (transitionConfig === "full" || (Array.isArray(transitionConfig) && transitionConfig.includes(p)) || (transitionConfig === "default" && ["text", "bg", "border"].includes(p)))) {
174
+ const transS = `${importantSelector}.nightwind .${baseClass}, ${importantSelector}.nightwind .dark\\:${baseClass}`
175
+ nightwindClasses[transS] = { transitionDuration: transitionDurationValue, transitionProperty: theme("transitionProperty.colors"), transitionTimingFunction: "ease-in-out" }
176
+ }
154
177
  })
155
- }
178
+ })
156
179
  })
157
180
  })
158
181
 
159
- const nightwindClasses = colorClasses.map((colorClass) => {
160
- let pseudoVariant = ""
161
- colorVariants.forEach((v) => { if (colorClass.includes(v)) pseudoVariant = (v == "last" || v == "first") ? ":" + v + "-child" : (v == "odd") ? ":nth-child(odd)" : (v == "even") ? ":nth-child(2n)" : (v == "group-hover") ? "" : ":" + v })
162
-
163
- const invertResults = invertColor(colorClass)
164
- let colorValue = invertResults.colorValue
165
- let defaultColorValue = invertResults.defaultColorValue
166
- if (!colorValue) return null
167
-
168
- let cleanClass = colorClass.replace(/\\/g, "")
169
-
170
- const generateClass = (prefix, property, selectorSuffix = "") => {
171
- const twOpacityVar = `var(--tw-${prefix}, 1)`
172
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${selectorSuffix}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${selectorSuffix}`
173
- return {
174
- [selector]: { [property]: hexToRGB(colorValue, twOpacityVar) + importantProperty },
175
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}${selectorSuffix}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}${selectorSuffix}`]: { [property]: hexToRGB(defaultColorValue, twOpacityVar) + importantProperty },
176
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}${selectorSuffix}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}${selectorSuffix}`]: { [property]: hexToRGB(defaultColorValue, twOpacityVar) + importantProperty }
177
- }
178
- }
182
+ addComponents(nightwindClasses)
179
183
 
180
- if (colorClass.includes("ring-offset-")) {
181
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
182
- return {
183
- [selector]: { "--tw-ring-offset-color": colorValue + importantProperty },
184
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "--tw-ring-offset-color": defaultColorValue + importantProperty },
185
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "--tw-ring-offset-color": defaultColorValue + importantProperty }
186
- }
187
- }
188
- if (colorClass.includes("ring-")) return generateClass("ring-opacity", "--tw-ring-color")
189
- if (colorClass.includes("divide-")) {
190
- const twOpacityVar = `var(--tw-divide-opacity, 1)`
191
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden]), ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant} > :not([hidden]) ~ :not([hidden])`
192
- return {
193
- [selector]: { borderColor: hexToRGB(colorValue, twOpacityVar) + importantProperty },
194
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass} > :not([hidden]) ~ :not([hidden]), ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass} > :not([hidden]) ~ :not([hidden])`]: { borderColor: hexToRGB(defaultColorValue, twOpacityVar) + importantProperty },
195
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden]), ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]: { borderColor: hexToRGB(defaultColorValue, twOpacityVar) + importantProperty }
196
- }
197
- }
198
- if (colorClass.includes("placeholder-")) {
199
- const twOpacityVar = `var(--tw-placeholder-opacity, 1)`
200
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}::placeholder, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}::placeholder`
201
- return {
202
- [selector]: { color: hexToRGB(colorValue, twOpacityVar) + importantProperty },
203
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}::placeholder, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}::placeholder`]: { color: hexToRGB(defaultColorValue, twOpacityVar) + importantProperty },
204
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}::placeholder, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}::placeholder`]: { color: hexToRGB(defaultColorValue, twOpacityVar) + importantProperty }
205
- }
206
- }
207
- if (colorClass.includes("text-")) return generateClass("text-opacity", "color")
208
- if (colorClass.includes("bg-")) return generateClass("bg-opacity", "backgroundColor")
209
- if (colorClass.includes("border-")) return generateClass("border-opacity", "borderColor")
210
- if (colorClass.includes("ring-")) return generateClass("ring-opacity", "--tw-ring-color")
211
- if (colorClass.includes("outline-")) {
212
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
213
- return {
214
- [selector]: { "outlineColor": colorValue + importantProperty },
215
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "outlineColor": defaultColorValue + importantProperty },
216
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "outlineColor": defaultColorValue + importantProperty }
217
- }
218
- }
219
- if (colorClass.includes("decoration-")) {
220
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
221
- return {
222
- [selector]: { "textDecorationColor": colorValue + importantProperty },
223
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "textDecorationColor": defaultColorValue + importantProperty },
224
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "textDecorationColor": defaultColorValue + importantProperty }
225
- }
226
- }
227
- if (colorClass.includes("accent-")) {
228
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
229
- return {
230
- [selector]: { "accentColor": colorValue + importantProperty },
231
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "accentColor": defaultColorValue + importantProperty },
232
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "accentColor": defaultColorValue + importantProperty }
233
- }
234
- }
235
- if (colorClass.includes("caret-")) {
236
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
237
- return {
238
- [selector]: { "caretColor": colorValue + importantProperty },
239
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "caretColor": defaultColorValue + importantProperty },
240
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "caretColor": defaultColorValue + importantProperty }
241
- }
242
- }
243
- if (colorClass.includes("fill-")) {
244
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
245
- return {
246
- [selector]: { "fill": colorValue + importantProperty },
247
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "fill": defaultColorValue + importantProperty },
248
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "fill": defaultColorValue + importantProperty }
249
- }
250
- }
251
- if (colorClass.includes("stroke-")) {
252
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
253
- return {
254
- [selector]: { "stroke": colorValue + importantProperty },
255
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "stroke": defaultColorValue + importantProperty },
256
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "stroke": defaultColorValue + importantProperty }
257
- }
258
- }
259
- if (colorClass.includes("shadow-")) {
260
- const selector = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
261
- return {
262
- [selector]: { "--tw-shadow-color": colorValue + importantProperty },
263
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "--tw-shadow-color": defaultColorValue + importantProperty },
264
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "--tw-shadow-color": defaultColorValue + importantProperty }
265
- }
266
- }
267
- if (colorClass.includes("from-")) {
268
- const s = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
269
- return {
270
- [s]: { "--tw-gradient-from": colorValue + importantProperty, "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(colorValue, "0")})` + importantProperty },
271
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "--tw-gradient-from": defaultColorValue + importantProperty, "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(defaultColorValue, "0")})` + importantProperty },
272
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "--tw-gradient-from": defaultColorValue + importantProperty, "--tw-gradient-stops": `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(defaultColorValue, "0")})` + importantProperty }
273
- }
274
- }
275
- if (colorClass.includes("via-")) {
276
- const s = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
277
- return {
278
- [s]: { "--tw-gradient-stops": `var(--tw-gradient-from), ${colorValue}, var(--tw-gradient-to, ${hexToRGB(colorValue, "0")})` + importantProperty },
279
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "--tw-gradient-stops": `var(--tw-gradient-from), ${defaultColorValue}, var(--tw-gradient-to, ${hexToRGB(defaultColorValue, "0")})` + importantProperty },
280
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "--tw-gradient-stops": `var(--tw-gradient-from), ${defaultColorValue}, var(--tw-gradient-to, ${hexToRGB(defaultColorValue, "0")})` + importantProperty }
281
- }
282
- }
283
- if (colorClass.includes("to-")) {
284
- const s = `${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}`
285
- return {
286
- [s]: { "--tw-gradient-to": colorValue + importantProperty },
287
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} [class*="${cleanClass}/"]${pseudoVariant}${fixedElementClass}`]: { "--tw-gradient-to": defaultColorValue + importantProperty },
288
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} [class*="${cleanClass}/"]${pseudoVariant}`]: { "--tw-gradient-to": defaultColorValue + importantProperty }
289
- }
290
- }
291
- return null
292
- }).filter(Boolean)
184
+ // Arbitrary colors support - Dynamic
185
+ const arbitraryPrefixes = {
186
+ text: "color", bg: "backgroundColor", border: "borderColor", ring: "--tw-ring-color", outline: "outlineColor", decoration: "textDecorationColor", accent: "accentColor", caret: "caretColor", fill: "fill", stroke: "stroke"
187
+ }
188
+ Object.keys(arbitraryPrefixes).forEach((prefix) => {
189
+ matchUtilities(
190
+ {
191
+ [prefix]: (value) => {
192
+ if (typeof value !== "string") return null
193
+ const inverted = invertColorValue(value)
194
+ if (inverted === value) return null
195
+ return { [`${darkSelector} &`]: { [arbitraryPrefixes[prefix]]: inverted + importantProperty } }
196
+ },
197
+ },
198
+ { values: {}, type: "color" }
199
+ )
200
+ })
293
201
 
294
202
  if (theme("nightwind.typography")) {
295
203
  Object.keys(theme("typography") || {}).forEach((modifier) => {
@@ -298,31 +206,16 @@ const nightwind = plugin(
298
206
  Object.keys(n).forEach(classname => {
299
207
  const colorProp = Object.keys(n[classname]).find(p => p.includes("color") || p.includes("Color"))
300
208
  if (colorProp) {
301
- const colorVal = hexToTailwind(n[classname][colorProp])
302
- if (!typographyValues[modifier]) typographyValues[modifier] = {}
303
- if (!typographyValues[modifier][classname]) typographyValues[modifier][classname] = {}
304
- typographyValues[modifier][classname][colorProp] = colorVal
209
+ const invertResults = invertColor(n[classname][colorProp])
210
+ const colorValue = invertResults.colorValue || n[classname][colorProp]
211
+ const defaultColorValue = invertResults.defaultColorValue
212
+ const s = `${importantSelector}${darkSelector} .${classname}${modifier !== "DEFAULT" ? `-${modifier}` : ""}`
213
+ addComponents({ [s]: { [colorProp]: colorValue }, [`${s}.${fixedElementClass}`]: { [colorProp]: defaultColorValue } })
305
214
  }
306
215
  })
307
216
  })
308
217
  })
309
-
310
- Object.keys(typographyValues).forEach((modifier) => {
311
- Object.keys(typographyValues[modifier]).forEach((classname) => {
312
- Object.keys(typographyValues[modifier][classname]).forEach((property) => {
313
- const invertResults = invertColor(typographyValues[modifier][classname][property])
314
- const colorValue = invertResults.colorValue || typographyValues[modifier][classname][property]
315
- const defaultColorValue = invertResults.defaultColorValue
316
- const s = `${importantSelector}${darkSelector} .${classname}${modifier !== "DEFAULT" ? `-${modifier}` : ""}`
317
- typographyClasses.push({ [s]: { [property]: colorValue }, [`${s}${fixedElementClass}`]: { [property]: defaultColorValue } })
318
- })
319
- })
320
- })
321
218
  }
322
-
323
- addComponents(nightwindClasses)
324
- addComponents(typographyClasses)
325
- theme("nightwind.importantNode") ? addComponents(transitionClasses) : addUtilities(transitionClasses)
326
219
  },
327
220
  { theme: { extend: { transitionDuration: { 0: "0ms" } } } }
328
221
  )