🐾

React TypeScript chakra-react-select でNotionのMulti-selectみたいなUIを作成する

2022/12/31に公開約2,400字

作りたいもの

NotionのMulti-selectみたいなやつ

使用パッケージ

  • chakra-ui/react
  • chakra-react-select

コード

import { Box, Center } from '@chakra-ui/react';
import {
  ActionMeta,
  MultiValue,
  Select,
  GroupBase,
  OptionBase,
} from 'chakra-react-select';
import { useState } from 'react';

class CatBreed implements OptionBase {
  constructor(
    public value: string,
    public label: string,
    public colorScheme: string,
  ) {}
}

const MultiSelect = () => {
  const CatBreeds: CatBreed[] = [
    new CatBreed('bri', 'ブリティッシュショートヘア', 'gray'),
    new CatBreed('blue', 'ロシアンブルー', 'blue'),
    new CatBreed('sco', 'スコティッシュフォールド', 'yellow'),
    new CatBreed('chart', 'シャルトリュー', 'pink'),
    new CatBreed('ame', 'アメリカンショートヘア', 'green'),
    new CatBreed('abi', 'アビシニアン', 'red'),
    new CatBreed('somari', 'ソマリ', 'purple'),
    new CatBreed('rag', 'ラグドール', 'teal'),
    new CatBreed('munch', 'マンチカン', 'orange'),
  ];

  const [selectedCatBreeds, setSelectedCatBreeds] = useState<CatBreed[]>([]);

  const handleOnChangeSelectedCats = (
    _newValue: MultiValue<CatBreed>,
    actionMeta: ActionMeta<CatBreed>,
  ) => {
    switch (actionMeta.action) {
      case 'select-option':
        if (actionMeta.option) {
          const catBreed = actionMeta.option;
          setSelectedCatBreeds((prev) => [...prev, catBreed]);
          break;
        }
        break;

      case 'remove-value':
      case 'pop-value':
        if (actionMeta.removedValue) {
          const toDeleteCatBreed = actionMeta.removedValue;

          setSelectedCatBreeds((prev) =>
            prev.filter((catBreed) => catBreed.value != toDeleteCatBreed.value),
          );
          break;
        }
        break;

      case 'clear':
        setSelectedCatBreeds([]);
        break;
      default:
        break;
    }
  };

  return (
    <Center>
      <Box p={5} w='500px'>
        <Select<CatBreed, true, GroupBase<CatBreed>>
          isMulti
          name='multiSelectOptions'
          placeholder='複数選択'
          options={CatBreeds}
          value={selectedCatBreeds}
          onChange={handleOnChangeSelectedCats}
        />
      </Box>
    </Center>
  );
};

export default MultiSelect;

UI

参考

https://www.npmjs.com/package/chakra-react-select
https://chakra-ui.com/

Discussion

ログインするとコメントできます