PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 1.5.3
GenerateBlocks v1.5.3
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / src / components / number-control / index.js
generateblocks / src / components / number-control Last commit date
editor.scss 4 years ago index.js 4 years ago
index.js
224 lines
1 /**
2 * External dependencies
3 */
4 import { useState } from '@wordpress/element';
5 import { settings as settingsIcon } from '@wordpress/icons';
6 import { __ } from '@wordpress/i18n';
7 import { applyFilters } from '@wordpress/hooks';
8 import {
9 TextControl,
10 ButtonGroup,
11 Button,
12 BaseControl,
13 Tooltip,
14 } from '@wordpress/components';
15 import useLocalStorageState from 'use-local-storage-state';
16
17 /**
18 * Internal dependencies
19 */
20 import UnitPicker from '../unit-picker';
21 import hasNumericValue from '../../utils/has-numeric-value';
22 import getResponsivePlaceholder from '../../utils/get-responsive-placeholder';
23 import './editor.scss';
24
25 export default function NumberControl( props ) {
26 const {
27 label,
28 attributeName,
29 attributes,
30 setAttributes,
31 units = [],
32 unit = 'px',
33 device,
34 presets = [],
35 min = 0,
36 max,
37 step,
38 id = attributeName,
39 defaultPlaceholder = '',
40 } = props;
41
42 const [ isCustom, setCustom ] = useState( false );
43
44 const [ inputPreferences, setInputPreferences ] = useLocalStorageState(
45 'generateblocksCustomInputs', {
46 ssr: true,
47 defaultValue: [],
48 }
49 );
50
51 const attributeNames = {
52 value: attributeName,
53 unit: attributeName + 'Unit',
54 };
55
56 if ( device && 'Desktop' !== device ) {
57 attributeNames.value += device;
58 }
59
60 const allPresets = applyFilters(
61 'generateblocns.editor.numberPresets',
62 presets,
63 props,
64 );
65
66 const presetData = allPresets.length > 0 ? allPresets[ 0 ].data : [];
67 const presetUnit = allPresets.length > 0 ? allPresets[ 0 ].unit : 'px';
68
69 const presetsHaveValue = presetData.length > 0 && 'object' === typeof presetData[ 0 ]
70 ? presetData.find( ( preset ) => {
71 return preset.value === attributes[ attributeNames.value ];
72 } )
73 : presetData.includes( attributes[ attributeNames.value ] );
74
75 const hasParentValue = 'Desktop' !== device &&
76 getResponsivePlaceholder( attributeNames.value, attributes, device, '' );
77
78 const showCustom = allPresets.length === 0 ||
79 (
80 !! hasNumericValue( attributes[ attributeNames.value ] ) &&
81 ! presetsHaveValue
82 ) ||
83 hasParentValue ||
84 isCustom ||
85 inputPreferences.some( ( pref ) => pref.includes( attributeName ) );
86
87 return (
88 <BaseControl
89 label={ units.length === 0 ? label : null }
90 id={ id }
91 className="gblocks-number-component"
92 >
93 { units.length > 0 &&
94 <UnitPicker
95 label={ label }
96 id={ id }
97 value={ attributes[ attributeNames.unit ] || unit }
98 units={ units }
99 singleOption={ ! showCustom }
100 onClick={ ( value ) => {
101 if ( 'undefined' !== typeof attributes[ attributeNames.unit ] ) {
102 setAttributes( {
103 [ attributeNames.unit ]: value,
104 } );
105 }
106
107 return false;
108 } }
109 />
110 }
111
112 { ! showCustom &&
113 <ButtonGroup className="gblocks-component-number-presets">
114 {
115 presetData.map( ( preset, index ) => {
116 const presetValue = 'object' === typeof preset
117 ? preset.value
118 : preset;
119
120 const presetLabel = 'object' === typeof preset
121 ? preset.label
122 : preset;
123
124 return (
125 <Button
126 key={ index }
127 isPrimary={
128 presetValue === attributes[ attributeNames.value ] ||
129 ( presetValue === defaultPlaceholder && ! hasNumericValue( attributes[ attributeNames.value ] ) )
130 }
131 onClick={ () => {
132 if ( attributes[ attributeNames.value ] !== presetValue ) {
133 setAttributes( {
134 [ attributeNames.value ]: presetValue,
135 [ attributeNames.unit ]: presetUnit,
136 } );
137 } else {
138 setAttributes( { [ attributeNames.value ]: '' } );
139 }
140 } }
141 >
142 { presetLabel }
143 </Button>
144 );
145 } )
146 }
147
148 <Tooltip text={ __( 'Custom', 'generateblocks' ) }>
149 <Button
150 icon={ settingsIcon }
151 onClick={ () => {
152 setCustom( true );
153 setInputPreferences( [ ...inputPreferences, attributeName ] );
154 } }
155 />
156 </Tooltip>
157 </ButtonGroup>
158 }
159
160 { showCustom &&
161 <div className="gblocks-number-component__input">
162 <TextControl
163 type="number"
164 value={ hasNumericValue( attributes[ attributeNames.value ] ) ? attributes[ attributeNames.value ] : '' }
165 placeholder={ getResponsivePlaceholder( attributeNames.value, attributes, device, defaultPlaceholder ) }
166 id={ id }
167 min={ min }
168 max={ max }
169 step={ step }
170 autoComplete="off"
171 onChange={ ( value ) => {
172 if ( min >= 0 ) {
173 // No hyphens allowed here.
174 value = value.toString().replace( /-/g, '' );
175 }
176
177 setAttributes( {
178 [ attributeNames.value ]: value,
179 } );
180 } }
181 onBlur={ () => {
182 if (
183 '' !== attributes[ attributeNames.value ] &&
184 false !== attributes[ attributeNames.value ]
185 ) {
186 setAttributes( {
187 [ attributeNames.value ]: parseFloat( attributes[ attributeNames.value ] ),
188 } );
189 }
190 } }
191 onClick={ ( e ) => {
192 // Make sure onBlur fires in Firefox.
193 e.currentTarget.focus();
194 } }
195 />
196
197 {
198 allPresets.length > 0 &&
199 (
200 presetsHaveValue ||
201 ! hasNumericValue( attributes[ attributeNames.value ] )
202 ) &&
203 ! hasParentValue &&
204 <Tooltip text={ __( 'Presets', 'generateblocks' ) }>
205 <Button
206 icon={ settingsIcon }
207 onClick={ () => {
208 setCustom( false );
209
210 setAttributes( {
211 [ attributeNames.unit ]: presetUnit,
212 } );
213
214 setInputPreferences( inputPreferences.filter( ( pref ) => pref !== attributeName ) );
215 } }
216 />
217 </Tooltip>
218 }
219 </div>
220 }
221 </BaseControl>
222 );
223 }
224