@thiagormoreira/nightwind 1.1.13 → 1.2.0
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.
- package/.github/workflows/ci.yml +35 -0
- package/.prettierrc +7 -0
- package/README.md +30 -80
- package/__tests__/helper.test.js +100 -0
- package/__tests__/index.test.js +60 -0
- package/eslint.config.js +24 -0
- package/helper.js +22 -63
- package/jest.config.js +8 -0
- package/package.json +14 -2
- package/src/index.js +133 -114
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: CI Workflow
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- master
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
node-version: [16.x, 18.x, 20.x]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout code
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
23
|
+
uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: ${{ matrix.node-version }}
|
|
26
|
+
cache: 'npm'
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm ci
|
|
30
|
+
|
|
31
|
+
- name: Run ESLint
|
|
32
|
+
run: npm run lint
|
|
33
|
+
|
|
34
|
+
- name: Run Tests
|
|
35
|
+
run: npm run test
|
package/.prettierrc
ADDED
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
|
+
IMPORTANT: This repository is a maintained fork of the original "nightwind" project (https://github.com/jjranalli/nightwind). The original package was abandoned by its author. I (thiagormoreira) forked the project and will continue maintaining and publishing updates, fixes and compatibility improvements here.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
3
7
|
A Tailwind CSS plugin that gives you an **out-of-the-box, customisable, overridable dark mode.**
|
|
4
8
|
|
|
5
9
|
---
|
|
@@ -123,7 +127,7 @@ export default function Navbar() {
|
|
|
123
127
|
|
|
124
128
|
### BeforeTransition
|
|
125
129
|
|
|
126
|
-
Nightwind also exports a `beforeTransition` function that you can leverage in case you prefer to build your own toggle functions. It prevents unwanted transitions as a side-effect of having nightwind
|
|
130
|
+
Nightwind also exports a `beforeTransition` function that you can leverage in case you prefer to build your own toggle functions. It prevents unwanted transitions as a side-effect of having nightwind [...]
|
|
127
131
|
|
|
128
132
|
Check out the `toggle` function in the [Nextjs example below](#examples) for an example of how this could be implemented.
|
|
129
133
|
|
|
@@ -227,11 +231,10 @@ export default function Navbar() {
|
|
|
227
231
|
|
|
228
232
|
</details>
|
|
229
233
|
|
|
230
|
-
|
|
231
234
|
<details>
|
|
232
235
|
<summary>Pure JavaScript or Alpine.js</summary>
|
|
233
236
|
|
|
234
|
-
The whole idea is to deconstruct helper.js, converting it from a module to a var. And unpacking the 'init' function from within helper to be its own script body to execut at DOM render. Here is the
|
|
237
|
+
The whole idea is to deconstruct helper.js, converting it from a module to a var. And unpacking the 'init' function from within helper to be its own script body to execut at DOM render. Here is the co[...]
|
|
235
238
|
|
|
236
239
|
```js
|
|
237
240
|
<script>
|
|
@@ -248,20 +251,20 @@ var nightwind = {
|
|
|
248
251
|
}
|
|
249
252
|
},
|
|
250
253
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
254
|
+
toggle: () => {
|
|
255
|
+
nightwind.beforeTransition();
|
|
256
|
+
if (!document.documentElement.classList.contains('dark')) {
|
|
257
|
+
document.documentElement.classList.add('dark');
|
|
258
|
+
window.localStorage.setItem('nightwind-mode', 'dark');
|
|
259
|
+
} else {
|
|
260
|
+
document.documentElement.classList.remove('dark');
|
|
261
|
+
window.localStorage.setItem('nightwind-mode', 'light');
|
|
262
|
+
}
|
|
263
|
+
},
|
|
261
264
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
+
enable: (dark) => {
|
|
266
|
+
const mode = dark ? "dark" : "light";
|
|
267
|
+
const opposite = dark ? "light" : "dark";
|
|
265
268
|
|
|
266
269
|
nightwind.beforeTransition();
|
|
267
270
|
|
|
@@ -270,9 +273,11 @@ var nightwind = {
|
|
|
270
273
|
}
|
|
271
274
|
document.documentElement.classList.add(mode);
|
|
272
275
|
window.localStorage.setItem('nightwind-mode', mode);
|
|
273
|
-
|
|
274
|
-
|
|
276
|
+
|
|
277
|
+
},
|
|
278
|
+
}
|
|
275
279
|
</script>
|
|
280
|
+
|
|
276
281
|
<script>
|
|
277
282
|
(function() {
|
|
278
283
|
function getInitialColorMode() {
|
|
@@ -291,7 +296,8 @@ var nightwind = {
|
|
|
291
296
|
getInitialColorMode() == 'light' ? document.documentElement.classList.remove('dark') : document.documentElement.classList.add('dark');
|
|
292
297
|
})()
|
|
293
298
|
</script>
|
|
294
|
-
|
|
299
|
+
|
|
300
|
+
````
|
|
295
301
|
|
|
296
302
|
</details>
|
|
297
303
|
|
|
@@ -323,7 +329,7 @@ You can also extend Nightwind to other classes and variants:
|
|
|
323
329
|
|
|
324
330
|
Nightwind switches between opposite color weights when switching to dark mode. So a -50 color gets switched with a -900 color, -100 with -800 and so forth.
|
|
325
331
|
|
|
326
|
-
> Note: Except for the -50 and -900 weights, the sum of opposite weights is always 900. To customise how Nightwind inverts colors by default, see [how to set up a custom color scale](#custom-color-
|
|
332
|
+
> Note: Except for the -50 and -900 weights, the sum of opposite weights is always 900. To customise how Nightwind inverts colors by default, see [how to set up a custom color scale](#custom-color-sca[...])
|
|
327
333
|
|
|
328
334
|
If you add your custom colors in tailwind.config.js using number notation, Nightwind will treat them the same way as Tailwind's colors when switching into dark mode.
|
|
329
335
|
|
|
@@ -343,7 +349,7 @@ module.exports = {
|
|
|
343
349
|
},
|
|
344
350
|
},
|
|
345
351
|
}
|
|
346
|
-
|
|
352
|
+
````
|
|
347
353
|
|
|
348
354
|
Check out [**color mappings**](#color-mappings) to see how to further customize your dark theme.
|
|
349
355
|
|
|
@@ -381,7 +387,7 @@ If you want an element to remain exactly the same in both light and dark modes,
|
|
|
381
387
|
|
|
382
388
|
> Note: if you only want some of the colors to remain unchanged, consider using [overrides](#overrides).
|
|
383
389
|
|
|
384
|
-
To prevent all children of an element to remain unchanged in dark mode, you can add the **'nightwind-prevent-block'** class to the element. All descandant nodes of the element will be prevented from
|
|
390
|
+
To prevent all children of an element to remain unchanged in dark mode, you can add the **'nightwind-prevent-block'** class to the element. All descandant nodes of the element will be prevented from s[...]
|
|
385
391
|
|
|
386
392
|
You can customize the name of both classes in your tailwind.config.js file
|
|
387
393
|
|
|
@@ -433,7 +439,7 @@ module.exports = {
|
|
|
433
439
|
|
|
434
440
|
Nightwind by default generates transition classes for 'text', 'bg' and 'border' color classes. This should make most elements transition smoothly without affecting performances.
|
|
435
441
|
|
|
436
|
-
In your configuration file you can also set the **transitionClasses** property to 'full' to enable generation of transition classes for all color classes used throughout your website (i.e. rings,
|
|
442
|
+
In your configuration file you can also set the **transitionClasses** property to 'full' to enable generation of transition classes for all color classes used throughout your website (i.e. rings, divi[...]
|
|
437
443
|
|
|
438
444
|
```js
|
|
439
445
|
// tailwind.config.js
|
|
@@ -656,60 +662,4 @@ module.exports = {
|
|
|
656
662
|
},
|
|
657
663
|
},
|
|
658
664
|
}
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
## Overrides
|
|
662
|
-
|
|
663
|
-
The default dark variant allows you to write classes like 'dark:bg-gray-200' (not necessarily related to color classes) that only gets applied when you switch into dark mode.
|
|
664
|
-
|
|
665
|
-
The 'dark' variant can be used to override the automatic Nightwind classes.
|
|
666
|
-
|
|
667
|
-
```html
|
|
668
|
-
<h2 class="text-gray-900 dark:text-yellow-200">I'm yellow in dark mode</h2>
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
> Note: The 'dark' variant can also be concatenated with both screens and other variants, so you can write classes like 'sm:dark:hover:text-yellow-200'.
|
|
672
|
-
|
|
673
|
-
Please refer to the [Tailwind official documentation](https://tailwindcss.com/docs/dark-mode) to learn more about the 'dark' variant.
|
|
674
|
-
|
|
675
|
-
## Typography
|
|
676
|
-
|
|
677
|
-
If you're using the [Typography plugin](https://github.com/tailwindlabs/tailwindcss-typography), you can let Nightwind build an automatic dark mode of all typography color styles.
|
|
678
|
-
|
|
679
|
-
> Note: It will respect all customizations and [color mappings](#color-mappings) specified in your nightwind configuration.
|
|
680
|
-
|
|
681
|
-
Simply add the following line in your Nightwind theme configuration:
|
|
682
|
-
|
|
683
|
-
```js
|
|
684
|
-
// tailwind.config.js
|
|
685
|
-
module.exports = {
|
|
686
|
-
theme: {
|
|
687
|
-
nightwind: {
|
|
688
|
-
typography: true,
|
|
689
|
-
},
|
|
690
|
-
},
|
|
691
|
-
}
|
|
692
|
-
```
|
|
693
|
-
|
|
694
|
-
To fine-tune your typography dark mode, you can define the single classes by using the [individual color syntax](#individual-colors) (either hex or tailwind-based color codes).
|
|
695
|
-
|
|
696
|
-
```js
|
|
697
|
-
// tailwind.config.js
|
|
698
|
-
module.exports = {
|
|
699
|
-
theme: {
|
|
700
|
-
nightwind: {
|
|
701
|
-
typography: {
|
|
702
|
-
color: "blue.400",
|
|
703
|
-
h1: {
|
|
704
|
-
color: "#90e0ef",
|
|
705
|
-
},
|
|
706
|
-
indigo: {
|
|
707
|
-
a: {
|
|
708
|
-
color: "purple.300",
|
|
709
|
-
},
|
|
710
|
-
},
|
|
711
|
-
},
|
|
712
|
-
},
|
|
713
|
-
},
|
|
714
|
-
}
|
|
715
|
-
```
|
|
665
|
+
```
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const helper = require("../helper.js")
|
|
2
|
+
|
|
3
|
+
describe("nightwind/helper", () => {
|
|
4
|
+
let originalMatchMedia
|
|
5
|
+
let originalLocalStorage
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
// Mock for localStorage
|
|
9
|
+
const localStorageMock = (() => {
|
|
10
|
+
let store = {}
|
|
11
|
+
return {
|
|
12
|
+
getItem: (key) => store[key] || null,
|
|
13
|
+
setItem: (key, value) => {
|
|
14
|
+
store[key] = value.toString()
|
|
15
|
+
},
|
|
16
|
+
clear: () => {
|
|
17
|
+
store = {}
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
})()
|
|
21
|
+
|
|
22
|
+
// Mock for matchMedia
|
|
23
|
+
const matchMediaMock = jest.fn().mockImplementation((query) => ({
|
|
24
|
+
matches: false,
|
|
25
|
+
media: query,
|
|
26
|
+
onchange: null,
|
|
27
|
+
addListener: jest.fn(),
|
|
28
|
+
removeListener: jest.fn(),
|
|
29
|
+
addEventListener: jest.fn(),
|
|
30
|
+
removeEventListener: jest.fn(),
|
|
31
|
+
dispatchEvent: jest.fn(),
|
|
32
|
+
}))
|
|
33
|
+
|
|
34
|
+
originalMatchMedia = window.matchMedia
|
|
35
|
+
originalLocalStorage = window.localStorage
|
|
36
|
+
|
|
37
|
+
Object.defineProperty(window, "localStorage", {
|
|
38
|
+
value: localStorageMock,
|
|
39
|
+
writable: true,
|
|
40
|
+
})
|
|
41
|
+
Object.defineProperty(window, "matchMedia", {
|
|
42
|
+
value: matchMediaMock,
|
|
43
|
+
writable: true,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
document.documentElement.className = ""
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
window.matchMedia = originalMatchMedia
|
|
51
|
+
window.localStorage = originalLocalStorage
|
|
52
|
+
jest.clearAllMocks()
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
describe("init()", () => {
|
|
56
|
+
it("should return the initialization script logic", () => {
|
|
57
|
+
const script = helper.init()
|
|
58
|
+
expect(typeof script).toBe("string")
|
|
59
|
+
expect(script).toContain("getInitialColorMode")
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe("toggle()", () => {
|
|
64
|
+
it("should toggle to 'dark' when current is not 'dark'", () => {
|
|
65
|
+
helper.toggle()
|
|
66
|
+
expect(document.documentElement.classList.contains("dark")).toBe(true)
|
|
67
|
+
expect(window.localStorage.getItem("nightwind-mode")).toBe("dark")
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it("should toggle to 'light' when current is 'dark'", () => {
|
|
71
|
+
document.documentElement.classList.add("dark")
|
|
72
|
+
helper.toggle()
|
|
73
|
+
expect(document.documentElement.classList.contains("dark")).toBe(false)
|
|
74
|
+
expect(window.localStorage.getItem("nightwind-mode")).toBe("light")
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it("should add nightwind transition class", () => {
|
|
78
|
+
helper.toggle()
|
|
79
|
+
expect(document.documentElement.classList.contains("nightwind")).toBe(
|
|
80
|
+
true
|
|
81
|
+
)
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
describe("enable()", () => {
|
|
86
|
+
it("should enable 'dark' mode", () => {
|
|
87
|
+
helper.enable(true)
|
|
88
|
+
expect(document.documentElement.classList.contains("dark")).toBe(true)
|
|
89
|
+
expect(window.localStorage.getItem("nightwind-mode")).toBe("dark")
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it("should enable 'light' mode", () => {
|
|
93
|
+
document.documentElement.classList.add("dark")
|
|
94
|
+
helper.enable(false)
|
|
95
|
+
expect(document.documentElement.classList.contains("light")).toBe(true)
|
|
96
|
+
expect(document.documentElement.classList.contains("dark")).toBe(false)
|
|
97
|
+
expect(window.localStorage.getItem("nightwind-mode")).toBe("light")
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
50: "#fef2f2",
|
|
15
|
+
300: "#fca5a5",
|
|
16
|
+
600: "#dc2626",
|
|
17
|
+
900: "#7f1d1d",
|
|
18
|
+
},
|
|
19
|
+
blue: {
|
|
20
|
+
300: "#93c5fd",
|
|
21
|
+
500: "#3b82f6",
|
|
22
|
+
600: "#2563eb",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
plugins: [nightwind],
|
|
28
|
+
...config,
|
|
29
|
+
}),
|
|
30
|
+
]).process("@tailwind utilities; @tailwind components;", {
|
|
31
|
+
from: undefined,
|
|
32
|
+
})
|
|
33
|
+
return result.css
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe("nightwind plugin", () => {
|
|
37
|
+
it("should invert background classes", async () => {
|
|
38
|
+
const css = await generateCss('<div class="bg-red-600"></div>')
|
|
39
|
+
expect(css).toContain(".dark .bg-red-600")
|
|
40
|
+
// For tailwind 3.x with JIT, it generates the specific utility and the dark version
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it("should invert text classes", async () => {
|
|
44
|
+
const css = await generateCss('<div class="text-blue-300"></div>')
|
|
45
|
+
expect(css).toContain(".dark .text-blue-300")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("should handle white and black backgrounds", async () => {
|
|
49
|
+
const css = await generateCss('<div class="bg-white text-black"></div>')
|
|
50
|
+
expect(css).toContain(".dark .bg-white")
|
|
51
|
+
expect(css).toContain(".dark .text-black")
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it("should generate prevent switch classes", async () => {
|
|
55
|
+
const css = await generateCss(
|
|
56
|
+
'<div class="bg-red-600 nightwind-prevent"></div>'
|
|
57
|
+
)
|
|
58
|
+
expect(css).toContain(".nightwind-prevent")
|
|
59
|
+
})
|
|
60
|
+
})
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const jestPlugin = require("eslint-plugin-jest");
|
|
2
|
+
|
|
3
|
+
module.exports = [
|
|
4
|
+
jestPlugin.configs["flat/recommended"],
|
|
5
|
+
{
|
|
6
|
+
languageOptions: {
|
|
7
|
+
ecmaVersion: 2021,
|
|
8
|
+
sourceType: "commonjs",
|
|
9
|
+
globals: {
|
|
10
|
+
require: true,
|
|
11
|
+
module: true,
|
|
12
|
+
window: true,
|
|
13
|
+
document: true,
|
|
14
|
+
console: true,
|
|
15
|
+
__dirname: true
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
rules: {
|
|
19
|
+
"no-unused-vars": "warn",
|
|
20
|
+
"no-undef": "error",
|
|
21
|
+
"jest/expect-expect": "warn"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
];
|
package/helper.js
CHANGED
|
@@ -17,84 +17,43 @@ module.exports = {
|
|
|
17
17
|
}
|
|
18
18
|
getInitialColorMode() == 'light' ? document.documentElement.classList.remove('dark') : document.documentElement.classList.add('dark');
|
|
19
19
|
})()
|
|
20
|
-
|
|
21
|
-
return codeToRunOnClient
|
|
20
|
+
`
|
|
21
|
+
return codeToRunOnClient
|
|
22
22
|
},
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
beforeTransition: () => {
|
|
25
|
-
const doc = document.documentElement
|
|
25
|
+
const doc = document.documentElement
|
|
26
26
|
const onTransitionDone = () => {
|
|
27
|
-
doc.classList.remove(
|
|
28
|
-
doc.removeEventListener(
|
|
27
|
+
doc.classList.remove("nightwind")
|
|
28
|
+
doc.removeEventListener("transitionend", onTransitionDone)
|
|
29
29
|
}
|
|
30
|
-
doc.addEventListener(
|
|
31
|
-
if (!doc.classList.contains(
|
|
32
|
-
doc.classList.add(
|
|
30
|
+
doc.addEventListener("transitionend", onTransitionDone)
|
|
31
|
+
if (!doc.classList.contains("nightwind")) {
|
|
32
|
+
doc.classList.add("nightwind")
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
|
|
36
36
|
toggle: () => {
|
|
37
|
-
module.exports.beforeTransition()
|
|
38
|
-
if (!document.documentElement.classList.contains(
|
|
39
|
-
document.documentElement.classList.add(
|
|
40
|
-
window.localStorage.setItem(
|
|
37
|
+
module.exports.beforeTransition()
|
|
38
|
+
if (!document.documentElement.classList.contains("dark")) {
|
|
39
|
+
document.documentElement.classList.add("dark")
|
|
40
|
+
window.localStorage.setItem("nightwind-mode", "dark")
|
|
41
41
|
} else {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
document.documentElement.classList.remove("dark")
|
|
43
|
+
window.localStorage.setItem("nightwind-mode", "light")
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
enable: (dark) => {
|
|
48
|
-
const mode = dark ? "dark" : "light"
|
|
49
|
-
const opposite = dark ? "light" : "dark"
|
|
48
|
+
const mode = dark ? "dark" : "light"
|
|
49
|
+
const opposite = dark ? "light" : "dark"
|
|
50
50
|
|
|
51
|
-
module.exports.beforeTransition()
|
|
51
|
+
module.exports.beforeTransition()
|
|
52
52
|
|
|
53
53
|
if (document.documentElement.classList.contains(opposite)) {
|
|
54
|
-
document.documentElement.classList.remove(opposite)
|
|
55
|
-
}
|
|
56
|
-
document.documentElement.classList.add(mode);
|
|
57
|
-
window.localStorage.setItem('nightwind-mode', mode);
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
// Old
|
|
61
|
-
|
|
62
|
-
checkNightMode: () => {
|
|
63
|
-
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
watchNightMode: () => {
|
|
67
|
-
if (!window.matchMedia) return;
|
|
68
|
-
window.matchMedia('(prefers-color-scheme: dark)').addListener(module.exports.addNightModeSelector());
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
addNightModeSelector: () => {
|
|
72
|
-
if (module.exports.checkNightMode()) {
|
|
73
|
-
document.documentElement.classList.add('dark');
|
|
74
|
-
} else {
|
|
75
|
-
document.documentElement.classList.remove('dark');
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
addNightTransitions: () => {
|
|
80
|
-
if (!document.documentElement.classList.contains('nightwind')) {
|
|
81
|
-
document.documentElement.classList.add('nightwind');
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
initNightwind: () => {
|
|
86
|
-
module.exports.watchNightMode();
|
|
87
|
-
module.exports.addNightModeSelector();
|
|
88
|
-
module.exports.addNightTransitions();
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
toggleNightMode: () => {
|
|
92
|
-
if (!document.documentElement.classList.contains('dark')) {
|
|
93
|
-
document.documentElement.classList.add('dark');
|
|
94
|
-
window.localStorage.setItem('nightwind-mode', 'dark');
|
|
95
|
-
} else {
|
|
96
|
-
document.documentElement.classList.remove('dark');
|
|
97
|
-
window.localStorage.setItem('nightwind-mode', 'light');
|
|
54
|
+
document.documentElement.classList.remove(opposite)
|
|
98
55
|
}
|
|
56
|
+
document.documentElement.classList.add(mode)
|
|
57
|
+
window.localStorage.setItem("nightwind-mode", mode)
|
|
99
58
|
},
|
|
100
59
|
}
|
package/jest.config.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thiagormoreira/nightwind",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "An automatic, overridable, customisable Tailwind dark mode plugin",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -27,6 +27,18 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/thiagormoreira/nightwind#readme",
|
|
29
29
|
"scripts": {
|
|
30
|
-
"test": "
|
|
30
|
+
"test": "jest",
|
|
31
|
+
"lint": "eslint .",
|
|
32
|
+
"format": "prettier --write \"**/*.{js,jsx,json,md}\""
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"autoprefixer": "^10.4.24",
|
|
36
|
+
"eslint": "^10.0.0",
|
|
37
|
+
"eslint-plugin-jest": "^29.15.0",
|
|
38
|
+
"jest": "^30.2.0",
|
|
39
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
40
|
+
"postcss": "^8.5.6",
|
|
41
|
+
"prettier": "^3.8.1",
|
|
42
|
+
"tailwindcss": "^3.4.19"
|
|
31
43
|
}
|
|
32
44
|
}
|
package/src/index.js
CHANGED
|
@@ -339,9 +339,8 @@ const nightwind = plugin(
|
|
|
339
339
|
if (!typographyValues[`${modifier}`][`${classname}`]) {
|
|
340
340
|
typographyValues[`${modifier}`][`${classname}`] = {}
|
|
341
341
|
}
|
|
342
|
-
typographyValues[`${modifier}`][`${classname}`][
|
|
343
|
-
|
|
344
|
-
] = colorValue
|
|
342
|
+
typographyValues[`${modifier}`][`${classname}`][property] =
|
|
343
|
+
colorValue
|
|
345
344
|
}
|
|
346
345
|
})
|
|
347
346
|
}
|
|
@@ -561,24 +560,27 @@ const nightwind = plugin(
|
|
|
561
560
|
|
|
562
561
|
const generateClass = (prefix, property) => {
|
|
563
562
|
return {
|
|
564
|
-
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
importantProperty,
|
|
581
|
-
|
|
563
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
564
|
+
{
|
|
565
|
+
[`${property}`]: colorValue + importantProperty,
|
|
566
|
+
[`${property}`]:
|
|
567
|
+
hexToRGB(`${colorValue}`, `var(--tw-${prefix})`) +
|
|
568
|
+
importantProperty,
|
|
569
|
+
},
|
|
570
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}`]:
|
|
571
|
+
{
|
|
572
|
+
[`${property}`]: defaultColorValue + importantProperty,
|
|
573
|
+
[`${property}`]:
|
|
574
|
+
hexToRGB(`${defaultColorValue}`, `var(--tw-${prefix})`) +
|
|
575
|
+
importantProperty,
|
|
576
|
+
},
|
|
577
|
+
[`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}`]:
|
|
578
|
+
{
|
|
579
|
+
[`${property}`]: defaultColorValue + importantProperty,
|
|
580
|
+
[`${property}`]:
|
|
581
|
+
hexToRGB(`${defaultColorValue}`, `var(--tw-${prefix})`) +
|
|
582
|
+
importantProperty,
|
|
583
|
+
},
|
|
582
584
|
}
|
|
583
585
|
}
|
|
584
586
|
|
|
@@ -608,24 +610,27 @@ const nightwind = plugin(
|
|
|
608
610
|
return generateClass("ring-opacity", "--tw-ring-color")
|
|
609
611
|
} else if (colorClass.includes("divide-")) {
|
|
610
612
|
return {
|
|
611
|
-
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]:
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
importantProperty,
|
|
628
|
-
|
|
613
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]:
|
|
614
|
+
{
|
|
615
|
+
borderColor: colorValue + importantProperty,
|
|
616
|
+
borderColor:
|
|
617
|
+
hexToRGB(`${colorValue}`, `var(--tw-divide-opacity)`) +
|
|
618
|
+
importantProperty,
|
|
619
|
+
},
|
|
620
|
+
[`${importantSelector}${darkSelector} ${fixedElementClass}.${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]:
|
|
621
|
+
{
|
|
622
|
+
borderColor: defaultColorValue + importantProperty,
|
|
623
|
+
borderColor:
|
|
624
|
+
hexToRGB(`${defaultColorValue}`, `var(--tw-divide-opacity)`) +
|
|
625
|
+
importantProperty,
|
|
626
|
+
},
|
|
627
|
+
[`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant} > :not([hidden]) ~ :not([hidden])`]:
|
|
628
|
+
{
|
|
629
|
+
borderColor: defaultColorValue + importantProperty,
|
|
630
|
+
borderColor:
|
|
631
|
+
hexToRGB(`${defaultColorValue}`, `var(--tw-divide-opacity)`) +
|
|
632
|
+
importantProperty,
|
|
633
|
+
},
|
|
629
634
|
}
|
|
630
635
|
} else if (colorClass.includes("placeholder-")) {
|
|
631
636
|
return {
|
|
@@ -635,93 +640,107 @@ const nightwind = plugin(
|
|
|
635
640
|
hexToRGB(`${colorValue}`, `var(--tw-text-opacity)`) +
|
|
636
641
|
importantProperty,
|
|
637
642
|
},
|
|
638
|
-
[`${importantSelector}${darkSelector} ${fixedElementClass}.${colorClass}::placeholder`]:
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
643
|
+
[`${importantSelector}${darkSelector} ${fixedElementClass}.${colorClass}::placeholder`]:
|
|
644
|
+
{
|
|
645
|
+
color: defaultColorValue + importantProperty,
|
|
646
|
+
color:
|
|
647
|
+
hexToRGB(`${defaultColorValue}`, `var(--tw-text-opacity)`) +
|
|
648
|
+
importantProperty,
|
|
649
|
+
},
|
|
650
|
+
[`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}::placeholder`]:
|
|
651
|
+
{
|
|
652
|
+
color: defaultColorValue + importantProperty,
|
|
653
|
+
color:
|
|
654
|
+
hexToRGB(`${defaultColorValue}`, `var(--tw-text-opacity)`) +
|
|
655
|
+
importantProperty,
|
|
656
|
+
},
|
|
650
657
|
}
|
|
651
658
|
} else if (colorClass.includes("ring-offset-")) {
|
|
652
659
|
return {
|
|
653
|
-
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
}
|
|
660
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
661
|
+
{
|
|
662
|
+
"--tw-ring-offset-color": colorValue + importantProperty,
|
|
663
|
+
},
|
|
664
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}`]:
|
|
665
|
+
{
|
|
666
|
+
"--tw-ring-offset-color": defaultColorValue + importantProperty,
|
|
667
|
+
},
|
|
668
|
+
[`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}`]:
|
|
669
|
+
{
|
|
670
|
+
"--tw-ring-offset-color": defaultColorValue + importantProperty,
|
|
671
|
+
},
|
|
662
672
|
}
|
|
663
673
|
} else if (colorClass.includes("from-")) {
|
|
664
674
|
return {
|
|
665
|
-
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
675
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
676
|
+
{
|
|
677
|
+
"--tw-gradient-from": colorValue + importantProperty,
|
|
678
|
+
"--tw-gradient-stops":
|
|
679
|
+
`var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(
|
|
680
|
+
`${colorValue}`,
|
|
681
|
+
"0"
|
|
682
|
+
)})` + importantProperty,
|
|
683
|
+
},
|
|
684
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}`]:
|
|
685
|
+
{
|
|
686
|
+
"--tw-gradient-from": defaultColorValue + importantProperty,
|
|
687
|
+
"--tw-gradient-stops":
|
|
688
|
+
`var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(
|
|
689
|
+
`${defaultColorValue}`,
|
|
690
|
+
"0"
|
|
691
|
+
)})` + importantProperty,
|
|
692
|
+
},
|
|
693
|
+
[`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}`]:
|
|
694
|
+
{
|
|
695
|
+
"--tw-gradient-from": defaultColorValue + importantProperty,
|
|
696
|
+
"--tw-gradient-stops":
|
|
697
|
+
`var(--tw-gradient-from), var(--tw-gradient-to, ${hexToRGB(
|
|
698
|
+
`${defaultColorValue}`,
|
|
699
|
+
"0"
|
|
700
|
+
)})` + importantProperty,
|
|
701
|
+
},
|
|
689
702
|
}
|
|
690
703
|
} else if (colorClass.includes("via-")) {
|
|
691
704
|
return {
|
|
692
|
-
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
705
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
706
|
+
{
|
|
707
|
+
"--tw-gradient-stops":
|
|
708
|
+
`var(--tw-gradient-from), ${colorValue}, var(--tw-gradient-to, ${hexToRGB(
|
|
709
|
+
`${colorValue}`,
|
|
710
|
+
"0"
|
|
711
|
+
)})` + importantProperty,
|
|
712
|
+
},
|
|
713
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}`]:
|
|
714
|
+
{
|
|
715
|
+
"--tw-gradient-stops":
|
|
716
|
+
`var(--tw-gradient-from), ${defaultColorValue}, var(--tw-gradient-to, ${hexToRGB(
|
|
717
|
+
`${defaultColorValue}`,
|
|
718
|
+
"0"
|
|
719
|
+
)})` + importantProperty,
|
|
720
|
+
},
|
|
721
|
+
[`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}`]:
|
|
722
|
+
{
|
|
723
|
+
"--tw-gradient-stops":
|
|
724
|
+
`var(--tw-gradient-from), ${defaultColorValue}, var(--tw-gradient-to, ${hexToRGB(
|
|
725
|
+
`${defaultColorValue}`,
|
|
726
|
+
"0"
|
|
727
|
+
)})` + importantProperty,
|
|
728
|
+
},
|
|
713
729
|
}
|
|
714
730
|
} else if (colorClass.includes("to-")) {
|
|
715
731
|
return {
|
|
716
|
-
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
}
|
|
732
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}`]:
|
|
733
|
+
{
|
|
734
|
+
"--tw-gradient-to": colorValue + importantProperty,
|
|
735
|
+
},
|
|
736
|
+
[`${importantSelector}${darkSelector} .${colorClass}${pseudoVariant}${fixedElementClass}`]:
|
|
737
|
+
{
|
|
738
|
+
"--tw-gradient-to": defaultColorValue + importantProperty,
|
|
739
|
+
},
|
|
740
|
+
[`${importantSelector}${darkSelector} ${fixedBlockClass} .${colorClass}${pseudoVariant}`]:
|
|
741
|
+
{
|
|
742
|
+
"--tw-gradient-to": defaultColorValue + importantProperty,
|
|
743
|
+
},
|
|
725
744
|
}
|
|
726
745
|
}
|
|
727
746
|
})
|