[code-review] 2

kirin.logยท2021๋…„ 9์›” 9์ผ
0

๐Ÿ’ก react-color ์ ์šฉํ•˜์—ฌ "๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ปฌ๋Ÿฌํ‘œ๊ฐ€ ๋ณด์—ฌ์ง€๋Š” ๊ธฐ๋Šฅ" ๋งŒ๋“ค๊ธฐ
react-color

๐Ÿ”จ ์‚ฌ์šฉ library

  • react-color
  • antd

๐Ÿ”จ ์ ์šฉ ๊ณผ์ •

  • antd์˜ Dropdown์œผ๋กœ ๋ฒ„ํŠผ๊ณผ dropdown ์ƒ์„ฑ
  • dropdown list ์•ˆ์— react color(sketch) ๋„ฃ๊ธฐ

1) react-color ์„ค์น˜
(typescript ์ ์šฉ๋˜์–ด ์žˆ์Œ)

yarn add @types/react-color

2) importํ•ด์ฃผ๊ธฐ

import { SketchPicker, ColorResult } from 'react-color';
// SketchPicker ์™ธ ๋‹ค์–‘ํ•œ Color Pickers Collection์ด ์žˆ๋‹ค. (์„ ํƒ๊ฐ€๋Šฅ)
import { Menu, Dropdown } from 'antd';

3) UI ๊ตฌ์„ฑ

// antd "dropdown list" ๋ถ€๋ถ„
const menu = (
    <Menu>
      <Menu.Item>
        // react color ์ปดํฌ๋„ŒํŠธ ์‚ฝ์ž…(dropdown list์—์„œ SketchPicker ์ปฌ๋ŸฌํŒ ๋ณด์—ฌ์ง€๋„๋ก)
        <SketchPicker
          // react color component APIs 
          color={selectedColor}
          onChange={handleChangeSketchPicker}
        />
      </Menu.Item>
    </Menu>
  );


// dropdown ๊ธฐ๋Šฅ์ด ์ ์šฉ๋œ "color point UI" ๋ถ€๋ถ„
<Dropdown
    // dropdown component API
    overlay={menu}
    trigger={['click']}
    visible={isDropdownShow}
    onVisibleChange={(visible) => {
      setIsDropdownShow(visible);
      }
    }>
    <a className="ant-dropdown-link"
        onClick={(e) => {
          setIsDropdownShow(true);
          e.preventDefault();
        }
     }>
      // color point ๋ฅผ styled component๋กœ ๊ตฌ์„ฑ, ๋ฐฐ๊ฒฝ์ƒ‰๋งŒ inline์œผ๋กœ ์ ์šฉ
       <ColorPoint style={{ backgroundColor: selectedColor }}></ColorPoint>
    </a>
</Dropdown>

โ—๏ธ antd ์™€ react color ๊ฐ€ library์ธ ๋งŒํผ ๊ณต์‹ document ๋‚ด ๊ฐ ์ปดํฌ๋„ŒํŠธ API๋ฅผ ์ž˜ ์ฝ์–ด๋ณด๊ณ  ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค.
โ—๏ธ antd dropdown์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฒ„ํŠผ์„ ํด๋ฆญ(trigger={['click']} ์ ์šฉ)ํ•˜๋ฉด dropdown์ด ์—ด๋ฆฌ๊ณ , dropdown ๋‚ด list๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋‹ซํžˆ๋Š” ๊ตฌ์กฐ์ด๋‹ค.
ํ•˜์ง€๋งŒ colorPicker๋Š” ๊ณ„์† ํด๋ฆญํ•ด๋„ dropdown list๊ฐ€ ๋‹ซํžˆ์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
๋”ฐ๋ผ์„œ antd dropdown API ๋‚ด visible์„ ํ™œ์šฉํ•ด์„œ ํ•œ ๋ฒˆ ํด๋ฆญํ•ด์„œ list๋ฅผ ์—ด์€ ํ›„์—๋Š” ํด๋ฆญํ•ด๋„ ๋‹ซํžˆ์ง€ ์•Š๋„๋ก ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

react color ๊ณต์‹ Component API

  • color : ๊ธฐ๋ณธ ์ƒ‰์ƒ ์„ค์ •
  • onChange(color, event) : ์ƒ‰์ƒ์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌ
    (color, event ๋‘ ๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›๋Š”๋‹ค - ๋ณ€๊ฒฝ์ƒ‰ ์ ์šฉ / ๋ฐœ์ƒ ์ด๋ฒคํŠธ ์„ค์ • ๊ฐ€๋Šฅ)
  • onChangeComplete : ์ƒ‰์ƒ ๋ณ€๊ฒฝ์ด ์™„๋ฃŒ๋˜๋ฉด ํ˜ธ์ถœํ•  ํ•จ์ˆ˜ ์ „๋‹ฌ
