Build out components #45
28 changed files with 443 additions and 43 deletions
|
|
@ -8,9 +8,11 @@
|
||||||
title: 'Actions/Button',
|
title: 'Actions/Button',
|
||||||
component: Button,
|
component: Button,
|
||||||
args: {
|
args: {
|
||||||
onClick: fn(),
|
onclick: fn(),
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
|
active: { control: 'boolean' },
|
||||||
|
animation: { control: 'boolean' },
|
||||||
block: { control: 'boolean' },
|
block: { control: 'boolean' },
|
||||||
color: {
|
color: {
|
||||||
control: 'select',
|
control: 'select',
|
||||||
|
|
@ -20,28 +22,25 @@
|
||||||
'secondary',
|
'secondary',
|
||||||
'accent',
|
'accent',
|
||||||
'ghost',
|
'ghost',
|
||||||
'link',
|
|
||||||
'info',
|
'info',
|
||||||
'success',
|
'success',
|
||||||
'warning',
|
'warning',
|
||||||
'error',
|
'error',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
disabled: { control: 'boolean' },
|
||||||
full: { control: 'boolean' },
|
full: { control: 'boolean' },
|
||||||
glass: { control: 'boolean' },
|
glass: { control: 'boolean' },
|
||||||
outline: {
|
shape: {
|
||||||
control: 'boolean',
|
control: 'select',
|
||||||
|
options: ['circle', 'square'],
|
||||||
},
|
},
|
||||||
responsive: { control: 'boolean' },
|
|
||||||
size: {
|
size: {
|
||||||
control: 'select',
|
control: 'select',
|
||||||
options: ['Default', 'xs', 'sm', 'lg'],
|
options: ['xs', 'sm', '-', 'lg'],
|
||||||
defaultValue: 'Default',
|
defaultValue: 'Default',
|
||||||
},
|
},
|
||||||
type: {
|
variant: { control: 'select', options: ['link', 'outline'] },
|
||||||
control: 'select',
|
|
||||||
options: ['button', 'reset', 'submit'],
|
|
||||||
},
|
|
||||||
wide: { control: 'boolean' },
|
wide: { control: 'boolean' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,61 +1,68 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { DaisyColor, DaisySize } from '$lib/types';
|
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||||
|
Yeah, onclick is the default prop name on elements in svelte, its not the same as with React where it follows JS camel case styling. Yeah, onclick is the default prop name on elements in svelte, its not the same as with React where it follows JS camel case styling.
kk thanks, good to know kk thanks, good to know
actually, I think I'm gonig to redo the typing here, there is redundancy actually, I think I'm gonig to redo the typing here, there is redundancy
|
|||||||
import type { Snippet } from 'svelte';
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
import type { HTMLButtonAttributes } from 'svelte/elements';
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
|
active?: boolean;
|
||||||
|
animation?: boolean;
|
||||||
block?: boolean;
|
block?: boolean;
|
||||||
children: Snippet;
|
|
||||||
color?: DaisyColor;
|
color?: DaisyColor;
|
||||||
full?: boolean;
|
full?: boolean;
|
||||||
glass?: boolean;
|
glass?: boolean;
|
||||||
outline?: boolean;
|
shape?: 'circle' | 'square';
|
||||||
onClick?: () => void;
|
|
||||||
responsive?: boolean;
|
|
||||||
size?: DaisySize;
|
size?: DaisySize;
|
||||||
type?: HTMLButtonAttributes['type'];
|
variant?: 'link' | 'outline';
|
||||||
wide?: boolean;
|
wide?: boolean;
|
||||||
}
|
} & SvelteHTMLElements['button'];
|
||||||
|
|
||||||
let {
|
let {
|
||||||
|
active = false,
|
||||||
|
animation = true,
|
||||||
block = false,
|
block = false,
|
||||||
children,
|
children,
|
||||||
|
class: className,
|
||||||
color,
|
color,
|
||||||
|
disabled,
|
||||||
full = false,
|
full = false,
|
||||||
glass = false,
|
glass = false,
|
||||||
outline = false,
|
shape,
|
||||||
onClick,
|
|
||||||
responsive = false,
|
|
||||||
size,
|
size,
|
||||||
type = 'button',
|
|
||||||
wide = false,
|
wide = false,
|
||||||
|
variant,
|
||||||
|
...props
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
{type}
|
{...props}
|
||||||
onclick={onClick}
|
{disabled}
|
||||||
class:btn-outline={outline}
|
class={twMerge('btn', className)}
|
||||||
|
class:btn-active={active}
|
||||||
|
class:no-animation={!animation}
|
||||||
class:btn-block={block}
|
class:btn-block={block}
|
||||||
class:btn-wide={wide}
|
|
||||||
class:w-full={full}
|
|
||||||
class:glass
|
|
||||||
class:btn-xs={size === 'xs'}
|
|
||||||
class:btn-sm={size === 'sm'}
|
|
||||||
class:btn-lg={size === 'lg'}
|
|
||||||
class:btn-neutral={color === 'neutral'}
|
class:btn-neutral={color === 'neutral'}
|
||||||
class:btn-primary={color === 'primary'}
|
class:btn-primary={color === 'primary'}
|
||||||
class:btn-secondary={color === 'secondary'}
|
class:btn-secondary={color === 'secondary'}
|
||||||
class:btn-accent={color === 'accent'}
|
class:btn-accent={color === 'accent'}
|
||||||
class:btn-ghost={color === 'ghost'}
|
class:btn-ghost={color === 'ghost'}
|
||||||
class:btn-link={color === 'link'}
|
|
||||||
class:btn-info={color === 'info'}
|
class:btn-info={color === 'info'}
|
||||||
class:btn-success={color === 'success'}
|
class:btn-success={color === 'success'}
|
||||||
class:btn-warning={color === 'warning'}
|
class:btn-warning={color === 'warning'}
|
||||||
class:btn-error={color === 'error'}
|
class:btn-error={color === 'error'}
|
||||||
class={`btn ${responsive && 'btn-xs sm:btn-sm md:btn-md lg:btn-lg'}`}
|
class:btn-disabled={disabled}
|
||||||
|
class:w-full={full}
|
||||||
|
class:glass
|
||||||
|
class:btn-circle={shape === 'circle'}
|
||||||
|
class:btn-square={shape === 'square'}
|
||||||
|
class:btn-xs={size === 'xs'}
|
||||||
|
class:btn-sm={size === 'sm'}
|
||||||
|
class:btn-lg={size === 'lg'}
|
||||||
|
class:btn-link={variant === 'link'}
|
||||||
|
class:btn-outline={variant === 'outline'}
|
||||||
|
class:btn-wide={wide}
|
||||||
>
|
>
|
||||||
{@render children()}
|
{@render children?.()}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@
|
||||||
class:input-secondary={color === 'secondary'}
|
class:input-secondary={color === 'secondary'}
|
||||||
class:input-accent={color === 'accent'}
|
class:input-accent={color === 'accent'}
|
||||||
class:input-ghost={color === 'ghost'}
|
class:input-ghost={color === 'ghost'}
|
||||||
class:input-link={color === 'link'}
|
|
||||||
class:input-info={color === 'info'}
|
class:input-info={color === 'info'}
|
||||||
class:input-success={color === 'success'}
|
class:input-success={color === 'success'}
|
||||||
class:input-warning={color === 'warning'}
|
class:input-warning={color === 'warning'}
|
||||||
|
|
|
||||||
25
src/lib/components/Feedback/Alert.stories.svelte
Normal file
25
src/lib/components/Feedback/Alert.stories.svelte
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import Alert from './Alert.svelte';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
import { InfoIcon } from '../Icons';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Feedback/Alert',
|
||||||
|
component: Alert,
|
||||||
|
argTypes: {
|
||||||
|
status: { control: 'select', options: ['info', 'success', 'warning', 'error'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(props: ComponentProps<typeof Alert>)}
|
||||||
|
<Alert {...props}>
|
||||||
|
{#snippet icon()}
|
||||||
|
<InfoIcon class="h-6 w-6 shrink-0 stroke-info" />
|
||||||
|
{/snippet}
|
||||||
|
<span>Hello world!</span>
|
||||||
|
</Alert>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story name="Default" args={{}} children={template} />
|
||||||
24
src/lib/components/Feedback/Alert.svelte
Normal file
24
src/lib/components/Feedback/Alert.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { DaisyColor } from '$lib/types';
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children?: Snippet;
|
||||||
|
icon?: Snippet;
|
||||||
|
status?: Extract<DaisyColor, 'info' | 'success' | 'warning' | 'error'>;
|
||||||
|
};
|
||||||
|
|
||||||
|
let { children, icon, status: color }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
role="alert"
|
||||||
|
class="alert"
|
||||||
|
class:alert-info={color === 'info'}
|
||||||
|
class:alert-success={color === 'success'}
|
||||||
|
class:alert-warning={color === 'warning'}
|
||||||
|
class:alert-error={color === 'error'}
|
||||||
|
>
|
||||||
|
{@render icon?.()}
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
||||||
40
src/lib/components/Feedback/Loading.stories.svelte
Normal file
40
src/lib/components/Feedback/Loading.stories.svelte
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
import Loading from './Loading.svelte';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Feedback/Loading',
|
||||||
|
component: Loading,
|
||||||
|
argTypes: {
|
||||||
|
color: {
|
||||||
|
control: 'select',
|
||||||
|
options: [
|
||||||
|
'neutral',
|
||||||
|
'primary',
|
||||||
|
'secondary',
|
||||||
|
'accent',
|
||||||
|
'info',
|
||||||
|
'success',
|
||||||
|
'warning',
|
||||||
|
'error',
|
||||||
|
],
|
||||||
|
I see some of them also used in the alert and other place, maybe it could be worth it to put them in an array or enums as UI tokens I see some of them also used in the alert and other place, maybe it could be worth it to put them in an array or enums as UI tokens
Same thing for the sizes tokens and anything you see used in common Same thing for the sizes tokens and anything you see used in common
Just noticed my comment is on the stories file but I meant it to be on the component itself Just noticed my comment is on the stories file but I meant it to be on the component itself
It did occur to me, there can be variation between components though, some will have ghost, others might have neutral, or not. So I just haven't made a decision for it yet. It did occur to me, there can be variation between components though, some will have ghost, others might have neutral, or not. So I just haven't made a decision for it yet.
|
|||||||
|
},
|
||||||
|
size: { control: 'select', options: ['xs', 'sm', 'md', 'lg'] },
|
||||||
|
variant: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['spinner', 'dots', 'ring', 'ball', 'bars', 'infinity'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(props: ComponentProps<typeof Loading>)}
|
||||||
|
<Loading {...props} />
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story
|
||||||
|
name="Default"
|
||||||
|
args={{ color: 'neutral', size: 'md', variant: 'spinner' }}
|
||||||
|
children={template}
|
||||||
|
/>
|
||||||
31
src/lib/components/Feedback/Loading.svelte
Normal file
31
src/lib/components/Feedback/Loading.svelte
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
color?: Exclude<DaisyColor, 'ghost'>;
|
||||||
|
size?: DaisySize | 'md';
|
||||||
|
variant?: 'spinner' | 'dots' | 'ring' | 'ball' | 'bars' | 'infinity';
|
||||||
|
};
|
||||||
|
let { color, size = 'md', variant = 'spinner' }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="loading"
|
||||||
|
class:text-primary={color === 'primary'}
|
||||||
|
class:text-secondary={color === 'secondary'}
|
||||||
|
class:text-accent={color === 'accent'}
|
||||||
|
class:text-info={color === 'info'}
|
||||||
|
class:text-success={color === 'success'}
|
||||||
|
class:text-warning={color === 'warning'}
|
||||||
|
class:text-error={color === 'error'}
|
||||||
|
class:loading-xs={size === 'xs'}
|
||||||
|
class:loading-sm={size === 'sm'}
|
||||||
|
class:loading-md={size === 'md'}
|
||||||
|
class:loading-lg={size === 'lg'}
|
||||||
|
class:loading-spinner={variant === 'spinner'}
|
||||||
|
class:loading-dots={variant === 'dots'}
|
||||||
|
class:loading-ring={variant === 'ring'}
|
||||||
|
class:loading-ball={variant === 'ball'}
|
||||||
|
class:loading-bars={variant === 'bars'}
|
||||||
|
class:loading-infinity={variant === 'infinity'}
|
||||||
|
></span>
|
||||||
24
src/lib/components/Feedback/Progress.stories.svelte
Normal file
24
src/lib/components/Feedback/Progress.stories.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
import Progress from './Progress.svelte';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Feedback/Progress',
|
||||||
|
component: Progress,
|
||||||
|
argTypes: {
|
||||||
|
color: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'],
|
||||||
|
},
|
||||||
|
value: { control: 'number' },
|
||||||
|
max: { control: 'number' },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(props: ComponentProps<typeof Progress>)}
|
||||||
|
<Progress {...props} />
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story name="Default" args={{}} children={template} />
|
||||||
24
src/lib/components/Feedback/Progress.svelte
Normal file
24
src/lib/components/Feedback/Progress.svelte
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { DaisyColor } from '$lib/types';
|
||||||
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
color?: Exclude<DaisyColor, 'neutral' | 'ghost'>;
|
||||||
|
} & SvelteHTMLElements['progress'];
|
||||||
|
let { children, class: className, color, ...props }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<progress
|
||||||
|
class={twMerge(className, 'progress')}
|
||||||
|
class:progress-primary={color === 'primary'}
|
||||||
|
class:progress-secondary={color === 'secondary'}
|
||||||
|
class:progress-accent={color === 'accent'}
|
||||||
|
class:progress-info={color === 'info'}
|
||||||
|
class:progress-success={color === 'success'}
|
||||||
|
class:progress-warning={color === 'warning'}
|
||||||
|
class:progress-error={color === 'error'}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</progress>
|
||||||
18
src/lib/components/Feedback/Skeleton.stories.svelte
Normal file
18
src/lib/components/Feedback/Skeleton.stories.svelte
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import Skeleton from './Skeleton.svelte';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Feedback/Skeleton',
|
||||||
|
component: Skeleton,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(props: ComponentProps<typeof Skeleton>)}
|
||||||
|
<Skeleton {...props} />
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story name="Default" args={{ class: 'h-32 w-32' }} children={template} />
|
||||||
|
|
||||||
|
<Story name="Circle" args={{ class: 'h-32 w-32 rounded-full' }} children={template} />
|
||||||
12
src/lib/components/Feedback/Skeleton.svelte
Normal file
12
src/lib/components/Feedback/Skeleton.svelte
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children?: Snippet;
|
||||||
|
} & SvelteHTMLElements['div'];
|
||||||
|
let { children, class: className, ...props }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div {...props} class={twMerge('skeleton', className)}>{@render children?.()}</div>
|
||||||
27
src/lib/components/Feedback/Tooltip.stories.svelte
Normal file
27
src/lib/components/Feedback/Tooltip.stories.svelte
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import Tooltip from './Tooltip.svelte';
|
||||||
|
import { Button } from '../Actions';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Feedback/Tooltip',
|
||||||
|
component: Tooltip,
|
||||||
|
argTypes: {
|
||||||
|
color: {
|
||||||
|
control: 'select',
|
||||||
|
options: ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'],
|
||||||
|
},
|
||||||
|
open: { control: 'boolean' },
|
||||||
|
position: { control: 'select', options: ['top', 'bottom', 'left', 'right'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(props: ComponentProps<typeof Tooltip>)}
|
||||||
|
<Tooltip {...props}>
|
||||||
|
<Button color="primary">Button</Button>
|
||||||
|
</Tooltip>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story name="Default" args={{ tip: "It's a button" }} children={template} />
|
||||||
33
src/lib/components/Feedback/Tooltip.svelte
Normal file
33
src/lib/components/Feedback/Tooltip.svelte
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { DaisyColor } from '$lib/types';
|
||||||
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
color?: Exclude<DaisyColor, 'neutral' | 'ghost'>;
|
||||||
|
open?: boolean;
|
||||||
|
position?: 'top' | 'bottom' | 'left' | 'right';
|
||||||
|
tip?: string;
|
||||||
|
} & SvelteHTMLElements['div'];
|
||||||
|
let { children, class: className, color, open, position, tip, ...props }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={twMerge('tooltip', className)}
|
||||||
|
class:tooltip-primary={color === 'primary'}
|
||||||
|
class:tooltip-secondary={color === 'secondary'}
|
||||||
|
class:tooltip-accent={color === 'accent'}
|
||||||
|
class:tooltip-info={color === 'info'}
|
||||||
|
class:tooltip-success={color === 'success'}
|
||||||
|
class:tooltip-warning={color === 'warning'}
|
||||||
|
class:tooltip-error={color === 'error'}
|
||||||
|
class:tooltip-open={open}
|
||||||
|
class:tooltip-top={position === 'top'}
|
||||||
|
class:tooltip-bottom={position === 'bottom'}
|
||||||
|
class:tooltip-left={position === 'left'}
|
||||||
|
class:tooltip-right={position === 'right'}
|
||||||
|
data-tip={tip}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
||||||
6
src/lib/components/Feedback/index.ts
Normal file
6
src/lib/components/Feedback/index.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
export { default as Alert } from './Alert.svelte';
|
||||||
|
export { default as Loader } from './Loader.svelte';
|
||||||
|
export { default as Loading } from './Loading.svelte';
|
||||||
|
export { default as Progress } from './Progress.svelte';
|
||||||
|
export { default as Skeleton } from './Skeleton.svelte';
|
||||||
|
export { default as Tooltip } from './Tooltip.svelte';
|
||||||
8
src/lib/components/Icons/InfoIcon.svelte
Normal file
8
src/lib/components/Icons/InfoIcon.svelte
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
let { class: className, ...props }: SvelteHTMLElements['i'] = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<i {...props} class={twMerge(className, 'fi fi-sr-info')}></i>
|
||||||
1
src/lib/components/Icons/index.ts
Normal file
1
src/lib/components/Icons/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export { default as InfoIcon } from './InfoIcon.svelte';
|
||||||
41
src/lib/components/Layout/Divider.stories.svelte
Normal file
41
src/lib/components/Layout/Divider.stories.svelte
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import Divider from './Divider.svelte';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Layout/Divider',
|
||||||
|
component: Divider,
|
||||||
|
argTypes: {
|
||||||
|
color: {
|
||||||
|
control: 'select',
|
||||||
|
options: [
|
||||||
|
'neutral',
|
||||||
|
'primary',
|
||||||
|
'secondary',
|
||||||
|
'accent',
|
||||||
|
'info',
|
||||||
|
'success',
|
||||||
|
'warning',
|
||||||
|
'error',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
direction: { control: 'select', options: ['horizontal', 'vertical'] },
|
||||||
|
variant: { control: 'select', options: ['start', 'end'] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(props: ComponentProps<typeof Divider>)}
|
||||||
|
<div
|
||||||
|
class="flex"
|
||||||
|
class:flex-row={props.direction === 'horizontal'}
|
||||||
|
class:flex-col={props.direction === 'vertical'}
|
||||||
|
>
|
||||||
|
<span>Side A</span>
|
||||||
|
<Divider {...props} />
|
||||||
|
<span>Side B</span>
|
||||||
|
</div>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story name="Default" args={{}} children={template} />
|
||||||
31
src/lib/components/Layout/Divider.svelte
Normal file
31
src/lib/components/Layout/Divider.svelte
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { DaisyColor } from '$lib/types';
|
||||||
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
color?: Exclude<DaisyColor, 'ghost'>;
|
||||||
|
direction?: 'horizontal' | 'vertical';
|
||||||
|
variant?: 'start' | 'end';
|
||||||
|
} & SvelteHTMLElements['div'];
|
||||||
|
let { children, class: className, color, direction, variant, ...props }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={twMerge('divider', className)}
|
||||||
|
class:divider-neutral={color === 'neutral'}
|
||||||
|
class:divider-primary={color === 'primary'}
|
||||||
|
class:divider-secondary={color === 'secondary'}
|
||||||
|
class:divider-accent={color === 'accent'}
|
||||||
|
class:divider-info={color === 'info'}
|
||||||
|
class:divider-success={color === 'success'}
|
||||||
|
class:divider-warning={color === 'warning'}
|
||||||
|
class:divider-error={color === 'error'}
|
||||||
|
class:divider-horizontal={direction === 'horizontal'}
|
||||||
|
class:divider-vertical={direction === 'vertical'}
|
||||||
|
class:divider-start={variant === 'start'}
|
||||||
|
class:divider-end={variant === 'end'}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
||||||
0
src/lib/components/Layout/index.ts
Normal file
0
src/lib/components/Layout/index.ts
Normal file
31
src/lib/components/Navigation/Link.stories.svelte
Normal file
31
src/lib/components/Navigation/Link.stories.svelte
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<script module lang="ts">
|
||||||
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
|
import type { ComponentProps } from 'svelte';
|
||||||
|
import Link from './Link.svelte';
|
||||||
|
|
||||||
|
const { Story } = defineMeta({
|
||||||
|
title: 'Navigation/Link',
|
||||||
|
component: Link,
|
||||||
|
argTypes: {
|
||||||
|
color: {
|
||||||
|
control: 'select',
|
||||||
|
options: [
|
||||||
|
'primary',
|
||||||
|
'secondary',
|
||||||
|
'accent',
|
||||||
|
'neutral',
|
||||||
|
'info',
|
||||||
|
'success',
|
||||||
|
'warning',
|
||||||
|
'error',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet template(props: ComponentProps<typeof Link>)}
|
||||||
|
<Link {...props}>Hello world!</Link>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<Story name="Default" children={template} />
|
||||||
23
src/lib/components/Navigation/Link.svelte
Normal file
23
src/lib/components/Navigation/Link.svelte
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { DaisyColor } from '$lib/types';
|
||||||
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
type Props = { color?: DaisyColor; hover?: boolean } & SvelteHTMLElements['a'];
|
||||||
|
|
||||||
|
let { children, class: className, color, hover, ...props }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class={twMerge(className, 'link')}
|
||||||
|
class:link-primary={color === 'primary'}
|
||||||
|
class:link-secondary={color === 'secondary'}
|
||||||
|
class:link-accent={color === 'accent'}
|
||||||
|
class:link-neutral={color === 'neutral'}
|
||||||
|
class:link-info={color === 'info'}
|
||||||
|
class:link-success={color === 'success'}
|
||||||
|
class:link-warning={color === 'warning'}
|
||||||
|
class:link-error={color === 'error'}
|
||||||
|
class:link-hover={hover}
|
||||||
|
{...props}>{@render children?.()}</a
|
||||||
|
>
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import Navbar from './Navbar';
|
import Navbar from './Navbar';
|
||||||
import Tabs from './Tabs';
|
import Tabs from './Tabs';
|
||||||
|
|
||||||
|
export { default as Link } from './Link.svelte';
|
||||||
export { Navbar, Tabs };
|
export { Navbar, Tabs };
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
import Loader from './Loader.svelte';
|
|
||||||
|
|
||||||
export default Loader;
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
export type DaisyColor =
|
export type DaisyColor =
|
||||||
| 'default'
|
|
||||||
| 'neutral'
|
| 'neutral'
|
||||||
| 'primary'
|
| 'primary'
|
||||||
| 'secondary'
|
| 'secondary'
|
||||||
| 'accent'
|
| 'accent'
|
||||||
| 'ghost'
|
| 'ghost'
|
||||||
| 'link'
|
|
||||||
| 'info'
|
| 'info'
|
||||||
| 'success'
|
| 'success'
|
||||||
| 'warning'
|
| 'warning'
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import Loader from '$lib/components/common/Loader';
|
import { Loader } from '$lib/components/Feedback';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions justify-center px-8 pb-4">
|
<div class="card-actions justify-center px-8 pb-4">
|
||||||
<Button outline type="submit" full>{messages.sms_button_submit()}</Button>
|
<Button type="submit" variant="outline" full>{messages.sms_button_submit()}</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue
Any reason or standard you had to change the onClick to onclick?