merged staging, updated components from last pr typahead inputs. Added SearchLayout for the templates, components, and tooling routes. Looks feasible for now, but still needs an overhaul of the components used in those routes.

This commit is contained in:
brittneypostma
2021-09-04 13:42:06 -04:00
parent 237359ccb0
commit 6fd8668c85
10 changed files with 210 additions and 403 deletions

View File

@@ -6,6 +6,7 @@
"$layout": ["src/lib/components/layout"], "$layout": ["src/lib/components/layout"],
"$layouts": ["src/lib/layouts"], "$layouts": ["src/lib/layouts"],
"$lib": ["src/lib"], "$lib": ["src/lib"],
"$utils": ["src/lib/utils"],
"$styles": ["src/lib/styles"], "$styles": ["src/lib/styles"],
"$stores": ["src/lib/stores"] "$stores": ["src/lib/stores"]
} }

View File

@@ -8,23 +8,23 @@
div { div {
font-size: 1rem; font-size: 1rem;
border: 2px solid var(--dark-gray); border: 2px solid var(--dark-gray);
border-radius: 5px; border-radius: 3px;
height: 100%;
background-color: white; background-color: white;
color: var(--dark-gray); color: var(--dark-gray);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 5px 15px; padding: var(--s-2);
position: relative; position: relative;
} }
div.small { div.small {
font-size: var(--font-100); font-size: var(--font-100);
padding: 3px 10px;
} }
div:hover { div:hover {
cursor: pointer; cursor: pointer;
border-color: var(--primary); border-color: var(--secondary);
color: var(--primary); color: var(--secondary);
} }
.arrow { .arrow {
@@ -35,7 +35,7 @@
background-color: var(--dark-gray); background-color: var(--dark-gray);
} }
div:hover .arrow { div:hover .arrow {
background-color: var(--dark-gray); background-color: var(--secondary);
} }
.arrow.active { .arrow.active {
background-color: var(--dark-gray); background-color: var(--dark-gray);
@@ -52,7 +52,7 @@
z-index: 100; z-index: 100;
margin: 0; margin: 0;
padding: 0; padding: 0;
border: 2px solid var(--primary); border: 2px solid var(--secondary);
border-radius: 5px; border-radius: 5px;
background: white; background: white;
} }

View File

