๋ฐ˜์‘ํ˜•

HTMLAttributes


checkbox ํƒ€์ž…์˜ <input>์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Toggle ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. <input>์—˜๋ฆฌ๋จผํŠธ๋Š” autoFocus, required, readOnly ๋“ฑ์˜ ๊ธฐ๋ณธ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ๊ฐ€์ง„๋‹ค.

 

๋งŒ์•ฝ <input>์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ Toggle ์ปดํฌ๋„ŒํŠธ์˜ props๋กœ ๋„˜๊ธฐ๊ณ  ์‹ถ๋‹ค๋ฉด? ๋ชจ๋“  ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•ด์•ผ ํ• ๊นŒ?

 

์ด๋• InputHTMLAttributes ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿผ ๊ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์˜ prop ํƒ€์ž…์„ ์ผ์ผ์ด ์ •์˜ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ์ œ๋„ค๋ฆญ T๋Š” onChange ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ์—˜๋ฆฌ๋จผํŠธ ํƒ€์ž…์ด ๋“ค์–ด๊ฐ€๋ฏ€๋กœ HTMLInputElement ๊ฐ™์€ ํƒ€์ž…์„ ๋„˜๊ธฐ๋ฉด ๋œ๋‹ค.

// InputHTMLAttributes ๊ตฌ์กฐ | node_modules/@types/react/index.d.ts
interface InputHTMLAttributes<T> extends HTMLAttributes<T> {
  accept?: string | undefined;
  alt?: string | undefined;
  autoComplete?: string | undefined;
  // ...
  onChange?: ChangeEventHandler<T> | undefined;
}

type ChangeEventHandler<T = Element> = EventHandler<ChangeEvent<T>>;

 

๐Ÿ’ก InputHTMLAttributes, InputAttributes ๋“ฑ์€ @types/react ํŒจํ‚ค์ง€์—์„œ ์ œ๊ณตํ•˜๋Š” ํƒ€์ž…์ด๋‹ค

 

์ฐธ๊ณ ๋กœ id, className, draggable ๊ฐ™์€ HTML ์š”์†Œ์˜ ๊ณตํ†ต์ ์ธ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋Š” HTMLAttributes ํƒ€์ž…์—์„œ ์ƒ์† ๋ฐ›์•„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. DOMAttributes์˜ ์ œ๋„ค๋ฆญ T๋Š” ์œ„์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—˜๋ฆฌ๋จผํŠธ ํƒ€์ž…์„ ๋ฐ›๋Š”๋‹ค.

// HTMLAttributes ๊ตฌ์กฐ | node_modules/@types/react/index.d.ts
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
  // React-specific Attributes
  defaultChecked?: boolean | undefined;
  defaultValue?: string | number | ReadonlyArray<string> | undefined;
  // ...

  // Standard HTML Attributes
  accessKey?: string | undefined;
  className?: string | undefined;
  // ...
}

interface DOMAttributes<T> {
  // ...
  onCopy?: ClipboardEventHandler<T> | undefined;
  // ...
}

 

ํ™œ์šฉ ์˜ˆ์ œ โšก๏ธ


<input>์—˜๋ฆฌ๋จผํŠธ์˜ ๊ธฐ๋ณธ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋Š” InputHTMLAttributes<HTMLInputElement> ํƒ€์ž…์„ ํ†ตํ•ด ์ƒ์†๋ฐ›๊ณ , label color ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ ์ˆ˜์ค€์—์„œ ํ•„์š”ํ•œ prop๋งŒ ToggleProps ์ธํ„ฐํŽ˜์ด์Šค์— ์ถ”๊ฐ€ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

 

ํ•œํŽธ size ์†์„ฑ์€ <input>์˜ ๊ธฐ๋ณธ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ(number | undefined)์ง€๋งŒ ํ”„๋กœ์ ํŠธ์—์„œ ์š”๊ตฌํ•˜๋Š” ์‚ฌ์ด์ฆˆ ํƒ€์ž… TSize์— ๋งž์ถฐ์•ผํ•˜๋Š” ์ƒํ™ฉ์ด๋‹ค. ๋”ฐ๋ผ์„œ Omit ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์œผ๋กœ InputHTMLAttributes์˜ size ์†์„ฑ์„ ์ œ์™ธํ•˜๊ณ  ToggleProps ์ธํ„ฐํŽ˜์ด์Šค์— TSize ํƒ€์ž…์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

// Toggle.tsx
import React, { InputHTMLAttributes } from "react";

// TColor : primary | error | background | ...
// TSize : base | lg | md | ...

interface ToggleProps
  extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
  className?: string;
  label?: string;
  color?: TColor;
  size?: TSize; // size๋Š” <input>์˜ ๊ธฐ๋ณธ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์ง€๋งŒ ํ”„๋กœ์ ํŠธ์—์„œ ์š”๊ตฌํ•˜๋Š” ํƒ€์ž…์œผ๋กœ ๋Œ€์ฒด
}

export default function Toggle({
  className,
  label,
  color,
  size,
  ...inputProps
}: ToggleProps) {
  // ... ์ปดํฌ๋„ŒํŠธ ๋ณธ๋ฌธ ๋ฐ return๋ฌธ ์ƒ์„ธ ์ƒ๋žต
  return <input type="checkbox" {...inputProps} />;
}

 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•