Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/key-ui/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { StorybookConfig } from '@storybook/react-vite'

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-vitest', '@storybook/addon-docs'],
framework: {
name: '@storybook/react-vite',
options: {},
},
}

export default config
84 changes: 84 additions & 0 deletions packages/key-ui/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { Preview, ReactRenderer } from '@storybook/react-vite'
import type { DecoratorFunction } from 'storybook/internal/types'
import { useEffect } from 'react'
import '../src/styles/base.css'

const mobileViewports = {
iPhoneSE: {
name: 'iPhone SE',
styles: { width: '375px', height: '667px' },
type: 'mobile' as const,
},
iPhone13: {
name: 'iPhone 13',
styles: { width: '390px', height: '844px' },
type: 'mobile' as const,
},
iPhone13ProMax: {
name: 'iPhone 13 Pro Max',
styles: { width: '428px', height: '926px' },
type: 'mobile' as const,
},
}

const preview: Preview = {
parameters: {
viewport: {
viewports: mobileViewports,
defaultViewport: 'iPhone13',
},
backgrounds: {
disable: true,
},
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
globalTypes: {
theme: {
name: 'Theme',
description: 'Color theme',
defaultValue: 'light',
toolbar: {
icon: 'paintbrush',
items: [
{ value: 'light', title: 'Light', icon: 'sun' },
{ value: 'dark', title: 'Dark', icon: 'moon' },
],
dynamicTitle: true,
},
},
},
decorators: [
((Story, context) => {
const theme = context.globals['theme'] || 'light'

useEffect(() => {
if (theme === 'dark') {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
}, [theme])

return (
<div className={`min-h-screen bg-background text-foreground transition-colors ${theme === 'dark' ? 'dark' : ''}`}>
<div
className="mx-auto p-4"
style={{
maxWidth: 428,
minHeight: '100vh',
}}
>
<Story />
</div>
</div>
)
}) as DecoratorFunction<ReactRenderer>,
],
}

export default preview
7 changes: 7 additions & 0 deletions packages/key-ui/.storybook/vitest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { beforeAll } from 'vitest'
import { setProjectAnnotations } from '@storybook/react-vite'
import * as previewAnnotations from './preview'

const annotations = setProjectAnnotations([previewAnnotations])

beforeAll(annotations.beforeAll)
11 changes: 9 additions & 2 deletions packages/key-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@
"typecheck": "tsc --noEmit",
"typecheck:run": "tsc --noEmit",
"test": "vitest",
"test:run": "vitest run --passWithNoTests",
"test:storybook": "echo 'No storybook'",
"test:run": "vitest run --project unit --passWithNoTests",
"test:storybook": "vitest run --project storybook --passWithNoTests",
"storybook": "storybook dev -p 6008",
"storybook:build": "storybook build",
"lint:run": "oxlint .",
"i18n:run": "echo 'No i18n'",
"theme:run": "echo 'No theme'"
Expand All @@ -54,13 +56,18 @@
"react-dom": "^19.0.0"
},
"devDependencies": {
"@storybook/addon-docs": "^10.0.0",
"@storybook/addon-vitest": "^10.0.0",
"@storybook/react-vite": "^10.0.0",
"@testing-library/react": "^16.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitest/browser-playwright": "^4.0.0",
"clsx": "^2.1.1",
"eslint-plugin-file-component-constraints": "workspace:*",
"jsdom": "^26.1.0",
"oxlint": "^1.32.0",
"storybook": "^10.0.0",
"tailwind-merge": "^3.4.0",
"typescript": "^5.9.3",
"vite": "^7.3.0",
Expand Down
81 changes: 81 additions & 0 deletions packages/key-ui/src/address-display/AddressDisplay.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { Meta, StoryObj } from '@storybook/react-vite'
import { AddressDisplay } from './AddressDisplay'

const meta: Meta<typeof AddressDisplay> = {
title: 'Components/AddressDisplay',
component: AddressDisplay,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
mode: {
control: 'select',
options: ['auto', 'compact', 'standard', 'detailed', 'full'],
},
copyable: {
control: 'boolean',
},
},
}

export default meta
type Story = StoryObj<typeof meta>

const SAMPLE_ADDRESS = '0x1234567890abcdef1234567890abcdef12345678'

export const Default: Story = {
args: {
address: SAMPLE_ADDRESS,
},
}

export const Compact: Story = {
args: {
address: SAMPLE_ADDRESS,
mode: 'compact',
},
}

export const Standard: Story = {
args: {
address: SAMPLE_ADDRESS,
mode: 'standard',
},
}

export const Detailed: Story = {
args: {
address: SAMPLE_ADDRESS,
mode: 'detailed',
},
}

export const Full: Story = {
args: {
address: SAMPLE_ADDRESS,
mode: 'full',
},
}

export const NotCopyable: Story = {
args: {
address: SAMPLE_ADDRESS,
copyable: false,
},
}

export const CustomChars: Story = {
args: {
address: SAMPLE_ADDRESS,
startChars: 10,
endChars: 8,
},
}

export const Empty: Story = {
args: {
address: '',
placeholder: 'No address',
},
}
106 changes: 106 additions & 0 deletions packages/key-ui/src/amount-display/AmountDisplay.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import type { Meta, StoryObj } from '@storybook/react-vite'
import { AmountDisplay } from './AmountDisplay'

const meta: Meta<typeof AmountDisplay> = {
title: 'Components/AmountDisplay',
component: AmountDisplay,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
argTypes: {
sign: {
control: 'select',
options: ['auto', 'always', 'never'],
},
color: {
control: 'select',
options: ['auto', 'default', 'positive', 'negative'],
},
size: {
control: 'select',
options: ['xs', 'sm', 'md', 'lg', 'xl'],
},
weight: {
control: 'select',
options: ['normal', 'medium', 'semibold', 'bold'],
},
},
}

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {
args: {
value: '1234.56789',
symbol: 'ETH',
},
}

export const Positive: Story = {
args: {
value: '1234.56789',
symbol: 'ETH',
sign: 'always',
color: 'auto',
},
}

export const Negative: Story = {
args: {
value: '-1234.56789',
symbol: 'ETH',
sign: 'auto',
color: 'auto',
},
}

export const Compact: Story = {
args: {
value: '1234567.89',
symbol: 'ETH',
compact: true,
},
}

export const Large: Story = {
args: {
value: '1234.56789',
symbol: 'ETH',
size: 'xl',
weight: 'bold',
},
}

export const Loading: Story = {
args: {
value: '0',
symbol: 'ETH',
loading: true,
},
}

export const Hidden: Story = {
args: {
value: '1234.56789',
symbol: 'ETH',
hidden: true,
},
}

export const NoAnimation: Story = {
args: {
value: '1234.56789',
symbol: 'ETH',
animated: false,
},
}

export const HighDecimals: Story = {
args: {
value: '0.00000001',
symbol: 'BTC',
decimals: 8,
},
}
Loading