1
mirror of https://github.com/jakejarvis/dark-mode.git synced 2025-04-29 16:10:29 -04:00

Compare commits

..

No commits in common. "main" and "0.8.0" have entirely different histories.
main ... 0.8.0

11 changed files with 2404 additions and 2072 deletions

View File

@ -1,17 +0,0 @@
# http://editorconfig.org
# this file is the top-most editorconfig file
root = true
# all files
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
# site content
[*.md]
trim_trailing_whitespace = false

View File

@ -1,16 +1,18 @@
{ {
"extends": [ "extends": [
"@jakejarvis/eslint-config", "@jakejarvis/eslint-config"
"plugin:@typescript-eslint/recommended"
], ],
"plugins": [ "parserOptions": {
"@typescript-eslint" "ecmaVersion": 2015,
], "sourceType": "module"
"parser": "@typescript-eslint/parser", },
"env": { "env": {
"browser": true "browser": true,
"node": true
}, },
"ignorePatterns": [ "ignorePatterns": [
"dist/**" "*.d.ts",
"dist/**",
"rollup.config.js"
] ]
} }

2
.gitattributes vendored
View File

@ -1,2 +0,0 @@
# Set default behavior to automatically normalize line endings.
* text=auto eol=lf

View File

@ -3,17 +3,17 @@ name: CI
on: on:
push: push:
branches: branches:
- main - main
pull_request: pull_request:
jobs: jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-node@v2 - uses: actions/setup-node@v2
with: with:
node-version: 16.x node-version: '14.x'
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn lint - run: yarn lint
- run: yarn build - run: yarn build

View File

@ -3,18 +3,20 @@ name: Release
on: on:
push: push:
tags: tags:
- 'v*' - '*'
jobs: jobs:
npm: npm:
name: Publish to NPM
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: actions/setup-node@v2 - uses: actions/setup-node@v2
with: with:
node-version: 16.x node-version: 14
registry-url: https://registry.npmjs.org/ registry-url: https://registry.npmjs.org/
- run: yarn install --frozen-lockfile - env:
- run: yarn publish NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
env: run: |
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} yarn install --frozen-lockfile
yarn publish

View File

