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

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