From 434346dc364b10ddce99e2f12e48ed63e8ecd87b Mon Sep 17 00:00:00 2001 From: Cory Dransfeldt Date: Wed, 28 Feb 2024 08:51:13 -0800 Subject: [PATCH] chore: theme toggle web component --- .eleventy.js | 5 +- package-lock.json | 122 +++++++++--------- package.json | 3 +- src/assets/scripts/components/theme-toggle.js | 60 --------- src/assets/styles/partials/vars.css | 4 +- .../building-a-theme-toggle-web-component.md | 4 +- 6 files changed, 76 insertions(+), 122 deletions(-) delete mode 100644 src/assets/scripts/components/theme-toggle.js diff --git a/.eleventy.js b/.eleventy.js index 48086668..06dd274d 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -54,11 +54,14 @@ export default async function (eleventyConfig) { // passthrough eleventyConfig.addPassthroughCopy('src/assets') eleventyConfig.addPassthroughCopy('_redirects') + eleventyConfig.addPassthroughCopy({ + 'node_modules/@daviddarnes/mastodon-post/mastodon-post.js': 'assets/scripts/components/mastodon-post.js' + }) eleventyConfig.addPassthroughCopy({ 'node_modules/@zachleat/pagefind-search/pagefind-search.js': 'assets/scripts/components/pagefind-search.js', }) eleventyConfig.addPassthroughCopy({ - 'node_modules/@daviddarnes/mastodon-post/mastodon-post.js': 'assets/scripts/components/mastodon-post.js' + 'node_modules/@cdransf/theme-toggle/theme-toggle.js': 'assets/scripts/components/theme-toggle.js', }) eleventyConfig.addPassthroughCopy({ 'node_modules/@zachleat/webcare-webshare/webcare-webshare.js': 'assets/scripts/components/webcare-webshare.js' diff --git a/package-lock.json b/package-lock.json index c2394d88..da1f99a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "coryd.dev", - "version": "6.6.0", + "version": "6.6.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coryd.dev", - "version": "6.6.0", + "version": "6.6.3", "license": "MIT", "dependencies": { + "@cdransf/theme-toggle": "^1.0.2", "@daviddarnes/mastodon-post": "^1.1.1", "@remy/webmention": "^1.5.0", "@zachleat/pagefind-search": "^1.0.3", @@ -1203,9 +1204,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1215,9 +1216,9 @@ } }, "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -1228,6 +1229,11 @@ "node": ">=6.9.0" } }, + "node_modules/@cdransf/theme-toggle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@cdransf/theme-toggle/-/theme-toggle-1.0.2.tgz", + "integrity": "sha512-8vtIEtDV6yBMO4fiQWErlymdpnONh+PhFgDz19hH7lDf0pv404FUZIln+/49r0EIxKHg7eIMw7r4z0rTSeGdaw==" + }, "node_modules/@daviddarnes/mastodon-post": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@daviddarnes/mastodon-post/-/mastodon-post-1.1.1.tgz", @@ -2208,12 +2214,12 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.1.3.tgz", - "integrity": "sha512-u3TAAUJieDAesbKHN0w+0PazLJNmJLE/oWuuf0DYa5lhJJYLfSzX919Bb/Ul50lZ22h9lS1rFWV+5ubTrnyFQw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.1.4.tgz", + "integrity": "sha512-AW2WUZmBAzgO3V3ovKtsUbI3aBNMeQKFDumoqkNxaVDWF/xfnxAWqBKDr/NuG7c06N2Rm4xeZLPiJH/d+na0HA==", "dev": true, "dependencies": { - "@smithy/node-config-provider": "^2.2.3", + "@smithy/node-config-provider": "^2.2.4", "@smithy/types": "^2.10.1", "@smithy/util-config-provider": "^2.2.1", "@smithy/util-middleware": "^2.1.3", @@ -2224,16 +2230,16 @@ } }, "node_modules/@smithy/core": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.3.4.tgz", - "integrity": "sha512-A466yS5wzrtL02L5x+XiAu4W77VYsof3pimGoBPgWVyaRf4sE3JvM7TV0htkIywVzRuSd9vIlDkfhgvrW8NhmA==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.3.5.tgz", + "integrity": "sha512-Rrc+e2Jj6Gu7Xbn0jvrzZlSiP2CZocIOfZ9aNUA82+1sa6GBnxqL9+iZ9EKHeD9aqD1nU8EK4+oN2EiFpSv7Yw==", "dev": true, "dependencies": { - "@smithy/middleware-endpoint": "^2.4.3", - "@smithy/middleware-retry": "^2.1.3", + "@smithy/middleware-endpoint": "^2.4.4", + "@smithy/middleware-retry": "^2.1.4", "@smithy/middleware-serde": "^2.1.3", "@smithy/protocol-http": "^3.2.1", - "@smithy/smithy-client": "^2.4.1", + "@smithy/smithy-client": "^2.4.2", "@smithy/types": "^2.10.1", "@smithy/util-middleware": "^2.1.3", "tslib": "^2.5.0" @@ -2243,12 +2249,12 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.2.3.tgz", - "integrity": "sha512-gTrddTHipIgi4ZeFx8yTMRXzmOMY2lii/h/cnL0o53c+F0wm6kP9b/bsBtKXDsmE95h9w+CiMl+5M5yyBDOEMg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.2.4.tgz", + "integrity": "sha512-DdatjmBZQnhGe1FhI8gO98f7NmvQFSDiZTwC3WMvLTCKQUY+Y1SVkhJqIuLu50Eb7pTheoXQmK+hKYUgpUWsNA==", "dev": true, "dependencies": { - "@smithy/node-config-provider": "^2.2.3", + "@smithy/node-config-provider": "^2.2.4", "@smithy/property-provider": "^2.1.3", "@smithy/types": "^2.10.1", "@smithy/url-parser": "^2.1.3", @@ -2427,14 +2433,14 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.4.3.tgz", - "integrity": "sha512-iwYHQiU4w6nqxvZFBSdy+TpbimbkpLOKPivXZ1Ee2sBz86Q/vE34hlGd5nKUo17P/Yk9Evg9+mj9EXRVHvJoNA==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.4.4.tgz", + "integrity": "sha512-4yjHyHK2Jul4JUDBo2sTsWY9UshYUnXeb/TAK/MTaPEb8XQvDmpwSFnfIRDU45RY1a6iC9LCnmJNg/yHyfxqkw==", "dev": true, "dependencies": { "@smithy/middleware-serde": "^2.1.3", - "@smithy/node-config-provider": "^2.2.3", - "@smithy/shared-ini-file-loader": "^2.3.3", + "@smithy/node-config-provider": "^2.2.4", + "@smithy/shared-ini-file-loader": "^2.3.4", "@smithy/types": "^2.10.1", "@smithy/url-parser": "^2.1.3", "@smithy/util-middleware": "^2.1.3", @@ -2445,15 +2451,15 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.1.3.tgz", - "integrity": "sha512-5Ni2ax/D1x34/Rz1fa8kI/bzpl4iNsoHE5hqMeiYvxcfSS1OVqKlj2lLvFKxvgd9mFhQatiqbuMwsh6R/VSzGw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.1.4.tgz", + "integrity": "sha512-Cyolv9YckZTPli1EkkaS39UklonxMd08VskiuMhURDjC0HHa/AD6aK/YoD21CHv9s0QLg0WMLvk9YeLTKkXaFQ==", "dev": true, "dependencies": { - "@smithy/node-config-provider": "^2.2.3", + "@smithy/node-config-provider": "^2.2.4", "@smithy/protocol-http": "^3.2.1", "@smithy/service-error-classification": "^2.1.3", - "@smithy/smithy-client": "^2.4.1", + "@smithy/smithy-client": "^2.4.2", "@smithy/types": "^2.10.1", "@smithy/util-middleware": "^2.1.3", "@smithy/util-retry": "^2.1.3", @@ -2500,13 +2506,13 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.2.3.tgz", - "integrity": "sha512-+r8Dn5nq+jLGcayG3zrTxzlk2LJqtCf/F7FDOrjACgOutRpxFxZRkG9QOglRbSm/r1wfn7q4MiTMVdc2r0u3/Q==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.2.4.tgz", + "integrity": "sha512-nqazHCp8r4KHSFhRQ+T0VEkeqvA0U+RhehBSr1gunUuNW3X7j0uDrWBxB2gE9eutzy6kE3Y7L+Dov/UXT871vg==", "dev": true, "dependencies": { "@smithy/property-provider": "^2.1.3", - "@smithy/shared-ini-file-loader": "^2.3.3", + "@smithy/shared-ini-file-loader": "^2.3.4", "@smithy/types": "^2.10.1", "tslib": "^2.5.0" }, @@ -2596,9 +2602,9 @@ } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.3.3.tgz", - "integrity": "sha512-umdj358yVatYHG1vxtytCpvXxq3oMQEMYN61RAIfDVD8B26WRsqhucnUUdPl1MWEpLYB+7uDCltrgHZuHJ2kTQ==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.3.4.tgz", + "integrity": "sha512-CiZmPg9GeDKbKmJGEFvJBsJcFnh0AQRzOtQAzj1XEa8N/0/uSN/v1LYzgO7ry8hhO8+9KB7+DhSW0weqBra4Aw==", "dev": true, "dependencies": { "@smithy/types": "^2.10.1", @@ -2628,12 +2634,12 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.4.1.tgz", - "integrity": "sha512-dt5wlcym8lryne1jcZ6/Vp41T4gS4nCTzQ91a0Dz1/EXDA64/TwGGp79LkvJNkBbHw0rjiJk83CSH6u1HrTCvQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.4.2.tgz", + "integrity": "sha512-ntAFYN51zu3N3mCd95YFcFi/8rmvm//uX+HnK24CRbI6k5Rjackn0JhgKz5zOx/tbNvOpgQIwhSX+1EvEsBLbA==", "dev": true, "dependencies": { - "@smithy/middleware-endpoint": "^2.4.3", + "@smithy/middleware-endpoint": "^2.4.4", "@smithy/middleware-stack": "^2.1.3", "@smithy/protocol-http": "^3.2.1", "@smithy/types": "^2.10.1", @@ -2727,13 +2733,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.1.3.tgz", - "integrity": "sha512-VSAB+fOLo9/b3Aedi1lNxLPxHjzfMdppc9IpD7rsKN51EkJJzDuqmZu18zC1Jpkmxig21BYFqMTH49i5d7Lsgw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.1.4.tgz", + "integrity": "sha512-J6XAVY+/g7jf03QMnvqPyU+8jqGrrtXoKWFVOS+n1sz0Lg8HjHJ1ANqaDN+KTTKZRZlvG8nU5ZrJOUL6VdwgcQ==", "dev": true, "dependencies": { "@smithy/property-provider": "^2.1.3", - "@smithy/smithy-client": "^2.4.1", + "@smithy/smithy-client": "^2.4.2", "@smithy/types": "^2.10.1", "bowser": "^2.11.0", "tslib": "^2.5.0" @@ -2743,16 +2749,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.2.2.tgz", - "integrity": "sha512-cbfyXbAIXYe6HYUJMAIDB9vV/9R9hBoPBK8M4znvBfCGheS7Uc32XuKFsVTnHsR1FB435Ob9UZgfJgl4A2PJOA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.2.3.tgz", + "integrity": "sha512-ttUISrv1uVOjTlDa3nznX33f0pthoUlP+4grhTvOzcLhzArx8qHB94/untGACOG3nlf8vU20nI2iWImfzoLkYA==", "dev": true, "dependencies": { - "@smithy/config-resolver": "^2.1.3", - "@smithy/credential-provider-imds": "^2.2.3", - "@smithy/node-config-provider": "^2.2.3", + "@smithy/config-resolver": "^2.1.4", + "@smithy/credential-provider-imds": "^2.2.4", + "@smithy/node-config-provider": "^2.2.4", "@smithy/property-provider": "^2.1.3", - "@smithy/smithy-client": "^2.4.1", + "@smithy/smithy-client": "^2.4.2", "@smithy/types": "^2.10.1", "tslib": "^2.5.0" }, @@ -2761,12 +2767,12 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.1.3.tgz", - "integrity": "sha512-89LfHuyUEVjPo3e42U8P6TeWEkP1KDNs519xWKPEpoPFdIPrg77+0TrmIQWTCLgj7Dbvj5FbRbt+v+6sN5up3g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.1.4.tgz", + "integrity": "sha512-/qAeHmK5l4yQ4/bCIJ9p49wDe9rwWtOzhPHblu386fwPNT3pxmodgcs9jDCV52yK9b4rB8o9Sj31P/7Vzka1cg==", "dev": true, "dependencies": { - "@smithy/node-config-provider": "^2.2.3", + "@smithy/node-config-provider": "^2.2.4", "@smithy/types": "^2.10.1", "tslib": "^2.5.0" }, diff --git a/package.json b/package.json index f5f3793f..ad560699 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coryd.dev", - "version": "6.6.2", + "version": "6.6.3", "description": "The source for my personal site. Built using 11ty and hosted on Netlify.", "type": "module", "scripts": { @@ -20,6 +20,7 @@ "author": "Cory Dransfeldt", "license": "MIT", "dependencies": { + "@cdransf/theme-toggle": "^1.0.2", "@daviddarnes/mastodon-post": "^1.1.1", "@remy/webmention": "^1.5.0", "@zachleat/pagefind-search": "^1.0.3", diff --git a/src/assets/scripts/components/theme-toggle.js b/src/assets/scripts/components/theme-toggle.js deleted file mode 100644 index 8f0532d2..00000000 --- a/src/assets/scripts/components/theme-toggle.js +++ /dev/null @@ -1,60 +0,0 @@ -const themeToggleTemplate = document.createElement('template') - -themeToggleTemplate.innerHTML = ` - -` - -themeToggleTemplate.id = "theme-toggle-template" - -if (!document.getElementById(themeToggleTemplate.id)) document.body.appendChild(themeToggleTemplate) - -class ThemeToggle extends HTMLElement { - static register(tagName) { - if ("customElements" in window) customElements.define(tagName || "theme-toggle", ThemeToggle) - } - - async connectedCallback() { - this.append(this.template) - const btn = this.querySelector('.theme__toggle') - const setTheme = (isOnLoad) => { - const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches - const currentTheme = localStorage?.getItem('theme') - let theme - if (!currentTheme) localStorage?.setItem('theme', (prefersDarkScheme ? 'dark' : 'light')) - if (isOnLoad) { - if (currentTheme === 'dark') { - document.body.classList.add('theme__dark') - } else if (currentTheme === 'light') { - document.body.classList.add('theme__light') - } else if (prefersDarkScheme) { - document.body.classList.add('theme__dark') - } else if (!prefersDarkScheme) { - document.body.classList.add('theme__light') - } - } - if (prefersDarkScheme) { - theme = document.body.classList.contains('theme__light') ? 'light' : 'dark' - } else { - theme = document.body.classList.contains('theme__dark') ? 'dark' : 'light' - } - localStorage?.setItem('theme', theme) - } - - setTheme(true); - - btn.addEventListener('click', () => { - document.body.classList.toggle('theme__light') - document.body.classList.toggle('theme__dark') - setTheme() - }) - } - - get template() { - return document.getElementById(themeToggleTemplate.id).content.cloneNode(true) - } -} - -ThemeToggle.register() \ No newline at end of file diff --git a/src/assets/styles/partials/vars.css b/src/assets/styles/partials/vars.css index 23c71bb8..17e8e065 100644 --- a/src/assets/styles/partials/vars.css +++ b/src/assets/styles/partials/vars.css @@ -31,7 +31,7 @@ --gray-lighter: var(--gray-50); --gray-dark: var(--gray-700); - /* theme */ + /* base theme */ --color-lightest: var(--white); --color-darkest: var(--black); --text-color: var(--color-darkest); @@ -116,6 +116,7 @@ } } +/* light theme */ :root body.theme__light { --text-color: var(--color-darkest); --background-color: var(--color-lightest); @@ -130,6 +131,7 @@ --brand-github: #333; } +/* dark theme */ :root body.theme__dark { --text-color: var(--color-lightest); --background-color: var(--color-darkest); diff --git a/src/posts/2024/building-a-theme-toggle-web-component.md b/src/posts/2024/building-a-theme-toggle-web-component.md index f173409b..51de1af8 100644 --- a/src/posts/2024/building-a-theme-toggle-web-component.md +++ b/src/posts/2024/building-a-theme-toggle-web-component.md @@ -140,4 +140,6 @@ The final template that leverages the component looks like this: I load the web component script, embed my styles, define the template such that preferred icons are included using [Eleventy](https://www.11ty.dev/) shortcodes and the result is wrapped in an `li` to match the rest of my menu items, with `.client-side` added to hide the component should JavaScript be disabled. -[The complete JavaScript can be viewed in the source for my site.](https://github.com/cdransf/coryd.dev/blob/main/src/assets/scripts/components/theme-toggle.js) \ No newline at end of file +[The complete JavaScript can be viewed in the source for my site.](https://github.com/cdransf/coryd.dev/blob/main/src/assets/scripts/components/theme-toggle.js) + +You can also install the component via npm using `npm i @cdransf/theme-toggle`. \ No newline at end of file