Skip to content

Commit

Permalink
add arrow key + enter navigation on landing page
Browse files Browse the repository at this point in the history
node scripts/index.js update-existing

updating screenshots failed with skipping beatbump due to TypeError: Right-hand side of 'instanceof' is not an object

fix sort after svelte-zoo transition
  • Loading branch information
janosh committed Jan 28, 2023
1 parent 68ee9de commit 216b02c
Show file tree
Hide file tree
Showing 13 changed files with 327 additions and 207 deletions.
10 changes: 2 additions & 8 deletions site/src/lib/Filters.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import MultiSelect from 'svelte-multiselect'
import { RadioButtons } from 'svelte-zoo'
import {
Expand All @@ -13,8 +12,7 @@
export let tags: [string, number][]
export let contributors: [string, number][]
const dispatch = createEventDispatcher()
export let sort_order: 'asc' | 'desc' = `desc`
</script>

<div class="filters">
Expand Down Expand Up @@ -57,11 +55,7 @@
bind:selected={$sort_by}
/>
{#if $sort_by?.length > 0}
<RadioButtons
selected="desc"
on:change={() => dispatch(`toggle-sort`)}
options={[`asc`, `desc`]}
/>
<RadioButtons bind:selected={sort_order} options={[`asc`, `desc`]} />
{/if}
</div>
</div>
Expand Down
14 changes: 14 additions & 0 deletions site/src/lib/PrevNextSite.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
<script lang="ts">
import { goto } from '$app/navigation'
import Icon from '@iconify/svelte'
import { SitePreview } from '.'
import type { Site } from './types'
export let prev: Site
export let next: Site
const goto_options = { replaceState: true, noScroll: true }
function handle_keyup(event: KeyboardEvent) {
const to = {
ArrowLeft: prev?.slug,
ArrowRight: next?.slug,
Escape: `/`,
}[event.key]
if (to) goto(to, goto_options)
}
</script>

<svelte:window on:keyup={handle_keyup} />

<ul data-sveltekit-noscroll>
<li>
<h3>
Expand Down
25 changes: 24 additions & 1 deletion site/src/lib/SiteList.svelte
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
<script lang="ts">
import { goto } from '$app/navigation'
import { flip } from 'svelte/animate'
import { fade } from 'svelte/transition'
import { SitePreview } from '.'
import type { Site } from './types'
export let sites: Site[]
let active_idx = -1
function handle_keyup(event: KeyboardEvent) {
if (event.key === `Enter` && active_idx >= 0) {
const site = sites[active_idx]
goto(site.slug)
}
const to = {
// wrap around
ArrowLeft: (active_idx - 1 + sites.length) % sites.length,
ArrowRight: (active_idx + 1) % sites.length,
Escape: -1,
}[event.key]
if (to !== undefined && to >= 0) active_idx = to
// keep active_idx in viewport
const active = document.querySelector(`ol > li.active`)
if (active) active.scrollIntoViewIfNeeded()
}
</script>

<svelte:window on:keyup={handle_keyup} />

<ol>
{#each sites as site, idx (site.url)}
<li
animate:flip={{ duration: 400 }}
in:fade|local={{ delay: 100 }}
out:fade|local={{ delay: 100 }}
class:active={idx === active_idx}
>
<SitePreview {site} idx={idx + 1} tags />
</li>
Expand All @@ -31,7 +54,7 @@
border-radius: 1ex;
padding: 10pt;
}
ol li:hover {
ol > :is(li:hover, li.active) {
transform: scale(1.01);
background-color: rgba(255, 255, 255, 0.05);
}
Expand Down
16 changes: 8 additions & 8 deletions site/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,22 @@
return query_match && tag_match && contrib_match
})
let sort_order: 'asc' | 'desc' = `desc`
$: sort_factor = sort_order == `asc` ? -1 : 1
// arr.sort() sorts in-place but we need to reassign filtered_sites so Svelte rerenders
$: if ($sort_by[0] === `GitHub repo stars`) {
$sorted_sites = filtered_sites.sort(
(siteA, siteB) => (siteB.repo_stars ?? 0) - (siteA.repo_stars ?? 0)
(siteA, siteB) => sort_factor * ((siteB.repo_stars ?? 0) - (siteA.repo_stars ?? 0))
)
} else if ($sort_by[0] === `Date created`) {
$sorted_sites = filtered_sites.sort(
(siteA, siteB) => +new Date(siteB.date_created) - +new Date(siteA.date_created)
(siteA, siteB) =>
sort_factor * (+new Date(siteB.date_created) - +new Date(siteA.date_created))
)
} else if ($sort_by[0] === `Date last updated`) {
$sorted_sites = filtered_sites.sort(
(siteA, siteB) => +new Date(siteB.last_updated) - +new Date(siteA.last_updated)
(siteA, siteB) =>
sort_factor * (+new Date(siteB.last_updated) - +new Date(siteA.last_updated))
)
}
Expand All @@ -101,11 +105,7 @@
{sites.length} Awesome Examples of SvelteKit in the Wild
</h1>

<Filters
{tags}
on:toggle-sort={() => ($sorted_sites = $sorted_sites.reverse())}
{contributors}
/>
<Filters {tags} bind:sort_order {contributors} />

{#if $sorted_sites.length < sites.length}
<p>
Expand Down
15 changes: 0 additions & 15 deletions site/src/routes/[slug]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script lang="ts">
import { goto } from '$app/navigation'
import { PrevNextSite, SiteDetails } from '$lib'
import { repository } from '$site/package.json'
import Icon from '@iconify/svelte'
Expand All @@ -9,18 +8,6 @@
$: head_title = `${data.site.title} | Awesome SvelteKit`
$: plain_description = data.site?.description?.replace(/<[^>]*>/g, ``)
const goto_options = { replaceState: true, noScroll: true }
function handle_keyup(event: KeyboardEvent) {
if (event.key === `ArrowLeft`) {
goto(data.prev?.slug ?? ``, goto_options)
} else if (event.key === `ArrowRight`) {
goto(data.next?.slug ?? ``, goto_options)
} else if (event.key === `Escape`) {
goto(`/`, goto_options)
}
}
</script>

<svelte:head>
Expand All @@ -35,8 +22,6 @@
{/if}
</svelte:head>

<svelte:window on:keyup={handle_keyup} />

<a href="." class="back">&laquo; home</a>

<main>
Expand Down
Loading

0 comments on commit 216b02c

Please sign in to comment.