1
0
mirror of https://github.com/morris/vanilla-todo.git synced 2025-08-21 21:25:25 +02:00

add dark mode

This commit is contained in:
Morris Brodersen
2024-12-29 14:27:21 +01:00
parent 044178a234
commit 93e0766bea
13 changed files with 95 additions and 45 deletions

View File

@@ -889,6 +889,7 @@ Thanks!
### 12/2024
- Add dark mode
- Add Playwright config for testing more browsers
- Update dependencies

View File

@@ -1,25 +0,0 @@
{
"root": true,
"extends": ["eslint:recommended", "plugin:compat/recommended"],
"globals": {
"Set": "readonly",
"Map": "readonly"
},
"env": {
"browser": true
},
"parserOptions": {
"ecmaVersion": 5
},
"rules": {},
"settings": {
"polyfills": [
"Set",
"Map",
"fetch",
"Object.assign",
"requestAnimationFrame",
"performance.now"
]
}
}

View File

@@ -1,10 +0,0 @@
{
"extends": ["stylelint-config-standard", "stylelint-rscss/config"],
"rules": {
"property-no-vendor-prefix": null,
"selector-class-pattern": "[a-z\\-][a-z0-9\\-]+",
"media-feature-range-notation": "prefix",
"color-function-notation": "legacy",
"declaration-block-no-redundant-longhand-properties": null
}
}

View File

@@ -5,7 +5,6 @@
color: #999;
}
/* stylelint-disable-next-line rscss/no-descendant-combinator */
.app-footer a {
color: #999;
}

View File

@@ -7,9 +7,11 @@ const cache = {};
* @param {HTMLElement} el
*/
export function AppIcon(el) {
if (el.children.length > 0) return;
if (el.dataset.lid === el.dataset.id) return;
const id = el.dataset.id;
el.dataset.lid = id;
let promise = cache[id];
if (!promise) {

View File

@@ -18,6 +18,9 @@ export function TodoApp(el) {
VANILLA TODO
</h1>
<p class="actions">
<label class="app-button invertcolorscheme" title="Enable dark mode">
<i class="app-icon" data-id="moon-16"></i>
</label>
<label class="app-button import" title="Import data">
<i class="app-icon" data-id="upload-16"></i>
<input type="file" name="importFile" hidden>
@@ -60,6 +63,14 @@ export function TodoApp(el) {
TodoFrameDays(el.querySelector('.todo-frame.-days'));
TodoFrameCustom(el.querySelector('.todo-frame.-custom'));
el.querySelector(
'.app-header > .actions > .invertcolorscheme',
).addEventListener('click', () => {
localStorage.invertColorScheme =
localStorage.invertColorScheme === 'true' ? 'false' : 'true';
update();
});
el.querySelector('[name=importFile]').addEventListener('change', (e) => {
const f = e.target.files[0];
if (!f) return;
@@ -153,6 +164,26 @@ export function TodoApp(el) {
el.querySelectorAll('.app-collapsible').forEach((el) =>
el.dispatchEvent(new CustomEvent('collapse')),
);
updateColorScheme();
}
function updateColorScheme() {
const prefersDarkColorScheme = window.matchMedia(
'(prefers-color-scheme: dark)',
).matches;
const invertColorScheme = localStorage.invertColorScheme === 'true';
document.body.classList.toggle('-invertcolorscheme', invertColorScheme);
const iconEl = el.querySelector(
'.app-header > .actions > .invertcolorscheme > .app-icon',
);
iconEl.dataset.id =
prefersDarkColorScheme === invertColorScheme ? 'moon-16' : 'sun-16';
AppIcon(iconEl);
}
function beforeFlip(e) {

View File

@@ -31,19 +31,16 @@
width: 100%;
}
/* stylelint-disable-next-line rscss/class-format */
.app-date-picker > .dates > thead > tr > th {
font-weight: normal;
text-transform: uppercase;
padding-bottom: 0.4em;
}
/* stylelint-disable-next-line rscss/class-format */
.app-date-picker > .dates > tbody > tr > td {
padding: 0;
}
/* stylelint-disable-next-line rscss/class-format */
.app-date-picker > .dates > tbody > tr > td > button {
width: 100%;
height: 1.9em;

View File

@@ -8,7 +8,6 @@
margin: 0;
}
/* stylelint-disable-next-line rscss/no-descendant-combinator */
.app-footer a {
color: var(--aside-text);
}

View File

@@ -12,12 +12,11 @@ html,
body {
margin: 0;
padding: 0;
height: 100%;
background: var(--main-bg);
color: var(--main-text);
}
body {
background: var(--main-bg);
color: var(--main-text);
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, Helvetica, 'Helvetica Neue',
Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif;

View File

@@ -37,6 +37,8 @@
outline: 0;
border-radius: 0;
vertical-align: middle;
color: inherit;
background: inherit;
}
.todo-custom-list > .header > .form > .delete {
@@ -57,7 +59,7 @@
box-shadow:
10px 0 12px -14px rgb(0 0 0 / 30%),
-10px 0 12px -14px rgb(0 0 0 / 30%);
background: #fff;
background: var(--main-bg);
opacity: 0.8;
}

View File

@@ -18,6 +18,7 @@
font-size: inherit;
line-height: 1.5em;
background: transparent;
color: inherit;
}
.todo-item-input > .save {

View File

@@ -56,6 +56,7 @@
font-size: inherit;
line-height: 1.5em;
background: transparent;
color: inherit;
}
.todo-item > .form > .save {

View File

@@ -24,3 +24,56 @@
--button-active-bg: var(--grey4);
--button-highlight-text: var(--red);
}
.-invertcolorscheme {
--main-text: var(--white);
--main-bg: var(--black);
--main-border: var(--grey3);
--main-border-light: var(--grey2);
--header-text: var(--grey2);
--header-bg: var(--black);
--highlight-text: var(--red);
--disabled-text: var(--grey1);
--aside-text: var(--grey2);
--button-text: var(--grey2);
--button-bg: transparent;
--button-active-text: var(--white);
--button-active-bg: var(--grey1);
--button-highlight-text: var(--red);
}
@media (prefers-color-scheme: dark) {
:root {
--main-text: var(--white);
--main-bg: var(--black);
--main-border: var(--grey3);
--main-border-light: var(--grey2);
--header-text: var(--grey2);
--header-bg: var(--black);
--highlight-text: var(--red);
--disabled-text: var(--grey1);
--aside-text: var(--grey2);
--button-text: var(--grey2);
--button-bg: transparent;
--button-active-text: var(--white);
--button-active-bg: var(--grey1);
--button-highlight-text: var(--red);
}
.-invertcolorscheme {
--main-text: var(--black);
--main-bg: var(--white);
--main-border: var(--grey2);
--main-border-light: var(--grey3);
--header-text: var(--grey1);
--header-bg: var(--white);
--highlight-text: var(--red);
--disabled-text: var(--grey2);
--aside-text: var(--grey1);
--button-text: var(--grey1);
--button-bg: transparent;
--button-active-text: var(--black);
--button-active-bg: var(--grey4);
--button-highlight-text: var(--red);
}
}