🐾
React TypeScript chakra-react-select でNotionのMulti-selectみたいなUIを作成する
作りたいもの
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
参考
Discussion