@@ -17,14 +17,12 @@
font-size: 0.875rem; font-size: 0.875rem;
} }
.themed { .themed {
--inputFontSize: 0.875rem; /* --inputFontSize: 0.875rem; */
--multiItemActiveBG: var(--color); --multiItemActiveBG: var(--secondary);
--height: 1rem; --borderHoverColor: var(--secondary);
--borderHoverColor: var(--color); --borderFocusColor: var(--secondary);
--borderFocusColor: var(--color); --itemIsActiveBG: var(--secondary);
--itemHoverBG: var(--color-shadow); /* --indicatorTop: calc(50% - 13px); */
--itemIsActiveBG: var(--color);
--indicatorTop: calc(50% - 13px);
position: relative; position: relative;
display: flex; display: flex;
@@ -35,7 +33,7 @@
cursor: pointer; cursor: pointer;
flex: 1; flex: 1;
align-items: center; align-items: center;
padding: 1rem; padding: var(--s-2);
gap: 10px; gap: 10px;
min-width: 150px; min-width: 150px;
min-height: 3rem; min-height: 3rem;
@@ -44,12 +42,12 @@
.themed :global(.multiSelectItem) { .themed :global(.multiSelectItem) {
font-size: 0.875rem; font-size: 0.875rem;
align-items: center; align-items: center;
--multiItemBorderRadius: var(--radius-100); --multiItemBorderRadius: var(--s-1);
--multiItemHeight: 1.25rem; --multiItemHeight: 1.25rem;
--multiItemMargin: 0; --multiItemMargin: 0;
--multiItemPadding: 0.2rem 0.3rem; --multiItemPadding: 0.2rem 0.3rem;
--multiClearBG: transparent; --multiClearBG: transparent;
--multiClearFill: var(--color-text-secondary); --multiClearFill: var(--secondary);
--multiClearHoverBG: transparent; --multiClearHoverBG: transparent;
--multiClearHoverFill: var(--color-bg); --multiClearHoverFill: var(--color-bg);
--multiLabelMargin: 1px 5px 0 0; --multiLabelMargin: 1px 5px 0 0;
@@ -65,7 +63,4 @@
cursor: pointer; cursor: pointer;
} }
.themed :global(.listItem) {
--height: 1.4rem;
}
</style> </style>

View File

@@ -0,0 +1,8 @@
<script>
export let title;
</script>
<h1>{title}</h1>
<slot name="controls" />
<hr />
<slot name="items" />

View File

@@ -93,3 +93,107 @@ li {
place-items: center; place-items: center;
place-content: center; place-content: center;
} }
/***********TEMPLATES & COMPONENTS STYLES***********/
hr {
margin-block: 4rem;
}
.submit {
position: absolute;
top: calc(100% + 1rem);
left: 0;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
font-family: Overpass;
position: relative;
}
.inputs {
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 0.5rem;
margin-right: 2rem;
}
.searchbar {
align-self: flex-start;
width: 35%;
font-family: Overpass;
border-width: 0;
background: #f3f6f9 url(/images/search-icon.svg) 98% no-repeat;
margin: 0;
padding: 10px 15px;
border: 1px solid transparent;
}
.searchbar:focus {
outline: none;
border: 1px solid var(--secondary);
}
.searchbar-count {
position: absolute;
top: calc(100% + 1rem);
right: 0;
}
ul.popin {
padding: 0.5ex;
margin: 0;
font-size: 0.7em;
max-height: 50vh;
overflow-y: auto;
}
ul.popin li {
list-style: none;
padding: 0;
margin: 0;
text-transform: capitalize;
}
ul.popin li:hover {
background: #eee;
border-radius: 3px;
}
ul.popin li.tag-search {
position: sticky;
top: -0.5ex;
margin: 0 -0.5ex;
padding: 0.5ex;
border-radius: 4px;
background: white;
}
ul.popin li.tag-search input {
margin: 0;
background: #f3f6f9;
width: 100%;
min-width: 15ch;
}
ul.popin li.tag-search:hover {
background: white;
}
ul.popin.no-wrap li {
white-space: nowrap;
}
ul.popin li label {
display: flex;
align-items: center;
line-height: 0.7rem;
padding: 0.8ex;
}
ul.popin li input {
flex: 0;
margin: 0 1ex 0 0;
}
@media screen and (max-width: 1024px) {
.controls {
flex-flow: column-reverse;
align-items: stretch;
}
.inputs {
grid-template-columns: auto;
width: 100%;
}
.searchbar {
align-self: flex-start;
margin-bottom: 1ex;
width: var(--s-full);
}
}

View File

@@ -30,10 +30,4 @@
main { main {
padding: var(--s-10) var(--s-5) var(--s-20); padding: var(--s-10) var(--s-5) var(--s-20);
} }
@media (min-width: 1024px) {
main {
padding: var(--s-20) 0 var(--s-40);
}
}
</style> </style>

View File

@@ -1,18 +1,16 @@
<script> <script>
import SearchLayout from '$layouts/SearchLayout.svelte';
import ComponentCard from '$lib/components/ComponentIndex/Card.svelte'; import ComponentCard from '$lib/components/ComponentIndex/Card.svelte';
import List from '$lib/components/ComponentIndex/CardList.svelte'; import List from '$components/ComponentIndex/CardList.svelte';
import Button from '$lib/components/ComponentIndex/ArrowButton.svelte'; import Button from '$components/ComponentIndex/ArrowButton.svelte';
import components from './components.json'; import components from './components.json';
import { compare, selectSortItems } from '$lib/utils/sort'; import { compare, selectSortItems } from '$lib/utils/sort';
import Select from '$components/Select.svelte'; import Select from '$components/Select.svelte';
let searchValue; let searchValue;
const tags = Array.from(new Set(components.map((item) => item.tags).flat())); const tags = Array.from(new Set(components.map((item) => item.tags).flat()));
const tagItems = tags.map((t) => ({ label: t, value: t })); const tagItems = tags.map((t) => ({ label: t, value: t }));
let filterTag = []; let filterTag = [];
let selectedTags = null; let selectedTags = null;
const allCategories = Array.from(new Set(components.map((item) => item.category).flat())); const allCategories = Array.from(new Set(components.map((item) => item.category).flat()));
const categoryItems = [ const categoryItems = [
{ label: 'All', value: null }, { label: 'All', value: null },
@@ -20,22 +18,17 @@
]; ];
let selectedCategory = null; let selectedCategory = null;
let filterCategory = null; let filterCategory = null;
let sorting = 'stars_desc'; let sorting = 'stars_desc';
let selectedSorting = { value: 'stars_desc', label: 'Stars Desc' }; let selectedSorting = { value: 'stars_desc', label: 'Stars Desc' };
$: sorting = selectedSorting?.value || 'stars_desc'; $: sorting = selectedSorting?.value || 'stars_desc';
let packageManager = 'npm'; let packageManager = 'npm';
const intersection = (array1, array2) => { const intersection = (array1, array2) => {
return array1.filter((item) => array2.includes(item)); return array1.filter((item) => array2.includes(item));
}; };
$: filterCategory = selectedCategory?.value || null; $: filterCategory = selectedCategory?.value || null;
$: dataToDisplay = components $: dataToDisplay = components
.filter((component) => { .filter((component) => {
if (!searchValue && filterTag.length === 0 && filterCategory === null) return true; if (!searchValue && filterTag.length === 0 && filterCategory === null) return true;
if ( if (
(searchValue && (searchValue &&
!( !(
@@ -47,11 +40,9 @@
) { ) {
return false; return false;
} }
return true; return true;
}) })
.sort(compare(sorting)); .sort(compare(sorting));
$: categories = Array.from(new Set(dataToDisplay.map((item) => item.category))); $: categories = Array.from(new Set(dataToDisplay.map((item) => item.category)));
$: filterTag = selectedTags?.map((obj) => obj.value) || []; $: filterTag = selectedTags?.map((obj) => obj.value) || [];
</script> </script>
@@ -60,193 +51,58 @@
<title>Components - Svelte Society</title> <title>Components - Svelte Society</title>
</svelte:head> </svelte:head>
<main class="wrapper"> <SearchLayout title="Components">
<h1>Components</h1> <section class="controls" slot="controls">
<div class="controls">
<div class="inputs"> <div class="inputs">
<Button active={filterTag.length > 0}> <Select bind:value={selectedTags} items={tagItems} isMulti label="Tags" />
Tags {#if filterTag.length > 0}<small>({filterTag.length})</small>{/if} <Select
<ul slot="menu" role="menu" class="popin"> label="Category"
<li class="tag-search"><input placeholder="Search for tags..." bind:value={searchTag} /></li> bind:value={selectedCategory}
{#each tagSearchResult as tag} items={categoryItems}
<li><label><input type="checkbox" bind:group={filterTag} value={tag}> {tag}</label></li> placeholder="Category"
{/each} isClearable={false}
</ul> showIndicator
</Button> />
<Button active={filterCategory !== null}> <Select
Categories items={selectSortItems}
<ul slot="menu" role="menu" class="popin"> bind:value={selectedSorting}
<li><label><input type="radio" bind:group={filterCategory} value={null}> All</label></li> label="Sorting"
{#each allCategories as category} showIndicator
<li><label><input type="radio" bind:group={filterCategory} value={category}> {category||"Unclassified"}</label></li> isClearable={false}
{/each} />
</ul>
</Button>
<Button active={sorting !== ''}>
Sort
<ul slot="menu" role="menu" class="popin no-wrap">
<li><label><input type="radio" bind:group={sorting} value="added_desc"> Last Added first</label></li>
<li><label><input type="radio" bind:group={sorting} value="added_asc"> Oldest first</label></li>
<li><label><input type="radio" bind:group={sorting} value="stars_desc"> Stars Desc</label></li>
<li><label><input type="radio" bind:group={sorting} value="stars_asc"> Stars Asc</label></li>
<li><label><input type="radio" bind:group={sorting} value="name_asc"> Name Asc</label></li>
<li><label><input type="radio" bind:group={sorting} value="name_desc"> Name Desc</label></li>
</ul>
</Button>
<Button small active={packageManager !== ''}> <Button small active={packageManager !== ''}>
Package Manager Package Manager
<ul slot="menu" role="menu" class="popin no-wrap"> <ul slot="menu" role="menu" class="popin no-wrap">
<li><label><input type="radio" bind:group={packageManager} value="npm"> NPM</label></li> <li><label><input type="radio" bind:group={packageManager} value="npm" /> NPM</label></li>
<li><label><input type="radio" bind:group={packageManager} value="pnpm"> PNPM</label></li> <li>
<li><label><input type="radio" bind:group={packageManager} value="yarn"> Yarn</label></li> <label><input type="radio" bind:group={packageManager} value="pnpm" /> PNPM</label>
</li>
<li>
<label><input type="radio" bind:group={packageManager} value="yarn" /> Yarn</label>
</li>
</ul> </ul>
</Button> </Button>
<a href = "/help/components" class="submit">Submit a component</a>
</div> </div>
<a href="/help/components" class="submit">Submit a component</a>
<input <input
class="searchbar" class="searchbar"
type="text" type="text"
placeholder="Search for components..." placeholder="Search for components..."
bind:value={searchValue} /> bind:value={searchValue}
<span class="searchbar-count">{dataToDisplay.length} result{#if dataToDisplay.length !== 1}s{/if}</span> />
</div> <span class="searchbar-count"
<hr /> >{dataToDisplay.length} result{#if dataToDisplay.length !== 1}s{/if}</span
>
</section>
<section slot="items">
{#each categories as category} {#each categories as category}
<List title={category||"Unclassified"}> <List title={category || 'Unclassified'}>
{#each dataToDisplay.filter(d => d.category === category) as data} {#each dataToDisplay.filter((d) => d.category === category) as data}
<ComponentCard {...data} manager={packageManager} /> <ComponentCard {...data} manager={packageManager} />
{/each} {/each}
</List> </List>
{/each} {/each}
</main> </section>
</SearchLayout>
<style>
.submit {
align-self: flex-end;
}
hr {
margin-block: 4rem;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
font-family: Overpass;
position: relative;
}
.inputs {
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 0.5rem;
margin-right: 2rem;
}
.searchbar {
height: 100%;
width: 35%;
font-family: Overpass;
border-width: 0;
background: #f3f6f9 url(/images/search-icon.svg) 98% no-repeat;
margin: 0;
padding: 10px 15px;
}
.searchbar-count {
position: absolute;
top: 100%;
right: 0;
}
ul.popin {
padding: 0.5ex;
margin: 0;
font-size: 0.7em;
max-height: 50vh;
overflow-y: auto;
}
ul.popin li {
list-style: none;
padding: 0;
margin: 0;
text-transform: capitalize;
}
ul.popin li:hover {
background: #eee;
border-radius: 3px;
}
ul.popin li.tag-search {
position: sticky;
top: -0.5ex;
margin: 0 -0.5ex;
padding: 0.5ex;
border-radius: 4px;
background: white;
}
ul.popin li.tag-search input {
margin: 0;
background: #f3f6f9;
width: 100%;
min-width: 15ch;
}
ul.popin li.tag-search:hover {
background: white;
}
ul.popin.no-wrap li {
white-space: nowrap;
}
ul.popin li label {
display: flex;
align-items: center;
line-height: 0.7rem;
padding: 0.8ex;
}
ul.popin li input {
flex: 0;
margin: 0 1ex 0 0;
}
@media screen and (max-width: 1024px) {
.controls {
flex-flow: column-reverse;
}
.inputs {
align-self: flex-start;
width: 100%;
grid-template-columns: repeat(3, auto);
}
.searchbar {
align-self: flex-end;
margin-bottom: 1ex;
}
}
@media screen and (max-width: 700px) {
.controls {
align-items: stretch;
}
.inputs {
grid-template-columns: auto;
}
.searchbar {
width: auto;
align-self: stretch;
}
:global(.select-container) {
width: 100%;
}
}
</style>

View File

@@ -1,10 +1,10 @@
<script> <script>
import ComponentCard from '$lib/components/ComponentIndex/Card.svelte'; import ComponentCard from '$lib/components/ComponentIndex/Card.svelte';
import List from '$lib/components/ComponentIndex/CardList.svelte'; import List from '$lib/components/ComponentIndex/CardList.svelte';
import Button from '$lib/components/ComponentIndex/ArrowButton.svelte';
import components from './templates.json'; import components from './templates.json';
import { compare, selectSortItems } from '$lib/utils/sort'; import { compare, selectSortItems } from '$lib/utils/sort';
import Select from '$lib/components/Select.svelte'; import Select from '$lib/components/Select.svelte';
import SearchLayout from '$lib/layouts/SearchLayout.svelte';
let searchValue; let searchValue;
@@ -57,9 +57,8 @@
<title>Templates - Svelte Society</title> <title>Templates - Svelte Society</title>
</svelte:head> </svelte:head>
<main class="wrapper"> <SearchLayout title="Templates">
<h1>Templates</h1> <section class="controls" slot="controls">
<div class="controls">
<div class="inputs"> <div class="inputs">
<Select bind:value={selectedTags} items={tagItems} isMulti label="Tags" /> <Select bind:value={selectedTags} items={tagItems} isMulti label="Tags" />
<Select <Select
@@ -78,7 +77,7 @@
isClearable={false} isClearable={false}
/> />
<Button on:click={() => (location.href = '/help/components')}>Submit a template</Button> <a href='/help/components' class="submit">Submit a template</a>
</div> </div>
<input <input
@@ -90,8 +89,8 @@
<span class="searchbar-count" <span class="searchbar-count"
>{dataToDisplay.length} result{#if dataToDisplay.length !== 1}s{/if}</span >{dataToDisplay.length} result{#if dataToDisplay.length !== 1}s{/if}</span
> >
</div> </section>
<hr /> <section slot="items">
{#each categories as category} {#each categories as category}
<List title={category || 'Unclassified'}> <List title={category || 'Unclassified'}>
{#each dataToDisplay.filter((d) => d.category === category) as data} {#each dataToDisplay.filter((d) => d.category === category) as data}
@@ -99,81 +98,6 @@
{/each} {/each}
</List> </List>
{/each} {/each}
</main> </section>
</SearchLayout>
<style>
h1 {
@apply text-5xl;
}
hr {
margin-block: 4rem;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
font-family: Overpass;
position: relative;
}
.inputs {
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 0.5rem;
margin-right: 2rem;
padding-top: 1rem;
}
.searchbar {
height: 100%;
width: 35%;
font-family: Overpass;
border-width: 0;
background: #f3f6f9 url(/images/search-icon.svg) 98% no-repeat;
margin: 0;
padding: 10px 15px;
}
.searchbar-count {
position: absolute;
top: 100%;
right: 0;
}
@media screen and (max-width: 1024px) {
.controls {
flex-flow: column-reverse;
}
.inputs {
align-self: flex-start;
width: 100%;
grid-template-columns: repeat(3, auto);
}
.searchbar {
align-self: flex-end;
margin-bottom: 1ex;
}
}
@media screen and (max-width: 700px) {
.controls {
align-items: stretch;
}
.inputs {
grid-template-columns: auto;
}
.searchbar {
width: auto;
align-self: stretch;
}
:global(.select-container) {
width: 100%;
}
}
</style>

View File

@@ -1,7 +1,7 @@
<script> <script>
import ComponentCard from '$lib/components/ComponentIndex/Card.svelte'; import ComponentCard from '$lib/components/ComponentIndex/Card.svelte';
import List from '$lib/components/ComponentIndex/CardList.svelte'; import List from '$lib/components/ComponentIndex/CardList.svelte';
import Button from '$lib/components/ComponentIndex/ArrowButton.svelte'; import SearchLayout from '$layouts/SearchLayout.svelte';
import tools from './tools.json'; import tools from './tools.json';
import Select from '$lib/components/Select.svelte'; import Select from '$lib/components/Select.svelte';
import { compare, selectSortItems } from '$lib/utils/sort'; import { compare, selectSortItems } from '$lib/utils/sort';
@@ -56,9 +56,8 @@
<title>Tooling - Svelte Society</title> <title>Tooling - Svelte Society</title>
</svelte:head> </svelte:head>
<main class="wrapper"> <SearchLayout title="Tooling">
<h1>Tooling</h1> <section slot="controls" class="controls">
<div class="controls">
<div class="inputs"> <div class="inputs">
<Select bind:value={selectedTags} items={tagItems} isMulti label="Tags" /> <Select bind:value={selectedTags} items={tagItems} isMulti label="Tags" />
<Select <Select
@@ -76,7 +75,7 @@
showIndicator showIndicator
isClearable={false} isClearable={false}
/> />
<Button on:click={() => (location.href = '/help/components')}>Submit a tool</Button> <a href="/help/components" class="submit">Submit a tool</a>
</div> </div>
<input <input
@@ -88,8 +87,8 @@
<span class="searchbar-count" <span class="searchbar-count"
>{dataToDisplay.length} result{#if dataToDisplay.length !== 1}s{/if}</span >{dataToDisplay.length} result{#if dataToDisplay.length !== 1}s{/if}</span
> >
</div> </section>
<hr /> <section slot="items">
{#each categories as category} {#each categories as category}
<List title={category || 'Unclassified'}> <List title={category || 'Unclassified'}>
{#each dataToDisplay.filter((d) => d.category === category) as data} {#each dataToDisplay.filter((d) => d.category === category) as data}
@@ -97,81 +96,6 @@
{/each} {/each}
</List> </List>
{/each} {/each}
</main>
<style> </section>
h1 { </SearchLayout>
@apply text-5xl;
}
hr {
margin-block: 4rem;
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
font-family: Overpass;
position: relative;
}
.inputs {
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 0.5rem;
margin-right: 2rem;
}
.searchbar {
height: 100%;
width: 35%;
font-family: Overpass;
border-width: 0;
background: #f3f6f9 url(/images/search-icon.svg) 98% no-repeat;
margin: 0;
padding: 10px 15px;
}
.searchbar-count {
position: absolute;
top: 100%;
right: 0;
}
@media screen and (max-width: 1024px) {
.controls {
flex-flow: column-reverse;
}
.inputs {
align-self: flex-start;
width: 100%;
grid-template-columns: repeat(3, auto);
}
.searchbar {
align-self: flex-end;
margin-bottom: 1ex;
}
}
@media screen and (max-width: 700px) {
.controls {
align-items: stretch;
}
.inputs {
grid-template-columns: auto;
}
.searchbar {
width: auto;
align-self: stretch;
}
:global(.select-container) {
width: 100%;
}
}
</style>

View File

@@ -34,6 +34,7 @@ const config = {
$components: path.resolve('./src/lib/components'), $components: path.resolve('./src/lib/components'),
$layout: path.resolve('./src/lib/components/layout'), $layout: path.resolve('./src/lib/components/layout'),
$layouts: path.resolve('./src/lib/layouts'), $layouts: path.resolve('./src/lib/layouts'),
$utils: path.resolve('./src/lib/utils'),
$styles: path.resolve('./src/lib/styles'), $styles: path.resolve('./src/lib/styles'),
$stores: path.resolve('./src/lib/stores') $stores: path.resolve('./src/lib/stores')
} }