@thiagormoreira/nightwind 1.3.3 → 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.
@@ -15,7 +15,7 @@ jobs:
15
15
 
16
16
  strategy:
17
17
  matrix:
18
- node-version: [18.x, 20.x, 22.x]
18
+ node-version: [20, 22]
19
19
 
20
20
  steps:
21
21
  - name: Checkout code
@@ -0,0 +1 @@
1
+ npm run lint && npm run test
package/CHANGELOG.md CHANGED
@@ -5,7 +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
- ## [Unreleased]
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
+
42
+ ## [2.0.0] - 2026-02-20
43
+
44
+ ### Added
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.
46
+ - **100% Color Utility Coverage**: Added support for `outline-`, `decoration-`, `accent-`, `caret-`, `fill-`, `stroke-`, and `shadow-color` (via `--tw-shadow-color`).
47
+ - **Enhanced Transitions**: Default transition duration increased to `400ms` with `ease-in-out` for a smoother theme-switching experience.
48
+
49
+ ### Fixed
50
+ - **PostCSS Performance**: Resolved Out-Of-Memory (OOM) errors and hangs caused by static opacity combinatorial explosion.
51
+ - **Color Inversion Precision**: Improved `white`/`black` inversion when modifiers are present.
52
+ - **Utility Conflicts**: Fixed detection logic for overlapping utilities like `ring-` and `ring-offset-`.
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.
9
65
 
10
66
  ## [1.1.13] - 2023-02-21
11
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": "1.3.3",
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,13 +29,20 @@
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"
36
+ },
37
+ "engines": {
38
+ "node": ">=20.12.0"
33
39
  },
