Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard sorting #501

Merged
merged 16 commits into from
Apr 22, 2019
58 changes: 33 additions & 25 deletions README.md

Large diffs are not rendered by default.

54 changes: 47 additions & 7 deletions src/.stories/Storybook.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@import url(https://fonts.googleapis.com/css?family=Montserrat:400);

$focusedOutlineColor: #4c9ffe;

.root {
display: flex;
height: 100%;
Expand All @@ -21,6 +23,17 @@
.item {
position: relative;
border-bottom: 1px solid #999;

cursor: grab;
touch-action: manipulation;

&.sorting {
pointer-events: none;
}
}

.containsDragHandle {
cursor: default;
}

// Stylized
Expand All @@ -32,6 +45,7 @@
border-radius: 3px;
outline: none;
}

.stylizedItem {
display: flex;
align-items: center;
Expand All @@ -41,9 +55,15 @@
border-bottom: 1px solid #efefef;
box-sizing: border-box;
user-select: none;
outline: none;

color: #333;
font-weight: 400;

&:focus:not(.containsDragHandle) {
text-indent: -2px;
border: 2px solid $focusedOutlineColor;
}
}

.disabled {
Expand All @@ -52,13 +72,24 @@
}

// Drag handle
.handleWrapper {
width: 18px;
height: 18px;
outline: none;
}

.handle {
display: block;
width: 18px;
height: 18px;
opacity: 0.25;
margin-right: 20px;
cursor: row-resize;
overflow: hidden;

> svg {
opacity: 0.3;
}

cursor: grab;
}

// Horizontal list
Expand Down Expand Up @@ -147,26 +178,35 @@
.helper {
box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.2),
0 -5px 5px -5px rgba(0, 0, 0, 0.2);

cursor: grabbing;
}

.stylizedHelper {
box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.2),
0 -5px 5px -5px rgba(0, 0, 0, 0.2);
background-color: rgba(255, 255, 255, 0.8);
cursor: row-resize;
border: 1px solid #efefef;
box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.2);
background-color: rgba(255, 255, 255, 0.9);
border-radius: 3px;

&.horizontalItem {
cursor: col-resize;
}

&.gridItem {
background-color: transparent;
white-space: nowrap;
box-shadow: none;
border: none;

.wrapper {
background-color: rgba(255, 255, 255, 0.8);
background-color: rgba(255, 255, 255, 0.9);
box-shadow: 0 0 7px rgba(0, 0, 0, 0.15);
}
}

&:focus {
box-shadow: 0 0px 5px 1px $focusedOutlineColor;
}
}

.shrinkedHelper {
Expand Down
18 changes: 17 additions & 1 deletion src/.stories/grouping-items/Item/Item.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ import {sortableElement} from '../../../../src';

import styles from './Item.scss';

const ENTER_KEY = 13;

function Item(props) {
const {dragging, onClick, selected, selectedItemsCount, value} = props;
const {
dragging,
sorting,
onClick,
selected,
selectedItemsCount,
value,
} = props;
const shouldRenderItemCountBadge = dragging && selectedItemsCount > 1;

return (
Expand All @@ -14,8 +23,15 @@ function Item(props) {
styles.Item,
selected && !dragging && styles.selected,
dragging && styles.dragging,
sorting && styles.sorting,
)}
onClick={() => onClick(value)}
onKeyPress={(event) => {
if (event.which === ENTER_KEY) {
onClick(value);
}
}}
tabIndex={0}
>
Item {value}
{shouldRenderItemCountBadge ? <Badge count={selectedItemsCount} /> : null}
Expand Down
39 changes: 28 additions & 11 deletions src/.stories/grouping-items/Item/Item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,62 @@ $borderWidth: 1px;
$borderColor: #efefef;

$selectedColor: $white;
$selectedBackgroundColor: #759fff;
$selectedBorderColor: #5e83d6;
$selectedBackgroundColor: rgba(216, 232, 251, 0.9);
$selectedBorderColor: #bbcee8;

$badgeColor: $white;
$badgeBackgroundColor: #f75959;
$badgeBorderColor: #da4553;

$focusedOutlineColor: #4c9ffe;

.Item {
display: flex;
align-items: center;
width: 100%;
padding: 20px;
height: 59px;
padding: 0 20px;
background-color: $backgroundColor;
border-top: $borderWidth solid #efefef;
border-bottom: $borderWidth solid #efefef;
box-sizing: border-box;
user-select: none;
outline: none;

color: $color;
font-weight: $fontWeight-regular;

&:first-child {
border-top: none;
cursor: grab;

&:last-child {
border-bottom: none;
}

&.selected {
background: $selectedBackgroundColor;
border: 1px solid $selectedBorderColor;
color: $selectedColor;
font-weight: $fontWeight-bold;
border-bottom-color: $selectedBorderColor;

& + .Item {
border-top: none;
&:focus {
border-bottom-color: $focusedOutlineColor;
}
}

&.sorting {
pointer-events: none;
}

&.dragging {
border-radius: $borderRadius;
border: $borderWidth solid #efefef;
box-shadow: $boxShadow;

&:focus {
box-shadow: 0 0px 5px 1px $focusedOutlineColor;
}
}

&:focus {
text-indent: -2px;
border: 2px solid $focusedOutlineColor;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/.stories/grouping-items/List/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Item from '../Item';

import styles from './List.scss';

function List({items, selectedItems, sortingItemKey, onItemSelect}) {
function List({items, isSorting, selectedItems, sortingItemKey, onItemSelect}) {
return (
<div className={styles.List}>
{items.map((value, index) => {
Expand All @@ -17,6 +17,7 @@ function List({items, selectedItems, sortingItemKey, onItemSelect}) {
key={`item-${value}`}
selected={isSelected}
dragging={itemIsBeingDragged}
sorting={isSorting}
index={index}
value={value}
onClick={onItemSelect}
Expand Down
10 changes: 9 additions & 1 deletion src/.stories/grouping-items/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ class GroupedItems extends React.Component {
};

render() {
const {items, selectedItems, sortingItemKey} = this.state;
const {items, isSorting, selectedItems, sortingItemKey} = this.state;

return (
<SortableList
items={items.filter(this.filterItems)}
isSorting={isSorting}
sortingItemKey={sortingItemKey}
selectedItems={selectedItems}
onItemSelect={this.handleItemSelect}
shouldCancelStart={this.handleShouldCancelStart}
updateBeforeSortStart={this.handleUpdateBeforeSortStart}
onSortStart={this.handleSortStart}
onSortEnd={this.handleSortEnd}
distance={3}
/>
Expand Down Expand Up @@ -56,6 +58,10 @@ class GroupedItems extends React.Component {
);
};

handleSortStart() {
document.body.style.cursor = 'grabbing';
}

handleSortEnd = ({oldIndex, newIndex}) => {
const {selectedItems} = this.state;
let newItems;
Expand All @@ -80,6 +86,8 @@ class GroupedItems extends React.Component {
sortingItemKey: null,
selectedItems: [],
});

document.body.style.cursor = '';
};

handleItemSelect = (item) => {
Expand Down
Loading