Update todo style
parent
1a31ef2a74
commit
734b9d378a
|
@ -21,9 +21,9 @@
|
||||||
"@babel/runtime": "^7.0.0",
|
"@babel/runtime": "^7.0.0",
|
||||||
"@mdi/js": "^5.7.55",
|
"@mdi/js": "^5.7.55",
|
||||||
"@rollup/plugin-babel": "^5.0.0",
|
"@rollup/plugin-babel": "^5.0.0",
|
||||||
"@rollup/plugin-commonjs": "^14.0.0",
|
"@rollup/plugin-commonjs": "^16.0.0",
|
||||||
"@rollup/plugin-dynamic-import-vars": "^1.1.0",
|
"@rollup/plugin-dynamic-import-vars": "^1.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^8.0.0",
|
"@rollup/plugin-node-resolve": "^10.0.0",
|
||||||
"@rollup/plugin-replace": "^2.3.4",
|
"@rollup/plugin-replace": "^2.3.4",
|
||||||
"@rollup/plugin-url": "^5.0.0",
|
"@rollup/plugin-url": "^5.0.0",
|
||||||
"autoprefixer": "^10.0.1",
|
"autoprefixer": "^10.0.1",
|
||||||
|
@ -33,11 +33,10 @@
|
||||||
"postcss-load-config": "^3.0.0",
|
"postcss-load-config": "^3.0.0",
|
||||||
"postcss-nested": "^5.0.1",
|
"postcss-nested": "^5.0.1",
|
||||||
"rollup": "^2.3.4",
|
"rollup": "^2.3.4",
|
||||||
"rollup-plugin-svelte": "^6.0.0",
|
"rollup-plugin-svelte": "^7.0.0",
|
||||||
"rollup-plugin-terser": "^7.0.0",
|
"rollup-plugin-terser": "^7.0.0",
|
||||||
"sapper": "^0.28.0",
|
"sapper": "^0.28.0",
|
||||||
"svelte": "^3.17.3",
|
"svelte": "^3.17.3",
|
||||||
"svelte-masonry": "^0.0.17",
|
|
||||||
"svelte-preprocess": "^4.5.1",
|
"svelte-preprocess": "^4.5.1",
|
||||||
"svelte-simple-modal": "^0.6.1",
|
"svelte-simple-modal": "^0.6.1",
|
||||||
"tailwindcss": "^1.9.5"
|
"tailwindcss": "^1.9.5"
|
||||||
|
|
|
@ -34,8 +34,10 @@ export default {
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
svelte({
|
svelte({
|
||||||
dev,
|
compilerOptions: {
|
||||||
hydratable: true,
|
dev,
|
||||||
|
hydratable: true,
|
||||||
|
},
|
||||||
emitCss: true,
|
emitCss: true,
|
||||||
preprocess,
|
preprocess,
|
||||||
}),
|
}),
|
||||||
|
@ -95,9 +97,11 @@ export default {
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
svelte({
|
svelte({
|
||||||
generate: 'ssr',
|
compilerOptions: {
|
||||||
hydratable: true,
|
generate: 'ssr',
|
||||||
dev,
|
hydratable: true,
|
||||||
|
dev,
|
||||||
|
},
|
||||||
preprocess,
|
preprocess,
|
||||||
}),
|
}),
|
||||||
url({
|
url({
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
<script>
|
||||||
|
import { onMount, onDestroy, getContext, setContext, tick } from 'svelte';
|
||||||
|
export let stretchFirst = false,
|
||||||
|
columnCount,
|
||||||
|
gridGap = '0.5em',
|
||||||
|
colWidth = 'minmax(Min(20em, 100%), 1fr)',
|
||||||
|
items = []; // pass in data if it's dynamically updated
|
||||||
|
let grids = [],
|
||||||
|
masonryElement;
|
||||||
|
|
||||||
|
export const refreshLayout = async () => {
|
||||||
|
grids.forEach(async (grid) => {
|
||||||
|
/* get the post relayout number of columns */
|
||||||
|
let ncol = getComputedStyle(grid._el).gridTemplateColumns.split(' ').length;
|
||||||
|
columnCount = ncol;
|
||||||
|
|
||||||
|
grid.items.forEach((c) => {
|
||||||
|
let new_h = c.getBoundingClientRect().height;
|
||||||
|
|
||||||
|
if (new_h !== +c.dataset.h) {
|
||||||
|
c.dataset.h = new_h;
|
||||||
|
grid.mod++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* if the number of columns has changed */
|
||||||
|
if (grid.ncol !== ncol || grid.mod) {
|
||||||
|
/* update number of columns */
|
||||||
|
grid.ncol = ncol;
|
||||||
|
/* revert to initial positioning, no margin */
|
||||||
|
grid.items.forEach((c) => c.style.removeProperty('margin-top'));
|
||||||
|
/* if we have more than one column */
|
||||||
|
if (grid.ncol > 1) {
|
||||||
|
grid.items.slice(ncol).forEach((c, i) => {
|
||||||
|
let prev_fin = grid.items[i].getBoundingClientRect().bottom /* bottom edge of item above */,
|
||||||
|
curr_ini = c.getBoundingClientRect().top; /* top edge of current item */
|
||||||
|
|
||||||
|
c.style.marginTop = `${prev_fin + grid.gap - curr_ini}px`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
grid.mod = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const calcGrid = async (_masonryArr) => {
|
||||||
|
await tick();
|
||||||
|
if (_masonryArr.length && getComputedStyle(_masonryArr[0]).gridTemplateRows !== 'masonry') {
|
||||||
|
grids = _masonryArr.map((grid) => {
|
||||||
|
return {
|
||||||
|
_el: grid,
|
||||||
|
gap: parseFloat(getComputedStyle(grid).gridRowGap),
|
||||||
|
items: [...grid.childNodes].filter((c) => c.nodeType === 1 && +getComputedStyle(c).gridColumnEnd !== -1),
|
||||||
|
ncol: 0,
|
||||||
|
mod: 0,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
refreshLayout(); /* initial load */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let _window;
|
||||||
|
onMount(() => {
|
||||||
|
_window = window;
|
||||||
|
_window.addEventListener('resize', refreshLayout, false); /* on resize */
|
||||||
|
});
|
||||||
|
onDestroy(() => {
|
||||||
|
if (_window) {
|
||||||
|
_window.removeEventListener('resize', refreshLayout, false); /* on resize */
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$: if (masonryElement) {
|
||||||
|
calcGrid([masonryElement]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (items) {
|
||||||
|
// update if items are changed
|
||||||
|
masonryElement = masonryElement; // refresh masonryElement
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
$w: var(--col-width); // minmax(Min(20em, 100%), 1fr);
|
||||||
|
$s: var(--grid-gap); // .5em;
|
||||||
|
-->
|
||||||
|
<style>
|
||||||
|
:global(.__grid--masonry) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, var(--col-width));
|
||||||
|
grid-template-rows: masonry;
|
||||||
|
justify-content: center;
|
||||||
|
grid-gap: var(--grid-gap);
|
||||||
|
padding: var(--grid-gap);
|
||||||
|
}
|
||||||
|
:global(.__grid--masonry > *) {
|
||||||
|
align-self: start;
|
||||||
|
}
|
||||||
|
:global(.__grid--masonry.__stretch-first > *:first-child) {
|
||||||
|
grid-column: 1/ -1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
An almost direct copy and paste of: https://css-tricks.com/a-lightweight-masonry-solution
|
||||||
|
Usage:
|
||||||
|
- stretchFirst stretches the first item across the top
|
||||||
|
<Masonry stretchFirst={true} >
|
||||||
|
{#each data as o}
|
||||||
|
<div class="_card _padding">
|
||||||
|
Here's some stuff {o.name}
|
||||||
|
<header>
|
||||||
|
<h3>{o.name}</h3>
|
||||||
|
</header>
|
||||||
|
<section>
|
||||||
|
<p>{o.text}</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</Masonry>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={masonryElement}
|
||||||
|
class={`__grid--masonry ${stretchFirst ? '__stretch-first' : ''}`}
|
||||||
|
style={`--grid-gap: ${gridGap}; --col-width: ${colWidth};`}>
|
||||||
|
<slot />
|
||||||
|
</div>
|
|
@ -3,7 +3,7 @@
|
||||||
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiLoading } from '@mdi/js';
|
import { mdiChevronLeft, mdiChevronRight, mdiClose, mdiLoading } from '@mdi/js';
|
||||||
import { todos, loading } from '../stores/todo';
|
import { todos, loading } from '../stores/todo';
|
||||||
import { itemList } from '../data/itemList';
|
import { itemList } from '../data/itemList';
|
||||||
import Masonry from 'svelte-masonry/Masonry.svelte';
|
import Masonry from '../components/Masonry.svelte';
|
||||||
import Icon from '../components/Icon.svelte';
|
import Icon from '../components/Icon.svelte';
|
||||||
import Button from '../components/Button.svelte';
|
import Button from '../components/Button.svelte';
|
||||||
import TodoDeleteModal from '../components/TodoDeleteModal.svelte';
|
import TodoDeleteModal from '../components/TodoDeleteModal.svelte';
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
const { open: openModal, close: closeModal } = getContext('simple-modal');
|
const { open: openModal, close: closeModal } = getContext('simple-modal');
|
||||||
|
|
||||||
let refreshLayout;
|
let refreshLayout;
|
||||||
|
let columnCount = 1;
|
||||||
let numberFormat = Intl.NumberFormat();
|
let numberFormat = Intl.NumberFormat();
|
||||||
let adding = false;
|
let adding = false;
|
||||||
let todayOnly = false;
|
let todayOnly = false;
|
||||||
|
@ -19,6 +20,8 @@
|
||||||
let today = getCurrentDay();
|
let today = getCurrentDay();
|
||||||
let summary = [];
|
let summary = [];
|
||||||
|
|
||||||
|
let id = Math.random();
|
||||||
|
|
||||||
async function reorder(index, pos) {
|
async function reorder(index, pos) {
|
||||||
if ((index === 0 && pos === -1) || (index === $todos.length - 1 && pos === 1)) return;
|
if ((index === 0 && pos === -1) || (index === $todos.length - 1 && pos === 1)) return;
|
||||||
|
|
||||||
|
@ -101,21 +104,30 @@
|
||||||
return prev;
|
return prev;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
id = Math.random();
|
||||||
await tick();
|
await tick();
|
||||||
refreshLayout();
|
refreshLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {});
|
function updateId() {
|
||||||
|
id = Math.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await tick();
|
||||||
|
id = Math.random();
|
||||||
|
});
|
||||||
|
|
||||||
$: $todos, updateSummary();
|
$: $todos, updateSummary();
|
||||||
$: todayOnly, updateSummary();
|
$: todayOnly, updateSummary();
|
||||||
|
$: columnCount, updateId();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Todo List - Paimon.moe</title>
|
<title>Todo List - Paimon.moe</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
<div class="lg:ml-64 pt-20 px-2 md:px-8 lg:pt-8">
|
<div class="lg:ml-64 pt-20 px-2 md:px-8 lg:pt-8">
|
||||||
<Masonry stretchFirst={true} bind:refreshLayout>
|
<Masonry stretchFirst={true} bind:refreshLayout bind:columnCount items={id}>
|
||||||
<h1 class="font-display font-black text-3xl lg:text-left lg:text-5xl text-white">Todo List</h1>
|
<h1 class="font-display font-black text-3xl lg:text-left lg:text-5xl text-white">Todo List</h1>
|
||||||
<div class="bg-item rounded-xl p-4 text-white">
|
<div class="bg-item rounded-xl p-4 text-white">
|
||||||
{#if $loading}
|
{#if $loading}
|
||||||
|
@ -236,6 +248,9 @@
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{#if (i + 1) % (columnCount - 1) === 0}
|
||||||
|
<div />
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</Masonry>
|
</Masonry>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue