@elementor/editor-controls 4.0.0-498 → 4.0.0-499
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/dist/index.d.mts +28 -19
- package/dist/index.d.ts +28 -19
- package/dist/index.js +165 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/components/size/unit-select.tsx +69 -0
- package/src/components/size/unstable-size-field.tsx +63 -0
- package/src/components/size/unstable-size-input.tsx +46 -0
- package/src/hooks/use-size-value.ts +49 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-controls",
|
|
3
3
|
"description": "This package contains the controls model and utils for the Elementor editor",
|
|
4
|
-
"version": "4.0.0-
|
|
4
|
+
"version": "4.0.0-499",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,22 +40,22 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-current-user": "4.0.0-
|
|
44
|
-
"@elementor/editor-elements": "4.0.0-
|
|
45
|
-
"@elementor/editor-props": "4.0.0-
|
|
46
|
-
"@elementor/editor-responsive": "4.0.0-
|
|
47
|
-
"@elementor/editor-ui": "4.0.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "4.0.0-
|
|
49
|
-
"@elementor/env": "4.0.0-
|
|
50
|
-
"@elementor/http-client": "4.0.0-
|
|
43
|
+
"@elementor/editor-current-user": "4.0.0-499",
|
|
44
|
+
"@elementor/editor-elements": "4.0.0-499",
|
|
45
|
+
"@elementor/editor-props": "4.0.0-499",
|
|
46
|
+
"@elementor/editor-responsive": "4.0.0-499",
|
|
47
|
+
"@elementor/editor-ui": "4.0.0-499",
|
|
48
|
+
"@elementor/editor-v1-adapters": "4.0.0-499",
|
|
49
|
+
"@elementor/env": "4.0.0-499",
|
|
50
|
+
"@elementor/http-client": "4.0.0-499",
|
|
51
51
|
"@elementor/icons": "^1.63.0",
|
|
52
|
-
"@elementor/locations": "4.0.0-
|
|
53
|
-
"@elementor/mixpanel": "4.0.0-
|
|
54
|
-
"@elementor/query": "4.0.0-
|
|
55
|
-
"@elementor/session": "4.0.0-
|
|
52
|
+
"@elementor/locations": "4.0.0-499",
|
|
53
|
+
"@elementor/mixpanel": "4.0.0-499",
|
|
54
|
+
"@elementor/query": "4.0.0-499",
|
|
55
|
+
"@elementor/session": "4.0.0-499",
|
|
56
56
|
"@elementor/ui": "1.36.17",
|
|
57
|
-
"@elementor/utils": "4.0.0-
|
|
58
|
-
"@elementor/wp-media": "4.0.0-
|
|
57
|
+
"@elementor/utils": "4.0.0-499",
|
|
58
|
+
"@elementor/wp-media": "4.0.0-499",
|
|
59
59
|
"@wordpress/i18n": "^5.13.0",
|
|
60
60
|
"@monaco-editor/react": "^4.7.0",
|
|
61
61
|
"dayjs": "^1.11.18",
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useId } from 'react';
|
|
3
|
+
import { type SizePropValue } from '@elementor/editor-props';
|
|
4
|
+
import { MenuListItem } from '@elementor/editor-ui';
|
|
5
|
+
import { bindMenu, bindTrigger, Button, Menu, styled, usePopupState } from '@elementor/ui';
|
|
6
|
+
|
|
7
|
+
type Props< T = SizePropValue[ 'value' ][ 'unit' ] > = {
|
|
8
|
+
options: T[];
|
|
9
|
+
value: T;
|
|
10
|
+
onClick: ( value: T ) => void;
|
|
11
|
+
showPrimaryColor: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const menuItemContentStyles = {
|
|
15
|
+
display: 'flex',
|
|
16
|
+
flexDirection: 'column',
|
|
17
|
+
justifyContent: 'center',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const UnitSelect = ( { value, showPrimaryColor, onClick, options }: Props ) => {
|
|
21
|
+
const popupState = usePopupState( {
|
|
22
|
+
variant: 'popover',
|
|
23
|
+
popupId: useId(),
|
|
24
|
+
} );
|
|
25
|
+
|
|
26
|
+
const handleMenuItemClick = ( index: number ) => {
|
|
27
|
+
onClick( options[ index ] );
|
|
28
|
+
|
|
29
|
+
popupState.close();
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<>
|
|
34
|
+
<StyledButton isPrimaryColor={ showPrimaryColor } size="small" { ...bindTrigger( popupState ) }>
|
|
35
|
+
{ value }
|
|
36
|
+
</StyledButton>
|
|
37
|
+
|
|
38
|
+
<Menu MenuListProps={ { dense: true } } { ...bindMenu( popupState ) }>
|
|
39
|
+
{ options.map( ( option, index ) => (
|
|
40
|
+
<MenuListItem
|
|
41
|
+
key={ option }
|
|
42
|
+
onClick={ () => handleMenuItemClick( index ) }
|
|
43
|
+
primaryTypographyProps={ {
|
|
44
|
+
variant: 'caption',
|
|
45
|
+
sx: {
|
|
46
|
+
...menuItemContentStyles,
|
|
47
|
+
lineHeight: '1',
|
|
48
|
+
},
|
|
49
|
+
} }
|
|
50
|
+
menuItemTextProps={ {
|
|
51
|
+
sx: menuItemContentStyles,
|
|
52
|
+
} }
|
|
53
|
+
>
|
|
54
|
+
{ option.toUpperCase() }
|
|
55
|
+
</MenuListItem>
|
|
56
|
+
) ) }
|
|
57
|
+
</Menu>
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const StyledButton = styled( Button, {
|
|
63
|
+
shouldForwardProp: ( prop ) => prop !== 'isPrimaryColor',
|
|
64
|
+
} )( ( { isPrimaryColor, theme } ) => ( {
|
|
65
|
+
color: isPrimaryColor ? theme.palette.text.primary : theme.palette.text.tertiary,
|
|
66
|
+
font: 'inherit',
|
|
67
|
+
minWidth: 'initial',
|
|
68
|
+
textTransform: 'uppercase',
|
|
69
|
+
} ) );
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PropValue, SizePropValue } from '@elementor/editor-props';
|
|
3
|
+
import { InputAdornment } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
import { useSizeValue } from '../../hooks/use-size-value';
|
|
6
|
+
import { type Unit } from '../../utils/size-control';
|
|
7
|
+
import { UnitSelect } from './unit-select';
|
|
8
|
+
import { UnstableSizeInput } from './unstable-size-input';
|
|
9
|
+
|
|
10
|
+
type Props< TValue > = {
|
|
11
|
+
units: Unit[];
|
|
12
|
+
value: TValue;
|
|
13
|
+
defaultValue?: Partial< TValue >;
|
|
14
|
+
onChange: ( value: TValue ) => void;
|
|
15
|
+
onBlur?: ( event: React.FocusEvent< HTMLInputElement > ) => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const DEFAULT_VALUE: SizePropValue[ 'value' ] = {
|
|
19
|
+
unit: 'px',
|
|
20
|
+
size: 0,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const UnstableSizeField = < T extends SizePropValue[ 'value' ] >( {
|
|
24
|
+
value,
|
|
25
|
+
defaultValue,
|
|
26
|
+
onChange,
|
|
27
|
+
onBlur,
|
|
28
|
+
units,
|
|
29
|
+
}: Props< T > ) => {
|
|
30
|
+
const { size, unit, setSize, setUnit } = useSizeValue< T >( value, onChange, {
|
|
31
|
+
...DEFAULT_VALUE,
|
|
32
|
+
...defaultValue,
|
|
33
|
+
} as T );
|
|
34
|
+
|
|
35
|
+
const shouldHighlightUnit = () => {
|
|
36
|
+
return hasValue( size );
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<UnstableSizeInput
|
|
41
|
+
type="number"
|
|
42
|
+
value={ size ?? '' }
|
|
43
|
+
onBlur={ onBlur }
|
|
44
|
+
onChange={ ( event ) => setSize( event.target.value ) }
|
|
45
|
+
InputProps={ {
|
|
46
|
+
endAdornment: (
|
|
47
|
+
<InputAdornment position="end">
|
|
48
|
+
<UnitSelect
|
|
49
|
+
options={ units }
|
|
50
|
+
value={ unit }
|
|
51
|
+
onClick={ setUnit }
|
|
52
|
+
showPrimaryColor={ shouldHighlightUnit() }
|
|
53
|
+
/>
|
|
54
|
+
</InputAdornment>
|
|
55
|
+
),
|
|
56
|
+
} }
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const hasValue = ( value: PropValue ): boolean => {
|
|
62
|
+
return value !== null && value !== '';
|
|
63
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import type { PropValue } from '@elementor/editor-props';
|
|
4
|
+
import type { TextFieldProps } from '@elementor/ui';
|
|
5
|
+
|
|
6
|
+
import { NumberInput } from '../number-input';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
type: 'number' | 'text';
|
|
10
|
+
value: PropValue;
|
|
11
|
+
focused?: boolean;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
onChange: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
|
|
14
|
+
onKeyDown?: ( event: React.KeyboardEvent< HTMLInputElement > ) => void;
|
|
15
|
+
onKeyUp?: ( event: React.KeyboardEvent< HTMLInputElement > ) => void;
|
|
16
|
+
onBlur?: ( event: React.FocusEvent< HTMLInputElement > ) => void;
|
|
17
|
+
InputProps: TextFieldProps[ 'InputProps' ] & {
|
|
18
|
+
endAdornment: React.JSX.Element;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const UnstableSizeInput = forwardRef(
|
|
23
|
+
( { type, value, onChange, onKeyDown, onKeyUp, InputProps, onBlur, focused, disabled }: Props, ref ) => {
|
|
24
|
+
return (
|
|
25
|
+
<NumberInput
|
|
26
|
+
ref={ ref }
|
|
27
|
+
size="tiny"
|
|
28
|
+
fullWidth
|
|
29
|
+
type={ type }
|
|
30
|
+
value={ value }
|
|
31
|
+
onKeyUp={ onKeyUp }
|
|
32
|
+
focused={ focused }
|
|
33
|
+
disabled={ disabled }
|
|
34
|
+
onKeyDown={ onKeyDown }
|
|
35
|
+
onInput={ onChange }
|
|
36
|
+
onBlur={ onBlur }
|
|
37
|
+
InputProps={ InputProps }
|
|
38
|
+
sx={ getCursorStyle( InputProps?.readOnly ?? false ) }
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const getCursorStyle = ( readOnly: boolean ) => ( {
|
|
45
|
+
input: { cursor: readOnly ? 'default !important' : undefined },
|
|
46
|
+
} );
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type SizePropValue } from '@elementor/editor-props';
|
|
2
|
+
|
|
3
|
+
import { useSyncExternalState } from '../hooks/use-sync-external-state';
|
|
4
|
+
|
|
5
|
+
export const useSizeValue = < T extends SizePropValue[ 'value' ] >(
|
|
6
|
+
externalValue: T,
|
|
7
|
+
onChange: ( value: T ) => void,
|
|
8
|
+
defaultValue: T
|
|
9
|
+
) => {
|
|
10
|
+
const [ sizeValue, setSizeValue ] = useSyncExternalState< T >( {
|
|
11
|
+
external: externalValue,
|
|
12
|
+
setExternal: ( newState ) => {
|
|
13
|
+
if ( newState !== null ) {
|
|
14
|
+
onChange( newState as T );
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
persistWhen: ( newState ) => differsFromExternal( newState as T, externalValue ),
|
|
18
|
+
fallback: () => defaultValue,
|
|
19
|
+
} );
|
|
20
|
+
|
|
21
|
+
const setSize = ( value: string ) => {
|
|
22
|
+
const newState = {
|
|
23
|
+
...sizeValue,
|
|
24
|
+
size: value.trim() === '' ? null : Number( value ),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
setSizeValue( newState );
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const setUnit = ( unit: SizePropValue[ 'value' ][ 'unit' ] ) => {
|
|
31
|
+
const newState = {
|
|
32
|
+
...sizeValue,
|
|
33
|
+
unit,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
setSizeValue( newState );
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
size: sizeValue.size,
|
|
41
|
+
unit: sizeValue.unit,
|
|
42
|
+
setSize,
|
|
43
|
+
setUnit,
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const differsFromExternal = ( newState: SizePropValue[ 'value' ], externalState: SizePropValue[ 'value' ] ) => {
|
|
48
|
+
return newState.size !== externalState.size || newState.unit !== externalState.unit;
|
|
49
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -51,6 +51,7 @@ export { FloatingActionsBar } from './components/floating-bar';
|
|
|
51
51
|
export { PopoverGridContainer } from './components/popover-grid-container';
|
|
52
52
|
export { InlineEditor } from './components/inline-editor';
|
|
53
53
|
export { InlineEditorToolbar } from './components/inline-editor-toolbar';
|
|
54
|
+
export { UnstableSizeField } from './components/size/unstable-size-field';
|
|
54
55
|
|
|
55
56
|
// types
|
|
56
57
|
export type { ControlComponent } from './create-control';
|