Closed fe-Jay closed 1 week ago
/**
*
* @param {Object} props - 컴포넌트
* @param {string} props.label - 라벨
* @param {function} props.onClick - 온 클릭 이벤트
* @param {boolean} [props.primary] - 필수 값
* @param {string} [props.className] - html 클래스 네임
*/
const Button: React.FC<{
label: string;
onClick: () => void;
primary?: boolean;
className?: string;
}> = ({ label, onClick, primary = false, className = '' }) => {
return (
<button
className={`btn ${primary ? 'btn-primary' : 'btn-secondary'} ${className}`}
onClick={onClick}
>
{label}
</button>
);
};
interface ButtonProps {
label: string;
onClick: () => void;
disabled?: boolean;
variant?: 'primary' | 'secondary' | 'danger';
size?: 'small' | 'medium' | 'large';
}
/**
* 기본 버튼 컴포넌트
*
* @component
* @example
* ```tsx
* <Button
* label="제출하기"
* onClick={() => console.log('clicked')}
* variant="primary"
* size="medium"
* />
* ```
*
* @param {Object} props - 버튼 컴포넌트 속성
* @param {string} props.label - 버튼에 표시될 텍스트
* @param {Function} props.onClick - 클릭 이벤트 핸들러
* @param {boolean} [props.disabled] - 버튼 비활성화 여부
* @param {('primary'|'secondary'|'danger')} [props.variant='primary'] - 버튼 스타일 변형
* @param {('small'|'medium'|'large')} [props.size='medium'] - 버튼 크기
*
* @returns {JSX.Element} 버튼 컴포넌트
*/
const Button: React.FC<ButtonProps> = ({
label,
onClick,
disabled = false,
variant = 'primary',
size = 'medium'
}) => {
return (
<button
onClick={onClick}
disabled={disabled}
className={`btn btn-${variant} btn-${size}`}
>
{label}
</button>
);
};
Google Material-UI 스타일
/**
* Modal component that follows Material Design guidelines.
*
* @see https://material.io/components/dialogs - 공식 문서 링크 제공
* @fires {Event} onOpen - 이벤트 발생 명시
* @fires {Event} onClose
* @example
* ```jsx
* <Modal
* open={isOpen}
* onClose={handleClose}
* aria-labelledby="modal-title"
* >
* <ModalContent>
* <Typography id="modal-title">Modal Title</Typography>
* </ModalContent>
* </Modal>
* ```
*/
interface ModalProps {
open: boolean;
onClose: () => void;
'aria-labelledby': string; // 접근성 고려
}
//
const Modal: React.FC<ModalProps> = ({ open, onClose, children }) => {};
Airbnb 스타일:
/**
* A composable rating component.
*
* @accessibility - 접근성 관련 정보
* Uses role="img" with aria-label for screen readers.
* Keyboard navigation supported for interactive ratings.
*
* @performance - 성능 관련 정보
* Component is memoized to prevent unnecessary re-renders.
* SVG icons are loaded using dynamic imports.
*/
interface RatingProps {
value: number;
onChange?: (value: number) => void;
maxRating?: number;
}
const Rating = React.memo(({ value, onChange, maxRating = 5 }: RatingProps) => {
return (
<div role="img" aria-label={`Rating: ${value} of ${maxRating}`} />
);
});
ESLint 규칙 추천
{
"rules": {
"jsdoc/require-jsdoc": "error", // 모든 함수와 클래스에 JSDoc 주석 필수
"jsdoc/require-param": "error", // 모든 매개변수에 대한 @param 설명 필수
"jsdoc/require-returns": "error", // 반환값에 대한 @returns 설명 필수
"jsdoc/require-example": "error" // 사용 예시 @example 필수
}
}
템플릿 스니펫
{
"React Component JSDoc": {
"prefix": "jsdoc-react",
"body": [
"/**",
" * ${1:컴포넌트 설명}",
" * ",
" * @component",
" * @example",
" * ```tsx",
" * <${2:ComponentName} />",
" * ```",
" * ",
" * @param {Object} props - 컴포넌트 props",
" * @returns {JSX.Element}",
" */"
]
}
}
// 설치
npm install -g jsdoc
jsdoc -c jsdoc.json
// jsdoc.json
{
"source": {
"include": ["src"],
"includePattern": ".+\\.jsx?$"
},
"plugins": ["plugins/markdown"],
"opts": {
"recurse": true,
"destination": "docs"
},
"templates": {
"cleverLinks": false,
"monospaceLinks": false
}
}
import React from 'react';
import "./Button.css"
/**
* 버튼 컴포넌트
*
* @component
* @param {Object} props - text와 onClick을 props로 받습니다
* @param {string} props.text - 버튼에 표시될 텍스트
* @param {function} props.onClick - 클릭 이벤트 핸들러
* @returns {JSX.Element} 렌더링된 버튼 컴포넌트
*
* @example
* // "Click Me" 텍스트를 가진 버튼 렌더링
* <Button text="Click Me" onClick={() => console.log('Button clicked!')} />
*/
function Button({ text, onClick }) {
return (
<button className='myButton' onClick={onClick}>
{text}
</button>
);
}
export default Button;
📝 p 269
❓ 컴포넌트 속성 타입을 명시하기 위해 JSDocs를 사용할 수 있습니다. 원활한 협업을 위해 어떤식으로 JSDocs에 타입을 명시해볼 수 있을지, 예시를 작성해주세요.