@elementor/editor-controls 0.35.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/dist/index.d.mts +24 -13
- package/dist/index.d.ts +24 -13
- package/dist/index.js +809 -558
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +748 -491
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
- package/src/bound-prop-context/use-bound-prop.ts +4 -1
- package/src/components/control-form-label.tsx +3 -3
- package/src/components/control-label.tsx +1 -1
- package/src/components/font-family-selector.tsx +8 -10
- package/src/components/popover-grid-container.tsx +7 -10
- package/src/components/repeater.tsx +2 -4
- package/src/components/size-control/size-input.tsx +125 -0
- package/src/components/{text-field-inner-selection.tsx → size-control/text-field-inner-selection.tsx} +33 -16
- package/src/components/sortable.tsx +4 -2
- package/src/components/text-field-popover.tsx +47 -0
- package/src/controls/background-control/background-overlay/background-image-overlay/background-image-overlay-position.tsx +14 -5
- package/src/controls/background-control/background-overlay/background-image-overlay/background-image-overlay-size.tsx +9 -4
- package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +1 -1
- package/src/controls/box-shadow-repeater-control.tsx +11 -9
- package/src/controls/equal-unequal-sizes-control.tsx +38 -18
- package/src/controls/font-family-control/font-family-control.tsx +3 -1
- package/src/controls/gap-control.tsx +20 -7
- package/src/controls/image-control.tsx +2 -2
- package/src/controls/link-control.tsx +1 -1
- package/src/controls/linked-dimensions-control.tsx +71 -83
- package/src/controls/size-control.tsx +179 -149
- package/src/controls/stroke-control.tsx +9 -6
- package/src/hooks/use-size-extended-options.ts +21 -0
- package/src/index.ts +2 -1
- package/src/utils/size-control.ts +10 -0
|
@@ -1,183 +1,213 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { sizePropTypeUtil,
|
|
4
|
-
import {
|
|
2
|
+
import { type MutableRefObject, useEffect, useState } from 'react';
|
|
3
|
+
import { sizePropTypeUtil, type SizePropValue } from '@elementor/editor-props';
|
|
4
|
+
import { useActiveBreakpoint } from '@elementor/editor-responsive';
|
|
5
|
+
import { usePopupState } from '@elementor/ui';
|
|
5
6
|
|
|
6
7
|
import { useBoundProp } from '../bound-prop-context';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
8
|
+
import { SizeInput } from '../components/size-control/size-input';
|
|
9
|
+
import { TextFieldPopover } from '../components/text-field-popover';
|
|
9
10
|
import { createControl } from '../create-control';
|
|
11
|
+
import { useSizeExtendedOptions } from '../hooks/use-size-extended-options';
|
|
10
12
|
import { useSyncExternalState } from '../hooks/use-sync-external-state';
|
|
13
|
+
import { defaultUnits, type ExtendedOption, isUnitExtendedOption, type Unit } from '../utils/size-control';
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
const DEFAULT_UNIT = 'px';
|
|
16
|
+
const DEFAULT_SIZE = NaN;
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const defaultUnit = 'px';
|
|
18
|
-
const defaultSize = NaN;
|
|
18
|
+
type SizeValue = SizePropValue[ 'value' ];
|
|
19
19
|
|
|
20
20
|
type SizeControlProps = {
|
|
21
21
|
placeholder?: string;
|
|
22
22
|
startIcon?: React.ReactNode;
|
|
23
23
|
units?: Unit[];
|
|
24
|
-
|
|
24
|
+
extendedOptions?: ExtendedOption[];
|
|
25
|
+
disableCustom?: boolean;
|
|
26
|
+
anchorRef?: MutableRefObject< HTMLElement | undefined >;
|
|
25
27
|
};
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
external: sizeValue,
|
|
33
|
-
setExternal: setSizeValue,
|
|
34
|
-
persistWhen: ( controlValue ) => !! controlValue?.size || controlValue?.size === 0,
|
|
35
|
-
fallback: ( controlValue ) => ( { unit: controlValue?.unit || defaultUnit, size: defaultSize } ),
|
|
36
|
-
} );
|
|
37
|
-
|
|
38
|
-
const handleUnitChange = ( unit: Unit ) => {
|
|
39
|
-
setState( ( prev ) => ( {
|
|
40
|
-
size: prev?.size ?? defaultSize,
|
|
41
|
-
unit,
|
|
42
|
-
} ) );
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const handleSizeChange = ( event: React.ChangeEvent< HTMLInputElement > ) => {
|
|
46
|
-
const { value: size } = event.target;
|
|
47
|
-
|
|
48
|
-
setState( ( prev ) => ( {
|
|
49
|
-
...prev,
|
|
50
|
-
size: size || size === '0' ? parseFloat( size ) : defaultSize,
|
|
51
|
-
} ) );
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const Input = extendedValues?.length ? ExtendedSizeInput : SizeInput;
|
|
55
|
-
|
|
56
|
-
return (
|
|
57
|
-
<Input
|
|
58
|
-
disabled={ disabled }
|
|
59
|
-
size={ state.size }
|
|
60
|
-
unit={ state.unit }
|
|
61
|
-
placeholder={ placeholder }
|
|
62
|
-
startIcon={ startIcon }
|
|
63
|
-
units={ units }
|
|
64
|
-
extendedValues={ extendedValues }
|
|
65
|
-
handleSizeChange={ handleSizeChange }
|
|
66
|
-
handleUnitChange={ handleUnitChange }
|
|
67
|
-
onBlur={ restoreValue }
|
|
68
|
-
/>
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
);
|
|
29
|
+
type State = {
|
|
30
|
+
numeric: number;
|
|
31
|
+
custom: string;
|
|
32
|
+
unit: Unit | ExtendedOption;
|
|
33
|
+
};
|
|
72
34
|
|
|
73
|
-
const
|
|
74
|
-
const {
|
|
75
|
-
const {
|
|
35
|
+
export const SizeControl = createControl( ( props: SizeControlProps ) => {
|
|
36
|
+
const { units = [ ...defaultUnits ], placeholder, startIcon, anchorRef } = props;
|
|
37
|
+
const { value: sizeValue, setValue: setSizeValue, disabled, restoreValue } = useBoundProp( sizePropTypeUtil );
|
|
38
|
+
const [ internalState, setInternalState ] = useState( createStateFromSizeProp( sizeValue ) );
|
|
39
|
+
const activeBreakpoint = useActiveBreakpoint();
|
|
40
|
+
|
|
41
|
+
const extendedOptions = useSizeExtendedOptions( props.extendedOptions || [], props.disableCustom ?? false );
|
|
42
|
+
const popupState = usePopupState( { variant: 'popover' } );
|
|
43
|
+
|
|
44
|
+
const [ state, setState ] = useSyncExternalState( {
|
|
45
|
+
external: internalState,
|
|
46
|
+
setExternal: ( newState: State | null ) => setSizeValue( extractValueFromState( newState ) ),
|
|
47
|
+
persistWhen: ( newState ) => {
|
|
48
|
+
if ( ! newState?.unit ) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if ( isUnitExtendedOption( newState.unit ) ) {
|
|
53
|
+
return newState.unit === 'auto' ? true : !! newState.custom;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return !! newState?.numeric || newState?.numeric === 0;
|
|
57
|
+
},
|
|
58
|
+
fallback: ( newState ) => ( {
|
|
59
|
+
unit: newState?.unit ?? DEFAULT_UNIT,
|
|
60
|
+
numeric: newState?.numeric ?? DEFAULT_SIZE,
|
|
61
|
+
custom: newState?.custom ?? '',
|
|
62
|
+
} ),
|
|
63
|
+
} );
|
|
64
|
+
|
|
65
|
+
const { size: controlSize = DEFAULT_SIZE, unit: controlUnit = DEFAULT_UNIT } = extractValueFromState( state ) || {};
|
|
66
|
+
|
|
67
|
+
const handleUnitChange = ( newUnit: Unit | ExtendedOption ) => {
|
|
68
|
+
if ( newUnit === 'custom' ) {
|
|
69
|
+
popupState.open( anchorRef?.current );
|
|
70
|
+
}
|
|
76
71
|
|
|
77
|
-
|
|
72
|
+
setState( ( prev ) => ( { ...prev, unit: newUnit } ) );
|
|
73
|
+
};
|
|
78
74
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
const handleSizeChange = ( event: React.ChangeEvent< HTMLInputElement > ) => {
|
|
76
|
+
const { value: size } = event.target;
|
|
77
|
+
|
|
78
|
+
if ( controlUnit === 'auto' ) {
|
|
79
|
+
setState( ( prev ) => ( { ...prev, unit: controlUnit } ) );
|
|
80
|
+
|
|
81
|
+
return;
|
|
84
82
|
}
|
|
83
|
+
|
|
84
|
+
setState( ( prev ) => ( {
|
|
85
|
+
...prev,
|
|
86
|
+
[ controlUnit === 'custom' ? 'custom' : 'numeric' ]: formatSize( size, controlUnit ),
|
|
87
|
+
unit: controlUnit,
|
|
88
|
+
} ) );
|
|
85
89
|
};
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
unit={ unit }
|
|
93
|
-
/>
|
|
94
|
-
);
|
|
95
|
-
};
|
|
91
|
+
const onInputFocus = ( event: React.FocusEvent< HTMLInputElement > ) => {
|
|
92
|
+
if ( isUnitExtendedOption( state.unit ) ) {
|
|
93
|
+
( event.target as HTMLElement )?.blur();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
units: Unit[];
|
|
103
|
-
extendedValues?: ExtendedValue[];
|
|
104
|
-
onBlur?: ( event: React.FocusEvent< HTMLInputElement > ) => void;
|
|
105
|
-
handleUnitChange: ( unit: Unit ) => void;
|
|
106
|
-
handleSizeChange: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
|
|
107
|
-
disabled?: boolean;
|
|
108
|
-
};
|
|
97
|
+
const onInputClick = ( event: React.MouseEvent ) => {
|
|
98
|
+
if ( ( event.target as HTMLElement ).closest( 'input' ) && 'custom' === state.unit ) {
|
|
99
|
+
popupState.open( anchorRef?.current );
|
|
100
|
+
}
|
|
101
|
+
};
|
|
109
102
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
placeholder,
|
|
117
|
-
startIcon,
|
|
118
|
-
onBlur,
|
|
119
|
-
size,
|
|
120
|
-
unit,
|
|
121
|
-
disabled,
|
|
122
|
-
}: SizeInputProps ) => {
|
|
123
|
-
const unitInputBufferRef = useRef( '' );
|
|
124
|
-
|
|
125
|
-
const handleKeyUp = ( event: React.KeyboardEvent< HTMLInputElement > ) => {
|
|
126
|
-
const { key } = event;
|
|
127
|
-
|
|
128
|
-
if ( ! /^[a-zA-Z%]$/.test( key ) ) {
|
|
103
|
+
useEffect( () => {
|
|
104
|
+
const newState = createStateFromSizeProp( sizeValue );
|
|
105
|
+
const currentUnit = isUnitExtendedOption( state.unit ) ? 'custom' : 'numeric';
|
|
106
|
+
const mergedStates = { ...state, [ currentUnit ]: newState[ currentUnit ] };
|
|
107
|
+
|
|
108
|
+
if ( mergedStates.unit !== 'auto' && areStatesEqual( state, mergedStates ) ) {
|
|
129
109
|
return;
|
|
130
110
|
}
|
|
131
111
|
|
|
132
|
-
|
|
112
|
+
if ( state.unit === newState.unit ) {
|
|
113
|
+
setInternalState( mergedStates );
|
|
114
|
+
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
133
117
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
118
|
+
setState( newState );
|
|
119
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
120
|
+
}, [ sizeValue ] );
|
|
137
121
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
units.find( ( u ) => u.startsWith( newChar ) ) ||
|
|
141
|
-
units.find( ( u ) => u.includes( newChar ) );
|
|
122
|
+
useEffect( () => {
|
|
123
|
+
const newState = createStateFromSizeProp( sizeValue );
|
|
142
124
|
|
|
143
|
-
if (
|
|
144
|
-
|
|
125
|
+
if ( activeBreakpoint && ! areStatesEqual( newState, state ) ) {
|
|
126
|
+
setState( newState );
|
|
145
127
|
}
|
|
146
|
-
|
|
128
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
129
|
+
}, [ activeBreakpoint ] );
|
|
147
130
|
|
|
148
131
|
return (
|
|
149
|
-
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
value={ Number.isNaN( size ) ? '' : size }
|
|
132
|
+
<>
|
|
133
|
+
<SizeInput
|
|
134
|
+
disabled={ disabled }
|
|
135
|
+
size={ controlSize }
|
|
136
|
+
unit={ controlUnit }
|
|
137
|
+
units={ [ ...units, ...( extendedOptions || [] ) ] }
|
|
138
|
+
placeholder={ placeholder }
|
|
139
|
+
startIcon={ startIcon }
|
|
140
|
+
handleSizeChange={ handleSizeChange }
|
|
141
|
+
handleUnitChange={ handleUnitChange }
|
|
142
|
+
onBlur={ restoreValue }
|
|
143
|
+
onFocus={ onInputFocus }
|
|
144
|
+
onClick={ onInputClick }
|
|
145
|
+
popupState={ popupState }
|
|
146
|
+
/>
|
|
147
|
+
{ anchorRef?.current && (
|
|
148
|
+
<TextFieldPopover
|
|
149
|
+
popupState={ popupState }
|
|
150
|
+
anchorRef={ anchorRef as MutableRefObject< HTMLElement > }
|
|
151
|
+
restoreValue={ restoreValue }
|
|
152
|
+
value={ controlSize as string }
|
|
171
153
|
onChange={ handleSizeChange }
|
|
172
|
-
onBlur={ onBlur }
|
|
173
|
-
onKeyDown={ ( event ) => {
|
|
174
|
-
if ( RESTRICTED_INPUT_KEYS.includes( event.key ) ) {
|
|
175
|
-
event.preventDefault();
|
|
176
|
-
}
|
|
177
|
-
} }
|
|
178
|
-
onKeyUp={ handleKeyUp }
|
|
179
154
|
/>
|
|
180
|
-
|
|
181
|
-
|
|
155
|
+
) }
|
|
156
|
+
</>
|
|
182
157
|
);
|
|
183
|
-
};
|
|
158
|
+
} );
|
|
159
|
+
|
|
160
|
+
function formatSize< TSize extends string | number >( size: TSize, unit: Unit | ExtendedOption ): TSize {
|
|
161
|
+
if ( isUnitExtendedOption( unit ) ) {
|
|
162
|
+
return unit === 'auto' ? ( '' as TSize ) : ( String( size ?? '' ) as TSize );
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return size || size === 0 ? ( Number( size ) as TSize ) : ( NaN as TSize );
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function createStateFromSizeProp( sizeValue: SizeValue | null ): State {
|
|
169
|
+
const unit = sizeValue?.unit ?? DEFAULT_UNIT;
|
|
170
|
+
const size = sizeValue?.size ?? '';
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
numeric:
|
|
174
|
+
! isUnitExtendedOption( unit ) && ! isNaN( Number( size ) ) && ( size || size === 0 )
|
|
175
|
+
? Number( size )
|
|
176
|
+
: DEFAULT_SIZE,
|
|
177
|
+
custom: unit === 'custom' ? String( size ) : '',
|
|
178
|
+
unit,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function extractValueFromState( state: State | null ): SizeValue | null {
|
|
183
|
+
if ( ! state ) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if ( ! state?.unit ) {
|
|
188
|
+
return { size: DEFAULT_SIZE, unit: DEFAULT_UNIT };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const { unit } = state;
|
|
192
|
+
|
|
193
|
+
if ( unit === 'auto' ) {
|
|
194
|
+
return { size: '', unit };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
size: state[ unit === 'custom' ? 'custom' : 'numeric' ],
|
|
199
|
+
unit,
|
|
200
|
+
} as SizeValue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function areStatesEqual( state1: State, state2: State ): boolean {
|
|
204
|
+
if ( state1.unit !== state2.unit || state1.custom !== state2.custom ) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if ( isUnitExtendedOption( state1.unit ) ) {
|
|
209
|
+
return state1.custom === state2.custom;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return state1.numeric === state2.numeric || ( isNaN( state1.numeric ) && isNaN( state2.numeric ) );
|
|
213
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { forwardRef, type MutableRefObject, useRef } from 'react';
|
|
2
3
|
import { strokePropTypeUtil } from '@elementor/editor-props';
|
|
3
4
|
import { Grid } from '@elementor/ui';
|
|
4
5
|
import { __ } from '@wordpress/i18n';
|
|
@@ -7,8 +8,9 @@ import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-conte
|
|
|
7
8
|
import { ControlFormLabel } from '../components/control-form-label';
|
|
8
9
|
import { SectionContent } from '../components/section-content';
|
|
9
10
|
import { createControl } from '../create-control';
|
|
11
|
+
import { type Unit } from '../utils/size-control';
|
|
10
12
|
import { ColorControl } from './color-control';
|
|
11
|
-
import { SizeControl
|
|
13
|
+
import { SizeControl } from './size-control';
|
|
12
14
|
|
|
13
15
|
type StrokeProps = {
|
|
14
16
|
bind: string;
|
|
@@ -20,12 +22,13 @@ const units: Unit[] = [ 'px', 'em', 'rem' ];
|
|
|
20
22
|
|
|
21
23
|
export const StrokeControl = createControl( () => {
|
|
22
24
|
const propContext = useBoundProp( strokePropTypeUtil );
|
|
25
|
+
const rowRef: MutableRefObject< HTMLElement | undefined > = useRef();
|
|
23
26
|
|
|
24
27
|
return (
|
|
25
28
|
<PropProvider { ...propContext }>
|
|
26
29
|
<SectionContent>
|
|
27
|
-
<Control bind="width" label={ __( 'Stroke width', 'elementor' ) }>
|
|
28
|
-
<SizeControl units={ units } />
|
|
30
|
+
<Control bind="width" label={ __( 'Stroke width', 'elementor' ) } ref={ rowRef }>
|
|
31
|
+
<SizeControl units={ units } anchorRef={ rowRef } />
|
|
29
32
|
</Control>
|
|
30
33
|
<Control bind="color" label={ __( 'Stroke color', 'elementor' ) }>
|
|
31
34
|
<ColorControl />
|
|
@@ -35,9 +38,9 @@ export const StrokeControl = createControl( () => {
|
|
|
35
38
|
);
|
|
36
39
|
} );
|
|
37
40
|
|
|
38
|
-
const Control = ( { bind, label, children }: StrokeProps ) => (
|
|
41
|
+
const Control = forwardRef( ( { bind, label, children }: StrokeProps, ref ) => (
|
|
39
42
|
<PropKeyProvider bind={ bind }>
|
|
40
|
-
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
43
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap" ref={ ref }>
|
|
41
44
|
<Grid item xs={ 6 }>
|
|
42
45
|
<ControlFormLabel>{ label }</ControlFormLabel>
|
|
43
46
|
</Grid>
|
|
@@ -46,4 +49,4 @@ const Control = ( { bind, label, children }: StrokeProps ) => (
|
|
|
46
49
|
</Grid>
|
|
47
50
|
</Grid>
|
|
48
51
|
</PropKeyProvider>
|
|
49
|
-
);
|
|
52
|
+
) );
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { type ExtendedOption } from '@elementor/editor-controls';
|
|
3
|
+
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
|
+
|
|
5
|
+
const EXPERIMENT_ID = 'e_v_3_30';
|
|
6
|
+
|
|
7
|
+
export function useSizeExtendedOptions( options: ExtendedOption[], disableCustom: boolean ) {
|
|
8
|
+
return useMemo( () => {
|
|
9
|
+
const isVersion330Active = isExperimentActive( EXPERIMENT_ID );
|
|
10
|
+
const shouldDisableCustom = ! isVersion330Active || disableCustom;
|
|
11
|
+
const extendedOptions = [ ...options ];
|
|
12
|
+
|
|
13
|
+
if ( ! shouldDisableCustom && ! extendedOptions.includes( 'custom' ) ) {
|
|
14
|
+
extendedOptions.push( 'custom' );
|
|
15
|
+
} else if ( options.includes( 'custom' ) ) {
|
|
16
|
+
extendedOptions.splice( extendedOptions.indexOf( 'custom' ), 1 );
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return extendedOptions;
|
|
20
|
+
}, [ options, disableCustom ] );
|
|
21
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ export { SwitchControl } from './controls/switch-control';
|
|
|
23
23
|
// components
|
|
24
24
|
export { ControlFormLabel } from './components/control-form-label';
|
|
25
25
|
export { ControlToggleButtonGroup } from './components/control-toggle-button-group';
|
|
26
|
+
export { FontFamilySelector } from './components/font-family-selector';
|
|
26
27
|
|
|
27
28
|
// types
|
|
28
29
|
export type { ControlComponent } from './create-control';
|
|
@@ -31,7 +32,7 @@ export type { EqualUnequalItems } from './controls/equal-unequal-sizes-control';
|
|
|
31
32
|
export type { ControlActionsItems } from './control-actions/control-actions-context';
|
|
32
33
|
export type { PropProviderProps } from './bound-prop-context';
|
|
33
34
|
export type { SetValue } from './bound-prop-context/prop-context';
|
|
34
|
-
export type {
|
|
35
|
+
export type { ExtendedOption } from './utils/size-control';
|
|
35
36
|
export type { ToggleControlProps } from './controls/toggle-control';
|
|
36
37
|
export type { FontCategory } from './controls/font-family-control/font-family-control';
|
|
37
38
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const defaultUnits = [ 'px', '%', 'em', 'rem', 'vw', 'vh' ] as const;
|
|
2
|
+
const defaultExtendedOptions = [ 'auto', 'custom' ] as const;
|
|
3
|
+
|
|
4
|
+
export type Unit = ( typeof defaultUnits )[ number ];
|
|
5
|
+
|
|
6
|
+
export type ExtendedOption = ( typeof defaultExtendedOptions )[ number ];
|
|
7
|
+
|
|
8
|
+
export function isUnitExtendedOption( unit: Unit | ExtendedOption ): unit is ExtendedOption {
|
|
9
|
+
return defaultExtendedOptions.includes( unit as ExtendedOption );
|
|
10
|
+
}
|