1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-29 15:11:58 +00:00

feat: add storybook

This commit is contained in:
Jason Rasmussen 2024-06-04 18:06:28 -04:00
parent e0ec75119f
commit 146f24eaae
No known key found for this signature in database
GPG key ID: 75AD31BF84C94773
9 changed files with 8659 additions and 333 deletions

View file

@ -6,6 +6,7 @@ module.exports = {
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended',
'plugin:unicorn/recommended',
'plugin:storybook/recommended',
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],

2
web/.gitignore vendored
View file

@ -6,3 +6,5 @@ node_modules
.env
.env.*
!.env.example
*storybook.log

17
web/.storybook/main.ts Normal file
View file

@ -0,0 +1,17 @@
import type { StorybookConfig } from '@storybook/sveltekit';
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx|svelte)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@chromatic-com/storybook',
'@storybook/addon-interactions',
'@storybook/addon-svelte-csf',
],
framework: {
name: '@storybook/sveltekit',
options: {},
},
};
export default config;

15
web/.storybook/preview.ts Normal file
View file

@ -0,0 +1,15 @@
import type { Preview } from '@storybook/svelte';
import '../src/app.css';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};
export default preview;

8838
web/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -20,11 +20,22 @@
"test": "vitest --run",
"test:cov": "vitest --coverage",
"test:watch": "vitest dev",
"prepare": "svelte-kit sync"
"prepare": "svelte-kit sync",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.5.0",
"@faker-js/faker": "^8.4.1",
"@socket.io/component-emitter": "^3.1.0",
"@storybook/addon-essentials": "^8.1.5",
"@storybook/addon-interactions": "^8.1.5",
"@storybook/addon-links": "^8.1.5",
"@storybook/addon-svelte-csf": "^4.1.3",
"@storybook/blocks": "^8.1.5",
"@storybook/svelte": "^8.1.5",
"@storybook/sveltekit": "^8.1.5",
"@storybook/test": "^8.1.5",
"@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/enhanced-img": "^0.2.0",
"@sveltejs/kit": "^2.5.2",
@ -42,6 +53,7 @@
"autoprefixer": "^10.4.17",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-storybook": "^0.8.0",
"eslint-plugin-svelte": "^2.35.1",
"eslint-plugin-unicorn": "^53.0.0",
"factory.ts": "^1.4.1",
@ -50,6 +62,7 @@
"prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-svelte": "^3.2.1",
"rollup-plugin-visualizer": "^5.12.0",
"storybook": "^8.1.5",
"svelte": "^4.2.12",
"svelte-check": "^3.6.5",
"tailwindcss": "^3.4.1",
@ -74,8 +87,8 @@
"lodash-es": "^4.17.21",
"luxon": "^3.4.4",
"socket.io-client": "^4.7.4",
"svelte-local-storage-store": "^0.6.4",
"svelte-i18n": "^4.0.0",
"svelte-local-storage-store": "^0.6.4",
"svelte-maplibre": "^0.9.0",
"thumbhash": "^0.1.1"
},

View file

@ -0,0 +1,68 @@
<script lang="ts">
import type { Color, OnBlur, OnClick, OnFocus, Shape, Size } from '$lib/ui/types';
import type { HTMLButtonAttributes } from 'svelte/elements';
export let type: HTMLButtonAttributes['type'] = 'button';
export let color: Color = 'primary';
export let size: Size = 'md';
export let shape: Shape = 'rounded';
export let disabled = false;
export let onClick: OnClick | undefined;
export let onFocus: OnFocus | undefined;
export let onBlur: OnBlur | undefined;
let className = '';
export { className as class };
const sizes: Record<Size, string> = {
xs: 'p-0 ml-2 mr-0 align-top font-small',
sm: 'px-4 py-2 text-sm font-medium',
md: 'px-6 py-3 font-medium',
lg: 'px-6 py-4 font-semibold',
xl: 'px-8 py-6 font-large font-semibold',
};
const colors: Record<Color, string> = {
primary:
'bg-immich-primary dark:bg-immich-dark-primary text-white dark:text-immich-dark-gray enabled:dark:hover:bg-immich-dark-primary/80 enabled:hover:bg-immich-primary/90',
secondary:
'bg-gray-500 dark:bg-gray-200 text-white dark:text-immich-dark-gray enabled:hover:bg-gray-500/90 enabled:dark:hover:bg-gray-200/90',
success: '',
danger: '',
warning: '',
info: '',
};
const rounded = {
xs: 'rounded-xs',
sm: 'rounded-sm',
md: 'rounded-md',
lg: 'rounded-lg',
xl: 'rounded-xl',
};
const getClasses = () => {
const classes = [className, sizes[size], colors[color]];
if (shape === 'rounded') {
classes.push(rounded[size]);
}
if (shape === 'circle') {
classes.push('rounded-full');
}
return classes.join(' ');
};
</script>
<button
{type}
{disabled}
on:click={onClick}
on:focus={onFocus}
on:blur={onBlur}
class="inline-flex items-center justify-center transition-colors disabled:cursor-not-allowed disabled:opacity-60 {getClasses()}"
>
<slot />
</button>

9
web/src/lib/ui/types.ts Normal file
View file

@ -0,0 +1,9 @@
export type Color = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
export type Shape = 'rounded' | 'circle';
export type OnClick = () => void;
export type OnBlur = () => void;
export type OnFocus = () => void;

View file

@ -0,0 +1,25 @@
<script context="module">
import Button from '$lib/ui/Button.svelte';
import { Template } from '@storybook/addon-svelte-csf';
export const meta = {
title: 'Button',
component: Button,
};
</script>
<script>
import { Story } from '@storybook/addon-svelte-csf';
</script>
<Template let:args>
<Button {...args}>{args.text ?? 'Click me'}</Button>
</Template>
<Story name="Primary" args={{}} />
<Story name="Secondary" args={{ color: 'secondary' }} />
<Story name="Size: tiny" args={{ size: 'xs' }} />
<Story name="Size: sm" args={{ size: 'sm' }} />
<Story name="Size: base" args={{ size: 'md' }} />
<Story name="Size: lg" args={{ size: 'lg' }} />
<Story name="Size: xl" args={{ size: 'xl' }} />