-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
all-input-control.js
116 lines (104 loc) · 2.69 KB
/
all-input-control.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
* External dependencies
*/
import { noop } from 'lodash';
/**
* Internal dependencies
*/
import UnitControl from './unit-control';
import {
ALL_SIDES,
LABELS,
getAllValue,
getAllUnitFallback,
isValuesMixed,
isValuesDefined,
} from './utils';
export default function AllInputControl( {
onChange = noop,
onFocus = noop,
onHoverOn = noop,
onHoverOff = noop,
values,
sides,
selectedUnits,
setSelectedUnits,
...props
} ) {
const allValue = getAllValue( values, sides );
const hasValues = isValuesDefined( values );
const isMixed = hasValues && isValuesMixed( values, sides );
const allPlaceholder = isMixed ? LABELS.mixed : null;
// Set meaningful unit selection if no allValue and user has previously
// selected units without assigning values while controls were unlinked.
const allUnitFallback = ! allValue
? getAllUnitFallback( selectedUnits )
: undefined;
const handleOnFocus = ( event ) => {
onFocus( event, { side: 'all' } );
};
// Applies a value to an object representing top, right, bottom and left
// sides while taking into account any custom side configuration.
const applyValueToSides = ( currentValues, newValue ) => {
const newValues = { ...currentValues };
if ( sides?.length ) {
sides.forEach( ( side ) => {
if ( side === 'vertical' ) {
newValues.top = newValue;
newValues.bottom = newValue;
} else if ( side === 'horizontal' ) {
newValues.left = newValue;
newValues.right = newValue;
} else {
newValues[ side ] = newValue;
}
} );
} else {
ALL_SIDES.forEach( ( side ) => ( newValues[ side ] = newValue ) );
}
return newValues;
};
const handleOnChange = ( next ) => {
const isNumeric = ! isNaN( parseFloat( next ) );
const nextValue = isNumeric ? next : undefined;
const nextValues = applyValueToSides( values, nextValue );
onChange( nextValues );
};
// Set selected unit so it can be used as fallback by unlinked controls
// when individual sides do not have a value containing a unit.
const handleOnUnitChange = ( unit ) => {
const newUnits = applyValueToSides( selectedUnits, unit );
setSelectedUnits( newUnits );
};
const handleOnHoverOn = () => {
onHoverOn( {
top: true,
bottom: true,
left: true,
right: true,
} );
};
const handleOnHoverOff = () => {
onHoverOff( {
top: false,
bottom: false,
left: false,
right: false,
} );
};
return (
<UnitControl
{ ...props }
disableUnits={ isMixed }
isOnly
value={ allValue }
unit={ allUnitFallback }
onChange={ handleOnChange }
onUnitChange={ handleOnUnitChange }
onFocus={ handleOnFocus }
onHoverOn={ handleOnHoverOn }
onHoverOff={ handleOnHoverOff }
placeholder={ allPlaceholder }
/>
);
}