PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.7.0
Block Animations, Motion & Scroll Effects – Ghost Kit v3.7.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 3.7.0, at gutenberg/components/input-drag/index.js

207 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useDrag } from '@use-gesture/react';
2 import { TextControl } from '@wordpress/components';
3 import { useRef, useState } from '@wordpress/element';
4 import classnames from 'classnames/dedupe';
5
6 const units = [
7 'px',
8 '%',
9 'rem',
10 'em',
11 'vh',
12 'vw',
13 'vmin',
14 'vmax',
15 'ex',
16 'cm',
17 'mm',
18 'in',
19 'pt',
20 'pc',
21 'ch',
22 ];
23
24 /**
25 * The function counts the number of digits after the decimal point.
26 *
27 * @param {number} number - Any Number.
28 * @return {number} - Number of decimal places.
29 */
30 const numberOfDecimal = (number) =>
31 number.toString().includes('.')
32 ? number.toString().split('.').pop().length
33 : 0;
34
35 function fixRounding(value, precision) {
36 const power = 10 ** (precision || 0);
37 return Math.round(value * power) / power;
38 }
39
40 /**
41 * Component
42 *
43 * @param {*} props component props.
44 * @return {*}
45 */
46 export default function InputDrag(props) {
47 const {
48 label,
49 help,
50 icon,
51 placeholder,
52 value,
53 step,
54 defaultUnit,
55 expandOnFocus,
56 autoComplete,
57 className,
58 onChange,
59 } = props;
60
61 const inputRef = useRef();
62 const [isFocused, setIsFocused] = useState(false);
63
64 function parseValue() {
65 let valueNum = parseFloat(value);
66 let unit = '';
67
68 // check if value contains units and save it.
69 if (value !== `${valueNum}`) {
70 const matchUnit = (value || '').match(
71 new RegExp(`${valueNum}(${units.join('|')})`, 'i')
72 );
73
74 if (matchUnit && matchUnit[1]) {
75 unit = matchUnit[1];
76 }
77 }
78
79 if (Number.isNaN(valueNum)) {
80 valueNum = 0;
81 if (typeof defaultUnit !== 'undefined') {
82 unit = defaultUnit;
83 }
84 }
85
86 return {
87 num: valueNum,
88 unit,
89 full: value,
90 };
91 }
92
93 function onDragChange(distance, shiftKey) {
94 let newVal = distance;
95 const shiftVal = 10;
96
97 if (step) {
98 newVal *= step;
99 }
100 if (shiftKey) {
101 newVal *= shiftVal;
102 }
103
104 const valueObj = parseValue();
105
106 // If value differs from full value, then do nothing.
107 // It may be for example when used value such as:
108 // - calc(10px)
109 // - var(--var-name)
110 if (
111 typeof valueObj.full !== 'undefined' &&
112 `${valueObj.num}${valueObj.unit}` !== valueObj.full
113 ) {
114 return;
115 }
116
117 newVal = valueObj.num + newVal;
118
119 // Fix rounding problem after multiplication.
120 // https://stackoverflow.com/questions/9993266/javascript-multiply-not-precise
121 const decimals = numberOfDecimal(newVal);
122 if (decimals > 10) {
123 newVal = fixRounding(newVal, decimals - 1);
124 }
125
126 onChange(newVal + valueObj.unit);
127 }
128
129 function keyDown(e) {
130 switch (e.keyCode) {
131 // down.
132 case 40:
133 e.preventDefault();
134 onDragChange(-1, e.shiftKey);
135 break;
136 // up.
137 case 38:
138 e.preventDefault();
139 onDragChange(1, e.shiftKey);
140 break;
141 // no default
142 }
143 }
144
145 const dragGestureProps = useDrag(
146 (dragProps) => {
147 const { event, dragging, _direction, shiftKey } = dragProps;
148
149 if (!dragging) {
150 return;
151 }
152
153 event.stopPropagation();
154
155 onDragChange(-1 * _direction[1], shiftKey);
156 },
157 {
158 axis: 'y',
159 threshold: 10,
160 enabled: true,
161 pointer: { capture: false },
162 }
163 );
164
165 let classHasIcon = 'ghostkit-component-input-drag-no-icon';
166
167 if (typeof icon !== 'undefined') {
168 classHasIcon = 'ghostkit-component-input-drag-has-icon';
169 }
170
171 return (
172 <div
173 className={classnames(
174 classHasIcon,
175 isFocused &&
176 expandOnFocus &&
177 value &&
178 value.length >= expandOnFocus &&
179 'ghostkit-component-input-drag-expand',
180 className
181 )}
182 >
183 {icon}
184 <TextControl
185 {...dragGestureProps()}
186 ref={inputRef}
187 label={label}
188 help={help}
189 placeholder={placeholder}
190 value={value || ''}
191 onKeyDown={keyDown}
192 onChange={(val) => {
193 onChange(val);
194 }}
195 onFocus={() => {
196 setIsFocused(true);
197 }}
198 onBlur={() => {
199 setIsFocused(false);
200 }}
201 className="ghostkit-component-input-drag"
202 autoComplete={autoComplete}
203 />
204 </div>
205 );
206 }
207