Skip to content

Commit acacbdd

Browse files
committed
adding draggable select example (mostly done by https://github.com/pwhipp)
1 parent 29499d4 commit acacbdd

File tree

4 files changed

+157
-1
lines changed

4 files changed

+157
-1
lines changed

examples/src/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import GithubUsers from './components/GithubUsers';
1111
import CustomComponents from './components/CustomComponents';
1212
import CustomRender from './components/CustomRender';
1313
import Multiselect from './components/Multiselect';
14+
import MultiselectSortable from './components/MultiselectSortable';
1415
import NumericSelect from './components/NumericSelect';
1516
import BooleanSelect from './components/BooleanSelect';
1617
import Virtualized from './components/Virtualized';
@@ -20,6 +21,7 @@ ReactDOM.render(
2021
<div>
2122
<States label="States" searchable />
2223
<Multiselect label="Multiselect" />
24+
<MultiselectSortable label="Multiselect (Sortable react-sortable-hoc)" />
2325
<Virtualized label="Virtualized" />
2426
<Contributors label="Contributors (Async)" />
2527
<GithubUsers label="GitHub users (Async with fetch.js)" />
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
import Select, { Value } from 'react-select';
3+
import { SortableContainer, SortableElement, SortableHandle, arrayMove } from 'react-sortable-hoc';
4+
5+
const FLAVOURS = [
6+
{ label: 'Chocolate', value: 'chocolate' },
7+
{ label: 'Vanilla', value: 'vanilla' },
8+
{ label: 'Strawberry', value: 'strawberry' },
9+
{ label: 'Caramel', value: 'caramel' },
10+
{ label: 'Cookies and Cream', value: 'cookiescream' },
11+
{ label: 'Peppermint', value: 'peppermint' },
12+
];
13+
14+
const SortableLabel = SortableHandle(({ label }) => <span>{label}</span>);
15+
const SortableValue = SortableElement(Value);
16+
const SortableSelect = SortableContainer(Select);
17+
18+
class MultiSelectSortableField extends React.Component{
19+
constructor(){
20+
super();
21+
this.state = {
22+
value: ['chocolate', 'vanilla', 'caramel']
23+
};
24+
}
25+
handleSelectChange(value){
26+
this.setState({ value });
27+
}
28+
onSortEnd({ oldIndex, newIndex }) {
29+
this.setState({
30+
value: arrayMove(this.state.value, oldIndex, newIndex),
31+
});
32+
}
33+
render(){
34+
const { value } = this.state;
35+
return (
36+
<div className="section">
37+
<h3 className="section-heading">{this.props.label}</h3>
38+
<SortableSelect
39+
multi
40+
onChange={(value) => this.handleSelectChange(value)}
41+
options={FLAVOURS}
42+
placeholder="Select your favourite(s)"
43+
value={value}
44+
valueRenderer={(option) => <SortableLabel label={option.label} />}
45+
valueComponent={SortableValue}
46+
axis="xy"
47+
helperClass="draggable-dragging"
48+
onSortEnd={(sortState) => this.onSortEnd(sortState)}
49+
useDragHandle={true}
50+
/>
51+
</div>
52+
);
53+
}
54+
}
55+
MultiSelectSortableField.displayName = 'MultiSelectSortableField';
56+
57+
module.exports = MultiSelectSortableField;

examples/src/example.less

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,94 @@ h6, .h6 {
254254
.virtual-scroll {
255255
z-index: 1;
256256
}
257+
258+
259+
// Draggable item
260+
// ------------------------------
261+
262+
// Replicate styles for the dragging state
263+
// @TODO need a better way to copy over style
264+
265+
@select-item-border-radius: 2px;
266+
@select-item-gutter: 5px;
267+
@select-item-padding-vertical: 2px;
268+
@select-item-padding-horizontal: 5px;
269+
@select-item-font-size: .9em;
270+
@select-item-color: #08c; // pale blue
271+
@select-item-bg: #f2f9fc;
272+
@select-item-border-color: darken(@select-item-bg, 10%);
273+
@select-item-hover-color: darken(@select-item-color, 5%); // pale blue
274+
@select-item-hover-bg: darken(@select-item-bg, 5%);
275+
@select-item-disabled-color: #333;
276+
@select-item-disabled-bg: #fcfcfc;
277+
@select-item-disabled-border-color: darken(@select-item-disabled-bg, 10%);
278+
279+
280+
.Select-value {
281+
&.draggable-dragging {
282+
background-color: @select-item-bg;
283+
border-radius: @select-item-border-radius;
284+
border: 1px solid @select-item-border-color;
285+
color: @select-item-color;
286+
display: inline-block;
287+
font-size: @select-item-font-size;
288+
line-height: 1.4;
289+
margin-left: @select-item-gutter;
290+
margin-top: @select-item-gutter;
291+
vertical-align: top;
292+
293+
// common
294+
.Select-value-icon,
295+
.Select-value-label {
296+
display: inline-block;
297+
vertical-align: middle;
298+
box-sizing: border-box;
299+
float: left;
300+
}
301+
302+
// label
303+
.Select-value-label {
304+
border-bottom-right-radius: @select-item-border-radius;
305+
border-top-right-radius: @select-item-border-radius;
306+
cursor: default;
307+
padding: @select-item-padding-vertical 0 @select-item-padding-vertical @select-item-padding-horizontal;
308+
}
309+
310+
// icon
311+
.Select-value-icon {
312+
cursor: pointer;
313+
border-bottom-left-radius: @select-item-border-radius;
314+
border-top-left-radius: @select-item-border-radius;
315+
border-right: 1px solid @select-item-border-color;
316+
317+
// move the baseline up by 1px
318+
padding: (@select-item-padding-vertical - 1) @select-item-padding-horizontal (@select-item-padding-vertical + 1);
319+
320+
&:hover,
321+
&:focus {
322+
background-color: @select-item-hover-bg;
323+
color: @select-item-hover-color;
324+
}
325+
&:active {
326+
background-color: @select-item-border-color;
327+
}
328+
}
329+
}
330+
}
331+
332+
.draggable-dragging {
333+
box-shadow: 0 2px 6px 0 rgba(0,0,0,.1);
334+
background-color: rgba(255, 255, 255, 0.8);
335+
cursor: row-resize;
336+
z-index: 10;
337+
border-radius: 5px;
338+
339+
* {
340+
-webkit-touch-callout: none;
341+
user-select: none;
342+
}
343+
344+
label, p {
345+
text-align: left;
346+
}
347+
}

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"react-dom": "^15.5.0",
5757
"react-gravatar": "^2.4.5",
5858
"react-highlight-words": "^0.8.1",
59+
"react-sortable-hoc": "^0.6.8",
5960
"react-test-renderer": "^15.6.1",
6061
"react-virtualized": "^9.9.0",
6162
"react-virtualized-select": "^3.1.0",
@@ -88,7 +89,12 @@
8889
"test": "cross-env NODE_ENV=test mocha --compilers js:babel-core/register",
8990
"precommit": "lint-staged && yarn run test"
9091
},
91-
"files": ["dist", "less", "lib", "scss"],
92+
"files": [
93+
"dist",
94+
"less",
95+
"lib",
96+
"scss"
97+
],
9298
"keywords": [
9399
"combobox",
94100
"form",

0 commit comments

Comments
 (0)