[WIP]npm์—์„œ pnpm์œผ๋กœ ๋ฐ”๊ฟจ๋”๋‹ˆ storybook action์ด ์•ˆ๋จนํžŒ๋‹ค

2025. 11. 3. 00:29ใ†Trouble Shooting & Issues/Linkiving

๋ฐ˜์‘ํ˜•

 

npm ์‹œ์ ˆ

// TextArea.stories.tsx
import { action } from '@storybook/addon-actions';
import { Meta, StoryObj } from '@storybook/react';
import React, { useState } from 'react';

import TextArea, { TextAreaProps } from './TextArea';

const meta = {
  title: 'Components/TextArea',
  component: TextArea,
  tags: ['autodocs'],
  argTypes: {
    placeholder: { control: 'text' },
    onSubmit: { action: 'submit' },
    width: {
      control: { type: 'radio' },
      options: ['sm', 'md', 'lg'],
    },
    height: {
      control: { type: 'radio' },
      options: ['sm', 'md', 'lg'],
    },
    maxLength: {
      control: 'number',
      description: '์ตœ๋Œ€ ๊ธ€์ž ์ˆ˜ ์ง€์ •',
    },
    radius: {
      control: { type: 'inline-radio' },
      options: ['none', 'sm', 'md', 'lg'],
    },
    variant: {
      control: { type: 'inline-radio' },
      options: ['default', 'surface'],
    },
  },
} satisfies Meta<typeof TextArea>;

export default meta;

type Story = StoryObj<typeof TextArea>;

/**
 * - Enter: ์ž…๋ ฅ ์™„๋ฃŒ(onSubmit ํ˜ธ์ถœ)
 * - Shift+Enter: ์ค„๋ฐ”๊ฟˆ
 */
function InteractiveTextArea(props: TextAreaProps) {
  const [text, setText] = useState('');

  return (
    <TextArea
      {...props}
      value={text}
      onChange={e => setText(e.target.value)}
      onSubmit={props.onSubmit ?? action('submit')}
    />
  );
}

export const Default: Story = {
  render: args => <InteractiveTextArea {...args} />,
  args: {
    placeholder: '๋ฌด์—‡์ด๋“  ๋ฌผ์–ด๋ณด์„ธ์š”',
    width: 'md',
    height: 'md',
    maxLength: 200,
  },
};

 

 

pnpm ๋ฒ„์ „

// TextArea.stories.tsx
import { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import React, { useState } from 'react';

import TextArea, { TextAreaProps } from './TextArea';

const meta = {
  title: 'Components/TextArea',
  component: TextArea,
  tags: ['autodocs'],
  parameters: {
    actions: { argTypesRegex: '^on.*' },
  },
  argTypes: {
    placeholder: { control: 'text' },
    width: {
      control: { type: 'radio' },
      options: ['sm', 'md', 'lg'],
    },
    height: {
      control: { type: 'radio' },
      options: ['sm', 'md', 'lg'],
    },
    maxLength: {
      control: 'number',
      description: '์ตœ๋Œ€ ๊ธ€์ž ์ˆ˜ ์ง€์ •',
    },
    radius: {
      control: { type: 'inline-radio' },
      options: ['none', 'sm', 'md', 'lg'],
    },
    variant: {
      control: { type: 'inline-radio' },
      options: ['default', 'surface'],
    },
  },
} satisfies Meta<typeof TextArea>;

export default meta;
type Story = StoryObj<typeof TextArea>;

function InteractiveTextArea(props: TextAreaProps) {
  const [text, setText] = useState('');

  return (
    <TextArea
      {...props}
      value={text}
      onChange={e => setText(e.target.value)}
      onSubmit={props.onSubmit ?? fn()} // fn() ์‚ฌ์šฉ
    />
  );
}

export const Default: Story = {
  render: args => <InteractiveTextArea {...args} />,
  args: {
    placeholder: '๋ฌด์—‡์ด๋“  ๋ฌผ์–ด๋ณด์„ธ์š”',
    width: 'md',
    height: 'md',
    maxLength: 200,
  },
};
๋ฐ˜์‘ํ˜•