Skip to content

Commit 6c7ed73

Browse files
authored
FilterComboBoxに適用・キャンセルボタンを追加して即時反映されないようにする (#1744)
1 parent 88b102a commit 6c7ed73

File tree

8 files changed

+66
-20
lines changed

8 files changed

+66
-20
lines changed

.changeset/filter-combobox-update.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"ingred-ui": patch
3+
---
4+
5+
FilterComboBoxコンポーネントの改善:
6+
- 複数選択時の一時保存機能を追加
7+
- 適用・キャンセルボタンを追加
8+
- UI/UXの改善(区切り線の追加、タグ削除機能の修正)

src/components/FilterComboBox/FilterComboBox.tsx

+46-10
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import {
1717
ContextMenu2Container,
1818
ContextMenu2TextInputItem,
1919
ContextMenu2CheckItem,
20+
ContextMenu2ButtonControlsItem,
21+
ContextMenu2SeparatorItem,
2022
} from "../ContextMenu2";
23+
import Button from "../Button";
2124
import Icon from "../Icon";
2225
import * as styled from "./styled";
2326

@@ -29,6 +32,7 @@ type FilterTagInputProps = {
2932
onChange: (values: string[]) => void;
3033
onSelectChange: (index: number) => void;
3134
};
35+
3236
export const FilterComboBox = ({
3337
values,
3438
options,
@@ -40,10 +44,13 @@ export const FilterComboBox = ({
4044
const [userValue, setUserValue] = useState("");
4145
const [userEnteredValue, setUserEnteredValue] = useState("");
4246
const [isComposing, setIsComposing] = useState(false);
47+
const [tempValues, setTempValues] = useState<string[]>(values);
48+
const [isOpen, setIsOpen] = useState(false);
4349

4450
// タグリスト部分で、CSS の overflow が発生しているか否か
4551
const [isInlineOverflowing, setIsInlineOverflowing] = useState(false);
4652
const inlineFieldEl = useRef<HTMLDivElement>(null);
53+
4754
// inlineFieldEl の大きさを監視して、
4855
// overflow したら isInlineOverflowing を true にする
4956
const checkInlineOverflow = useCallback(() => {
@@ -79,13 +86,13 @@ export const FilterComboBox = ({
7986

8087
const handleSelect = useCallback(
8188
(value: string) => {
82-
if (values.includes(value)) {
83-
onChange(values.filter((v) => v !== value));
89+
if (tempValues.includes(value)) {
90+
setTempValues(tempValues.filter((v) => v !== value));
8491
} else {
85-
onChange([...values, value]);
92+
setTempValues([...tempValues, value]);
8693
}
8794
},
88-
[values, onChange],
95+
[tempValues],
8996
);
9097

9198
const handleEnter = useCallback(() => {
@@ -125,15 +132,33 @@ export const FilterComboBox = ({
125132

126133
const handleRemove = useCallback(
127134
(value: string) => {
128-
onChange(values.filter((v) => v !== value));
135+
const newValues = values.filter((v) => v !== value);
136+
onChange(newValues);
129137
},
130138
[values, onChange],
131139
);
132140

133-
const handleOpenChange = useCallback(() => {
134-
setUserValue("");
135-
setUserEnteredValue("");
136-
}, [setUserValue, setUserEnteredValue]);
141+
const handleOpenChange = useCallback(
142+
(open: boolean) => {
143+
setIsOpen(open);
144+
if (open) {
145+
setTempValues(values);
146+
}
147+
setUserValue("");
148+
setUserEnteredValue("");
149+
},
150+
[values],
151+
);
152+
153+
const handleApply = useCallback(() => {
154+
onChange(tempValues);
155+
setIsOpen(false);
156+
}, [onChange, tempValues]);
157+
158+
const handleCancel = useCallback(() => {
159+
setTempValues(values);
160+
setIsOpen(false);
161+
}, [values]);
137162

138163
useEffect(() => {
139164
if (!window.ResizeObserver) return;
@@ -160,6 +185,7 @@ export const FilterComboBox = ({
160185
<styled.SelectContainer data-overflowing={isInlineOverflowing}>
161186
<ContextMenu2Container>
162187
<ContextMenu2
188+
open={isOpen}
163189
trigger={
164190
<styled.Select type="button">
165191
<styled.SelectIcon>
@@ -181,12 +207,22 @@ export const FilterComboBox = ({
181207
{filteredOptions.map((option) => (
182208
<ContextMenu2CheckItem
183209
key={option[0]}
184-
checked={values.includes(option[0])}
210+
checked={tempValues.includes(option[0])}
211+
closeOnChange={false}
185212
onChange={() => handleSelect(option[0])}
186213
>
187214
{option[0]}
188215
</ContextMenu2CheckItem>
189216
))}
217+
<ContextMenu2SeparatorItem />
218+
<ContextMenu2ButtonControlsItem>
219+
<Button size="small" color="clear" onClick={handleCancel}>
220+
キャンセル
221+
</Button>
222+
<Button size="small" onClick={handleApply}>
223+
適用
224+
</Button>
225+
</ContextMenu2ButtonControlsItem>
190226
</ContextMenu2>
191227
</ContextMenu2Container>
192228
<styled.TagList ref={inlineFieldEl}>

src/components/FilterComboBox/__tests__/__snapshots__/FilterComboBox.test.tsx.snap

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ exports[`FileUploader component testing FileUploader 1`] = `
1010
aria-expanded="false"
1111
aria-haspopup="dialog"
1212
aria-label="フィルターのタイプを選ぶ"
13-
class="sc-fLlhyt gvvYNu"
13+
class="sc-fLlhyt jqpZx"
1414
type="button"
1515
>
1616
<span
@@ -42,17 +42,17 @@ exports[`FileUploader component testing FileUploader 1`] = `
4242
</span>
4343
</button>
4444
<div
45-
class="sc-bBrHrO hCrcOQ"
45+
class="sc-iIPllB bxLXfc"
4646
data-overflowing="false"
4747
>
4848
<button
4949
aria-expanded="false"
5050
aria-haspopup="dialog"
51-
class="sc-cxabCf mpIUd"
51+
class="sc-ezWOiH lpjcvk"
5252
type="button"
5353
>
5454
<span
55-
class="sc-llJcti kPwAVH"
55+
class="sc-bZkfAO fZvvlw"
5656
>
5757
<span
5858
class="sc-bczRLJ gJuzRf"
@@ -70,7 +70,7 @@ exports[`FileUploader component testing FileUploader 1`] = `
7070
</span>
7171
</button>
7272
<div
73-
class="sc-ivTmOn fQPpsz"
73+
class="sc-gicCDI dQLHWf"
7474
>
7575
<span
7676
class="sc-hHLeRK igsLAy"

src/components/FilterComboBox/styled.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const SelectContainer = styled.div`
99
width: calc(100% + 46px);
1010
height: 100%;
1111
margin-left: -46px;
12+
background-color: ${colors.basic[100]};
1213
1314
&::before {
1415
content: "";
@@ -64,7 +65,7 @@ export const Select = styled.button`
6465
height: 100%;
6566
padding: 0 8px 0 54px;
6667
border: 0;
67-
background: transparent;
68+
background-color: ${colors.basic[100]};
6869
outline-offset: -1px;
6970
color: ${colors.basic[900]};
7071
cursor: pointer;
@@ -74,6 +75,7 @@ export const Select = styled.button`
7475
// z-index: 1;
7576
// }
7677
`;
78+
7779
export const SelectIcon = styled.span`
7880
flex-shrink: 0;
7981
width: 18px;

src/components/FilterInputAbstract/__tests__/__snapshots__/FilterInputAbstract.test.tsx.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ exports[`FileUploader component testing FileUploader 1`] = `
1010
aria-expanded="false"
1111
aria-haspopup="dialog"
1212
aria-label="フィルターのタイプを選ぶ"
13-
class="sc-fLlhyt gvvYNu"
13+
class="sc-fLlhyt jqpZx"
1414
type="button"
1515
>
1616
<span

src/components/FilterInputAbstract/styled.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const DropDownTrigger = styled.button`
6969
border-right: 1px solid ${colors.basic[400]};
7070
outline-offset: -1px;
7171
color: #000;
72-
background: transparent;
72+
background: #fff;
7373
cursor: pointer;
7474
7575
&:where(${FilterInputAbstract.toString()}[data-small="true"] *) {

src/components/FilterSelectInput/__tests__/__snapshots__/FilterSelectInput.test.tsx.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ exports[`FileUploader component testing FileUploader 1`] = `
1010
aria-expanded="false"
1111
aria-haspopup="dialog"
1212
aria-label="フィルターのタイプを選ぶ"
13-
class="sc-fLlhyt gvvYNu"
13+
class="sc-fLlhyt jqpZx"
1414
type="button"
1515
>
1616
<span

src/components/FilterTagInput/__tests__/__snapshots__/FilterTagInput.test.tsx.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ exports[`FileUploader component testing FileUploader 1`] = `
1010
aria-expanded="false"
1111
aria-haspopup="dialog"
1212
aria-label="フィルターのタイプを選ぶ"
13-
class="sc-fLlhyt gvvYNu"
13+
class="sc-fLlhyt jqpZx"
1414
type="button"
1515
>
1616
<span

0 commit comments

Comments
 (0)