-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the ability to sort by price (#65)
- Loading branch information
Showing
6 changed files
with
161 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<script lang="ts"> | ||
import { goto } from "$app/navigation"; | ||
import { page } from "$app/stores"; | ||
import { popup, type PopupSettings } from "@skeletonlabs/skeleton"; | ||
export let options: Option[]; | ||
export let defaultOption: Option; | ||
export let searchParam: string; | ||
export let directionParam: string | undefined = undefined; | ||
export let prefix: string | undefined = undefined; | ||
let filter = $page.url.searchParams.get(searchParam); | ||
let direction = directionParam ? $page.url.searchParams.get(searchParam) : null; | ||
let selectedOption: Option = defaultOption; | ||
if (filter) { | ||
for (const option of options) { | ||
if (filter === option.value) { | ||
if (option.direction) { | ||
if (direction && option.direction === direction) { | ||
selectedOption = option; | ||
break; | ||
} | ||
} else { | ||
selectedOption = option; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
const popupKey = `${searchParam}-options`; | ||
let menuOpen = false; | ||
const menuSettings: PopupSettings = { | ||
event: "click", | ||
target: popupKey, | ||
state: ({ state }) => (menuOpen = state) | ||
}; | ||
const handleClick = (option: Option) => { | ||
selectedOption = option; | ||
const newUrl = new URL($page.url); | ||
if (option === defaultOption) { | ||
newUrl.searchParams.delete(searchParam); | ||
if (directionParam) newUrl.searchParams.delete(directionParam); | ||
} else { | ||
newUrl.searchParams.set(searchParam, option.value); | ||
if (directionParam && option.direction) | ||
newUrl.searchParams.set(directionParam, option.direction); | ||
} | ||
goto(newUrl, { | ||
replaceState: true | ||
}); | ||
}; | ||
</script> | ||
|
||
<div class="flex flex-row space-x-4 pb-4"> | ||
<span class="relative"> | ||
<button | ||
class="variant-ringed-primary chip" | ||
class:variant-ghost-primary={selectedOption !== defaultOption} | ||
use:popup={menuSettings} | ||
> | ||
{#if selectedOption.direction === "asc"} | ||
<iconify-icon icon="ion:arrow-up" /> | ||
{:else if selectedOption.direction === "desc"} | ||
<iconify-icon icon="ion:arrow-down" /> | ||
{:else if prefix} | ||
<iconify-icon icon={prefix} /> | ||
{/if} | ||
<span>{selectedOption.displayValue}</span> | ||
<iconify-icon | ||
class="arrow text-xs duration-300 ease-out" | ||
class:rotate-180={menuOpen} | ||
icon="ion:caret-down" | ||
/> | ||
</button> | ||
<nav class="card list-nav p-4 shadow-xl" data-popup={popupKey}> | ||
<ul> | ||
{#each options as option} | ||
<li> | ||
<button class="list-option w-full" on:click={() => handleClick(option)}> | ||
{option.displayValue} | ||
</button> | ||
</li> | ||
{/each} | ||
</ul> | ||
</nav> | ||
</span> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,24 @@ | ||
<script lang="ts"> | ||
import { goto } from "$app/navigation"; | ||
import { page } from "$app/stores"; | ||
import { popup, type PopupSettings } from "@skeletonlabs/skeleton"; | ||
import BaseChip from "./BaseChip.svelte"; | ||
const CLAIM_OPTIONS = { | ||
all: "All", | ||
claimed: "Claimed", | ||
unclaimed: "Unclaimed" | ||
}; | ||
type ClaimOption = keyof typeof CLAIM_OPTIONS; | ||
const options: Option[] = [ | ||
{ | ||
value: "all", | ||
displayValue: "All" | ||
}, | ||
{ | ||
value: "claimed", | ||
displayValue: "Claimed" | ||
}, | ||
{ | ||
value: "unclaimed", | ||
displayValue: "Unclaimed" | ||
} | ||
]; | ||
let menuOpen = false; | ||
const menuSettings: PopupSettings = { | ||
event: "click", | ||
target: "view", | ||
state: ({ state }) => (menuOpen = state) | ||
}; | ||
let filter = $page.url.searchParams.get("filter"); | ||
let claimOption: ClaimOption = filter | ||
? Object.keys(CLAIM_OPTIONS).includes(filter) | ||
? (filter as ClaimOption) | ||
: "all" | ||
: "all"; | ||
const handleClick = (opt: unknown) => { | ||
const option = opt as ClaimOption; | ||
claimOption = option; | ||
const newUrl = new URL($page.url); | ||
if (option === "all") newUrl.searchParams.delete("filter"); | ||
else newUrl.searchParams.set("filter", option); | ||
goto(newUrl, { | ||
replaceState: true | ||
}); | ||
}; | ||
const defaultOption = options[0]; | ||
const searchParam = "filter"; | ||
const prefix = "ion:filter"; | ||
</script> | ||
|
||
<div class="flex flex-row space-x-4 pb-4"> | ||
<span class="relative"> | ||
<button | ||
class="variant-ringed-primary chip" | ||
class:variant-ghost-primary={claimOption !== "all"} | ||
use:popup={menuSettings} | ||
> | ||
<span>{CLAIM_OPTIONS[claimOption]}</span> | ||
<iconify-icon | ||
class="arrow text-xs duration-300 ease-out" | ||
class:rotate-180={menuOpen} | ||
icon="ion:caret-down" | ||
/> | ||
</button> | ||
<nav class="card list-nav p-4 shadow-xl" data-popup="view"> | ||
<ul> | ||
{#each Object.entries(CLAIM_OPTIONS) as [optionKey, optionValue]} | ||
<li> | ||
<button class="list-option w-full" on:click={() => handleClick(optionKey)}> | ||
{optionValue} | ||
</button> | ||
</li> | ||
{/each} | ||
</ul> | ||
</nav> | ||
</span> | ||
</div> | ||
<BaseChip {defaultOption} {options} {prefix} {searchParam} /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<script lang="ts"> | ||
import BaseChip from "./BaseChip.svelte"; | ||
const options: Option[] = [ | ||
{ | ||
value: "default", | ||
displayValue: "Default Sort" | ||
}, | ||
{ | ||
value: "price", | ||
direction: "asc", | ||
displayValue: "Price: Low to High" | ||
}, | ||
{ | ||
value: "price", | ||
direction: "desc", | ||
displayValue: "Price: High to Low" | ||
} | ||
]; | ||
const defaultOption = options[0]; | ||
const searchParam = "sort"; | ||
const directionParam = "dir"; | ||
const prefix = "ion:swap-vertical"; | ||
</script> | ||
|
||
<BaseChip {defaultOption} {directionParam} {options} {prefix} {searchParam} /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters