mirror of
https://github.com/aleksilassila/reiverr.git
synced 2026-04-26 18:55:12 +02:00
fix: Tab transition animations
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import classNames from 'classnames';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { modalStack } from '../Modal/modal.store';
|
||||
import Panel from '../Panel.svelte';
|
||||
|
||||
export let size: 'sm' | 'full' | 'lg' | 'dynamic' = 'sm';
|
||||
|
||||
@@ -16,20 +17,12 @@
|
||||
class="h-full flex items-center justify-center bg-primary-900/75 py-20 px-32"
|
||||
transition:fade={{ duration: 100 }}
|
||||
on:click|self={() => handleClose()}
|
||||
on:keypress={() => {
|
||||
/* For a11y*/
|
||||
}}
|
||||
>
|
||||
<div
|
||||
class={classNames(
|
||||
'bg-primary-800 rounded-2xl p-12 relative shadow-xl flex flex-col transition-[max-width]',
|
||||
{
|
||||
'flex-1 max-w-lg min-h-0 overflow-y-auto scrollbar-hide': size === 'sm',
|
||||
'flex-1 h-full overflow-hidden': size === 'full',
|
||||
'flex-1 max-w-[56rem] min-h-0 overflow-y-auto scrollbar-hide': size === 'lg',
|
||||
'': size === 'dynamic'
|
||||
},
|
||||
$$restProps.class
|
||||
)}
|
||||
>
|
||||
<Panel {size} class={$$restProps.class}>
|
||||
<slot close={handleClose} />
|
||||
</div>
|
||||
</Panel>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -103,8 +103,8 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog class="grid" size={$tab === Tabs.EditProfile ? 'sm' : 'dynamic'}>
|
||||
<Tab {...tab} tab={Tabs.EditProfile} class="space-y-4">
|
||||
<Dialog class="grid" size={'dynamic'}>
|
||||
<Tab {...tab} tab={Tabs.EditProfile} class="space-y-4 max-w-lg">
|
||||
<h1 class="header2">Edit Profile</h1>
|
||||
<TextField bind:value={name}>name</TextField>
|
||||
<SelectField value={profilePictureTitle} on:clickOrSelect={() => tab.set(Tabs.ProfilePictures)}>
|
||||
@@ -151,7 +151,7 @@
|
||||
}}
|
||||
>
|
||||
<h1 class="header2 mb-6">Select Profile Picture</h1>
|
||||
<Container direction="grid" gridCols={3} class="grid grid-cols-3 gap-4">
|
||||
<Container direction="grid" gridCols={3} class="grid grid-cols-3 gap-4 w-max">
|
||||
<ProfileIcon
|
||||
url={profilePictures.ana}
|
||||
on:clickOrSelect={() => setProfilePicture(profilePictures.ana)}
|
||||
|
||||
@@ -15,9 +15,15 @@
|
||||
</script>
|
||||
|
||||
<Dialog>
|
||||
{#each users as user}
|
||||
<SelectItem selected={user.Id === selectedUser?.Id} on:clickOrSelect={() => handleSelect(user)}>
|
||||
{user.Name}
|
||||
</SelectItem>
|
||||
{/each}
|
||||
<h1 class="header1 mb-2">Users</h1>
|
||||
<div class="space-y-4">
|
||||
{#each users as user}
|
||||
<SelectItem
|
||||
selected={user.Id === selectedUser?.Id}
|
||||
on:clickOrSelect={() => handleSelect(user)}
|
||||
>
|
||||
{user.Name}
|
||||
</SelectItem>
|
||||
{/each}
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
20
src/lib/components/Panel.svelte
Normal file
20
src/lib/components/Panel.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script lang="ts">
|
||||
import classNames from 'classnames';
|
||||
|
||||
export let size: 'sm' | 'full' | 'lg' | 'dynamic' = 'sm';
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={classNames(
|
||||
'bg-primary-800 rounded-2xl p-12 relative shadow-xl flex flex-col transition-[max-width]',
|
||||
{
|
||||
'flex-1 max-w-lg min-h-0 overflow-y-auto scrollbar-hide': size === 'sm',
|
||||
'flex-1 h-full overflow-hidden': size === 'full',
|
||||
'flex-1 max-w-[56rem] min-h-0 overflow-y-auto scrollbar-hide': size === 'lg',
|
||||
'max-w-max overflow-hidden': size === 'dynamic'
|
||||
},
|
||||
$$restProps.class
|
||||
)}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
@@ -7,7 +7,7 @@
|
||||
</script>
|
||||
|
||||
<Container
|
||||
class="flex items-center justify-between bg-primary-900 rounded-xl px-6 py-2.5 mb-4 font-medium
|
||||
class="flex items-center justify-between bg-primary-900 rounded-xl px-6 py-2.5 font-medium
|
||||
border-2 border-transparent focus:border-primary-500 hover:border-primary-500 cursor-pointer group"
|
||||
on:clickOrSelect
|
||||
on:enter
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
export let tab: number;
|
||||
export let index: number = tab;
|
||||
export let openTab: Writable<number>;
|
||||
export let size: 'hug' | 'stretch' = 'hug';
|
||||
|
||||
let selectable: Selectable;
|
||||
|
||||
@@ -33,19 +34,24 @@
|
||||
</script>
|
||||
|
||||
<Container
|
||||
class={classNames(
|
||||
$$restProps.class,
|
||||
'transition-all col-start-1 col-end-1 row-start-1 row-end-1',
|
||||
{
|
||||
'opacity-0 pointer-events-none absolute inset-0': !active,
|
||||
'-translate-x-10': !active && $openTab >= index,
|
||||
'translate-x-10': !active && $openTab < index
|
||||
}
|
||||
)}
|
||||
class={classNames('col-start-1 col-end-1 row-start-1 row-end-1', {
|
||||
'absolute pointer-events-none left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2':
|
||||
!active && size === 'hug',
|
||||
'absolute pointer-events-none inset-0': !active && size === 'stretch',
|
||||
'': active
|
||||
})}
|
||||
bind:selectable
|
||||
on:back
|
||||
on:navigate={handleNavigate}
|
||||
disabled={!active}
|
||||
>
|
||||
<slot />
|
||||
<div
|
||||
class={classNames($$restProps.class, 'transition-[transform,opacity]', {
|
||||
'opacity-0 pointer-events-none': !active,
|
||||
'-translate-x-10': !active && $openTab >= index,
|
||||
'translate-x-10': !active && $openTab < index
|
||||
})}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Tab from './Tab.svelte';
|
||||
|
||||
export function useTabs(defaultTab: number) {
|
||||
export function useTabs(defaultTab: number, props: Pick<ComponentProps<Tab>, 'size'> = {}) {
|
||||
const openTab = writable<number>(defaultTab);
|
||||
|
||||
const next = () => openTab.update((n) => n + 1);
|
||||
const previous = () => openTab.update((n) => n - 1);
|
||||
|
||||
return { subscribe: openTab.subscribe, openTab, set: openTab.set, next, previous };
|
||||
return { subscribe: openTab.subscribe, openTab, set: openTab.set, next, previous, ...props };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user