Skip to content

Commit d2b7f72

Browse files
authored
Merge pull request #15 from RedMadRobot/multiselect
Multiselect
2 parents e2e586f + 1ceb1c1 commit d2b7f72

File tree

6 files changed

+90
-25
lines changed

6 files changed

+90
-25
lines changed

example/MultiSelect/MultiSelect.css

+47-5
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,38 @@
99
}
1010

1111
.wrapper {
12+
position: relative;
1213
border: 1px solid #ccc;
1314
border-radius: 15px;
1415
min-width: 400px;
1516
max-width: 700px;
1617
padding: 2px 5px;
18+
padding-right: 50px;
1719
display: flex;
1820
flex-wrap: wrap;
1921
background-color: #fff;
2022
}
2123

24+
.wrapper::before {
25+
content: '';
26+
position: absolute;
27+
top: 50%;
28+
right: 10px;
29+
transform: translate(0, -50%) rotate(0deg);
30+
display: block;
31+
width: 16px;
32+
height: 16px;
33+
background-image: url('./img/chevron-down.svg');
34+
background-size: cover;
35+
background-position: center;
36+
background-repeat: no-repeat;
37+
transition: 0.3s ease-in-out;
38+
}
39+
40+
.wrapper-open::before {
41+
transform: translate(0, -50%) rotate(180deg);
42+
}
43+
2244
.input {
2345
width: 100px;
2446
flex-grow: 1;
@@ -43,21 +65,21 @@
4365
}
4466

4567
.item.selected::after {
46-
content: "";
68+
content: '';
4769
position: absolute;
4870
top: 5px;
4971
right: 5px;
5072
width: 10px;
5173
height: 10px;
52-
background-image: url("./check.svg");
74+
background-image: url('./img/check.svg');
5375
background-repeat: no-repeat;
5476
}
5577

5678
.multivalue {
5779
display: flex;
5880
justify-content: space-between;
5981
margin: 2px;
60-
padding: 5px 10px;
82+
padding: 2px 10px;
6183
padding-right: 5px;
6284
border: 1px solid #413d51;
6385
border-radius: 15px;
@@ -72,13 +94,33 @@
7294
border: none;
7395
border-radius: 50%;
7496
background-color: transparent;
75-
background-image: url("./close.svg");
97+
background-image: url('./img/close.svg');
7698
background-size: 10px 10px;
77-
background-position: center center;
99+
background-position: center;
78100
background-repeat: no-repeat;
79101
}
80102

81103
.remove:hover {
82104
outline: 1px solid #413d51;
83105
cursor: pointer;
84106
}
107+
108+
.reset {
109+
position: absolute;
110+
top: 50%;
111+
right: 30px;
112+
width: 16px;
113+
height: 16px;
114+
border: none;
115+
cursor: pointer;
116+
background-image: url('./img/x-circle.svg');
117+
background-position: center center;
118+
background-repeat: no-repeat;
119+
background-color: transparent;
120+
transform: translate(0, -50%);
121+
}
122+
123+
.reset:hover,
124+
.reset:focus {
125+
opacity: 0.5;
126+
}

example/MultiSelect/MultiSelect.tsx

+37-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import classNames from 'classnames';
22
import React, { ChangeEvent, KeyboardEvent, useMemo, useState } from 'react';
3+
import { createPortal } from 'react-dom';
34
import { DropdownState, ReducerAction, StateChangeType, useDropdown } from '../../src';
45
import './MultiSelect.css';
56

@@ -103,6 +104,11 @@ export const Dropdown: React.FC<Props> = ({ onSelect, values }) => {
103104
}
104105
};
105106

107+
const handleResetClick = (event) => {
108+
event.stopPropagation();
109+
onSelect([]);
110+
};
111+
106112
const handleRemoveClick = (item: Item) => (event) => {
107113
event.stopPropagation();
108114
const newArr = values.filter((el) => el.value !== item.value);
@@ -120,7 +126,7 @@ export const Dropdown: React.FC<Props> = ({ onSelect, values }) => {
120126

121127
return (
122128
<div
123-
className="wrapper"
129+
className={classNames('wrapper', { 'wrapper-open': isOpen })}
124130
{...getWrapperProps()}
125131
onKeyDown={handleKeyDown}
126132
onFocus={handleFocus}
@@ -154,26 +160,37 @@ export const Dropdown: React.FC<Props> = ({ onSelect, values }) => {
154160
autoComplete="off"
155161
/>
156162

157-
{isOpen && (
158-
<ul className="menu" {...(getMenuProps() as any)}>
159-
{options.length === 0 ? (
160-
<li>No data</li>
161-
) : (
162-
options.map((item: Item, index) => (
163-
<li
164-
key={item.value}
165-
className={classNames('item', {
166-
active: highlightedIndex === index,
167-
selected: values.some((el) => el.value === item.value),
168-
})}
169-
{...getItemProps(item, index)}
170-
>
171-
{item.name}
172-
</li>
173-
))
174-
)}
175-
</ul>
163+
{values.length === 0 ? null : (
164+
<button
165+
className="reset"
166+
onClick={handleResetClick}
167+
type="button"
168+
aria-label="Clear all values"
169+
></button>
176170
)}
171+
172+
{isOpen &&
173+
createPortal(
174+
<ul className="menu" {...(getMenuProps() as any)}>
175+
{options.length === 0 ? (
176+
<li>No data</li>
177+
) : (
178+
options.map((item: Item, index) => (
179+
<li
180+
key={item.value}
181+
className={classNames('item', {
182+
active: highlightedIndex === index,
183+
selected: values.some((el) => el.value === item.value),
184+
})}
185+
{...getItemProps(item, index)}
186+
>
187+
{item.name}
188+
</li>
189+
))
190+
)}
191+
</ul>,
192+
document.body
193+
)}
177194
</div>
178195
);
179196
};
File renamed without changes.
+3
Loading
File renamed without changes.

example/MultiSelect/img/x-circle.svg

+3
Loading

0 commit comments

Comments
 (0)