🚧 Use PageTransition as a div and switch

- use a page classed div for PageTransition which avoids to make global style for the page
- fix the loading spinner that was too short and would come and go before arriving on the page, now fades out when changing page as pageLoading is defined on the PageTransition afterUpdate
This commit is contained in:
2022-10-09 14:44:25 +02:00
parent 8e6a38381f
commit fd37c36595
23 changed files with 1252 additions and 1246 deletions

View File

@@ -336,162 +336,164 @@
/>
<PageTransition name="photos-page">
<section class="photos-page__intro"
class:is-passed={scrolledPastIntro}
>
<ScrollingTitle tag="h1" text="Houses">
<SplitText text="Houses" mode="chars" />
</ScrollingTitle>
<DiscoverText />
<div class="filters"
class:is-over={filtersOver}
class:is-transitioning={filtersTransitioning}
class:is-visible={filtersVisible}
<PageTransition>
<main class="photos-page">
<section class="photos-page__intro"
class:is-passed={scrolledPastIntro}
>
<div class="filters__bar">
<span class="text-label filters__label">Filter photos</span>
<ul>
<li>
<Select
name="country" id="filter_country"
options={[
{
value: defaultCountry,
name: 'Worldwide',
default: true,
selected: filterCountry === defaultCountry,
},
...countries.map(({ slug, name }) => ({
value: slug,
name,
selected: filterCountry === slug,
}))
]}
on:change={handleCountryChange}
value={filterCountry}
>
{#if countryFlagId}
<Image
class="icon"
id={countryFlagId}
sizeKey="square-small"
width={26} height={26}
alt="{filterCountry} flag"
/>
{:else}
<IconEarth class="icon" />
{/if}
</Select>
</li>
<li>
<Select
name="sort" id="filter_sort"
options={[
{
value: 'latest',
name: 'Latest',
default: true,
selected: filterSort === defaultSort
},
{
value: 'oldest',
name: 'Oldest',
selected: filterSort === 'oldest'
},
]}
on:change={handleSortChange}
value={filterSort}
>
<svg class="icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-label="Sort icon">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.878 15.93h-4.172c-.638 0-1.153.516-1.153 1.154 0 .639.515 1.154 1.153 1.154h4.172c.638 0 1.153-.515 1.153-1.154a1.152 1.152 0 0 0-1.153-1.153Zm3.244-5.396h-7.405c-.639 0-1.154.515-1.154 1.153 0 .639.515 1.154 1.154 1.154h7.405c.639 0 1.154-.515 1.154-1.154a1.145 1.145 0 0 0-1.154-1.153Zm3.244-5.408h-10.65c-.638 0-1.153.515-1.153 1.154 0 .639.515 1.154 1.154 1.154h10.65c.638 0 1.153-.515 1.153-1.154 0-.639-.515-1.154-1.154-1.154ZM7.37 20.679V3.376c0-.145-.03-.289-.082-.433a1.189 1.189 0 0 0-.628-.618 1.197 1.197 0 0 0-.886 0 1.045 1.045 0 0 0-.36.237c-.01 0-.01 0-.021.01L.82 7.145a1.156 1.156 0 0 0 0 1.638 1.156 1.156 0 0 0 1.637 0l2.596-2.596v11.7l-2.596-2.595a1.156 1.156 0 0 0-1.637 0 1.156 1.156 0 0 0 0 1.638l4.573 4.573c.103.103.237.185.37.247.135.062.289.082.433.082h.02c.145 0 .3-.03.433-.093a1.14 1.14 0 0 0 .629-.628.987.987 0 0 0 .092-.432Z" />
</svg>
</Select>
</li>
</ul>
<ScrollingTitle tag="h1" text="Houses">
<SplitText text="Houses" mode="chars" />
</ScrollingTitle>
<div class="filters__actions">
{#if filtered}
<button class="reset button-link"
on:click={resetFiltered}
transition:fly={{ y: 4, duration: 600, easing: quartOutSvelte }}
>
Reset
</button>
{/if}
</div>
</div>
</div>
</section>
<DiscoverText />
<section class="photos-page__content" bind:this={photosContentEl} style:--margin-sides="{sideMargins}px">
<div class="grid container">
{#if photos}
<div class="photos-page__grid" bind:this={photosGridEl} data-sveltekit-noscroll data-sveltekit-prefetch>
{#each photos as { id, image, slug, location, title, city }, index (id)}
<figure class="photo shadow-photo">
<a href="/{location.country.slug}/{location.slug}/{slug}" tabindex="0">
<Image
id={image.id}
sizeKey="photo-grid"
sizes={{
small: { width: 500 },
medium: { width: 900 },
large: { width: 1440 },
}}
ratio={1.5}
alt={image.title}
/>
</a>
<figcaption>
<PostCard
street={title}
location={city ? `${city}, ${location.name}` : location.name}
region={location.region}
country={location.country.name}
flagId={location.country.flag.id}
size={isSmall(index) ? 'small' : null}
/>
</figcaption>
</figure>
{/each}
</div>
<div class="filters"
class:is-over={filtersOver}
class:is-transitioning={filtersTransitioning}
class:is-visible={filtersVisible}
>
<div class="filters__bar">
<span class="text-label filters__label">Filter photos</span>
<ul>
<li>
<Select
name="country" id="filter_country"
options={[
{
value: defaultCountry,
name: 'Worldwide',
default: true,
selected: filterCountry === defaultCountry,
},
...countries.map(({ slug, name }) => ({
value: slug,
name,
selected: filterCountry === slug,
}))
]}
on:change={handleCountryChange}
value={filterCountry}
>
{#if countryFlagId}
<Image
class="icon"
id={countryFlagId}
sizeKey="square-small"
width={26} height={26}
alt="{filterCountry} flag"
/>
{:else}
<IconEarth class="icon" />
{/if}
</Select>
</li>
<li>
<Select
name="sort" id="filter_sort"
options={[
{
value: 'latest',
name: 'Latest',
default: true,
selected: filterSort === defaultSort
},
{
value: 'oldest',
name: 'Oldest',
selected: filterSort === 'oldest'
},
]}
on:change={handleSortChange}
value={filterSort}
>
<svg class="icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-label="Sort icon">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.878 15.93h-4.172c-.638 0-1.153.516-1.153 1.154 0 .639.515 1.154 1.153 1.154h4.172c.638 0 1.153-.515 1.153-1.154a1.152 1.152 0 0 0-1.153-1.153Zm3.244-5.396h-7.405c-.639 0-1.154.515-1.154 1.153 0 .639.515 1.154 1.154 1.154h7.405c.639 0 1.154-.515 1.154-1.154a1.145 1.145 0 0 0-1.154-1.153Zm3.244-5.408h-10.65c-.638 0-1.153.515-1.153 1.154 0 .639.515 1.154 1.154 1.154h10.65c.638 0 1.153-.515 1.153-1.154 0-.639-.515-1.154-1.154-1.154ZM7.37 20.679V3.376c0-.145-.03-.289-.082-.433a1.189 1.189 0 0 0-.628-.618 1.197 1.197 0 0 0-.886 0 1.045 1.045 0 0 0-.36.237c-.01 0-.01 0-.021.01L.82 7.145a1.156 1.156 0 0 0 0 1.638 1.156 1.156 0 0 0 1.637 0l2.596-2.596v11.7l-2.596-2.595a1.156 1.156 0 0 0-1.637 0 1.156 1.156 0 0 0 0 1.638l4.573 4.573c.103.103.237.185.37.247.135.062.289.082.433.082h.02c.145 0 .3-.03.433-.093a1.14 1.14 0 0 0 .629-.628.987.987 0 0 0 .092-.432Z" />
</svg>
</Select>
</li>
</ul>
<div class="controls grid">
<p class="controls__date" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
Last updated: <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>{dayjs().to(dayjs(latestPhoto.date_created))}</time>
</p>
<Button
tag="button"
text={!ended ? 'See more photos' : "You've seen it all!"}
size="large" color="beige"
on:click={loadMorePhotos}
disabled={ended}
/>
<div class="controls__count">
<span class="current">{currentPhotosAmount}</span>
<span>/</span>
<span class="total">{totalPhotos}</span>
<div class="filters__actions">
{#if filtered}
<button class="reset button-link"
on:click={resetFiltered}
transition:fly={{ y: 4, duration: 600, easing: quartOutSvelte }}
>
Reset
</button>
{/if}
</div>
</div>
{:else if !filteredCountryExists}
<div class="photos-page__message">
<p>
<strong>{$page.url.searchParams.get('country').replace(/(^|\s)\S/g, letter => letter.toUpperCase())}</strong> is not available… yet 👀
</p>
</div>
{/if}
</div>
</section>
<div class="grid-modules">
<div class="wrap">
<ShopModule />
<NewsletterModule theme="light" />
<section class="photos-page__content" bind:this={photosContentEl} style:--margin-sides="{sideMargins}px">
<div class="grid container">
{#if photos}
<div class="photos-page__grid" bind:this={photosGridEl} data-sveltekit-noscroll data-sveltekit-prefetch>
{#each photos as { id, image, slug, location, title, city }, index (id)}
<figure class="photo shadow-photo">
<a href="/{location.country.slug}/{location.slug}/{slug}" tabindex="0">
<Image
id={image.id}
sizeKey="photo-grid"
sizes={{
small: { width: 500 },
medium: { width: 900 },
large: { width: 1440 },
}}
ratio={1.5}
alt={image.title}
/>
</a>
<figcaption>
<PostCard
street={title}
location={city ? `${city}, ${location.name}` : location.name}
region={location.region}
country={location.country.name}
flagId={location.country.flag.id}
size={isSmall(index) ? 'small' : null}
/>
</figcaption>
</figure>
{/each}
</div>
<div class="controls grid">
<p class="controls__date" title={dayjs(latestPhoto.date_created).format('DD/MM/YYYY, hh:mm')}>
Last updated: <time datetime={dayjs(latestPhoto.date_created).format('YYYY-MM-DD')}>{dayjs().to(dayjs(latestPhoto.date_created))}</time>
</p>
<Button
tag="button"
text={!ended ? 'See more photos' : "You've seen it all!"}
size="large" color="beige"
on:click={loadMorePhotos}
disabled={ended}
/>
<div class="controls__count">
<span class="current">{currentPhotosAmount}</span>
<span>/</span>
<span class="total">{totalPhotos}</span>
</div>
</div>
{:else if !filteredCountryExists}
<div class="photos-page__message">
<p>
<strong>{$page.url.searchParams.get('country').replace(/(^|\s)\S/g, letter => letter.toUpperCase())}</strong> is not available… yet 👀
</p>
</div>
{/if}
<div class="grid-modules">
<div class="wrap">
<ShopModule />
<NewsletterModule theme="light" />
</div>
</div>
</div>
</div>
</section>
</section>
</main>
</PageTransition>