mirror of
https://github.com/MadeBaruna/paimon-moe.git
synced 2024-12-22 06:25:10 +01:00
Update todo style
This commit is contained in:
parent
1a31ef2a74
commit
734b9d378a
5 changed files with 213 additions and 1311 deletions
|
@ -21,9 +21,9 @@
|
|||
"@babel/runtime": "^7.0.0",
|
||||
"@mdi/js": "^5.7.55",
|
||||
"@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-node-resolve": "^8.0.0",
|
||||
"@rollup/plugin-node-resolve": "^10.0.0",
|
||||
"@rollup/plugin-replace": "^2.3.4",
|
||||
"@rollup/plugin-url": "^5.0.0",
|
||||
"autoprefixer": "^10.0.1",
|
||||
|
@ -33,11 +33,10 @@
|
|||
"postcss-load-config": "^3.0.0",
|
||||
"postcss-nested": "^5.0.1",
|
||||
"rollup": "^2.3.4",
|
||||
"rollup-plugin-svelte": "^6.0.0",
|
||||
"rollup-plugin-svelte": "^7.0.0",
|
||||
"rollup-plugin-terser": "^7.0.0",
|
||||
"sapper": "^0.28.0",
|
||||
"svelte": "^3.17.3",
|
||||
"svelte-masonry": "^0.0.17",
|
||||
"svelte-preprocess": "^4.5.1",
|
||||
"svelte-simple-modal": "^0.6.1",
|
||||
"tailwindcss": "^1.9.5"
|
||||
|
|
|
@ -34,8 +34,10 @@ export default {
|
|||
}),
|
||||
}),
|
||||
svelte({
|
||||
dev,
|
||||
hydratable: true,
|
||||
compilerOptions: {
|
||||
dev,
|
||||
hydratable: true,
|
||||
},
|
||||
emitCss: true,
|
||||
preprocess,
|
||||
}),
|
||||
|
@ -95,9 +97,11 @@ export default {
|
|||
}),
|
||||
}),
|
||||
svelte({
|
||||
generate: 'ssr',
|
||||
hydratable: true,
|
||||
dev,
|
||||
compilerOptions: {
|
||||
generate: 'ssr',
|
||||
hydratable: true,
|
||||
dev,
|
||||
},
|
||||
preprocess,
|
||||
}),
|
||||
url({
|
||||
|
|
129
src/components/Masonry.svelte
Normal file
129
src/components/Masonry.svelte
Normal file
|
@ -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 { todos, loading } from '../stores/todo';
|
||||
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 Button from '../components/Button.svelte';
|
||||
import TodoDeleteModal from '../components/TodoDeleteModal.svelte';
|
||||
|
@ -12,6 +12,7 @@
|
|||
const { open: openModal, close: closeModal } = getContext('simple-modal');
|
||||
|
||||
let refreshLayout;
|
||||
let columnCount = 1;
|
||||
let numberFormat = Intl.NumberFormat();
|
||||
let adding = false;
|
||||
let todayOnly = false;
|
||||
|
@ -19,6 +20,8 @@
|
|||
let today = getCurrentDay();
|
||||
let summary = [];
|
||||
|
||||
let id = Math.random();
|
||||
|
||||
async function reorder(index, pos) {
|
||||
if ((index === 0 && pos === -1) || (index === $todos.length - 1 && pos === 1)) return;
|
||||
|
||||
|
@ -101,21 +104,30 @@
|
|||
return prev;
|
||||
}, {});
|
||||
|
||||
id = Math.random();
|
||||
await tick();
|
||||
refreshLayout();
|
||||
}
|
||||
|
||||
onMount(() => {});
|
||||
function updateId() {
|
||||
id = Math.random();
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await tick();
|
||||
id = Math.random();
|
||||
});
|
||||
|
||||
$: $todos, updateSummary();
|
||||
$: todayOnly, updateSummary();
|
||||
$: columnCount, updateId();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Todo List - Paimon.moe</title>
|
||||
</svelte:head>
|
||||
<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>
|
||||
<div class="bg-item rounded-xl p-4 text-white">
|
||||
{#if $loading}
|
||||
|
@ -236,6 +248,9 @@
|
|||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{#if (i + 1) % (columnCount - 1) === 0}
|
||||
<div />
|
||||
{/if}
|
||||
{/each}
|
||||
</Masonry>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue