1 | import React, {PureComponent} from 'react';
|
2 | import PropTypes from 'prop-types';
|
3 |
|
4 | import Selection from './selection';
|
5 |
|
6 | export default function selectionShortcutsHOC(ComposedComponent) {
|
7 | return class SelectionShortcuts extends PureComponent {
|
8 | static propTypes = {
|
9 | ...ComposedComponent.propTypes,
|
10 | selection: PropTypes.instanceOf(Selection).isRequired,
|
11 | selectable: PropTypes.bool,
|
12 | onSelect: PropTypes.func,
|
13 | shortcuts: PropTypes.object
|
14 | };
|
15 |
|
16 | static defaultProps = {
|
17 | ...ComposedComponent.defaultProps,
|
18 | selectable: true,
|
19 | onSelect: () => {},
|
20 | shortcuts: {}
|
21 | };
|
22 |
|
23 | onUpPress = () => {
|
24 | const {selection, onSelect} = this.props;
|
25 | const newSelection = selection.moveUp();
|
26 |
|
27 | if (newSelection) {
|
28 | onSelect(newSelection);
|
29 | }
|
30 |
|
31 | return false;
|
32 | };
|
33 |
|
34 | onDownPress = () => {
|
35 | const {selection, onSelect} = this.props;
|
36 | const newSelection = selection.moveDown();
|
37 |
|
38 | if (newSelection) {
|
39 | onSelect(newSelection);
|
40 | }
|
41 |
|
42 | return false;
|
43 | };
|
44 |
|
45 | onShiftKeyDown = () => {
|
46 | const {selection} = this.props;
|
47 |
|
48 | if (selection.isSelected(selection.getFocused())) {
|
49 | this.shiftSelectionMode = 'deletion';
|
50 | } else {
|
51 | this.shiftSelectionMode = 'addition';
|
52 | }
|
53 | };
|
54 |
|
55 | shiftSelect = selection => {
|
56 | if (this.shiftSelectionMode === 'addition') {
|
57 | return selection.select();
|
58 | } else {
|
59 | return selection.deselect();
|
60 | }
|
61 | };
|
62 |
|
63 | onShiftUpPress = e => {
|
64 | e.preventDefault();
|
65 | const {selectable, selection, onSelect} = this.props;
|
66 |
|
67 | if (!selectable) {
|
68 | return;
|
69 | }
|
70 |
|
71 | const newSelection = this.shiftSelect(selection);
|
72 | const newMovedSelection = newSelection.moveUp();
|
73 |
|
74 | if (newMovedSelection) {
|
75 | onSelect(newMovedSelection);
|
76 | } else {
|
77 | onSelect(newSelection);
|
78 | }
|
79 | };
|
80 |
|
81 | onShiftDownPress = e => {
|
82 | e.preventDefault();
|
83 | const {selectable, selection, onSelect} = this.props;
|
84 |
|
85 | if (!selectable) {
|
86 | return;
|
87 | }
|
88 |
|
89 | const newSelection = this.shiftSelect(selection);
|
90 | const newMovedSelection = newSelection.moveDown();
|
91 |
|
92 | if (newMovedSelection) {
|
93 | onSelect(newMovedSelection);
|
94 | } else {
|
95 | onSelect(newSelection);
|
96 | }
|
97 | };
|
98 |
|
99 | onHomePress = () => {
|
100 | const {selection, onSelect} = this.props;
|
101 |
|
102 | const newSelection = selection.moveStart();
|
103 | if (newSelection) {
|
104 | onSelect(newSelection);
|
105 | }
|
106 |
|
107 | return false;
|
108 | };
|
109 |
|
110 | onEndPress = () => {
|
111 | const {selection, onSelect} = this.props;
|
112 |
|
113 | const newSelection = selection.moveEnd();
|
114 | if (newSelection) {
|
115 | onSelect(newSelection);
|
116 | }
|
117 |
|
118 | return false;
|
119 | };
|
120 |
|
121 | onSpacePress = () => {
|
122 | const {selectable, selection, onSelect} = this.props;
|
123 |
|
124 | if (!selectable) {
|
125 | return true;
|
126 | }
|
127 |
|
128 | onSelect(selection.toggleSelection());
|
129 | return false;
|
130 | };
|
131 |
|
132 | onEscPress = () => {
|
133 | const {selection, onSelect} = this.props;
|
134 |
|
135 | onSelect(selection.reset());
|
136 |
|
137 | };
|
138 |
|
139 | onCmdAPress = () => {
|
140 | const {selectable, selection, onSelect} = this.props;
|
141 |
|
142 | if (!selectable) {
|
143 | return true;
|
144 | }
|
145 |
|
146 | onSelect(selection.selectAll());
|
147 | return false;
|
148 | };
|
149 |
|
150 | shortcutsMap = {
|
151 | up: this.onUpPress,
|
152 | down: this.onDownPress,
|
153 | shift: this.onShiftKeyDown,
|
154 | 'shift+up': this.onShiftUpPress,
|
155 | 'shift+down': this.onShiftDownPress,
|
156 | home: this.onHomePress,
|
157 | end: this.onEndPress,
|
158 | space: this.onSpacePress,
|
159 | esc: this.onEscPress,
|
160 | 'command+a': this.onCmdAPress,
|
161 | 'ctrl+a': this.onCmdAPress
|
162 | };
|
163 |
|
164 | render() {
|
165 | const {selection, selectable, onSelect} = this.props;
|
166 | return (
|
167 | <ComposedComponent
|
168 | {...this.props}
|
169 | selection={selection}
|
170 | selectable={selectable}
|
171 | onSelect={onSelect}
|
172 | shortcutsMap={{...this.shortcutsMap, ...this.props.shortcuts}}
|
173 | />
|
174 | );
|
175 | }
|
176 | };
|
177 | }
|