34
40
  "devDependencies": {
35
41
  "@tailwindcss/postcss": "^4.2.0",
36
42
  "autoprefixer": "^10.4.24",
37
43
  "eslint": "^10.0.0",
38
44
  "eslint-plugin-jest": "^29.15.0",
45
+ "husky": "^9.1.7",
39
46
  "jest": "^30.2.0",
40
47
  "jest-environment-jsdom": "^30.2.0",
41
48
  "postcss": "^8.5.6",
package/src/index.js CHANGED
@@ -1,60 +1,42 @@
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 ({ addComponents, addUtilities, theme, variants, config }) {
27
+ function ({ addBase, addComponents, matchUtilities, theme, config }) {
5
28
  const darkSelector = ".dark"
6
- const fixedElementClass = `.${theme(
7
- "nightwind.fixedClass",
8
- "nightwind-prevent"
9
- )}`
10
- const fixedBlockClass = `.${theme(
11
- "nightwind.fixedBlockClass",
12
- "nightwind-prevent-block"
13
- )}`
29
+ const fixedElementClass = `${theme("nightwind.fixedClass", "nightwind-prevent")}`
30
+ const fixedBlockClass = `${theme("nightwind.fixedBlockClass", "nightwind-prevent-block")}`
14
31
  const transitionConfig = theme("nightwind.transitionClasses", "default")
15
- const colorClasses = []
16
- const transitionClasses = []
17
- const typographyValues = {}
18
- const typographyClasses = []
19
32
  const colors = theme("colors")
20
- const colorVariants = ["hover"]
21
- const prefixes = ["text", "bg", "border"]
22
33
  const weights = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]
23
34
  let importantSelector = ""
24
35
  let importantProperty = ""
25
36
 
26
- if (variants("nightwind")) {
27
- typeof variants("nightwind") === "object"
28
- ? colorVariants.push(...variants("nightwind"))
29
- : colorVariants.push(variants("nightwind"))
30
- } else if (variants("nightwind.variants")) {
31
- typeof variants("nightwind.variants") === "object"
32
- ? colorVariants.push(...variants("nightwind.variants"))
33
- : colorVariants.push(variants("nightwind.variants"))
34
- }
35
-
36
- if (theme("nightwind.colorClasses")) {
37
- typeof theme("nightwind.colorClasses") === "object"
38
- ? prefixes.push(...theme("nightwind.colorClasses"))
39
- : prefixes.push(theme("nightwind.colorClasses"))
40
- if (theme("nightwind.colorClasses").includes("gradient")) {
41
- prefixes.splice(prefixes.indexOf("gradient"), 1)
42
- prefixes.push(...["from", "via", "to"])
43
- }
44
- } else if (variants("nightwind.colorClasses")) {
45
- typeof variants("nightwind.colorClasses") === "object"
46
- ? prefixes.push(...variants("nightwind.colorClasses"))
47
- : prefixes.push(variants("nightwind.colorClasses"))
48
- if (variants("nightwind.colorClasses").includes("gradient")) {
49
- prefixes.splice(prefixes.indexOf("gradient"), 1)
50
- prefixes.push(...["from", "via", "to"])
51
- }
52
- }
53
-
54
37
  if (config("important")) {
55
38
  if (typeof config("important") === "string") {
56
- importantSelector = `${config("important")}${theme("nightwind.importantNode") ? "" : " "
57
- }`
39
+ importantSelector = `${config("important")}${theme("nightwind.importantNode") ? "" : " "}`
58
40
  }
59
41
  if (config("important") === true) {
60
42
  importantProperty = " !important"
@@ -62,173 +44,56 @@ const nightwind = plugin(
62
44
  }
63
45
 
64
46
  function hexToRGB(h, alpha) {
65
- if (h.includes("var(--")) {
66
- return h
67
- }
47
+ if (!h || h.includes("var(--")) return h
48
+ let r, g, b
68
49
  if (h.length == 4) {
69
- let rh = h[1] + h[1]
70
- let gh = h[2] + h[2]
71
- let bh = h[3] + h[3]
72
- var r = parseInt(rh, 16),
73
- g = parseInt(gh, 16),
74
- b = parseInt(bh, 16)
75
- }
76
- if (h.length == 7) {
77
- var r = parseInt(h.slice(1, 3), 16),
78
- g = parseInt(h.slice(3, 5), 16),
79
- b = parseInt(h.slice(5, 7), 16)
80
- }
81
-
82
- if (alpha) {
83
- return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")"
84
- } else {
85
- return "rgb(" + r + ", " + g + ", " + b + ")"
86
- }
87
- }
88
-
89
- const hexToTailwind = (hex) => {
90
- let colorCode = ""
91
- if (hex != "inherit" && hex != "current" && hex != "transparent") {
92
- Object.keys(colors).forEach((col) => {
93
- if (typeof theme(`colors.${col}`) === "string") {
94
- if (hex === theme(`colors.${col}`)) {
95
- colorCode = col
96
- }
97
- } else if (typeof theme(`colors.${col}`) === "object") {
98
- Object.keys(theme(`colors.${col}`)).forEach((wei) => {
99
- if (hex === theme(`colors.${col}.${wei}`)) {
100
- colorCode = col + "-" + wei
101
- }
102
- })
103
- }
104
- })
105
- } else {
106
- colorCode = hex
107
- }
108
- return colorCode
109
- }
110
-
111
- // Invert color logic
112
-
113
- let whiteSelector = "#000"
114
- let blackSelector = "#fff"
115
- if (theme(`nightwind.colors.white`)) {
116
- const colorMap = theme(`nightwind.colors.white`)
117
- whiteSelector = theme(`colors.${colorMap}`)
118
- ? theme(`colors.${colorMap}`)
119
- : colorMap
120
- }
121
- if (theme(`nightwind.colors.black`)) {
122
- const colorMap = theme(`nightwind.colors.black`)
123
- blackSelector = theme(`colors.${colorMap}`)
124
- ? theme(`colors.${colorMap}`)
125
- : colorMap
50
+ let rh = h[1] + h[1], gh = h[2] + h[2], bh = h[3] + h[3]
51
+ r = parseInt(rh, 16), g = parseInt(gh, 16), b = parseInt(bh, 16)
52
+ } else if (h.length == 7) {
53
+ r = parseInt(h.slice(1, 3), 16), g = parseInt(h.slice(3, 5), 16), b = parseInt(h.slice(5, 7), 16)
54
+ } else return h
55
+ return alpha ? `rgba(${r}, ${g}, ${b}, ${alpha})` : `rgb(${r}, ${g}, ${b})`
126
56
  }
127
57
 
128
58
  const invertColor = (colorClass) => {
129
59
  if (colorClass.includes("white") || colorClass.includes("black")) {
130
60
  return {
131
- colorValue: colorClass.includes("white")
132
- ? whiteSelector
133
- : blackSelector,
134
- defaultColorValue: colorClass.includes("white")
135
- ? theme("colors.white")
136
- : theme("colors.black"),
137
- }
138
- } else if (
139
- colorClass === "inherit" ||
140
- colorClass === "transparent" ||
141
- colorClass === "current"
142
- ) {
143
- return {
144
- colorValue: colorClass,
145
- defaultColorValue: colorClass,
146
- }
147
- } else {
148
- const colorValues = colorClass.split("-")
149
- const weight = colorValues.pop()
150
- const color = colorValues.pop()
151
- const defaultValue = theme(`colors.${color}.${weight}`)
152
-
153
- let invertWeightIndex = 9 - weights.indexOf(Number(weight))
154
- let invertWeight = String(weights[invertWeightIndex])
155
-
156
- if (theme("nightwind.colorScale.preset")) {
157
- switch (theme("nightwind.colorScale.preset")) {
158
- case "reduced":
159
- let reducedInvertWeightIndex =
160
- 10 - weights.indexOf(Number(weight))
161
- reducedInvertWeightIndex > 9
162
- ? (reducedInvertWeightIndex = 9)
163
- : reducedInvertWeightIndex
164
- invertWeight = String(weights[reducedInvertWeightIndex])
165
- break
166
- }
167
- } else if (theme("nightwind.colorScale")) {
168
- if (theme(`nightwind.colorScale.${weight}`)) {
169
- invertWeight = String(theme(`nightwind.colorScale.${weight}`))
170
- }
61
+ colorValue: colorClass.includes("white") ? (theme("nightwind.colors.white") ? (theme("colors." + theme("nightwind.colors.white")) || theme("nightwind.colors.white")) : "#000") : (theme("nightwind.colors.black") ? (theme("colors." + theme("nightwind.colors.black")) || theme("nightwind.colors.black")) : "#fff"),
62
+ defaultColorValue: colorClass.includes("white") ? theme("colors.white") : theme("colors.black"),
171
63
  }
64
+ }
65
+ if (["inherit", "transparent", "current"].includes(colorClass)) return { colorValue: colorClass, defaultColorValue: colorClass }
66
+
67
+ const colorValues = colorClass.split("-")
68
+ const weight = colorValues.pop()
69
+ const color = colorValues.join("-")
70
+ const defaultValue = theme(`colors.${color}.${weight}`)
71
+ if (!defaultValue) return { colorValue: null, defaultColorValue: null }
72
+
73
+ let invertWeightIndex = weights.indexOf(Number(weight))
74
+ if (invertWeightIndex === -1) return { colorValue: null, defaultColorValue: null }
75
+ invertWeightIndex = 9 - invertWeightIndex
76
+ let invertWeight = String(weights[invertWeightIndex])
77
+
78
+ if (theme("nightwind.colorScale.preset") === "reduced") {
79
+ let ri = 10 - weights.indexOf(Number(weight)); invertWeight = String(weights[ri > 9 ? 9 : ri])
80
+ } else if (theme(`nightwind.colorScale.${weight}`)) {
81
+ invertWeight = String(theme(`nightwind.colorScale.${weight}`))
82
+ }
172
83
 
173
- if (theme(`nightwind.colors.${color}.${weight}`)) {
174
- const colorMap = theme(`nightwind.colors.${color}.${weight}`)
175
- return {
176
- colorValue: theme(`colors.${colorMap}`)
177
- ? theme(`colors.${colorMap}`)
178
- : colorMap,
179
- defaultColorValue: defaultValue,
180
- }
181
- } else if (
182
- theme(`nightwind.colors.${color}`) &&
183
- typeof theme(`nightwind.colors.${color}`) === "string"
184
- ) {
185
- const colorMap = theme(`nightwind.colors.${color}`)
186
- if (theme(`colors.${colorMap}.${invertWeight}`)) {
187
- return {
188
- colorValue: theme(`colors.${colorMap}.${invertWeight}`),
189
- defaultColorValue: defaultValue,
190
- }
191
- } else if (colorMap.split(".").length === 2) {
192
- return {
193
- colorValue: theme(`colors.${colorMap}`),
194
- defaultColorValue: defaultValue,
195
- }
196
- } else if (
197
- theme(`colors.${colorMap}`) &&
198
- theme(`colors.${color}.${invertWeight}`)
199
- ) {
200
- return {
201
- colorValue: theme(`colors.${color}.${invertWeight}`),
202
- defaultColorValue: defaultValue,
203
- }
204
- } else {
205
- return {
206
- colorValue: colorMap,
207
- defaultColorValue: defaultValue,
208
- }
209
- }
210
- } else if (theme(`nightwind.colors.${color}.default`)) {
211
- const colorMap = theme(`nightwind.colors.${color}.default`)
212
- return {
213
- colorValue: theme(`colors.${colorMap}.${invertWeight}`),
214
- defaultColorValue: defaultValue,
215
- }
216
- } else {
217
- return {
218
- colorValue: theme(`colors.${color}.${invertWeight}`),
219
- defaultColorValue: defaultValue,
220
- }
221
- }
84
+ let colorValue = theme(`colors.${color}.${invertWeight}`)
85
+ if (theme(`nightwind.colors.${color}.${weight}`)) {
86
+ colorValue = theme(`colors.${theme(`nightwind.colors.${color}.${weight}`)}`) || theme(`nightwind.colors.${color}.${weight}`)
87
+ } else if (theme(`nightwind.colors.${color}`) && typeof theme(`nightwind.colors.${color}`) === "string") {
88
+ const colorMapSetting = theme(`nightwind.colors.${color}`)
89
+ colorValue = theme(`colors.${colorMapSetting}.${invertWeight}`) || theme(`colors.${colorMapSetting}`) || theme(`colors.${color}.${invertWeight}`) || colorMapSetting
222
90
  }
223
- }
224
91
 
225
- // Generate transition classes
92
+ return { colorValue, defaultColorValue: defaultValue }
93
+ }
226
94
 
227
95
  let transitionDurationValue = "400ms"
228
- if (
229
- theme("nightwind.transitionDuration") === false ||
230
- theme("transitionDuration.nightwind") === false
231
- ) {
96
+ if (theme("nightwind.transitionDuration") === false || theme("transitionDuration.nightwind") === false) {
232
97
  transitionDurationValue = ""
233
98
  } else if (typeof theme("nightwind.transitionDuration") === "string") {
234
99
  transitionDurationValue = theme("nightwind.transitionDuration")
@@ -237,536 +102,122 @@ const nightwind = plugin(
237
102
  }
238
103
 
239
104
  if (transitionDurationValue) {
240
- const transitionPrefixes = []
241
- if (transitionConfig === "full") {
242
- transitionPrefixes.push(...prefixes)
243
- } else if (
244
- typeof transitionConfig === "object" ||
245
- (typeof transitionConfig === "string" &&
246
- prefixes.includes(transitionConfig))
247
- ) {
248
- typeof transitionConfig === "object"
249
- ? transitionPrefixes.push(...transitionConfig)
250
- : transitionPrefixes.push(transitionConfig)
251
- } else {
252
- transitionPrefixes.push("text", "bg", "border")
253
- }
105
+ addBase({ ":root": { "--nightwind-transition-duration": transitionDurationValue } })
106
+ }
254
107
 
255
- Object.keys(colors).forEach((color) => {
256
- transitionPrefixes.forEach((prefix) => {
257
- if (prefix === "from" || prefix === "via" || prefix === "to") {
258
- return null
259
- }
260
- if (
261
- color == "transparent" ||
262
- color == "current" ||
263
- color == "white" ||
264
- color == "black"
265
- ) {
266
- const transitionClass = {
267
- [`${config("important") ? importantSelector : ""
268
- }.nightwind .${prefix}-${color}`]: {
269
- transitionDuration: transitionDurationValue,
270
- transitionProperty: theme("transitionProperty.colors"),
271
- transitionTimingFunction: "ease-in-out",
272
- },
273
- [`${config("important") ? importantSelector : ""
274
- }.nightwind .dark\\:${prefix}-${color}`]: {
275
- transitionDuration: transitionDurationValue,
276
- transitionProperty: theme("transitionProperty.colors"),
277
- transitionTimingFunction: "ease-in-out",
278
- },
279
- }
280
- transitionClasses.push(transitionClass)
281
- } else {
282
- weights.forEach((weight) => {
283
- const transitionClass = {
284
- [`${config("important") ? importantSelector : ""
285
- }.nightwind .${prefix}-${color}-${weight}`]: {
286
- transitionDuration: transitionDurationValue,
287
- transitionProperty: theme("transitionProperty.colors"),
288
- transitionTimingFunction: "ease-in-out",
289
- },
290
- [`${config("important") ? importantSelector : ""
291
- }.nightwind .dark\\:${prefix}-${color}-${weight}`]: {
292
- transitionDuration: transitionDurationValue,
293
- transitionProperty: theme("transitionProperty.colors"),
294
- transitionTimingFunction: "ease-in-out",
295
- },
296
- }
297
- transitionClasses.push(transitionClass)
298
- })
299
- }
300
- })
301
- })
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" }
302
129
  }
303
130
 
304
- // Invert typography
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
+ }
305
171
 
306
- if (theme("nightwind.typography")) {
307
- Object.keys(theme("typography")).forEach((modifier) => {
308
- Object.keys(theme(`typography.${modifier}.css`)).forEach((n) => {
309
- const themeParser = JSON.parse(
310
- JSON.stringify(theme(`typography.${modifier}.css[${n}]`))
311
- )
312
- Object.keys(themeParser).forEach((classname) => {
313
- const themeClass = themeParser[classname]
314
- if (
315
- typeof themeClass === "string" &&
316
- (classname.includes("color") || classname.includes("Color"))
317
- ) {
318
- const colorValue = hexToTailwind(themeClass)
319
- if (!typographyValues[`${modifier}`]) {
320
- typographyValues[`${modifier}`] = {}
321
- }
322
- if (!typographyValues[`${modifier}`]["prose"]) {
323
- typographyValues[`${modifier}`]["prose"] = {}
324
- }
325
- typographyValues[`${modifier}`]["prose"][classname] = colorValue
326
- } else if (typeof themeClass === "object") {
327
- Object.keys(themeClass).forEach((property) => {
328
- const themeProperty = themeClass[property]
329
- if (
330
- (typeof themeProperty === "string" &&
331
- property.includes("color")) ||
332
- property.includes("Color")
333
- ) {
334
- const colorValue = hexToTailwind(themeProperty)
335
- if (!typographyValues[`${modifier}`]) {
336
- typographyValues[`${modifier}`] = {}
337
- }
338
- if (!typographyValues[`${modifier}`][`${classname}`]) {
339
- typographyValues[`${modifier}`][`${classname}`] = {}
340
- }
341
- typographyValues[`${modifier}`][`${classname}`][property] =
342
- colorValue
343
- }
344
- })
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" }
345
176
  }
346
177
  })
347
178
  })
348
179
  })
180
+ })
349
181
 
350
- Object.keys(typographyValues).forEach((modifier) => {
351
- Object.keys(typographyValues[modifier]).forEach((classname) => {
352
- if (classname === "prose") {
353
- Object.keys(typographyValues[modifier]["prose"]).forEach(
354
- (property) => {
355
- let themeValue = ""
356
- let nightwindValue = ""
357
- if (modifier === "DEFAULT") {
358
- nightwindValue = theme(`nightwind.typography.${property}`)
359
- } else {
360
- nightwindValue = theme(
361
- `nightwind.typography.${modifier}.${property}`
362
- )
363
- }
364
- theme(`colors.${nightwindValue}`)
365
- ? (themeValue = theme(`colors.${nightwindValue}`))
366
- : (themeValue = nightwindValue)
367
-
368
- const colorValue = themeValue
369
- ? themeValue
370
- : invertColor(typographyValues[modifier]["prose"][property])
371
- .colorValue
372
- const defaultColorValue = invertColor(
373
- typographyValues[modifier]["prose"][property]
374
- ).defaultColorValue
375
-
376
- const typographyClass = {
377
- [`${importantSelector}${darkSelector} .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
378
- }`]: {
379
- [`${property}`]: colorValue,
380
- },
381
- [`${importantSelector}${darkSelector} ${fixedElementClass}.prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
382
- }`]: {
383
- [`${property}`]: defaultColorValue,
384
- },
385
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
386
- }`]: {
387
- [`${property}`]: defaultColorValue,
388
- },
389
- }
390
- typographyClasses.push(typographyClass)
391
-
392
- if (transitionDurationValue) {
393
- const typographyTransitionClass = {
394
- [`${config("important") ? importantSelector : ""
395
- }.nightwind .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
396
- }`]: {
397
- transitionDuration: transitionDurationValue,
398
- transitionProperty: theme("transitionProperty.colors"),
399
- transitionTimingFunction: "ease-in-out",
400
- },
401
- [`${config("important") ? importantSelector : ""
402
- }.nightwind .dark\\:prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
403
- }`]: {
404
- transitionDuration: transitionDurationValue,
405
- transitionProperty: theme("transitionProperty.colors"),
406
- transitionTimingFunction: "ease-in-out",
407
- },
408
- }
409
- transitionClasses.push(typographyTransitionClass)
410
- }
411
- }
412
- )
413
- } else {
414
- Object.keys(typographyValues[modifier][classname]).forEach(
415
- (property) => {
416
- let themeValue = ""
417
- let nightwindValue = ""
418
- if (modifier === "DEFAULT") {
419
- nightwindValue = theme(
420
- `nightwind.typography.${classname}.${property}`
421
- )
422
- } else {
423
- nightwindValue = theme(
424
- `nightwind.typography.${modifier}.${classname}.${property}`
425
- )
426
- }
427
- theme(`colors.${nightwindValue}`)
428
- ? (themeValue = theme(`colors.${nightwindValue}`))
429
- : (themeValue = nightwindValue)
430
-
431
- const colorValue = themeValue
432
- ? themeValue
433
- : invertColor(typographyValues[modifier][classname][property])
434
- .colorValue
435
- const defaultColorValue = invertColor(
436
- typographyValues[modifier][classname][property]
437
- ).defaultColorValue
182
+ addComponents(nightwindClasses)
438
183
 
439
- const typographyClass = {
440
- [`${importantSelector}${darkSelector} .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
441
- } ${classname}`]: {
442
- [`${property}`]: colorValue,
443
- },
444
- [`${importantSelector}${darkSelector} .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
445
- } ${classname}${fixedElementClass}`]: {
446
- [`${property}`]: defaultColorValue,
447
- },
448
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
449
- } ${classname}`]: {
450
- [`${property}`]: defaultColorValue,
451
- },
452
- [`${importantSelector}${darkSelector} .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
453
- } ${fixedBlockClass} ${classname}`]: {
454
- [`${property}`]: defaultColorValue,
455
- },
456
- }
457
- typographyClasses.push(typographyClass)
458
- if (transitionDurationValue) {
459
- const typographyTransitionClass = {
460
- [`${config("important") ? importantSelector : ""
461
- }.nightwind .prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
462
- } ${classname}`]: {
463
- transitionDuration: transitionDurationValue,
464
- transitionProperty: theme("transitionProperty.colors"),
465
- transitionTimingFunction: "ease-in-out",
466
- },
467
- [`${config("important") ? importantSelector : ""
468
- }.nightwind .dark\\:prose${modifier !== "DEFAULT" ? `-${modifier}` : ""
469
- } ${classname}`]: {
470
- transitionDuration: transitionDurationValue,
471
- transitionProperty: theme("transitionProperty.colors"),
472
- transitionTimingFunction: "ease-in-out",
473
- },
474
- }
475
- transitionClasses.push(typographyTransitionClass)
476
- }
477
- }
478
- )
479
- }
480
- })
481
- })
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"
482
187
  }
