kopia lustrzana https://github.com/learn-awesome/learndb
Fix #36 Use real masonry layout using svelte-bricks
rodzic
29c40f282b
commit
0f9baafbc3
|
@ -15,6 +15,7 @@
|
||||||
"d3-hierarchy": "^3.1.2",
|
"d3-hierarchy": "^3.1.2",
|
||||||
"marked": "^4.2.4",
|
"marked": "^4.2.4",
|
||||||
"svelte": "^3.55.0",
|
"svelte": "^3.55.0",
|
||||||
|
"svelte-bricks": "^0.1.7",
|
||||||
"vite": "^4.0.3"
|
"vite": "^4.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -797,6 +798,12 @@
|
||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svelte-bricks": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-bricks/-/svelte-bricks-0.1.7.tgz",
|
||||||
|
"integrity": "sha512-2wJseuhlVYVRoCKJGQuwCySTMsvBVS4dchah6Ecz9RNng0zufx6NxToXc7iGf0QOHjo9wwAsOczRI+Ou2q4gEg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/svelte-hmr": {
|
"node_modules/svelte-hmr": {
|
||||||
"version": "0.15.1",
|
"version": "0.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
||||||
|
@ -1387,6 +1394,12 @@
|
||||||
"integrity": "sha512-uGu2FVMlOuey4JoKHKrpZFkoYyj0VLjJdz47zX5+gVK5odxHM40RVhar9/iK2YFRVxvfg9FkhfVlR0sjeIrOiA==",
|
"integrity": "sha512-uGu2FVMlOuey4JoKHKrpZFkoYyj0VLjJdz47zX5+gVK5odxHM40RVhar9/iK2YFRVxvfg9FkhfVlR0sjeIrOiA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"svelte-bricks": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-bricks/-/svelte-bricks-0.1.7.tgz",
|
||||||
|
"integrity": "sha512-2wJseuhlVYVRoCKJGQuwCySTMsvBVS4dchah6Ecz9RNng0zufx6NxToXc7iGf0QOHjo9wwAsOczRI+Ou2q4gEg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"svelte-hmr": {
|
"svelte-hmr": {
|
||||||
"version": "0.15.1",
|
"version": "0.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"d3-hierarchy": "^3.1.2",
|
"d3-hierarchy": "^3.1.2",
|
||||||
"marked": "^4.2.4",
|
"marked": "^4.2.4",
|
||||||
"svelte": "^3.55.0",
|
"svelte": "^3.55.0",
|
||||||
|
"svelte-bricks": "^0.1.7",
|
||||||
"vite": "^4.0.3"
|
"vite": "^4.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<script>
|
||||||
|
export let parent;
|
||||||
|
|
||||||
|
function capitalize(str){
|
||||||
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function format_topic_name(topic){
|
||||||
|
if(topic.hname == undefined){
|
||||||
|
return capitalize(topic);
|
||||||
|
}
|
||||||
|
if(topic.hname.includes("/")){
|
||||||
|
return capitalize(topic.hname.split("/")[1]);
|
||||||
|
} else {
|
||||||
|
return capitalize(topic.hname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if parent && parent[0] !== 'Misc'}
|
||||||
|
<a href={"#/topic/" + parent[0].name}>
|
||||||
|
<div class="rounded shadow-md p-4 break-inside-avoid border border-secondary bg-primary_light ease-in-out duration-300 hover:rounded-3xl ">
|
||||||
|
{#if typeof(parent[0]) == "string"}
|
||||||
|
<span class="mt-1 p-1 font-extrabold text-lg text-primary underline">{ parent[0] }</span>
|
||||||
|
{:else}
|
||||||
|
<div class="group inline-flex">
|
||||||
|
<a href={"#/topic/" + parent[0].name}><span class="mt-1 p-1 text-primary font-extrabold text-lg ">{ format_topic_name(parent[0]) }</span>
|
||||||
|
<div class="w-5 mt-0.25 h-0.5 ml-1 bg-primary group-hover:w-full ease-in-out duration-300"></div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="mt-2 flex flex-wrap">
|
||||||
|
{#each parent[1].sort((t1,t2) => (t1.name.localeCompare(t2.name))) as child}
|
||||||
|
<a href={"#/topic/" + child.name} class="text-primary no-underline hover:underline hover:underline-offset-2 px-2 ">{format_topic_name(child)}</a>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if parent && parent[0] == 'Misc'}
|
||||||
|
<div class="rounded-lg shadow-md p-4 break-inside-avoid border border-secondary bg-primary_light ease-in-out duration-300 hover:rounded-3xl">
|
||||||
|
{#if typeof(parent[0]) == "string"}
|
||||||
|
<span class="mt-1 p-1 font-semibold text-lg text-primary ">{ parent[0] }</span>
|
||||||
|
{:else}
|
||||||
|
<a href={"#/topic/" + parent[0].name}><span class="mt-1 p-1 text-primary font-extrabold text-lg ">{ format_topic_name(parent[0]) }</span></a>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="mt-2 flex flex-wrap">
|
||||||
|
{#each parent[1].sort((t1,t2) => (t1.sort_index || 100) - (t2.sort_index || 100)) as child}
|
||||||
|
<a href={"#/topic/" + child.name} class="text-primary no-underline hover:underline hover:underline-offset-2 px-2 ">{format_topic_name(child)}</a>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
|
@ -1,4 +1,11 @@
|
||||||
<script>
|
<script>
|
||||||
|
import Masonry from 'svelte-bricks'
|
||||||
|
import MasonryItem from './MasonryItem.svelte';
|
||||||
|
|
||||||
|
let [minColWidth, maxColWidth, gap] = [300, 400, 15]
|
||||||
|
let width, height
|
||||||
|
// $: items = [...Array(20).keys()]
|
||||||
|
|
||||||
export let topicname = null; // undefined for top level
|
export let topicname = null; // undefined for top level
|
||||||
let topic;
|
let topic;
|
||||||
export let alltopics;
|
export let alltopics;
|
||||||
|
@ -8,17 +15,6 @@
|
||||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function format_topic_name(topic){
|
|
||||||
if(topic.hname == undefined){
|
|
||||||
return capitalize(topic);
|
|
||||||
}
|
|
||||||
if(topic.hname.includes("/")){
|
|
||||||
return capitalize(topic.hname.split("/")[1]);
|
|
||||||
} else {
|
|
||||||
return capitalize(topic.hname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function hierarchy(topic_array, parent_name){
|
function hierarchy(topic_array, parent_name){
|
||||||
let tempmap = new Map();
|
let tempmap = new Map();
|
||||||
// first pass to find all top-level objects
|
// first pass to find all top-level objects
|
||||||
|
@ -64,6 +60,13 @@
|
||||||
|
|
||||||
$: map = hierarchy(alltopics, topic?.name || null)
|
$: map = hierarchy(alltopics, topic?.name || null)
|
||||||
|
|
||||||
|
$: parents = [...map.entries()].sort((t1,t2) => (t1[0].sort_index || 100) - (t2[0].sort_index || 100))
|
||||||
|
|
||||||
|
const getId = (item) => {
|
||||||
|
if (typeof item[0] === `object`) return item[0].name
|
||||||
|
if (typeof item === `string`) return item
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -99,47 +102,18 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gap-8 columns-1 sm:columns-2 lg:columns-3 xl:columns-4 3xl:columns-5 mb-8">
|
{#if parents}
|
||||||
{#each [...map.entries()].sort((t1,t2) => (t1[0].sort_index || 100) - (t2[0].sort_index || 100)) as parent}
|
<Masonry
|
||||||
{#if parent[0] !== 'Misc'}
|
items={parents}
|
||||||
<a href={"#/topic/" + parent[0].name}>
|
{minColWidth}
|
||||||
<div class="rounded shadow-md p-4 break-inside-avoid mb-4 border border-secondary bg-primary_light ease-in-out duration-300 hover:rounded-3xl ">
|
{maxColWidth}
|
||||||
{#if typeof(parent[0]) == "string"}
|
{gap}
|
||||||
<span class="mt-1 p-1 font-extrabold text-lg text-primary underline">{ parent[0] }</span>
|
let:item
|
||||||
{:else}
|
{getId}
|
||||||
<div class="group inline-flex">
|
bind:width
|
||||||
<a href={"#/topic/" + parent[0].name}><span class="mt-1 p-1 text-primary font-extrabold text-lg ">{ format_topic_name(parent[0]) }</span>
|
bind:height
|
||||||
<div class="w-5 mt-0.25 h-0.5 ml-1 bg-primary group-hover:w-full ease-in-out duration-300"></div>
|
>
|
||||||
</a>
|
<MasonryItem parent={item}/>
|
||||||
</div>
|
</Masonry>
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="mt-2 flex flex-wrap">
|
|
||||||
{#each parent[1].sort((t1,t2) => (t1.name.localeCompare(t2.name))) as child}
|
|
||||||
<a href={"#/topic/" + child.name} class="text-primary no-underline hover:underline hover:underline-offset-2 px-2 ">{format_topic_name(child)}</a>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if parent[0] == 'Misc'}
|
|
||||||
<div class="rounded-lg shadow-md p-4 break-inside-avoid mb-4 border border-secondary bg-primary_light ease-in-out duration-300 hover:rounded-3xl">
|
|
||||||
{#if typeof(parent[0]) == "string"}
|
|
||||||
<span class="mt-1 p-1 font-semibold text-lg text-primary ">{ parent[0] }</span>
|
|
||||||
{:else}
|
|
||||||
<a href={"#/topic/" + parent[0].name}><span class="mt-1 p-1 text-primary font-extrabold text-lg ">{ format_topic_name(parent[0]) }</span></a>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<div class="mt-2 flex flex-wrap">
|
|
||||||
{#each parent[1].sort((t1,t2) => (t1.sort_index || 100) - (t2.sort_index || 100)) as child}
|
|
||||||
<a href={"#/topic/" + child.name} class="text-primary no-underline hover:underline hover:underline-offset-2 px-2 ">{format_topic_name(child)}</a>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue