mirror of
https://github.com/morris/vanilla-todo.git
synced 2025-08-22 13:43:06 +02:00
add dark mode
This commit is contained in:
@@ -889,6 +889,7 @@ Thanks!
|
|||||||
|
|
||||||
### 12/2024
|
### 12/2024
|
||||||
|
|
||||||
|
- Add dark mode
|
||||||
- Add Playwright config for testing more browsers
|
- Add Playwright config for testing more browsers
|
||||||
- Update dependencies
|
- Update dependencies
|
||||||
|
|
||||||
|
@@ -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"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@@ -5,7 +5,6 @@
|
|||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line rscss/no-descendant-combinator */
|
|
||||||
.app-footer a {
|
.app-footer a {
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
@@ -7,9 +7,11 @@ const cache = {};
|
|||||||
* @param {HTMLElement} el
|
* @param {HTMLElement} el
|
||||||
*/
|
*/
|
||||||
export function AppIcon(el) {
|
export function AppIcon(el) {
|
||||||
if (el.children.length > 0) return;
|
if (el.dataset.lid === el.dataset.id) return;
|
||||||
|
|
||||||
const id = el.dataset.id;
|
const id = el.dataset.id;
|
||||||
|
el.dataset.lid = id;
|
||||||
|
|
||||||
let promise = cache[id];
|
let promise = cache[id];
|
||||||
|
|
||||||
if (!promise) {
|
if (!promise) {
|
||||||
|
@@ -18,6 +18,9 @@ export function TodoApp(el) {
|
|||||||
VANILLA TODO
|
VANILLA TODO
|
||||||
</h1>
|
</h1>
|
||||||
<p class="actions">
|
<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">
|
<label class="app-button import" title="Import data">
|
||||||
<i class="app-icon" data-id="upload-16"></i>
|
<i class="app-icon" data-id="upload-16"></i>
|
||||||
<input type="file" name="importFile" hidden>
|
<input type="file" name="importFile" hidden>
|
||||||
@@ -60,6 +63,14 @@ export function TodoApp(el) {
|
|||||||
TodoFrameDays(el.querySelector('.todo-frame.-days'));
|
TodoFrameDays(el.querySelector('.todo-frame.-days'));
|
||||||
TodoFrameCustom(el.querySelector('.todo-frame.-custom'));
|
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) => {
|
el.querySelector('[name=importFile]').addEventListener('change', (e) => {
|
||||||
const f = e.target.files[0];
|
const f = e.target.files[0];
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
@@ -153,6 +164,26 @@ export function TodoApp(el) {
|
|||||||
el.querySelectorAll('.app-collapsible').forEach((el) =>
|
el.querySelectorAll('.app-collapsible').forEach((el) =>
|
||||||
el.dispatchEvent(new CustomEvent('collapse')),
|
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) {
|
function beforeFlip(e) {
|
||||||
|
@@ -31,19 +31,16 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line rscss/class-format */
|
|
||||||
.app-date-picker > .dates > thead > tr > th {
|
.app-date-picker > .dates > thead > tr > th {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
padding-bottom: 0.4em;
|
padding-bottom: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line rscss/class-format */
|
|
||||||
.app-date-picker > .dates > tbody > tr > td {
|
.app-date-picker > .dates > tbody > tr > td {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line rscss/class-format */
|
|
||||||
.app-date-picker > .dates > tbody > tr > td > button {
|
.app-date-picker > .dates > tbody > tr > td > button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 1.9em;
|
height: 1.9em;
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line rscss/no-descendant-combinator */
|
|
||||||
.app-footer a {
|
.app-footer a {
|
||||||
color: var(--aside-text);
|
color: var(--aside-text);
|
||||||
}
|
}
|
||||||
|
@@ -12,12 +12,11 @@ html,
|
|||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
|
||||||
background: var(--main-bg);
|
|
||||||
color: var(--main-text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
background: var(--main-bg);
|
||||||
|
color: var(--main-text);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica, 'Helvetica Neue',
|
font-family: -apple-system, BlinkMacSystemFont, Helvetica, 'Helvetica Neue',
|
||||||
Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif;
|
Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif;
|
||||||
|
@@ -37,6 +37,8 @@
|
|||||||
outline: 0;
|
outline: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
color: inherit;
|
||||||
|
background: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-custom-list > .header > .form > .delete {
|
.todo-custom-list > .header > .form > .delete {
|
||||||
@@ -57,7 +59,7 @@
|
|||||||
box-shadow:
|
box-shadow:
|
||||||
10px 0 12px -14px rgb(0 0 0 / 30%),
|
10px 0 12px -14px rgb(0 0 0 / 30%),
|
||||||
-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;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-item-input > .save {
|
.todo-item-input > .save {
|
||||||
|
@@ -56,6 +56,7 @@
|
|||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.todo-item > .form > .save {
|
.todo-item > .form > .save {
|
||||||
|
@@ -24,3 +24,56 @@
|
|||||||
--button-active-bg: var(--grey4);
|
--button-active-bg: var(--grey4);
|
||||||
--button-highlight-text: var(--red);
|
--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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user