mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2025-07-29 05:02:52 +08:00
storybook: add lint command and lint files
This commit is contained in:
@ -1,4 +1,8 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['tih'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: ['./tsconfig.json'],
|
||||
},
|
||||
};
|
||||
|
@ -7,6 +7,7 @@
|
||||
"build": "build-storybook --docs",
|
||||
"preview-storybook": "serve storybook-static",
|
||||
"clean": "rm -rf .turbo && rm -rf node_modules",
|
||||
"lint": "eslint stories/**/*.ts* --fix",
|
||||
"tsc": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Alert, AlertVariant } from '@tih/ui';
|
||||
import React from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { AlertVariant } from '@tih/ui';
|
||||
import { Alert } from '@tih/ui';
|
||||
|
||||
const alertVariants: ReadonlyArray<AlertVariant> = [
|
||||
'info',
|
||||
@ -10,24 +11,24 @@ const alertVariants: ReadonlyArray<AlertVariant> = [
|
||||
];
|
||||
|
||||
export default {
|
||||
title: 'Alert',
|
||||
component: Alert,
|
||||
argTypes: {
|
||||
title: {
|
||||
control: 'text',
|
||||
},
|
||||
variant: {
|
||||
options: alertVariants,
|
||||
control: { type: 'select' },
|
||||
options: alertVariants,
|
||||
},
|
||||
},
|
||||
component: Alert,
|
||||
title: 'Alert',
|
||||
} as ComponentMeta<typeof Alert>;
|
||||
|
||||
export const Basic = {
|
||||
args: {
|
||||
children: 'This is something you should pay your full attention to.',
|
||||
title: 'Please pay attention',
|
||||
variant: 'info',
|
||||
children: 'This is something you should pay your full attention to.',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Badge, BadgeVariant } from '@tih/ui';
|
||||
import React from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { BadgeVariant } from '@tih/ui';
|
||||
import { Badge } from '@tih/ui';
|
||||
|
||||
const badgeVariants: ReadonlyArray<BadgeVariant> = [
|
||||
'primary',
|
||||
@ -11,14 +12,14 @@ const badgeVariants: ReadonlyArray<BadgeVariant> = [
|
||||
];
|
||||
|
||||
export default {
|
||||
title: 'Badge',
|
||||
component: Badge,
|
||||
argTypes: {
|
||||
variant: {
|
||||
options: badgeVariants,
|
||||
control: { type: 'select' },
|
||||
options: badgeVariants,
|
||||
},
|
||||
},
|
||||
component: Badge,
|
||||
title: 'Badge',
|
||||
} as ComponentMeta<typeof Badge>;
|
||||
|
||||
export const Basic = {
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
|
||||
import {
|
||||
Button,
|
||||
import React from 'react';
|
||||
import { EnvelopeIcon } from '@heroicons/react/24/solid';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type {
|
||||
ButtonAddOnPosition,
|
||||
ButtonDisplay,
|
||||
ButtonSize,
|
||||
ButtonType,
|
||||
ButtonVariant,
|
||||
ButtonVariant} from '@tih/ui';
|
||||
import {
|
||||
Button
|
||||
} from '@tih/ui';
|
||||
import React from 'react';
|
||||
import { EnvelopeIcon } from '@heroicons/react/24/solid';
|
||||
|
||||
const buttonTypes: ReadonlyArray<ButtonType> = ['button', 'reset', 'submit'];
|
||||
const buttonSizes: ReadonlyArray<ButtonSize> = ['sm', 'md', 'lg'];
|
||||
@ -27,16 +27,14 @@ const buttonVariants: ReadonlyArray<ButtonVariant> = [
|
||||
];
|
||||
|
||||
export default {
|
||||
title: 'Button',
|
||||
component: Button,
|
||||
argTypes: {
|
||||
addonPosition: {
|
||||
options: buttonAddOnPositions,
|
||||
control: { type: 'select' },
|
||||
options: buttonAddOnPositions,
|
||||
},
|
||||
display: {
|
||||
options: buttonDisplays,
|
||||
control: { type: 'select' },
|
||||
options: buttonDisplays,
|
||||
},
|
||||
isDisabled: {
|
||||
control: 'boolean',
|
||||
@ -48,18 +46,20 @@ export default {
|
||||
control: 'text',
|
||||
},
|
||||
size: {
|
||||
options: buttonSizes,
|
||||
control: { type: 'select' },
|
||||
options: buttonSizes,
|
||||
},
|
||||
type: {
|
||||
options: buttonTypes,
|
||||
control: { type: 'select' },
|
||||
options: buttonTypes,
|
||||
},
|
||||
variant: {
|
||||
options: buttonVariants,
|
||||
control: { type: 'select' },
|
||||
options: buttonVariants,
|
||||
},
|
||||
},
|
||||
component: Button,
|
||||
title: 'Button',
|
||||
} as ComponentMeta<typeof Button>;
|
||||
|
||||
export const Basic = {
|
||||
@ -111,8 +111,8 @@ export function Disabled() {
|
||||
<div className="space-x-4">
|
||||
{buttonVariants.map((variant) => (
|
||||
<Button
|
||||
isDisabled={true}
|
||||
key={variant}
|
||||
isDisabled={true}
|
||||
label="Click Me"
|
||||
size="md"
|
||||
variant={variant}
|
||||
@ -128,8 +128,8 @@ export function Loading() {
|
||||
<div className="space-x-4">
|
||||
{buttonVariants.map((variant) => (
|
||||
<Button
|
||||
isLoading={true}
|
||||
key={variant}
|
||||
isLoading={true}
|
||||
label="Click Me"
|
||||
size="md"
|
||||
variant={variant}
|
||||
@ -139,9 +139,9 @@ export function Loading() {
|
||||
<div className="space-x-4">
|
||||
{buttonVariants.map((variant) => (
|
||||
<Button
|
||||
key={variant}
|
||||
isDisabled={true}
|
||||
isLoading={true}
|
||||
key={variant}
|
||||
label="Click Me"
|
||||
size="md"
|
||||
variant={variant}
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Button, Dialog } from '@tih/ui';
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import { Button, Dialog } from '@tih/ui';
|
||||
|
||||
export default {
|
||||
title: 'Dialog',
|
||||
component: Dialog,
|
||||
argTypes: {
|
||||
title: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
component: Dialog,
|
||||
title: 'Dialog',
|
||||
} as ComponentMeta<typeof Dialog>;
|
||||
|
||||
export function Basic({
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { DropdownMenu, DropdownMenuAlignment, DropdownMenuSize } from '@tih/ui';
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { DropdownMenuAlignment, DropdownMenuSize } from '@tih/ui';
|
||||
import { DropdownMenu } from '@tih/ui';
|
||||
|
||||
const DropdownMenuAlignments: ReadonlyArray<DropdownMenuAlignment> = [
|
||||
'start',
|
||||
@ -12,27 +13,27 @@ const DropdownMenuSizes: ReadonlyArray<DropdownMenuSize> = [
|
||||
];
|
||||
|
||||
export default {
|
||||
title: 'DropdownMenu',
|
||||
component: DropdownMenu,
|
||||
parameters: {
|
||||
docs: {
|
||||
inlineStories: false,
|
||||
iframeHeight: 300,
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
align: {
|
||||
options: DropdownMenuAlignments,
|
||||
control: { type: 'select' },
|
||||
options: DropdownMenuAlignments,
|
||||
},
|
||||
label: {
|
||||
control: 'text',
|
||||
},
|
||||
size: {
|
||||
options: DropdownMenuSizes,
|
||||
control: { type: 'select' },
|
||||
options: DropdownMenuSizes,
|
||||
},
|
||||
},
|
||||
component: DropdownMenu,
|
||||
parameters: {
|
||||
docs: {
|
||||
iframeHeight: 300,
|
||||
inlineStories: false,
|
||||
},
|
||||
},
|
||||
title: 'DropdownMenu',
|
||||
} as ComponentMeta<typeof DropdownMenu>;
|
||||
|
||||
export function Basic({
|
||||
@ -62,11 +63,11 @@ export function Basic({
|
||||
|
||||
return (
|
||||
<DropdownMenu align={align} label={label} size={size}>
|
||||
{menuItems.map(({ label, value }) => (
|
||||
{menuItems.map(({ label: itemLabel, value }) => (
|
||||
<DropdownMenu.Item
|
||||
key={value}
|
||||
isSelected={value === selectedValue}
|
||||
label={label}
|
||||
label={itemLabel}
|
||||
onClick={() => {
|
||||
setSelectedValue(value);
|
||||
}}
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Select, SelectDisplay } from '@tih/ui';
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { SelectDisplay } from '@tih/ui';
|
||||
import { Select } from '@tih/ui';
|
||||
|
||||
const SelectDisplays: ReadonlyArray<SelectDisplay> = ['inline', 'block'];
|
||||
|
||||
export default {
|
||||
title: 'Select',
|
||||
component: Select,
|
||||
argTypes: {
|
||||
display: {
|
||||
options: SelectDisplays,
|
||||
control: { type: 'select' },
|
||||
options: SelectDisplays,
|
||||
},
|
||||
isLabelHidden: {
|
||||
control: 'boolean',
|
||||
@ -22,6 +21,8 @@ export default {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
component: Select,
|
||||
title: 'Select',
|
||||
} as ComponentMeta<typeof Select>;
|
||||
|
||||
export function Basic({
|
||||
@ -40,7 +41,6 @@ export function Basic({
|
||||
display={display}
|
||||
isLabelHidden={isLabelHidden}
|
||||
label={label}
|
||||
onChange={setValue}
|
||||
name={name}
|
||||
options={[
|
||||
{
|
||||
@ -57,14 +57,15 @@ export function Basic({
|
||||
},
|
||||
]}
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Basic.args = {
|
||||
label: 'Select fruit',
|
||||
display: 'inline',
|
||||
isLabelHidden: false,
|
||||
label: 'Select fruit',
|
||||
};
|
||||
|
||||
export function Display() {
|
||||
@ -74,7 +75,6 @@ export function Display() {
|
||||
<div className="space-x-4">
|
||||
<Select
|
||||
label="Select a fruit"
|
||||
onChange={setValue}
|
||||
options={[
|
||||
{
|
||||
label: 'Apple',
|
||||
@ -90,6 +90,7 @@ export function Display() {
|
||||
},
|
||||
]}
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,26 +1,27 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Button, SlideOut, SlideOutEnterFrom, SlideOutSize } from '@tih/ui';
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { SlideOutEnterFrom, SlideOutSize } from '@tih/ui';
|
||||
import { Button, SlideOut } from '@tih/ui';
|
||||
|
||||
const slideOutEnterFrom: ReadonlyArray<SlideOutEnterFrom> = ['start', 'end'];
|
||||
const slideOutSize: ReadonlyArray<SlideOutSize> = ['sm', 'md', 'lg', 'xl'];
|
||||
|
||||
export default {
|
||||
title: 'SlideOut',
|
||||
component: SlideOut,
|
||||
argTypes: {
|
||||
enterFrom: {
|
||||
control: { type: 'select' },
|
||||
options: slideOutEnterFrom,
|
||||
},
|
||||
size: {
|
||||
control: { type: 'select' },
|
||||
options: slideOutSize,
|
||||
},
|
||||
title: {
|
||||
control: 'text',
|
||||
},
|
||||
enterFrom: {
|
||||
options: slideOutEnterFrom,
|
||||
control: { type: 'select' },
|
||||
},
|
||||
size: {
|
||||
options: slideOutSize,
|
||||
control: { type: 'select' },
|
||||
},
|
||||
},
|
||||
component: SlideOut,
|
||||
title: 'SlideOut',
|
||||
} as ComponentMeta<typeof SlideOut>;
|
||||
|
||||
export function Basic({
|
||||
@ -50,8 +51,8 @@ export function Basic({
|
||||
}
|
||||
|
||||
Basic.args = {
|
||||
title: 'Navigation',
|
||||
children: <div className="p-4">Hello World</div>,
|
||||
enterFrom: 'end',
|
||||
size: 'md',
|
||||
title: 'Navigation',
|
||||
};
|
||||
|
@ -1,32 +1,32 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
|
||||
import { Spinner, SpinnerColor, SpinnerSize, SpinnerDisplay } from '@tih/ui';
|
||||
import React from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import type { SpinnerColor, SpinnerDisplay,SpinnerSize } from '@tih/ui';
|
||||
import { Spinner } from '@tih/ui';
|
||||
|
||||
const spinnerColors: ReadonlyArray<SpinnerColor> = ['default', 'inherit'];
|
||||
const spinnerDisplays: ReadonlyArray<SpinnerDisplay> = ['block', 'inline'];
|
||||
const spinnerSizes: ReadonlyArray<SpinnerSize> = ['xs', 'sm', 'md', 'lg'];
|
||||
|
||||
export default {
|
||||
title: 'Spinner',
|
||||
component: Spinner,
|
||||
argTypes: {
|
||||
color: {
|
||||
options: spinnerColors,
|
||||
control: { type: 'select' },
|
||||
options: spinnerColors,
|
||||
},
|
||||
display: {
|
||||
options: spinnerDisplays,
|
||||
control: { type: 'select' },
|
||||
options: spinnerDisplays,
|
||||
},
|
||||
label: {
|
||||
control: 'text',
|
||||
},
|
||||
size: {
|
||||
options: spinnerSizes,
|
||||
control: { type: 'select' },
|
||||
options: spinnerSizes,
|
||||
},
|
||||
},
|
||||
component: Spinner,
|
||||
title: 'Spinner',
|
||||
} as ComponentMeta<typeof Spinner>;
|
||||
|
||||
export const Basic = {
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { Tabs } from '@tih/ui';
|
||||
import React, { useState } from 'react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import { Tabs } from '@tih/ui';
|
||||
|
||||
export default {
|
||||
title: 'Tabs',
|
||||
component: Tabs,
|
||||
argTypes: {
|
||||
label: {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
component: Tabs,
|
||||
title: 'Tabs',
|
||||
} as ComponentMeta<typeof Tabs>;
|
||||
|
||||
export function Basic({
|
||||
@ -20,7 +20,6 @@ export function Basic({
|
||||
return (
|
||||
<Tabs
|
||||
label={label}
|
||||
onChange={setValue}
|
||||
tabs={[
|
||||
{
|
||||
label: 'Apple',
|
||||
@ -36,6 +35,7 @@ export function Basic({
|
||||
},
|
||||
]}
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
EnvelopeIcon,
|
||||
KeyIcon,
|
||||
QuestionMarkCircleIcon,
|
||||
} from '@heroicons/react/24/solid';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import type { ComponentMeta } from '@storybook/react';
|
||||
import { TextInput } from '@tih/ui';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export default {
|
||||
title: 'TextInput',
|
||||
component: TextInput,
|
||||
argTypes: {
|
||||
autoComplete: {
|
||||
control: 'text',
|
||||
@ -36,6 +34,8 @@ export default {
|
||||
control: 'text',
|
||||
},
|
||||
},
|
||||
component: TextInput,
|
||||
title: 'TextInput',
|
||||
} as ComponentMeta<typeof TextInput>;
|
||||
|
||||
export const Basic = {
|
||||
@ -89,9 +89,9 @@ export function Icon() {
|
||||
onChange={setValue}
|
||||
/>
|
||||
<TextInput
|
||||
startIcon={QuestionMarkCircleIcon}
|
||||
label="Account number"
|
||||
placeholder="000-00-0000"
|
||||
startIcon={QuestionMarkCircleIcon}
|
||||
type="text"
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
@ -116,10 +116,10 @@ export function Error() {
|
||||
|
||||
return (
|
||||
<TextInput
|
||||
label="Email"
|
||||
errorMessage={
|
||||
value.length < 6 ? 'Password must be at least 6 characters' : undefined
|
||||
}
|
||||
label="Email"
|
||||
startIcon={KeyIcon}
|
||||
type="password"
|
||||
value={value}
|
||||
|
Reference in New Issue
Block a user