{"_id":"@brandonaaron/dark-pref","_rev":"1-271b14f742a45775534bed1d68284996","name":"@brandonaaron/dark-pref","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@brandonaaron/dark-pref","version":"1.0.0","description":"Dark mode preference manager and optional web components.","author":{"name":"Brandon Aaron"},"license":"ISC","repository":{"type":"git","url":"git+https://github.com/brandonaaron/dark-pref.git"},"main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.js","type":"module","scripts":{"lint":"eslint .","start":"run-p dev:*","test":"wtr src/*.test.ts","build":"run-s build:*","build:clean":"rimraf dist && rimraf docs","build:src":"rollup -c rollup.config.js","build:cem":"cem analyze --outdir dist --globs \"src/DarkPrefToggl*.ts\"","dev:serve":"wds --port 8888","dev:build":"rollup --watch -c rollup.config.js","prepare":"npm run build"},"devDependencies":{"@custom-elements-manifest/analyzer":"^0.9.0","@rollup/plugin-eslint":"^9.0.5","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-typescript":"^11.1.5","@types/chai":"^4.3.11","@types/mocha":"^10.0.6","@typescript-eslint/eslint-plugin":"^6.10.0","@typescript-eslint/parser":"^6.10.0","@web/dev-server":"^0.4.1","@web/dev-server-esbuild":"^1.0.1","@web/test-runner":"^0.18.0","@web/test-runner-mocha":"^0.9.0","@web/test-runner-playwright":"^0.11.0","chai":"npm:@esm-bundle/chai@^4.3.4-fix.0","eslint":"^8.53.0","happy-dom":"^12.10.3","npm-run-all":"^4.1.5","rimraf":"^5.0.5","rollup":"^4.4.1","tslib":"^2.6.2","typescript":"^5.2.2"},"_id":"@brandonaaron/dark-pref@1.0.0","gitHead":"8ce854ea7307d47ac95b2fe8b3e19dc3d2b67c21","bugs":{"url":"https://github.com/brandonaaron/dark-pref/issues"},"homepage":"https://github.com/brandonaaron/dark-pref#readme","_nodeVersion":"20.7.0","_npmVersion":"10.1.0","dist":{"integrity":"sha512-SP2r0950n/MQUnEzWhG/bP4CQUpHbI/bd2prQrqTXiimzfqjlvcvxJ3BgKNrxv4WkjJr+Fqv7nJ/il9bJ+sEbQ==","shasum":"9115890ca91433ea9b16a298b90ea2486c281a61","tarball":"https://registry.npmjs.org/@brandonaaron/dark-pref/-/dark-pref-1.0.0.tgz","fileCount":33,"unpackedSize":55056,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+MXJc61SY2g+gwgdJ1sGc8mrfTw9hkS0RNzJiMSPUTQIhAPg4vzVv2koxlbcJW8aYKu46LWiWmun5DBHZb4NMFV/3"}]},"_npmUser":{"name":"brandonaaron","email":"hello.brandon@aaron.sh"},"directories":{},"maintainers":[{"name":"brandonaaron","email":"hello.brandon@aaron.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/dark-pref_1.0.0_1700859994244_0.8758749341683918"},"_hasShrinkwrap":false},"1.0.1":{"name":"@brandonaaron/dark-pref","version":"1.0.1","description":"Dark mode preference manager and optional web components.","author":{"name":"Brandon Aaron"},"license":"ISC","repository":{"type":"git","url":"git+https://github.com/brandonaaron/dark-pref.git"},"exports":"./dist/index.js","main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","type":"module","scripts":{"lint":"eslint .","lint:fix":"eslint . --fix","lint:fix:staged":"npx lint-staged --verbose","start":"run-p dev:*","test":"wtr src/*.test.ts","build":"run-s build:*","build:clean":"rimraf dist && rimraf docs","build:src":"rollup -c rollup.config.js","build:cem":"cem analyze --outdir dist --globs \"src/DarkPrefToggl*.ts\"","dev:serve":"wds --port 8888","dev:build":"rollup --watch -c rollup.config.js","prepublishOnly":"npm run build","prepare":"husky install"},"devDependencies":{"@custom-elements-manifest/analyzer":"^0.9.0","@eslint/js":"^8.55.0","@rollup/plugin-terser":"^0.4.4","@rollup/plugin-typescript":"^11.1.5","@stylistic/eslint-plugin":"^1.5.1","@types/chai":"^4.3.11","@types/mocha":"^10.0.6","@typescript-eslint/eslint-plugin":"^6.14.0","@typescript-eslint/parser":"^6.14.0","@web/dev-server":"^0.4.1","@web/dev-server-esbuild":"^1.0.1","@web/test-runner":"^0.18.0","@web/test-runner-mocha":"^0.9.0","@web/test-runner-playwright":"^0.11.0","chai":"npm:@esm-bundle/chai@^4.3.4-fix.0","eslint":"^8.55.0","happy-dom":"^12.10.3","husky":"^8.0.3","lint-staged":"^15.2.0","npm-run-all":"^4.1.5","rimraf":"^5.0.5","rollup":"^4.4.1","tslib":"^2.6.2","typescript":"^5.2.2"},"lint-staged":{"*.{ts,js}":"eslint . --fix"},"_id":"@brandonaaron/dark-pref@1.0.1","gitHead":"30e178e8f042fda0ebc1e384103ab59cc515cfa4","bugs":{"url":"https://github.com/brandonaaron/dark-pref/issues"},"homepage":"https://github.com/brandonaaron/dark-pref#readme","_nodeVersion":"20.10.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-oR6VoROvVgYubEtfVIJ7ueukT1a0xd7Xuy65RzlCmPDj9VuIGHaElSFxIj+Zsj8EKCND3WFIm3DUjo87XxDI9w==","shasum":"a4596d4d701c8ac94da599797b5e2237af914ba1","tarball":"https://registry.npmjs.org/@brandonaaron/dark-pref/-/dark-pref-1.0.1.tgz","fileCount":37,"unpackedSize":55479,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCzw5L4TgbbiEPrvZDWnOnFsHq6wVUv40n4buKBQPAXBwIgDvOvuhHpUoTlT0vGWoXY9BupvlVUZR0wxYcpjhunHMg="}]},"_npmUser":{"name":"brandonaaron","email":"hello.brandon@aaron.sh"},"directories":{},"maintainers":[{"name":"brandonaaron","email":"hello.brandon@aaron.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/dark-pref_1.0.1_1703122075433_0.10148454162662368"},"_hasShrinkwrap":false}},"time":{"created":"2023-11-24T21:06:34.152Z","1.0.0":"2023-11-24T21:06:34.526Z","modified":"2023-12-21T01:27:55.787Z","1.0.1":"2023-12-21T01:27:55.629Z"},"maintainers":[{"name":"brandonaaron","email":"hello.brandon@aaron.sh"}],"description":"Dark mode preference manager and optional web components.","homepage":"https://github.com/brandonaaron/dark-pref#readme","repository":{"type":"git","url":"git+https://github.com/brandonaaron/dark-pref.git"},"author":{"name":"Brandon Aaron"},"bugs":{"url":"https://github.com/brandonaaron/dark-pref/issues"},"license":"ISC","readme":"# Dark Pref\n\nProvides a preference manager (`DarkPref`), an optional web component (`DarkPrefToggleElement`), an optional base web component (`DarkPrefToggleBaseElement`), and a tiny render blocking script to avoid a potential initial flash of content.\n\n* No dependencies, ES Modules, TypeScript, Unit Tests\n* Persists to `localStorage` if possible (uses `__dark-pref__` key)\n* Keeps multiple tabs in sync via `localStorage`\n* Provides information on system preference and user preference\n* Prioritizes the system dark mode preference\n* Emits a `darkpref:sync` custom event on the document with current state as the `detail`\n* `dark` class name toggled on `<html>` element\n\nSee how it works on my [personal site](https://meh.pub) (it is in the top right corner). [Details below](#usage-with-astro) about how I implemented it in Astro.\n\n## Quick Start\n\nAdd this to the `<head>`:\n\n```html\n<!-- tiny render blocking script to avoid flash of content -->\n<script src=\"https://cdn.jsdelivr.net/npm/@brandonaaron/dark-pref@1.0.0/dist/DarkPref.blocking.js\"></script>\n<!-- rest of the exports could be bundled with your favorite bundler too -->\n<script src=\"https://cdn.jsdelivr.net/npm/@brandonaaron/dark-pref@1.0.0/dist/DarkPrefToggleElement.js\" type=\"module\"></script>\n<style>\n  :root { /* optional css variables */\n    --dark-pref-when-light-color: #999; /* defaults to #000 */\n    --dark-pref-when-dark-color: #ccc; /* defaults to #fff */\n  }\n</style>\n```\n\nThen add the included custom element to the `<body>`:\n\n```html\n<dark-pref-toggle>\n  <!-- Optional slots \"light\" and \"dark\" (they default to a sun and moon svg) -->\n  <span slot=\"light\">Switch to dark mode</span>\n  <span slot=\"dark\">Switch to light mode</span>\n</dark-pref-toggle>\n```\n\nCheck the `examples` folder for other uses like creating your own custom element or not using custom elements at all.\n\n## Docs: DarkPref\n\n### DarkPref.current\n\nA getter that includes three props: `system` (`boolean`), `user` (`DarkPrefUserSetting`), and `isDark` (`boolean`)`.\n\n### DarkPref.reset()\n\nClear out any stored preference and resync. This always triggers the `darkpref:sync` event on the document.\n\n### DarkPref.sync()\n\nUsed to trigger a resync of the current state. This always triggers the `darkpref:sync` event on the document.\n\n### DarkPref.toggle(pref)\n\nChanges the user preference. The `pref` argument is optional but should be a `boolean` or `null` if passed (`DarkPrefUserSetting` type).\n\nThe `DarkPref.current.user` value will be `null` when their dark preference aligns with the system preference.\n\n\n## Docs: DarkPrefToggleBaseElement\n\nProvides a custom element to extend for your own custom element. Automatically hookes up a `click` and `darkpref:sync` event handlers on `connectedCallback`.  Does not register a tag.\n\n### ariaPressedForCurrentState (getter)\n\nProvides a value for `aria-pressed` attribute. The button is considered pressed only if the user has a different prefence from the current system preference.\n\n### ariaLabelForCurrentState (getter)\n\nProvides a value for `aria-label` attribute.\n\n### connectedCallback()\n\nConnects `click` and `darkpref:sync` event handlers.\n\n### disconnectedCallback()\n\nDisconnects `click` and `darkpref:sync` event handlers.\n\n### sync()\n\nThis needs to be implemented by the extending class. This should check `DarkPref.current` and implement necessary changes to the DOM.\n\n### toggle(pref)\n\nChanges the user preference. The `pref` argument is optional but should be a `boolean` or `null` if passed (`DarkPrefUserSetting` type).\n\n\n## Docs: DarkPrefToggleElement\n\nProvides a quick and easy button to toggle dark mode on/off. Provides two slots and two css variables for customization. This extends the `DarkPrefToggleBaseElement`. Automatically registers the tag name `dark-pref-toggle`.\n\nThere is a `dist/custom-elements.json` in the npm package.\n\n### CSS Variables\n\n * `--dark-pref-when-dark-color`: Controls the `color` when dark is preferred (defaults to `#fff`)\n * `--dark-pref-when-light-color`: Controls the `color` when light is preferred (defaults to `#000`)\n\n### Slots\n\n* `light`: Defaults to a sun svg icon\n* `dark`: Defults to a moon svg icon\n\n## Usage with Astro\n\nI'm using this on my personal site which is built with [Astro](https://astro.build/) and [TailwindCSS](https://tailwindcss.com/).\n\nFirst I npm installed it:\n\n```\nnpm install @brandonaaron/dark-pref\n```\n\nI copied over `dist/DarkPref.blocking.js` to the `public` directory and included that via an `is:inline` script tag in the `<head>` of my main layout:\n\n```html\n<script is:inline src=\"/DarkPref.blocking.js\"></script>\n```\n\nThen I created a `DarkPrefToggle.astro` component with the following:\n\n```astro\n---\n---\n<script>\n  import { DarkPref } from '@brandonaaron/dark-pref/dist/DarkPref.js'\n  import '@brandonaaron/dark-pref/dist/DarkPrefToggleElement.js'\n  // The following lines is applicable only if you're using transitions\n  document.addEventListener('astro:after-swap', () => { DarkPref.sync() })\n</script>\n<style>\n  :root {\n    --dark-pref-when-light-color: theme(\"colors.zinc.800\");\n    --dark-pref-when-dark-color: theme(\"colors.zinc.200\");\n  }\n</style>\n<dark-pref-toggle class=\"w-[24px] h-[24px]\"></dark-pref-toggle>\n```\n\nMy `tailwind.config.js` also has the following to ensure it works with html element dark mode class toggling:\n\n```js\nmodule.exports = {\n  //...\n  darkMode: 'class',\n  //...\n}\n```\n\n## Docker\n\nRun `docker compose up` to get a working dev environment. This will start a dev server on port 8888.\n\nRun `docker compose run --build dev npm run test` to just run the unit tests in isolation.\n\nThere is a config for a vscode devcontainer too. The devcontainer uses the same Dockerfile/docker-compose config but does not start a dev server. Instead open a terminal within vscode and run `npm start` (or `npm run test`, etc).\n","readmeFilename":"README.md"}