Daisy UI #14
5 changed files with 87 additions and 32 deletions
5
src/lib/components/common/Tabs/Tab.svelte
Normal file
5
src/lib/components/common/Tabs/Tab.svelte
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<script lang="ts">
|
||||||
|
let { active, label, onclick } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input aria-label={label} type="radio" role="tab" class="tab" class:tab-active={active} {onclick} />
|
||||||
27
src/lib/components/common/Tabs/Tabs.stories.svelte
Normal file
27
src/lib/components/common/Tabs/Tabs.stories.svelte
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
import Tabs from './Tabs.svelte';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Tabs',
|
||||||
|
component: Tabs,
|
||||||
|
tags: ['autodocs'],
|
||||||
|
argTypes: {
|
||||||
|
size: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['xs', 'sm', 'rg', 'lg']
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['none', 'bordered', 'lifted', 'boxed']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(args: Partial<ComponentProps<typeof Tabs>>)}
|
||||||
|
<Tabs tabs={['Tab 1', 'Tab 2']} {...args} />
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story name="Default" args={{}} children={template} />
|
||||||
36
src/lib/components/common/Tabs/Tabs.svelte
Normal file
36
src/lib/components/common/Tabs/Tabs.svelte
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { DaisySize } from '$lib/types';
|
||||||
|
import Tab from './Tab.svelte';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
size?: DaisySize;
|
||||||
|
tabs: string[];
|
||||||
|
selected?: number;
|
||||||
|
variant?: 'none' | 'bordered' | 'lifted' | 'boxed';
|
||||||
|
};
|
||||||
|
|
||||||
|
let { size, tabs, selected: value = $bindable(0), variant = 'none' }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
role="tablist"
|
||||||
|
class="tabs w-full"
|
||||||
|
class:tabs-xs={size === 'xs'}
|
||||||
|
class:tabs-sm={size === 'sm'}
|
||||||
|
class:tabs-lg={size === 'lg'}
|
||||||
|
class:tabs-bordered={variant === 'bordered'}
|
||||||
|
class:tabs-lifted={variant === 'lifted'}
|
||||||
|
class:tabs-boxed={variant === 'boxed'}
|
||||||
|
>
|
||||||
|
{#each tabs as tab, index}
|
||||||
|
{#key [tab, value]}
|
||||||
|
<Tab
|
||||||
|
active={index === value}
|
||||||
|
label={tab}
|
||||||
|
onclick={() => {
|
||||||
|
value = index;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
4
src/lib/components/common/Tabs/index.ts
Normal file
4
src/lib/components/common/Tabs/index.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
import Tabs from './Tabs.svelte';
|
||||||
|
|
||||||
|
export default Tabs;
|
||||||
|
export { default as Tabs } from './Tabs.svelte';
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
import Button from '$lib/components/Button.svelte';
|
import Button from '$lib/components/Button.svelte';
|
||||||
import Container from '$lib/components/common/Container.svelte';
|
import Container from '$lib/components/common/Container.svelte';
|
||||||
import TextInput from '$lib/components/TextInput.svelte';
|
import TextInput from '$lib/components/TextInput.svelte';
|
||||||
|
import Tabs from '$lib/components/common/Tabs';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
|
||||||
let mode: 'register' | 'login' = $state('login');
|
let tab: 0 | 1 = $state(0);
|
||||||
let action = $derived(mode === 'login' ? '?/login' : '?/register');
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet userIcon()}
|
{#snippet userIcon()}
|
||||||
|
|
@ -20,38 +20,21 @@
|
||||||
<i class="fi fi-rr-user"></i>
|
<i class="fi fi-rr-user"></i>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<div class="page" transition:fade>
|
{#snippet form(variant: 'login' | 'register')}
|
||||||
<Container>
|
<form class="flex w-full flex-col items-center gap-6" method="POST" action={`?/${variant}`}>
|
||||||
<form class="flex w-full flex-col items-center gap-6" method="POST" {action}>
|
|
||||||
<h1 class="text-3xl">Hestia</h1>
|
|
||||||
<br />
|
|
||||||
<div role="tablist" class="tabs tabs-bordered tabs-lg w-full">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
role="tab"
|
|
||||||
class="tab"
|
|
||||||
class:tab-active={mode === 'login'}
|
|
||||||
onclick={() => {
|
|
||||||
mode = 'login';
|
|
||||||
}}>Login</button
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
role="tab"
|
|
||||||
class="tab"
|
|
||||||
class:tab-active={mode === 'register'}
|
|
||||||
onclick={() => {
|
|
||||||
mode = 'register';
|
|
||||||
}}>Register</button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<TextInput start={userIcon} placeholder="Email" name="email" type="email" />
|
<TextInput start={userIcon} placeholder="Email" name="email" type="email" />
|
||||||
<TextInput start={passwordIcon} placeholder="Password" name="password" type="password" />
|
<TextInput start={passwordIcon} placeholder="Password" name="password" type="password" />
|
||||||
{#if mode === 'register'}
|
{#if variant === 'register'}
|
||||||
<TextInput start={nameIcon} placeholder="Name" name="name" fade />
|
<TextInput start={nameIcon} placeholder="Name" name="name" fade />
|
||||||
{/if}
|
{/if}
|
||||||
<Button block type="submit" label="Submit" outline />
|
<Button block type="submit" label="Submit" outline />
|
||||||
</form>
|
</form>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<div class="page" transition:fade>
|
||||||
|
<Container>
|
||||||
|
<Tabs variant="bordered" bind:selected={tab} tabs={['Login', 'Register']} />
|
||||||
|
{@render form(tab === 0 ? 'login' : 'register')}
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue