PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.0.2
GenerateBlocks v2.0.2
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 3 years ago
index.js
236 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 // Disable our legacy row gap option in the Grid block if this option is changed.
142 // Since 1.7.0.
143 if ( 'verticalGap' === attributeName ) {
144 setAttributes( { useLegacyRowGap: false } );
145 }
146 } }
147 >
148 { presetLabel }
149 </Button>
150 );
151 } )
152 }
153
154 <Tooltip text={ __( 'Custom', 'generateblocks' ) }>
155 <Button
156 icon={ settingsIcon }
157 onClick={ () => {
158 setCustom( true );
159 setInputPreferences( [ ...inputPreferences, attributeName ] );
160 } }
161 />
162 </Tooltip>
163 </ButtonGroup>
164 }
165
166 { showCustom &&
167 <div className="gblocks-number-component__input">
168 <TextControl
169 type="number"
170 value={ hasNumericValue( attributes[ attributeNames.value ] ) ? attributes[ attributeNames.value ] : '' }
171 placeholder={ getResponsivePlaceholder( attributeNames.value, attributes, device, defaultPlaceholder ) }
172 id={ id }
173 min={ min }
174 max={ max }
175 step={ step }
176 autoComplete="off"
177 onChange={ ( value ) => {
178 if ( min >= 0 ) {
179 // No hyphens allowed here.
180 value = value.toString().replace( /-/g, '' );
181 }
182
183 setAttributes( {
184 [ attributeNames.value ]: value,
185 } );
186 } }
187 onBlur={ () => {
188 if (
189 '' !== attributes[ attributeNames.value ] &&
190 false !== attributes[ attributeNames.value ]
191 ) {
192 setAttributes( {
193 [ attributeNames.value ]: parseFloat( attributes[ attributeNames.value ] ),
194 } );
195 }
196
197 // Disable our legacy row gap option in the Grid block if this option is changed.
198 // Since 1.7.0.
199 if ( 'verticalGap' === attributeName ) {
200 setAttributes( { useLegacyRowGap: false } );
201 }
202 } }
203 onClick={ ( e ) => {
204 // Make sure onBlur fires in Firefox.
205 e.currentTarget.focus();
206 } }
207 />
208
209 {
210 allPresets.length > 0 &&
211 (
212 presetsHaveValue ||
213 ! hasNumericValue( attributes[ attributeNames.value ] )
214 ) &&
215 ! hasParentValue &&
216 <Tooltip text={ __( 'Presets', 'generateblocks' ) }>
217 <Button
218 icon={ settingsIcon }
219 onClick={ () => {
220 setCustom( false );
221
222 setAttributes( {
223 [ attributeNames.unit ]: presetUnit,
224 } );
225
226 setInputPreferences( inputPreferences.filter( ( pref ) => pref !== attributeName ) );
227 } }
228 />
229 </Tooltip>
230 }
231 </div>
232 }
233 </BaseControl>
234 );
235 }
236