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 Container from '$lib/components/common/Container.svelte';
|
||||
import TextInput from '$lib/components/TextInput.svelte';
|
||||
import Tabs from '$lib/components/common/Tabs';
|
||||
import { fade } from 'svelte/transition';
|
||||
|
||||
let mode: 'register' | 'login' = $state('login');
|
||||
let action = $derived(mode === 'login' ? '?/login' : '?/register');
|
||||
let tab: 0 | 1 = $state(0);
|
||||
</script>
|
||||
|
||||
{#snippet userIcon()}
|
||||
|
|
@ -20,38 +20,21 @@
|
|||
<i class="fi fi-rr-user"></i>
|
||||
{/snippet}
|
||||
|
||||
<div class="page" transition:fade>
|
||||
<Container>
|
||||
<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>
|
||||
{#snippet form(variant: 'login' | 'register')}
|
||||
<form class="flex w-full flex-col items-center gap-6" method="POST" action={`?/${variant}`}>
|
||||
<TextInput start={userIcon} placeholder="Email" name="email" type="email" />
|
||||
<TextInput start={passwordIcon} placeholder="Password" name="password" type="password" />
|
||||
{#if mode === 'register'}
|
||||
{#if variant === 'register'}
|
||||
<TextInput start={nameIcon} placeholder="Name" name="name" fade />
|
||||
{/if}
|
||||
<Button block type="submit" label="Submit" outline />
|
||||
</form>
|
||||
{/snippet}
|
||||
|
||||
<div class="page" transition:fade>
|
||||
<Container>
|
||||
<Tabs variant="bordered" bind:selected={tab} tabs={['Login', 'Register']} />
|
||||
{@render form(tab === 0 ? 'login' : 'register')}
|
||||
</Container>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue