Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Merge categories/tags and improve filtering #541

Merged
merged 38 commits into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
aa12d08
Experiment with SSR and query params
lachlancollins Dec 21, 2023
1ef8829
Require all tags to be present
lachlancollins Dec 21, 2023
3cc9630
Merge branch 'main' into tags-rework
lachlancollins Dec 21, 2023
b1e463c
Fix when no query param present
lachlancollins Dec 21, 2023
f3c0f59
Add tag links
lachlancollins Dec 21, 2023
0ef2aeb
Working add/remove tags
lachlancollins Dec 21, 2023
0ff158c
Fix templates route
lachlancollins Dec 21, 2023
9636112
Remove old category/tags selectors
lachlancollins Dec 21, 2023
de84dd7
Merge branch 'main' into tags-rework
lachlancollins Dec 21, 2023
989c129
Button style
lachlancollins Dec 21, 2023
4564a3d
More styling
lachlancollins Dec 21, 2023
7caa520
Remove unused code
lachlancollins Dec 21, 2023
eae69f4
Remove @sindresorhus/slugify
lachlancollins Dec 21, 2023
4bd15ee
Format and disable prerender
lachlancollins Dec 21, 2023
743c251
Improve css grid
lachlancollins Dec 21, 2023
9c06da1
Use searchParams.getAll
lachlancollins Dec 22, 2023
f1cdfbf
Merge branch 'main' into tags-rework
lachlancollins Dec 23, 2023
2314441
Merge branch 'main' into tags-rework
lachlancollins Dec 23, 2023
e63f949
Merge branch 'main' into tags-rework
lachlancollins Dec 23, 2023
34bed7f
Merge branch 'main' into tags-rework
lachlancollins Dec 23, 2023
89c856e
Replace itemsjs with filter/sort functions
lachlancollins Dec 23, 2023
4f4e0f1
Merge branch 'main' into tags-rework
lachlancollins Dec 24, 2023
497dcbc
Always show selected tags
lachlancollins Dec 24, 2023
c8d83a4
Merge branch 'main' into tags-rework
lachlancollins Dec 24, 2023
36862d5
Add data-sveltekit-noscroll
lachlancollins Dec 25, 2023
771874b
Move sortableFields to prop level
lachlancollins Dec 25, 2023
f2a0948
Simplify code
lachlancollins Dec 25, 2023
deae2c8
Merge remote-tracking branch 'origin/main' into tags-rework
lachlancollins Dec 26, 2023
de5290b
Merge branch 'main' into tags-rework
lachlancollins Dec 26, 2023
40574a0
Fix sortArray for dates
lachlancollins Dec 26, 2023
eff3ae9
Merge branch 'main' into tags-rework
lachlancollins Dec 26, 2023
407d98b
Add an icon to clear filters
lachlancollins Dec 28, 2023
45e11f7
Merge branch 'main' into tags-rework
lachlancollins Dec 28, 2023
af1655f
Convert tags to kebab-case
lachlancollins Dec 30, 2023
536af74
Add category to tags
lachlancollins Dec 30, 2023
7723e19
Delete category field
lachlancollins Dec 30, 2023
2a41518
Remove duplicated tags
lachlancollins Dec 30, 2023
3ede42b
Merge more tags
lachlancollins Dec 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
},
"devDependencies": {
"@macfja/svelte-persistent-store": "2.4.1",
"@sindresorhus/slugify": "^2.2.1",
"@sveltejs/adapter-auto": "^3.0.1",
"@sveltejs/kit": "^2.0.1",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@types/eslint": "^8.44.9",
"@types/itemsjs": "^2.1.6",
"@types/node": "^20.10.5",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
Expand All @@ -31,7 +29,6 @@
"eslint-plugin-svelte": "^2.35.1",
"get-npm-tarball-url": "^2.1.0",
"highlight.js": "^11.9.0",
"itemsjs": "^2.1.24",
"mdsvex": "^0.11.0",
"package-name-regex": "^3.1.1",
"pako": "^2.1.0",
Expand Down
37 changes: 0 additions & 37 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

152 changes: 63 additions & 89 deletions src/lib/SearchableJson.svelte
Original file line number Diff line number Diff line change
@@ -1,106 +1,87 @@
<script lang="ts">
import slugify from '@sindresorhus/slugify';
import ComponentCard from '$lib/components/ComponentIndex/Card.svelte';
import CardList from '$lib/components/ComponentIndex/CardList.svelte';
import SearchLayout from '$layouts/SearchLayout.svelte';
import { extractUnique } from '$lib/utils/extractUnique';
import Seo from '$lib/components/Seo.svelte';
import Search from '$lib/components/Search.svelte';
import Select from '$lib/components/Select.svelte';
import { packageManager } from '$stores/packageManager';
import TagFilters from '$lib/TagFilters.svelte';
import { filterArray, sortArray } from '$utils/arrayUtils';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export let data: any[];
export let tags: string[];
export let selectedTags: string[];
export let sortableFields: { value: string; label: string; asc: boolean }[];
export let displayTitle = '';
export let displayTitleSingular = '';
export let submittingType = '';

const sortableFields = [
{ identifier: 'stars', title: 'Stars', ascending: false },
{ identifier: 'title', title: 'Name', ascending: true },
{ identifier: 'date', title: 'Date', ascending: false }
];

let searchValue: string;
let sort = sortableFields[0];

const dataDefault = { category: '' };
$: dataToDisplay = data.map((line) => ({ ...dataDefault, ...line }));

$: categories = extractUnique(dataToDisplay, 'category');
$: filteredData = filterArray(data, searchValue);
$: sortedData = sortArray(filteredData, sort);
</script>

<Seo title={displayTitle} />

<SearchLayout title={displayTitle}>
<section slot="controls" class="controls">
<div class="inputs">
<Search
data={dataToDisplay}
bind:query={searchValue}
{sortableFields}
searchableFields={['title', 'description']}
facetsConfig={[
{
title: 'Category',
identifier: 'category'
},
{
title: 'Tags',
identifier: 'tags',
isMulti: true
}
]}
on:search={(a) => (dataToDisplay = a.detail.data.items)}
/>
<Select
label="Package manager"
isClearable={false}
isSearchable={false}
showIndicator
value={{ value: $packageManager }}
on:select={({ detail }) => ($packageManager = detail.value)}
items={[
{ label: 'NPM', value: 'npm' },
{ label: 'PNPM', value: 'pnpm' },
{ label: 'Yarn', value: 'yarn' }
]}
/>
<a href="/help/submitting?type={submittingType}" class="submit"
>Submit a {displayTitleSingular}</a
>
</div>
<h1>{displayTitle}</h1>

<input
class="searchbar"
type="text"
placeholder="Search for {displayTitle.toLowerCase()}..."
bind:value={searchValue}
<TagFilters {tags} {selectedTags} />
<br />
<section class="controls">
<input
class="searchbar"
type="text"
placeholder="Search for {displayTitle.toLowerCase()}..."
bind:value={searchValue}
/>
<div class="inputs">
<Select
items={sortableFields}
bind:value={sort}
label="Sorting"
showIndicator
isClearable={false}
/>
<span class="searchbar-count"
>{dataToDisplay.length} result{#if dataToDisplay.length !== 1}s{/if}</span
<Select
label="Package manager"
isClearable={false}
isSearchable={false}
showIndicator
value={{ value: $packageManager }}
on:select={({ detail }) => ($packageManager = detail.value)}
items={[
{ label: 'NPM', value: 'npm' },
{ label: 'PNPM', value: 'pnpm' },
{ label: 'Yarn', value: 'yarn' }
]}
/>
<a href="/help/submitting?type={submittingType}" class="submit"
>Submit a {displayTitleSingular}</a
>
</section>
<section slot="items">
{#each categories as category}
<CardList title={category.label} id={slugify(category.label)}>
{#each dataToDisplay.filter((d) => d.category === category.value || (!categories
.map((v) => v.value)
.includes(d.category) && category.value === '')) as entry (entry.title)}
<ComponentCard
title={entry.title}
description={entry.description}
repository={entry.repository}
stars={entry.stars}
tags={entry.tags}
date={entry.date}
npm={entry.npm}
version={entry.version}
/>
{/each}
</CardList>
</div>
<span class="searchbar-count"
>{data.length} result{#if data.length !== 1}s{/if}</span
>
</section>
<hr />
<section>
<CardList>
{#each sortedData as entry (entry.title)}
<ComponentCard
title={entry.title}
description={entry.description}
repository={entry.repository}
stars={entry.stars}
tags={entry.tags}
date={entry.date}
npm={entry.npm}
version={entry.version}
/>
{/each}
</section>
</SearchLayout>
</CardList>
</section>

<style>
.controls {
Expand All @@ -119,7 +100,6 @@
padding: 20.5px var(--s-2);
border: 2px solid var(--dark-gray);
border-radius: 2px;
align-self: flex-end;
grid-row: 1/2;
font-family: Overpass;
background: #f3f6f9 url(/images/search-icon.svg) 98% no-repeat;
Expand All @@ -135,15 +115,9 @@
right: 0;
}

@media (min-width: 1280px) {
.controls {
grid-template-columns: 2fr 1fr;
}
@media (min-width: 1024px) {
.inputs {
grid-template-columns: repeat(4, auto);
}
.searchbar {
grid-row: auto;
grid-template-columns: repeat(2, auto);
}
}
</style>
68 changes: 68 additions & 0 deletions src/lib/TagFilters.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<script lang="ts">
import { page } from '$app/stores';
import Icon from '$lib/components/Icon/index.svelte';

export let tags: string[];
export let selectedTags: string[];
</script>

<div data-sveltekit-noscroll>
{#each selectedTags as tag}
{@const newTags = selectedTags.filter((t) => t !== tag)}
{@const title = tag.replaceAll('-', ' ')}
{#if newTags.length === 0}
<a class="tag active" href={$page.url.pathname}>{title}</a>
{:else}
<a
class="tag active"
href={`${$page.url.pathname}?${newTags.map((t) => `tag=${t}`).join('&')}`}
>
{title}
</a>
{/if}
{/each}

{#each tags as tag}
{#if !selectedTags.includes(tag)}
{@const newTags = [...selectedTags, tag]}
{@const title = tag.replaceAll('-', ' ')}
<a class="tag" href={`${$page.url.pathname}?${newTags.map((t) => `tag=${t}`).join('&')}`}>
{title}
</a>
{/if}
{/each}

{#if selectedTags.length !== 0}
<a href={$page.url.pathname}><Icon name="close" /></a>
{/if}
</div>

<style>
div {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
}

a {
border: none;
}

.tag {
padding: 4px 12px;
border: 1px solid var(--link-color);
border-radius: 9999px;
font-family: Overpass;
font-style: normal;
font-weight: normal;
font-size: 14px;
line-height: 150%;
text-align: center;
}

.active {
color: #ff3e01;
background: #ffdbcf;
}
</style>
13 changes: 0 additions & 13 deletions src/lib/components/ComponentIndex/CardList.svelte
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
<script lang="ts">
export let title: string;
export let id = `category-${title}`;
</script>

<div class="list">
<h1 {id}>{title} <a href="#{id}">#</a></h1>
<div class="grid">
<slot />
</div>
</div>

<style>
h1 {
font-family: Overpass;
font-style: normal;
font-weight: 600;
line-height: 150%;
margin-bottom: 1rem;
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
Expand Down
Loading