PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 2.25.0
Block Animations, Motion & Scroll Effects – Ghost Kit v2.25.0
3.7.2 3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / gutenberg / components / input-drag / index.js

index.js in Block Animations, Motion & Scroll Effects – Ghost Kit 2.25.0, at gutenberg/components/input-drag/index.js

246 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * External dependencies
3 */
4 import classnames from 'classnames/dedupe';
5
6 /**
7 * WordPress dependencies
8 */
9 const { Component } = wp.element;
10
11 const { TextControl } = wp.components;
12
13 /**
14 * Internal dependencies
15 */
16 const minDistanceToStart = 5;
17 const units = [
18 'px',
19 '%',
20 'rem',
21 'em',
22 'vh',
23 'vw',
24 'vmin',
25 'vmax',
26 'ex',
27 'cm',
28 'mm',
29 'in',
30 'pt',
31 'pc',
32 'ch',
33 ];
34
35 /**
36 * The function counts the number of digits after the decimal point.
37 *
38 * @param {number} number - Any Number.
39 * @return {number} - Number of decimal places.
40 */
41 const numberOfDecimal = (number) =>
42 number.toString().includes('.') ? number.toString().split('.').pop().length : 0;
43
44 /**
45 * Component Class
46 */
47 export default class InputDrag extends Component {
48 constructor(props) {
49 super(props);
50
51 this.parseValue = this.parseValue.bind(this);
52 this.reset = this.reset.bind(this);
53 this.mouseUp = this.mouseUp.bind(this);
54 this.mouseDown = this.mouseDown.bind(this);
55 this.mouseMove = this.mouseMove.bind(this);
56 this.keyDown = this.keyDown.bind(this);
57
58 this.reset();
59 }
60
61 componentDidMount() {
62 document.addEventListener('mouseup', this.mouseUp, false);
63 document.addEventListener('mousemove', this.mouseMove, false);
64 }
65
66 componentWillUnmount() {
67 document.removeEventListener('mouseup', this.mouseUp, false);
68 document.removeEventListener('mousemove', this.mouseMove, false);
69 }
70
71 parseValue() {
72 let valueNum = parseFloat(this.props.value);
73 let unit = '';
74 // check if value contains units and save it.
75 if (this.props.value !== `${valueNum}`) {
76 const matchUnit = this.props.value.match(new RegExp(`${valueNum}(${units.join('|')})`, 'i'));
77
78 if (matchUnit && matchUnit[1]) {
79 // eslint-disable-next-line prefer-destructuring
80 unit = matchUnit[1];
81 }
82 }
83
84 if (Number.isNaN(valueNum)) {
85 valueNum = 0;
86 if (typeof this.props.defaultUnit !== 'undefined') {
87 unit = this.props.defaultUnit;
88 }
89 }
90
91 return {
92 num: valueNum,
93 unit,
94 full: this.props.value,
95 };
96 }
97
98 reset() {
99 this.initialPosition = 0;
100 this.initialValue = 0;
101 this.initialUnit = '';
102 this.initialShiftKey = 0;
103
104 // states
105 // 0 - none
106 // 1 - retrieving value
107 // 2 - change value
108 this.dragState = 0;
109 }
110
111 mouseDown(e) {
112 this.initialPosition = {
113 x: e.pageX,
114 y: e.pageY,
115 };
116 const valueObj = this.parseValue();
117
118 this.initialValue = valueObj.num;
119 this.initialUnit = valueObj.unit;
120
121 if (e.shiftKey) {
122 this.initialShiftKey = 1;
123 }
124
125 this.dragState = 1;
126 }
127
128 mouseUp() {
129 this.reset();
130 }
131
132 mouseMove(e) {
133 const startDistance = this.props.startDistance || minDistanceToStart;
134
135 switch (this.dragState) {
136 // check for drag position
137 case 1:
138 if (Math.abs(this.initialPosition.x - e.pageX) > startDistance) {
139 this.reset();
140 } else if (Math.abs(this.initialPosition.y - e.pageY) > startDistance) {
141 this.dragState = 2;
142 }
143
144 break;
145 // change input value.
146 case 2: {
147 e.preventDefault();
148 let step = 1;
149 let shiftKeyMultiple = 10;
150
151 if (typeof this.props.step !== 'undefined' && !Number.isNaN(this.props.step)) {
152 step = this.props.step;
153 shiftKeyMultiple *= step;
154 }
155
156 const numbersOfDigit = numberOfDecimal(step);
157 let mouseValue =
158 this.initialValue +
159 (this.initialPosition.y - e.pageY) * (this.initialShiftKey ? shiftKeyMultiple : step);
160
161 // conversion for decimal steps
162 if (numbersOfDigit > 0) {
163 mouseValue = +mouseValue.toFixed(numbersOfDigit);
164 }
165
166 this.props.onChange(mouseValue + this.initialUnit);
167 break;
168 }
169 // no default
170 }
171 }
172
173 keyDown(e) {
174 if (this.initialPosition || (e.keyCode !== 40 && e.keyCode !== 38)) {
175 return;
176 }
177
178 e.preventDefault();
179
180 const valueObj = this.parseValue();
181 let newVal = 1;
182 let shiftVal = 10;
183
184 if (typeof this.props.step !== 'undefined' && !Number.isNaN(this.props.step)) {
185 newVal = this.props.step;
186 if (e.shiftKey) {
187 shiftVal *= this.props.step;
188 }
189 }
190
191 const numbersOfDigit = numberOfDecimal(newVal);
192 let keyDown = valueObj.num - newVal;
193 let keyUp = valueObj.num + newVal;
194
195 if (e.shiftKey) {
196 keyDown = valueObj.num - shiftVal;
197 keyUp = valueObj.num + shiftVal;
198 }
199
200 // conversion for decimal steps
201 if (numbersOfDigit > 0) {
202 keyDown = +keyDown.toFixed(numbersOfDigit);
203 keyUp = +keyUp.toFixed(numbersOfDigit);
204 }
205
206 switch (e.keyCode) {
207 // down.
208 case 40:
209 this.props.onChange(keyDown + valueObj.unit);
210 break;
211 // up.
212 case 38:
213 this.props.onChange(keyUp + valueObj.unit);
214 break;
215 // no default
216 }
217 }
218
219 render() {
220 const { value, onChange, icon, placeholder, autoComplete, className } = this.props;
221
222 let classHasIcon = 'ghostkit-component-input-drag-no-icon';
223
224 if (typeof icon !== 'undefined') {
225 classHasIcon = 'ghostkit-component-input-drag-has-icon';
226 }
227
228 return (
229 <div className={classnames(classHasIcon, className)}>
230 {icon}
231 <TextControl
232 onMouseDown={this.mouseDown}
233 onKeyDown={this.keyDown}
234 value={value}
235 onChange={(val) => {
236 onChange(val);
237 }}
238 className="ghostkit-component-input-drag"
239 placeholder={placeholder}
240 autoComplete={autoComplete}
241 />
242 </div>
243 );
244 }
245 }
246