// ๊ธฐ๋ณธ color state ์ง€์ •
const [selectedColor, setSelectedColor] = useState<string>('#ff9466');
  //console.log('๋ณ€๊ฒฝ๋œ ์ปฌ๋Ÿฌ : ', selectedColor). <- ์ปฌ๋Ÿฌํฌ์ธํŠธ ์ฐ์œผ๋ฉด ๋ณ€๊ฒฝ๋œ ์ƒ‰ ์ถœ๋ ฅ


// ์ƒ‰์ƒ์ด ๋ณ€๊ฒฝ๋  ๋•Œ ์ž‘๋™ํ•˜๋Š” ํ•จ์ˆ˜
const handleChangeSketchPicker = (selectedColor: ColorResult, event: React.ChangeEvent<HTMLInputElement>) => {
    event.stopPropagation();
    event.preventDefault();
    setSelectedColor(selectedColor.hex);  // ์ƒ‰์ƒ ๋ณ€๊ฒฝ ๊ฐ’์˜ hex ์ ์šฉ
  };


// ์ƒ‰์ƒ ๋ณ€๊ฒฝ ํ›„ ํ˜ธ์ถœ ๋ฐ ์ ์šฉํ•  ํ•จ์ˆ˜(onChange๋กœ ๋Œ€์ฒด ๊ฐ€๋Šฅํ•˜๋‹ค)
const handleChangeComplete = (color) => {
    setState( color.hex );  // hex ์™ธ์—๋„ rgb, hsl ๋“ฑ์˜ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  };

 return (
      <SketchPicker
        color={ selectedColor }
        onChange={handleChangeSketchPicker}
        onChangeComplete={ handleChangeComplete }
      />
    );

antd ๊ณต์‹ Component API

  • visible : (boolean) -> ํ˜„์žฌ dropdown list๊ฐ€ ๋ณด์ด๋Š”์ง€ ์•ˆ๋ณด์ด๋Š”์ง€ ์„ค์ •
  • onVisibleChange : (visible: boolean) => void -> visible state๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๋ถ€๋ฅด๋Š” ํ•จ์ˆ˜
// ๊ธฐ๋ณธ Visible state ์ง€์ •
const [isDropdownShow, setIsDropdownShow] = useState<boolean>(false);
// ๊ธฐ๋ณธ์ ์œผ๋กœ dropdown list๊ฐ€ ์•ˆ๋ณด์ด๋„๋ก(false) ์„ค์ •ํ•ด๋‘๊ณ  ์•„๋ž˜์— ์ ์šฉํ•œ๋‹ค

 <Dropdown
    overlay={menu}
    trigger={['click']}
    visible={isDropdownShow}  // console.log('๋น„์ง€๋ธ” : ', visible);  false
    onVisibleChange={(visible) => {  // true๋กœ ๋ฐ”๋€œ(์•„๋ž˜์—์„œ true๋กœ ๋ฐ”๊ฟ”์คฌ๊ธฐ ๋•Œ๋ฌธ) 
      setIsDropdownShow(visible);
      }
    }>
      // true๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— color ํŒ”๋ ˆํŠธ์— ๊ณ„์† ํด๋ฆญ์„ ํ•ด๋„ true์ƒํƒœ์ด๋‹ค(์•ˆ๋‹ซํž˜)
    <a className="ant-dropdown-link"
        onClick={(e) => {
          setIsDropdownShow(true);  // true๋กœ ๋ฐ”๊ฟˆ, Color point๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋ณด์ด๋„๋ก(true)
          e.preventDefault();
        }
     }>
      // color point ๋ฅผ styled component๋กœ ๊ตฌ์„ฑ, ๋ฐฐ๊ฒฝ์ƒ‰๋งŒ inline์œผ๋กœ ์ ์šฉ
       <ColorPoint style={{ backgroundColor: selectedColor }}></ColorPoint>
    </a>
</Dropdown>
profile
boma91@gmail.com

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2021๋…„ 9์›” 9์ผ

์ƒˆ๋ด„๋‹˜! ๊พธ์ค€ํžˆ ๊ณต๋ถ€ํ•˜๊ณ  velog ์“ฐ๋ฉด์„œ ์ง€๋‚ด๊ณ  ๊ณ„์…จ๊ตฐ์š”!ใ… ใ…  ๋„ˆ๋ฌด ๋ฐ˜๊ฐ‘๊ณ  ๊ฐ๋™... ์ž˜ ์ง€๋‚ด์‹œ์ฃ ?

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