483
-
484
- // Compose color classes
485
-
486
- prefixes.forEach((prefix) => {
487
- Object.keys(colors).forEach((color) => {
488
- if (color == "white" || color == "black") {
489
- let base = prefix + "-" + color
490
- colorClasses.push(base)
491
-
492
- colorVariants.forEach((variant) => {
493
- let baseVar = variant + "\\:" + prefix + "-" + color
494
- colorClasses.push(baseVar)
495
- })
496
- } else {
497
- return false
498
- }
499
- })
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
+ )
500
200
  })
501
201
 
502
- prefixes.forEach((prefix) => {
503
- Object.keys(colors).forEach((color) => {
504
- if (
505
- color == "transparent" ||
506
- color == "current" ||
507
- color == "white" ||
508
- color == "black"
509
- ) {
510
- return false
511
- } else if (typeof colors[color] !== "object") {
512
- // Flat custom colors (e.g. { "custom-hex": "#1a2b3c" })
513
- let base = prefix + "-" + color
514
- colorClasses.push(base)
515
-
516
- colorVariants.forEach((variant) => {
517
- let baseVar = variant + "\\:" + prefix + "-" + color
518
- colorClasses.push(baseVar)
519
- })
520
- } else {
521
- // Nested colors (e.g. { "red": { "500": "#ef4444" } })
522
- weights.forEach((weight) => {
523
- let base = prefix + "-" + color + "-" + weight
524
- colorClasses.push(base)
525
-
526
- colorVariants.forEach((variant) => {
527
- let baseVar =
528
- variant + "\\:" + prefix + "-" + color + "-" + weight
529
- colorClasses.push(baseVar)
530
- })
202
+ if (theme("nightwind.typography")) {
203
+ Object.keys(theme("typography") || {}).forEach((modifier) => {
204
+ const css = theme(`typography.${modifier}.css`) || []
205
+ css.forEach(n => {
206
+ Object.keys(n).forEach(classname => {
207
+ const colorProp = Object.keys(n[classname]).find(p => p.includes("color") || p.includes("Color"))
208
+ if (colorProp) {
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 } })
214
+ }
531
215
  })
532
- }
533
- })
534
- })
535
-
536
- // Generate dark classes
537
-
538
- const nightwindClasses = colorClasses.map((colorClass) => {
539
- let pseudoVariant = ""
540
-
541
- colorVariants.forEach((variant) => {
542
- if (colorClass.includes(variant)) {
543
- if (variant == "last" || variant == "first") {
544
- pseudoVariant = ":" + variant + "-child"
545
- } else if (variant == "odd") {
546
- pseudoVariant = ":nth-child(odd)"
547
- } else if (variant == "even") {
548
- pseudoVariant = ":nth-child(2n)"
549
- } else if (variant == "group-hover") {
550
- pseudoVariant = ""
551
- } else {
552
- pseudoVariant = ":" + variant
553
- }
554
- }
216
+ })
555
217
  })
556
-
557
- let colorValue = invertColor(colorClass).colorValue
558
- let defaultColorValue = invertColor(colorClass).defaultColorValue
559
-
560
- const generateClass = (prefix, property) => {
561
- // Here we rely on Tailwind dynamically falling back to the configured
562
- // --tw-xxx-opacity variable, which it natively defines when an opacity modifier is used
563
- const twOpacityVar = `var(--tw-${prefix})`
564
- return {
565
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}`]:
566
- {
567
- [`${property}`]: colorValue + importantProperty,
568
- [`${property}`]:
569
- hexToRGB(`${colorValue}`, twOpacityVar) +
570
- importantProperty,
571
- },
572
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}${fixedElementClass}`]:
573
- {
574
- [`${property}`]: defaultColorValue + importantProperty,
575
- [`${property}`]:
576
- hexToRGB(`${defaultColorValue}`, twOpacityVar) +
577
- importantProperty,
578
- },
579
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}\\/\\*${pseudoVariant}`]:
580
- {
581
- [`${property}`]: defaultColorValue + importantProperty,
582
- [`${property}`]:
583
- hexToRGB(`${defaultColorValue}`, twOpacityVar) +
584
- importantProperty,
585
- },
586
- }
587
- }
588
-
589
- if (
590
- colorVariants.includes("group-hover") &&
591
- colorClass.includes("group-hover\\:")
592
- ) {
593
- const originalColorClass = colorClass
594
- colorClass = "group:hover ." + originalColorClass
595
- }
596
-
597
- if (
598
- colorVariants.includes("group-focus") &&
599
- colorClass.includes("group-focus\\:")
600
- ) {
601
- const originalColorClass = colorClass
602
- colorClass = "group:focus ." + originalColorClass
603
- }
604
-
605
- if (colorClass.includes("text-")) {
606
- return generateClass("text-opacity", "color")
607
- } else if (colorClass.includes("bg-")) {
608
- return generateClass("bg-opacity", "backgroundColor")
609
- } else if (colorClass.includes("border-")) {
610
- return generateClass("border-opacity", "borderColor")
611
- } else if (colorClass.includes("ring-")) {
612
- return generateClass("ring-opacity", "--tw-ring-color")
613
- } else if (colorClass.includes("divide-")) {
614
- const twOpacityVar = `var(--tw-divide-opacity)`
615
- return {
616
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden]), ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]:
617
- {
618
- borderColor: colorValue + importantProperty,
619
- borderColor:
620
- hexToRGB(`${colorValue}`, twOpacityVar) +
621
- importantProperty,
622
- },
623
- [`${importantSelector}${darkSelector} ${fixedElementClass}.${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden]), ${importantSelector}${darkSelector} ${fixedElementClass}.${colorClass}\\/\\*${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]:
624
- {
625
- borderColor: defaultColorValue + importantProperty,
626
- borderColor:
627
- hexToRGB(`${defaultColorValue}`, twOpacityVar) +
628
- importantProperty,
629
- },
630
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden]), ${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}\\/\\*${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]:
631
- {
632
- borderColor: defaultColorValue + importantProperty,
633
- borderColor:
634
- hexToRGB(`${defaultColorValue}`, twOpacityVar) +
635
- importantProperty,
636
- },
637
- }
638
- } else if (colorClass.includes("placeholder-")) {
639
- const twOpacityVar = `var(--tw-text-opacity)`
640
- return {
641
- [`${importantSelector}${darkSelector} .${colorClass}::placeholder, ${importantSelector}${darkSelector} .${colorClass}\\/\\*::placeholder`]: {
642
- color: colorValue + importantProperty,
643
- color:
644
- hexToRGB(`${colorValue}`, twOpacityVar) +
645
- importantProperty,
646
- },
647
- [`${importantSelector}${darkSelector} ${fixedElementClass}.${colorClass}::placeholder, ${importantSelector}${darkSelector} ${fixedElementClass}.${colorClass}\\/\\*::placeholder`]:
648
- {
649
- color: defaultColorValue + importantProperty,
650
- color:
651
- hexToRGB(`${defaultColorValue}`, twOpacityVar) +
652
- importantProperty,
653
- },
654
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}::placeholder, ${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}\\/\\*::placeholder`]:
655
- {
656
- color: defaultColorValue + importantProperty,
657
- color:
658
- hexToRGB(`${defaultColorValue}`, twOpacityVar) +
659
- importantProperty,
660
- },
661
- }
662
- } else if (colorClass.includes("ring-offset-")) {
663
- return {
664
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}`]:
665
- {
666
- "--tw-ring-offset-color": colorValue + importantProperty,
667
- },
668
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}${fixedElementClass}`]:
669
- {
670
- "--tw-ring-offset-color": defaultColorValue + importantProperty,
671
- },
672
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}\\/\\*${pseudoVariant}`]:
673
- {
674
- "--tw-ring-offset-color": defaultColorValue + importantProperty,
675
- },
676
- }
677
- } else if (colorClass.includes("from-")) {
678
- return {
679
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}`]:
680
- {
681
- "--tw-gradient-from": colorValue + importantProperty,
682
- "--tw-gradient-stops":
683
- `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(
684
- `${colorValue}`,
685
- "0"
686
- )})` + importantProperty,
687
- },
688
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}${fixedElementClass}`]:
689
- {
690
- "--tw-gradient-from": defaultColorValue + importantProperty,
691
- "--tw-gradient-stops":
692
- `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(
693
- `${defaultColorValue}`,
694
- "0"
695
- )})` + importantProperty,
696
- },
697
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}\\/\\*${pseudoVariant}`]:
698
- {
699
- "--tw-gradient-from": defaultColorValue + importantProperty,
700
- "--tw-gradient-stops":
701
- `var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(
702
- `${defaultColorValue}`,
703
- "0"
704
- )})` + importantProperty,
705
- },
706
- }
707
- } else if (colorClass.includes("via-")) {
708
- return {
709
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}`]:
710
- {
711
- "--tw-gradient-stops":
712
- `var(--tw-gradient-from), ${colorValue}, var(--tw-gradient-to, ${hexToRGB(
713
- `${colorValue}`,
714
- "0"
715
- )})` + importantProperty,
716
- },
717
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}${fixedElementClass}`]:
718
- {
719
- "--tw-gradient-stops":
720
- `var(--tw-gradient-from), ${defaultColorValue}, var(--tw-gradient-to, ${hexToRGB(
721
- `${defaultColorValue}`,
722
- "0"
723
- )})` + importantProperty,
724
- },
725
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}\\/\\*${pseudoVariant}`]:
726
- {
727
- "--tw-gradient-stops":
728
- `var(--tw-gradient-from), ${defaultColorValue}, var(--tw-gradient-to, ${hexToRGB(
729
- `${defaultColorValue}`,
730
- "0"
731
- )})` + importantProperty,
732
- },
733
- }
734
- } else if (colorClass.includes("to-")) {
735
- return {
736
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}`]:
737
- {
738
- "--tw-gradient-to": colorValue + importantProperty,
739
- },
740
- [`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}, ${importantSelector}${darkSelector} .${colorClass}\\/\\*${pseudoVariant}${fixedElementClass}`]:
741
- {
742
- "--tw-gradient-to": defaultColorValue + importantProperty,
743
- },
744
- [`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}, ${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}\\/\\*${pseudoVariant}`]:
745
- {
746
- "--tw-gradient-to": defaultColorValue + importantProperty,
747
- },
748
- }
749
- }
750
- })
751
-
752
- addComponents(nightwindClasses, { variants: ["responsive"] })
753
- addComponents(typographyClasses)
754
- theme("nightwind.importantNode")
755
- ? addComponents(transitionClasses, { variants: ["responsive"] })
756
- : addUtilities(transitionClasses, { variants: ["responsive"] })
757
- },
758
- {
759
- theme: {
760
- extend: {
761
- transitionDuration: {
762
- 0: "0ms",
763
- },
764
- },
765
- },
218
+ }
766
219
  },
767
- {
768
- purge: ["./node_modules/nightwind/**/*.js"],
769
- }
220
+ { theme: { extend: { transitionDuration: { 0: "0ms" } } } }
770
221
  )
771
222
 
772
223
  module.exports = nightwind