94 lines
2.8 KiB
Svelte
94 lines
2.8 KiB
Svelte
<style lang="scss">
|
|
@import "./Locations";
|
|
</style>
|
|
|
|
<script lang="ts">
|
|
import { getContext } from 'svelte'
|
|
import { flip } from 'svelte/animate'
|
|
import { quartOut } from 'svelte/easing'
|
|
import reveal from '$animations/reveal'
|
|
import { send, receive } from '$animations/crossfade'
|
|
import { throttle } from 'utils/actions'
|
|
import { sendEvent } from '$utils/analytics'
|
|
// Components
|
|
import Button from '$components/atoms/Button/Button.svelte'
|
|
import Location from '$components/molecules/Location/Location.svelte'
|
|
|
|
export let locations: any[]
|
|
|
|
const { continents, settings: { explore_list } }: any = getContext('global')
|
|
|
|
// Continents filtering logic
|
|
let currentContinent: string = undefined
|
|
|
|
$: filteredLocations = locations.filter(({ country: { continent } }: any) => {
|
|
if (!currentContinent) {
|
|
// Show all locations by default
|
|
return true
|
|
} else {
|
|
// Location's continent matches the clicked continent
|
|
return continent.slug === currentContinent
|
|
}
|
|
})
|
|
|
|
|
|
/**
|
|
* Filter locations from continent
|
|
*/
|
|
const filterLocation = throttle((continent: string) => {
|
|
currentContinent = continent !== currentContinent ? continent : null
|
|
}, 600)
|
|
</script>
|
|
|
|
<div class="browse">
|
|
<div class="browse__description">
|
|
<p>{explore_list}</p>
|
|
</div>
|
|
|
|
<ul class="browse__continents">
|
|
{#each continents as { name, slug }}
|
|
<li class:is-active={currentContinent === slug}>
|
|
<Button
|
|
size="small"
|
|
text={name}
|
|
slotPosition="after"
|
|
class={'is-disabled'}
|
|
on:click={() => {
|
|
filterLocation(slug)
|
|
sendEvent('filterContinent')
|
|
}}
|
|
>
|
|
<svg width="12" height="12">
|
|
<use xlink:href="#cross" />
|
|
</svg>
|
|
</Button>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
|
|
<ul class="browse__locations" data-sveltekit-noscroll
|
|
use:reveal={{
|
|
children: '.location',
|
|
animation: { y: ['20%', 0], opacity: [0, 1] },
|
|
options: {
|
|
stagger: 0.105,
|
|
duration: 1,
|
|
threshold: 0.3,
|
|
},
|
|
}}
|
|
>
|
|
{#each filteredLocations as location (location)}
|
|
<li
|
|
animate:flip={{ duration: 1000, easing: quartOut }}
|
|
in:receive={{ key: location.slug }}
|
|
out:send={{ key: location.slug }}
|
|
>
|
|
<Location
|
|
location={location}
|
|
latestPhoto={location.photos[0]}
|
|
/>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
</div>
|