@elementor/editor-controls 1.3.0 → 1.5.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 +40 -0
- package/dist/index.d.mts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +777 -629
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +617 -458
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/components/font-family-selector.tsx +54 -56
- package/src/components/repeater.tsx +22 -11
- package/src/components/size-control/size-input.tsx +4 -4
- package/src/controls/color-control.tsx +12 -1
- package/src/controls/filter-control/drop-shadow-item-content.tsx +69 -0
- package/src/controls/filter-control/drop-shadow-item-label.tsx +20 -0
- package/src/controls/filter-repeater-control.tsx +108 -21
- package/src/controls/key-value-control.tsx +57 -46
- package/src/controls/repeatable-control.tsx +48 -29
- package/src/controls/size-control.tsx +25 -12
- package/src/controls/text-control.tsx +33 -18
- package/src/utils/size-control.ts +4 -2
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
type CreateOptions,
|
|
5
|
+
isTransformable,
|
|
6
|
+
keyValuePropTypeUtil,
|
|
7
|
+
type PropKey,
|
|
8
|
+
type Props,
|
|
9
|
+
stringPropTypeUtil,
|
|
10
|
+
} from '@elementor/editor-props';
|
|
11
|
+
import { FormHelperText, FormLabel, Grid } from '@elementor/ui';
|
|
5
12
|
import { __ } from '@wordpress/i18n';
|
|
6
13
|
|
|
7
|
-
import { useBoundProp } from '../bound-prop-context';
|
|
8
|
-
import ControlActions from '../control-actions/control-actions';
|
|
14
|
+
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
9
15
|
import { createControl } from '../create-control';
|
|
10
|
-
|
|
11
|
-
type FieldType = 'key' | 'value';
|
|
16
|
+
import { TextControl } from './text-control';
|
|
12
17
|
|
|
13
18
|
type KeyValueControlProps = {
|
|
14
19
|
keyName?: string;
|
|
@@ -19,9 +24,9 @@ type KeyValueControlProps = {
|
|
|
19
24
|
};
|
|
20
25
|
|
|
21
26
|
export const KeyValueControl = createControl( ( props: KeyValueControlProps = {} ) => {
|
|
22
|
-
const { value, setValue } = useBoundProp( keyValuePropTypeUtil );
|
|
23
|
-
const [ keyError, setKeyError ] = useState< string
|
|
24
|
-
const [ valueError, setValueError ] = useState< string
|
|
27
|
+
const { value, setValue, ...propContext } = useBoundProp( keyValuePropTypeUtil );
|
|
28
|
+
const [ keyError, setKeyError ] = useState< string >( '' );
|
|
29
|
+
const [ valueError, setValueError ] = useState< string >( '' );
|
|
25
30
|
|
|
26
31
|
const [ sessionState, setSessionState ] = useState( {
|
|
27
32
|
key: value?.key?.value || '',
|
|
@@ -43,31 +48,48 @@ export const KeyValueControl = createControl( ( props: KeyValueControlProps = {}
|
|
|
43
48
|
const validate = ( newValue: string, fieldType: string ): boolean => {
|
|
44
49
|
if ( fieldType === 'key' && keyRegex ) {
|
|
45
50
|
const isValid = keyRegex.test( newValue );
|
|
46
|
-
setKeyError( isValid ?
|
|
51
|
+
setKeyError( isValid ? '' : errMsg );
|
|
52
|
+
|
|
47
53
|
return isValid;
|
|
48
54
|
} else if ( fieldType === 'value' && valueRegex ) {
|
|
49
55
|
const isValid = valueRegex.test( newValue );
|
|
50
|
-
setValueError( isValid ?
|
|
56
|
+
setValueError( isValid ? '' : errMsg );
|
|
57
|
+
|
|
51
58
|
return isValid;
|
|
52
59
|
}
|
|
60
|
+
|
|
53
61
|
return true;
|
|
54
62
|
};
|
|
55
63
|
|
|
56
|
-
const handleChange = (
|
|
57
|
-
const
|
|
64
|
+
const handleChange = ( newValue: Props, options?: CreateOptions, meta?: { bind?: PropKey } ) => {
|
|
65
|
+
const fieldType = meta?.bind;
|
|
66
|
+
|
|
67
|
+
if ( ! fieldType ) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const newChangedValue = newValue[ fieldType ];
|
|
72
|
+
|
|
73
|
+
if ( isTransformable( newChangedValue ) && newChangedValue.$$type === 'dynamic' ) {
|
|
74
|
+
setValue( {
|
|
75
|
+
...value,
|
|
76
|
+
[ fieldType ]: newChangedValue,
|
|
77
|
+
} );
|
|
78
|
+
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const extractedValue = stringPropTypeUtil.extract( newChangedValue );
|
|
58
83
|
|
|
59
84
|
setSessionState( ( prev ) => ( {
|
|
60
85
|
...prev,
|
|
61
|
-
[ fieldType ]:
|
|
86
|
+
[ fieldType ]: extractedValue,
|
|
62
87
|
} ) );
|
|
63
88
|
|
|
64
|
-
if ( validate(
|
|
89
|
+
if ( extractedValue && validate( extractedValue, fieldType ) ) {
|
|
65
90
|
setValue( {
|
|
66
91
|
...value,
|
|
67
|
-
[ fieldType ]:
|
|
68
|
-
value: newValue,
|
|
69
|
-
$$type: 'string',
|
|
70
|
-
},
|
|
92
|
+
[ fieldType ]: newChangedValue,
|
|
71
93
|
} );
|
|
72
94
|
} else {
|
|
73
95
|
setValue( {
|
|
@@ -80,40 +102,29 @@ export const KeyValueControl = createControl( ( props: KeyValueControlProps = {}
|
|
|
80
102
|
}
|
|
81
103
|
};
|
|
82
104
|
|
|
83
|
-
const isKeyInvalid = keyError !== null;
|
|
84
|
-
const isValueInvalid = valueError !== null;
|
|
85
|
-
|
|
86
105
|
return (
|
|
87
|
-
<
|
|
106
|
+
<PropProvider { ...propContext } value={ value } setValue={ handleChange }>
|
|
88
107
|
<Grid container gap={ 1.5 }>
|
|
89
108
|
<Grid item xs={ 12 }>
|
|
90
109
|
<FormLabel size="tiny">{ keyLabel }</FormLabel>
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
size="tiny"
|
|
96
|
-
fullWidth
|
|
97
|
-
value={ sessionState.key }
|
|
98
|
-
onChange={ ( e: ChangeEvent< HTMLInputElement > ) => handleChange( e, 'key' ) }
|
|
99
|
-
error={ isKeyInvalid }
|
|
100
|
-
/>
|
|
101
|
-
{ isKeyInvalid && <FormHelperText error>{ keyError }</FormHelperText> }
|
|
110
|
+
<PropKeyProvider bind={ 'key' }>
|
|
111
|
+
<TextControl inputValue={ sessionState.key } error={ !! keyError } sx={ { pt: 1 } } />
|
|
112
|
+
</PropKeyProvider>
|
|
113
|
+
{ !! keyError && <FormHelperText error>{ keyError }</FormHelperText> }
|
|
102
114
|
</Grid>
|
|
103
115
|
<Grid item xs={ 12 }>
|
|
104
116
|
<FormLabel size="tiny">{ valueLabel }</FormLabel>
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{ isValueInvalid && <FormHelperText error>{ valueError }</FormHelperText> }
|
|
117
|
+
<PropKeyProvider bind={ 'value' }>
|
|
118
|
+
<TextControl
|
|
119
|
+
inputValue={ sessionState.value }
|
|
120
|
+
error={ !! valueError }
|
|
121
|
+
inputDisabled={ !! keyError }
|
|
122
|
+
sx={ { pt: 1 } }
|
|
123
|
+
/>
|
|
124
|
+
</PropKeyProvider>
|
|
125
|
+
{ !! valueError && <FormHelperText error>{ valueError }</FormHelperText> }
|
|
115
126
|
</Grid>
|
|
116
127
|
</Grid>
|
|
117
|
-
</
|
|
128
|
+
</PropProvider>
|
|
118
129
|
);
|
|
119
130
|
} );
|
|
@@ -3,7 +3,6 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { createArrayPropUtils, type PropKey } from '@elementor/editor-props';
|
|
4
4
|
import { Box } from '@elementor/ui';
|
|
5
5
|
|
|
6
|
-
/* eslint-disable */
|
|
7
6
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
8
7
|
import { PopoverContent } from '../components/popover-content';
|
|
9
8
|
import { PopoverGridContainer } from '../components/popover-grid-container';
|
|
@@ -26,6 +25,8 @@ type RepeatableControlProps = {
|
|
|
26
25
|
placeholder?: string;
|
|
27
26
|
};
|
|
28
27
|
|
|
28
|
+
const PLACEHOLDER_REGEX = /\$\{([^}]+)\}/g;
|
|
29
|
+
|
|
29
30
|
export const RepeatableControl = createControl(
|
|
30
31
|
( {
|
|
31
32
|
repeaterLabel,
|
|
@@ -48,17 +49,16 @@ export const RepeatableControl = createControl(
|
|
|
48
49
|
);
|
|
49
50
|
|
|
50
51
|
const contextValue = useMemo(
|
|
51
|
-
() => ({
|
|
52
|
+
() => ( {
|
|
52
53
|
...childControlConfig,
|
|
53
54
|
placeholder: placeholder || '',
|
|
54
55
|
patternLabel: patternLabel || '',
|
|
55
|
-
}),
|
|
56
|
+
} ),
|
|
56
57
|
[ childControlConfig, placeholder, patternLabel ]
|
|
57
58
|
);
|
|
58
59
|
|
|
59
60
|
const { propType, value, setValue } = useBoundProp( childArrayPropTypeUtil );
|
|
60
61
|
|
|
61
|
-
|
|
62
62
|
return (
|
|
63
63
|
<PropProvider propType={ propType } value={ value } setValue={ setValue }>
|
|
64
64
|
<RepeatableControlContext.Provider value={ contextValue }>
|
|
@@ -106,42 +106,63 @@ const Content = () => {
|
|
|
106
106
|
);
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
-
const interpolate = ( template: string, data:
|
|
109
|
+
const interpolate = ( template: string, data: Record< string, unknown > ) => {
|
|
110
110
|
if ( ! data ) {
|
|
111
111
|
return template;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
return
|
|
114
|
+
return template.replace( PLACEHOLDER_REGEX, ( _, path ): string => {
|
|
115
|
+
const value = getNestedValue( data, path );
|
|
116
|
+
|
|
117
|
+
if ( typeof value === 'object' && value !== null && ! Array.isArray( value ) ) {
|
|
118
|
+
if ( value.name ) {
|
|
119
|
+
return value.name as string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return JSON.stringify( value );
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if ( Array.isArray( value ) ) {
|
|
126
|
+
return value.join( ', ' );
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return String( value ?? '' );
|
|
130
|
+
} );
|
|
115
131
|
};
|
|
116
132
|
|
|
117
|
-
const getNestedValue = ( obj:
|
|
118
|
-
|
|
133
|
+
const getNestedValue = ( obj: Record< string, unknown >, path: string ) => {
|
|
134
|
+
return path.split( '.' ).reduce( ( current: Record< string, unknown >, key ) => {
|
|
135
|
+
if ( current && typeof current === 'object' ) {
|
|
136
|
+
return current[ key ] as Record< string, unknown >;
|
|
137
|
+
}
|
|
138
|
+
return {};
|
|
139
|
+
}, obj );
|
|
119
140
|
};
|
|
120
141
|
|
|
121
|
-
const isEmptyValue = (val: unknown) => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
142
|
+
const isEmptyValue = ( val: unknown ) => {
|
|
143
|
+
if ( typeof val === 'string' ) {
|
|
144
|
+
return val.trim() === '';
|
|
145
|
+
}
|
|
125
146
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
147
|
+
if ( Number.isNaN( val ) ) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
129
150
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
151
|
+
if ( Array.isArray( val ) ) {
|
|
152
|
+
return val.length === 0;
|
|
153
|
+
}
|
|
133
154
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
155
|
+
if ( typeof val === 'object' && val !== null ) {
|
|
156
|
+
return Object.keys( val ).length === 0;
|
|
157
|
+
}
|
|
137
158
|
|
|
138
|
-
|
|
159
|
+
return false;
|
|
139
160
|
};
|
|
140
161
|
|
|
141
|
-
const shouldShowPlaceholder = ( pattern: string, data: unknown ): boolean => {
|
|
162
|
+
const shouldShowPlaceholder = ( pattern: string, data: Record< string, unknown > ): boolean => {
|
|
142
163
|
const propertyPaths = getAllProperties( pattern );
|
|
143
164
|
|
|
144
|
-
const values = propertyPaths.map( path => getNestedValue( data, path ) );
|
|
165
|
+
const values = propertyPaths.map( ( path ) => getNestedValue( data, path ) );
|
|
145
166
|
|
|
146
167
|
if ( values.length === 0 ) {
|
|
147
168
|
return false;
|
|
@@ -158,7 +179,7 @@ const shouldShowPlaceholder = ( pattern: string, data: unknown ): boolean => {
|
|
|
158
179
|
return false;
|
|
159
180
|
};
|
|
160
181
|
|
|
161
|
-
const ItemLabel = ( { value }: { value:
|
|
182
|
+
const ItemLabel = ( { value }: { value: Record< string, unknown > } ) => {
|
|
162
183
|
const { placeholder, patternLabel } = useRepeatableControlContext();
|
|
163
184
|
|
|
164
185
|
const label = shouldShowPlaceholder( patternLabel, value ) ? placeholder : interpolate( patternLabel, value );
|
|
@@ -171,9 +192,7 @@ const ItemLabel = ( { value }: { value: any } ) => {
|
|
|
171
192
|
};
|
|
172
193
|
|
|
173
194
|
const getAllProperties = ( pattern: string ) => {
|
|
174
|
-
const properties = pattern.match(
|
|
175
|
-
match.slice(2, -1)
|
|
176
|
-
) || [];
|
|
195
|
+
const properties = pattern.match( PLACEHOLDER_REGEX )?.map( ( match ) => match.slice( 2, -1 ) ) || [];
|
|
177
196
|
|
|
178
197
|
return properties;
|
|
179
|
-
};
|
|
198
|
+
};
|
|
@@ -10,7 +10,13 @@ import { TextFieldPopover } from '../components/text-field-popover';
|
|
|
10
10
|
import { createControl } from '../create-control';
|
|
11
11
|
import { useSizeExtendedOptions } from '../hooks/use-size-extended-options';
|
|
12
12
|
import { useSyncExternalState } from '../hooks/use-sync-external-state';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
defaultUnits,
|
|
15
|
+
type DegreeUnit,
|
|
16
|
+
type ExtendedOption,
|
|
17
|
+
isUnitExtendedOption,
|
|
18
|
+
type Unit,
|
|
19
|
+
} from '../utils/size-control';
|
|
14
20
|
|
|
15
21
|
const DEFAULT_UNIT = 'px';
|
|
16
22
|
const DEFAULT_SIZE = NaN;
|
|
@@ -20,17 +26,17 @@ type SizeValue = SizePropValue[ 'value' ];
|
|
|
20
26
|
type SizeControlProps = {
|
|
21
27
|
placeholder?: string;
|
|
22
28
|
startIcon?: React.ReactNode;
|
|
23
|
-
units?: Unit[];
|
|
29
|
+
units?: ( Unit | DegreeUnit )[];
|
|
24
30
|
extendedOptions?: ExtendedOption[];
|
|
25
31
|
disableCustom?: boolean;
|
|
26
32
|
anchorRef?: RefObject< HTMLDivElement | null >;
|
|
27
|
-
defaultUnit?: Unit;
|
|
33
|
+
defaultUnit?: Unit | DegreeUnit;
|
|
28
34
|
};
|
|
29
35
|
|
|
30
36
|
type State = {
|
|
31
37
|
numeric: number;
|
|
32
38
|
custom: string;
|
|
33
|
-
unit: Unit | ExtendedOption;
|
|
39
|
+
unit: Unit | DegreeUnit | ExtendedOption;
|
|
34
40
|
};
|
|
35
41
|
|
|
36
42
|
export const SizeControl = createControl( ( props: SizeControlProps ) => {
|
|
@@ -58,15 +64,15 @@ export const SizeControl = createControl( ( props: SizeControlProps ) => {
|
|
|
58
64
|
return !! newState?.numeric || newState?.numeric === 0;
|
|
59
65
|
},
|
|
60
66
|
fallback: ( newState ) => ( {
|
|
61
|
-
unit: newState?.unit ??
|
|
67
|
+
unit: newState?.unit ?? defaultUnit,
|
|
62
68
|
numeric: newState?.numeric ?? DEFAULT_SIZE,
|
|
63
69
|
custom: newState?.custom ?? '',
|
|
64
70
|
} ),
|
|
65
71
|
} );
|
|
66
72
|
|
|
67
|
-
const { size: controlSize = DEFAULT_SIZE, unit: controlUnit =
|
|
73
|
+
const { size: controlSize = DEFAULT_SIZE, unit: controlUnit = defaultUnit } = extractValueFromState( state ) || {};
|
|
68
74
|
|
|
69
|
-
const handleUnitChange = ( newUnit: Unit | ExtendedOption ) => {
|
|
75
|
+
const handleUnitChange = ( newUnit: Unit | DegreeUnit | ExtendedOption ) => {
|
|
70
76
|
if ( newUnit === 'custom' ) {
|
|
71
77
|
popupState.open( anchorRef?.current );
|
|
72
78
|
}
|
|
@@ -103,9 +109,13 @@ export const SizeControl = createControl( ( props: SizeControlProps ) => {
|
|
|
103
109
|
};
|
|
104
110
|
|
|
105
111
|
useEffect( () => {
|
|
106
|
-
const newState = createStateFromSizeProp( sizeValue, defaultUnit );
|
|
107
|
-
const
|
|
108
|
-
const mergedStates = {
|
|
112
|
+
const newState = createStateFromSizeProp( sizeValue, state.unit === 'custom' ? state.unit : defaultUnit );
|
|
113
|
+
const currentUnitType = isUnitExtendedOption( state.unit ) ? 'custom' : 'numeric';
|
|
114
|
+
const mergedStates = {
|
|
115
|
+
...state,
|
|
116
|
+
unit: newState.unit ?? state.unit,
|
|
117
|
+
[ currentUnitType ]: newState[ currentUnitType ],
|
|
118
|
+
};
|
|
109
119
|
|
|
110
120
|
if ( mergedStates.unit !== 'auto' && areStatesEqual( state, mergedStates ) ) {
|
|
111
121
|
return;
|
|
@@ -159,7 +169,7 @@ export const SizeControl = createControl( ( props: SizeControlProps ) => {
|
|
|
159
169
|
);
|
|
160
170
|
} );
|
|
161
171
|
|
|
162
|
-
function formatSize< TSize extends string | number >( size: TSize, unit: Unit | ExtendedOption ): TSize {
|
|
172
|
+
function formatSize< TSize extends string | number >( size: TSize, unit: Unit | DegreeUnit | ExtendedOption ): TSize {
|
|
163
173
|
if ( isUnitExtendedOption( unit ) ) {
|
|
164
174
|
return unit === 'auto' ? ( '' as TSize ) : ( String( size ?? '' ) as TSize );
|
|
165
175
|
}
|
|
@@ -167,7 +177,10 @@ function formatSize< TSize extends string | number >( size: TSize, unit: Unit |
|
|
|
167
177
|
return size || size === 0 ? ( Number( size ) as TSize ) : ( NaN as TSize );
|
|
168
178
|
}
|
|
169
179
|
|
|
170
|
-
function createStateFromSizeProp(
|
|
180
|
+
function createStateFromSizeProp(
|
|
181
|
+
sizeValue: SizeValue | null,
|
|
182
|
+
defaultUnit: Unit | DegreeUnit | ExtendedOption
|
|
183
|
+
): State {
|
|
171
184
|
const unit = sizeValue?.unit ?? defaultUnit;
|
|
172
185
|
const size = sizeValue?.size ?? '';
|
|
173
186
|
|
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { stringPropTypeUtil } from '@elementor/editor-props';
|
|
3
|
-
import { TextField } from '@elementor/ui';
|
|
3
|
+
import { type SxProps, TextField } from '@elementor/ui';
|
|
4
4
|
|
|
5
5
|
import { useBoundProp } from '../bound-prop-context';
|
|
6
6
|
import ControlActions from '../control-actions/control-actions';
|
|
7
7
|
import { createControl } from '../create-control';
|
|
8
8
|
|
|
9
|
-
export const TextControl = createControl(
|
|
10
|
-
|
|
9
|
+
export const TextControl = createControl(
|
|
10
|
+
( {
|
|
11
|
+
placeholder,
|
|
12
|
+
error,
|
|
13
|
+
inputValue,
|
|
14
|
+
inputDisabled,
|
|
15
|
+
sx,
|
|
16
|
+
}: {
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
error?: boolean;
|
|
19
|
+
inputValue?: string;
|
|
20
|
+
inputDisabled?: boolean;
|
|
21
|
+
sx?: SxProps;
|
|
22
|
+
} ) => {
|
|
23
|
+
const { value, setValue, disabled } = useBoundProp( stringPropTypeUtil );
|
|
24
|
+
const handleChange = ( event: React.ChangeEvent< HTMLInputElement > ) => setValue( event.target.value );
|
|
11
25
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
26
|
+
return (
|
|
27
|
+
<ControlActions>
|
|
28
|
+
<TextField
|
|
29
|
+
size="tiny"
|
|
30
|
+
fullWidth
|
|
31
|
+
disabled={ inputDisabled ?? disabled }
|
|
32
|
+
value={ inputValue ?? value ?? '' }
|
|
33
|
+
onChange={ handleChange }
|
|
34
|
+
placeholder={ placeholder }
|
|
35
|
+
error={ error }
|
|
36
|
+
sx={ sx }
|
|
37
|
+
/>
|
|
38
|
+
</ControlActions>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
);
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export const defaultUnits = [ 'px', '%', 'em', 'rem', 'vw', 'vh' ] as const;
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
|
+
const degreeUnits = [ 'deg', 'rad', 'grad', 'turn' ] as const;
|
|
2
4
|
const defaultExtendedOptions = [ 'auto', 'custom' ] as const;
|
|
3
5
|
|
|
4
6
|
export type Unit = ( typeof defaultUnits )[ number ];
|
|
5
|
-
|
|
7
|
+
export type DegreeUnit = ( typeof degreeUnits )[ number ];
|
|
6
8
|
export type ExtendedOption = ( typeof defaultExtendedOptions )[ number ];
|
|
7
9
|
|
|
8
|
-
export function isUnitExtendedOption( unit: Unit | ExtendedOption ): unit is ExtendedOption {
|
|
10
|
+
export function isUnitExtendedOption( unit: Unit | DegreeUnit | ExtendedOption ): unit is ExtendedOption {
|
|
9
11
|
return defaultExtendedOptions.includes( unit as ExtendedOption );
|
|
10
12
|
}
|