@ -1,7 +1,8 @@
# 🌓 Dark Mode Switcheroo™ # 🌓 Dark Mode Switcheroo™
[![CI](https://github.com/jakejarvis/dark-mode/actions/workflows/ci.yml/badge.svg)](https://github.com/jakejarvis/dark-mode/actions/workflows/ci.yml) [![CI](https://github.com/jakejarvis/dark-mode/actions/workflows/ci.yml/badge.svg)](https://github.com/jakejarvis/dark-mode/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/dark-mode-switcheroo)](https://www.npmjs.com/package/dark-mode-switcheroo) [![npm](https://img.shields.io/npm/v/dark-mode-switcheroo?logo=npm)](https://www.npmjs.com/package/dark-mode-switcheroo)
[![MIT License](https://img.shields.io/github/license/jakejarvis/dark-mode?color=violet)](LICENSE)
Very simple CSS dark/light mode toggler with saved preference via local storage & dynamic OS setting detection. Zero dependencies and [only ~500 bytes gzipped!](https://bundlephobia.com/package/dark-mode-switcheroo) Very simple CSS dark/light mode toggler with saved preference via local storage & dynamic OS setting detection. Zero dependencies and [only ~500 bytes gzipped!](https://bundlephobia.com/package/dark-mode-switcheroo)
@ -20,7 +21,6 @@ Very simple CSS dark/light mode toggler with saved preference via local storage
- **`default`**: The initial `<body>` class hard-coded into the HTML template. (optional, default: `"light"`) - **`default`**: The initial `<body>` class hard-coded into the HTML template. (optional, default: `"light"`)
- **`storageKey`**: Name of the `localStorage` key holding the user's preference. (optional, default: `"dark_mode_pref"`) - **`storageKey`**: Name of the `localStorage` key holding the user's preference. (optional, default: `"dark_mode_pref"`)
- **`onInit([toggle])`**: Callback function executed at the end of initialization. The toggle above is passed in if set. (optional, default: `null`) - **`onInit([toggle])`**: Callback function executed at the end of initialization. The toggle above is passed in if set. (optional, default: `null`)
- **`onUserToggle([toggle])`**: Callback function executed when a user manually interacts with the toggle button. The toggle above (if set) is passed in. (optional, default: `null`)
- **`onChange([theme, toggle])`**: Callback function executed when theme is switched. The new theme and the toggle above (if set) are passed in. (optional, default: `null`) - **`onChange([theme, toggle])`**: Callback function executed when theme is switched. The new theme and the toggle above (if set) are passed in. (optional, default: `null`)
### Browser ### Browser

View File

@ -1,9 +1,8 @@
{ {
"name": "dark-mode-switcheroo", "name": "dark-mode-switcheroo",
"version": "0.10.0", "version": "0.8.0",
"description": "🌓 Simple CSS theme switching with saved preferences and automatic OS setting detection", "description": "🌓 Simple CSS theme switching with saved preferences and automatic OS setting detection",
"license": "MIT", "license": "MIT",
"homepage": "https://jrvs.io/darkmode",
"author": { "author": {
"name": "Jake Jarvis", "name": "Jake Jarvis",
"email": "jake@jarv.is", "email": "jake@jarv.is",
@ -14,32 +13,40 @@
"url": "https://github.com/jakejarvis/dark-mode.git" "url": "https://github.com/jakejarvis/dark-mode.git"
}, },
"type": "module", "type": "module",
"sideEffects": false,
"files": [ "files": [
"dist" "dist"
], ],
"source": "./src/dark-mode.ts", "main": "./dist/dark-mode.cjs.js",
"main": "./dist/dark-mode.cjs",
"module": "./dist/dark-mode.esm.js", "module": "./dist/dark-mode.esm.js",
"unpkg": "./dist/dark-mode.min.js", "unpkg": "./dist/dark-mode.min.js",
"types": "./dist/dark-mode.d.ts",
"exports": { "exports": {
"require": "./dist/dark-mode.cjs", "require": "./dist/dark-mode.cjs.js",
"import": "./dist/dark-mode.esm.js", "import": "./dist/dark-mode.esm.js",
"browser": "./dist/dark-mode.min.js" "browser": "./dist/dark-mode.min.js"
}, },
"types": "./dist/dark-mode.d.ts",
"scripts": { "scripts": {
"build": "microbundle --format cjs,esm,umd --name 'darkMode'", "build": "rollup -c",
"lint": "eslint .", "lint": "eslint .",
"prepublishOnly": "yarn build" "prepublishOnly": "yarn build"
}, },
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"@babel/core": "^7.15.5",
"@babel/preset-env": "^7.15.6",
"@jakejarvis/eslint-config": "*", "@jakejarvis/eslint-config": "*",
"@typescript-eslint/eslint-plugin": "^5.3.1", "@rollup/plugin-babel": "^5.3.0",
"@typescript-eslint/parser": "^5.3.1", "@rollup/plugin-eslint": "^8.0.1",
"eslint": "^8.2.0", "@rollup/plugin-node-resolve": "^13.0.4",
"microbundle": "^0.14.1", "eslint": "^7.32.0",
"typescript": "^4.4.4" "eslint-plugin-compat": "^3.13.0",
"eslint-plugin-import": "^2.24.2",
"rollup": "^2.56.3",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-delete": "^2.0.0",
"rollup-plugin-filesize": "^9.1.1",
"rollup-plugin-terser": "^7.0.2"
}, },
"keywords": [ "keywords": [
"front-end", "front-end",

90
rollup.config.js Normal file
View File

@ -0,0 +1,90 @@
import pkg from "./package.json";
import resolve from "@rollup/plugin-node-resolve";
import { babel } from "@rollup/plugin-babel";
import { terser } from "rollup-plugin-terser";
import eslint from "@rollup/plugin-eslint";
import filesize from "rollup-plugin-filesize";
import copy from "rollup-plugin-copy";
import del from "rollup-plugin-delete";
const banner = `/*! Dark Mode Switcheroo v${pkg.version} | MIT License | jrvs.io/darkmode */`;
export default [
{
// universal (browser and node)
input: "src/index.js",
output: [
{
name: "darkMode",
file: "dist/dark-mode.js",
format: "umd",
exports: "named",
esModule: false,
banner: banner,
},
{
name: "darkMode",
file: "dist/dark-mode.min.js",
format: "umd",
exports: "named",
esModule: false,
plugins: [
terser({
output: {
preamble: banner,
},
}),
],
},
],
plugins: [
del({ targets: "dist/*" }),
copy({
// clearly this isn't really typescript, so we need to manually copy the type definition file
targets: [
{
src: "src/index.d.ts",
dest: "dist",
rename: "dark-mode.d.ts",
},
],
}),
resolve(),
eslint(),
babel({
babelHelpers: "bundled",
presets: [["@babel/preset-env"]],
exclude: ["node_modules/**"],
}),
filesize(),
],
},
{
// modules
input: "src/index.js",
output: [
{
// ES6 module (import)
file: "dist/dark-mode.esm.js",
format: "esm",
exports: "named",
banner: banner,
},
{
// commonjs (require)
file: "dist/dark-mode.cjs.js",
format: "cjs",
exports: "named",
banner: banner,
},
],
plugins: [
resolve(),
babel({
babelHelpers: "bundled",
exclude: ["node_modules/**"],
}),
filesize(),
],
},
];

8
src/index.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
export function init(options?: {
toggle?: HTMLElement;
classes?: { dark: string, light: string };
default?: string;
storageKey?: string;
onInit?: (toggle?: HTMLElement) => unknown;
onChange?: (theme?: string, toggle?: HTMLElement) => unknown;
}): void;

View File

@ -1,12 +1,4 @@
export function init(options: { const init = function (options) {
toggle?: Element | null;
classes?: { dark: string, light: string };
default?: string;
storageKey?: string;
onInit?: (toggle?: Element | null) => unknown;
onUserToggle?: (toggle?: Element | null) => unknown;
onChange?: (theme: string, toggle?: Element | null) => unknown;
}): void {
options = options || {}; options = options || {};
// use a specified element(s) to trigger swap when clicked // use a specified element(s) to trigger swap when clicked
@ -27,12 +19,7 @@ export function init(options: {
let active = defaultTheme === dark; let active = defaultTheme === dark;
// receives a class name and switches <body> to it // receives a class name and switches <body> to it
const activateTheme = function (theme: string, remember?: boolean) { const activateTheme = function (theme, remember) {
// optional onChange callback function passed as option
if (typeof options.onChange === "function") {
options.onChange(theme, toggle);
}
document.body.classList.remove(dark, light); document.body.classList.remove(dark, light);
document.body.classList.add(theme); document.body.classList.add(theme);
active = theme === dark; active = theme === dark;
@ -40,17 +27,17 @@ export function init(options: {
if (remember) { if (remember) {
localStorage.setItem(storageKey, theme); localStorage.setItem(storageKey, theme);
} }
};
// optional onInit callback function passed as option // optional onChange callback function passed as option
if (typeof options.onInit === "function") { if (typeof options.onChange === "function") {
options.onInit(toggle); options.onChange(theme, toggle);
} }
};
// user has never clicked the button, so go by their OS preference until/if they do so // user has never clicked the button, so go by their OS preference until/if they do so
if (!pref) { if (!pref) {
// returns media query selector syntax // returns media query selector syntax
const prefers = function (colorScheme: "dark" | "light") { const prefers = function (colorScheme) {
// https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme // https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme
return `(prefers-color-scheme: ${colorScheme})`; return `(prefers-color-scheme: ${colorScheme})`;
}; };
@ -88,11 +75,6 @@ export function init(options: {
if (toggle !== null) { if (toggle !== null) {
// handle toggle click // handle toggle click
toggle.addEventListener("click", function () { toggle.addEventListener("click", function () {
// optional onUserToggle callback function passed as option
if (typeof options.onUserToggle === "function") {
options.onUserToggle(toggle);
}
// switch to the opposite theme & save preference in local storage // switch to the opposite theme & save preference in local storage
if (active) { if (active) {
activateTheme(light, true); activateTheme(light, true);
@ -101,4 +83,11 @@ export function init(options: {
} }
}); });
} }
}
// optional onInit callback function passed as option
if (typeof options.onInit === "function") {
options.onInit(toggle);
}
};
export { init };

4225
yarn.lock

File diff suppressed because it is too large Load Diff