@elementor/editor-controls 4.0.0-633 → 4.0.0-635

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/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-633",
4
+ "version": "4.0.0-635",
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-633",
44
- "@elementor/editor-elements": "4.0.0-633",
45
- "@elementor/editor-props": "4.0.0-633",
46
- "@elementor/editor-responsive": "4.0.0-633",
47
- "@elementor/editor-ui": "4.0.0-633",
48
- "@elementor/editor-v1-adapters": "4.0.0-633",
49
- "@elementor/env": "4.0.0-633",
50
- "@elementor/http-client": "4.0.0-633",
43
+ "@elementor/editor-current-user": "4.0.0-635",
44
+ "@elementor/editor-elements": "4.0.0-635",
45
+ "@elementor/editor-props": "4.0.0-635",
46
+ "@elementor/editor-responsive": "4.0.0-635",
47
+ "@elementor/editor-ui": "4.0.0-635",
48
+ "@elementor/editor-v1-adapters": "4.0.0-635",
49
+ "@elementor/env": "4.0.0-635",
50
+ "@elementor/http-client": "4.0.0-635",
51
51
  "@elementor/icons": "^1.68.0",
52
- "@elementor/locations": "4.0.0-633",
53
- "@elementor/events": "4.0.0-633",
54
- "@elementor/query": "4.0.0-633",
55
- "@elementor/session": "4.0.0-633",
52
+ "@elementor/locations": "4.0.0-635",
53
+ "@elementor/events": "4.0.0-635",
54
+ "@elementor/query": "4.0.0-635",
55
+ "@elementor/session": "4.0.0-635",
56
56
  "@elementor/ui": "1.36.17",
57
- "@elementor/utils": "4.0.0-633",
58
- "@elementor/wp-media": "4.0.0-633",
57
+ "@elementor/utils": "4.0.0-635",
58
+ "@elementor/wp-media": "4.0.0-635",
59
59
  "@wordpress/i18n": "^5.13.0",
60
60
  "@monaco-editor/react": "^4.7.0",
61
61
  "dayjs": "^1.11.18",
@@ -0,0 +1,68 @@
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 '../../../components/number-input';
7
+
8
+ type Props = {
9
+ type: 'number' | 'text';
10
+ value: PropValue;
11
+ placeholder?: string;
12
+ focused?: boolean;
13
+ disabled?: boolean;
14
+ id?: string;
15
+ onChange: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
16
+ onKeyDown?: ( event: React.KeyboardEvent< HTMLInputElement > ) => void;
17
+ onKeyUp?: ( event: React.KeyboardEvent< HTMLInputElement > ) => void;
18
+ onBlur?: ( event: React.FocusEvent< HTMLInputElement > ) => void;
19
+ InputProps: TextFieldProps[ 'InputProps' ] & {
20
+ endAdornment: React.JSX.Element;
21
+ };
22
+ inputProps?: TextFieldProps[ 'inputProps' ];
23
+ };
24
+
25
+ export const SizeInput = forwardRef(
26
+ (
27
+ {
28
+ id,
29
+ type,
30
+ value,
31
+ onBlur,
32
+ onKeyUp,
33
+ focused,
34
+ disabled,
35
+ onChange,
36
+ onKeyDown,
37
+ InputProps,
38
+ inputProps,
39
+ placeholder,
40
+ }: Props,
41
+ ref
42
+ ) => {
43
+ return (
44
+ <NumberInput
45
+ id={ id }
46
+ ref={ ref }
47
+ size="tiny"
48
+ fullWidth
49
+ type={ type }
50
+ value={ value }
51
+ placeholder={ placeholder }
52
+ onKeyUp={ onKeyUp }
53
+ focused={ focused }
54
+ disabled={ disabled }
55
+ onKeyDown={ onKeyDown }
56
+ onInput={ onChange }
57
+ onBlur={ onBlur }
58
+ InputProps={ InputProps }
59
+ inputProps={ inputProps }
60
+ sx={ getCursorStyle( InputProps?.readOnly ?? false ) }
61
+ />
62
+ );
63
+ }
64
+ );
65
+
66
+ const getCursorStyle = ( readOnly: boolean ) => ( {
67
+ input: { cursor: readOnly ? 'default !important' : undefined },
68
+ } );
@@ -0,0 +1,78 @@
1
+ import * as React from 'react';
2
+ import { type RefObject, useEffect, useRef } from 'react';
3
+ import { PopoverHeader } from '@elementor/editor-ui';
4
+ import { MathFunctionIcon } from '@elementor/icons';
5
+ import { bindPopover, Popover, type PopupState, TextField } from '@elementor/ui';
6
+ import { __ } from '@wordpress/i18n';
7
+
8
+ type Props = {
9
+ popupState: PopupState;
10
+ anchorRef: RefObject< HTMLDivElement | null >;
11
+ onClose?: () => void;
12
+ value: string;
13
+ onChange: ( event: React.ChangeEvent< HTMLInputElement > ) => void;
14
+ };
15
+
16
+ const SIZE = 'tiny';
17
+
18
+ export const TextFieldPopover = ( { popupState, anchorRef, value, onChange, onClose }: Props ) => {
19
+ const inputRef = useRef< HTMLInputElement >( null );
20
+
21
+ useEffect( () => {
22
+ if ( popupState.isOpen ) {
23
+ requestAnimationFrame( () => {
24
+ if ( inputRef.current ) {
25
+ inputRef.current.focus();
26
+ }
27
+ } );
28
+ }
29
+ }, [ popupState.isOpen ] );
30
+
31
+ const handleKeyDown = ( event: React.KeyboardEvent< HTMLInputElement > ) => {
32
+ if ( event.key.toLowerCase() === 'enter' ) {
33
+ handleClose();
34
+ }
35
+ };
36
+
37
+ const handleClose = () => {
38
+ onClose?.();
39
+
40
+ popupState.close();
41
+ };
42
+
43
+ return (
44
+ <Popover
45
+ disablePortal
46
+ slotProps={ {
47
+ paper: {
48
+ sx: {
49
+ borderRadius: 2,
50
+ width: anchorRef.current?.offsetWidth + 'px',
51
+ },
52
+ },
53
+ } }
54
+ { ...bindPopover( popupState ) }
55
+ anchorOrigin={ { vertical: 'bottom', horizontal: 'center' } }
56
+ transformOrigin={ { vertical: 'top', horizontal: 'center' } }
57
+ onClose={ handleClose }
58
+ >
59
+ <PopoverHeader
60
+ title={ __( 'CSS function', 'elementor' ) }
61
+ onClose={ handleClose }
62
+ icon={ <MathFunctionIcon fontSize={ SIZE } /> }
63
+ />
64
+ <TextField
65
+ value={ value }
66
+ onChange={ onChange }
67
+ onKeyDown={ handleKeyDown }
68
+ size="tiny"
69
+ type="text"
70
+ fullWidth
71
+ inputProps={ {
72
+ ref: inputRef,
73
+ } }
74
+ sx={ { pt: 0, pr: 1.5, pb: 1.5, pl: 1.5 } }
75
+ />
76
+ </Popover>
77
+ );
78
+ };
@@ -0,0 +1,80 @@
1
+ import * as React from 'react';
2
+ import { useId } from 'react';
3
+ import { MenuListItem } from '@elementor/editor-ui';
4
+ import { bindMenu, bindTrigger, Button, Menu, styled, usePopupState } from '@elementor/ui';
5
+
6
+ export type UnitSelectorProps< T extends string > = {
7
+ options: T[];
8
+ value: T;
9
+ onSelect: ( value: T ) => void;
10
+ isActive: boolean;
11
+ menuItemsAttributes?: { [ key in T ]?: Record< string, unknown > };
12
+ optionLabelOverrides?: { [ key in T ]?: React.ReactNode };
13
+ disabled?: boolean;
14
+ };
15
+
16
+ const menuItemContentStyles = {
17
+ display: 'flex',
18
+ flexDirection: 'column',
19
+ justifyContent: 'center',
20
+ };
21
+
22
+ export const UnitSelector = < T extends string >( {
23
+ value,
24
+ isActive,
25
+ onSelect,
26
+ options,
27
+ disabled,
28
+ menuItemsAttributes = {},
29
+ optionLabelOverrides = {},
30
+ }: UnitSelectorProps< T > ) => {
31
+ const popupState = usePopupState( {
32
+ variant: 'popover',
33
+ popupId: useId(),
34
+ } );
35
+
36
+ const handleMenuItemClick = ( option: T ) => {
37
+ onSelect( option );
38
+
39
+ popupState.close();
40
+ };
41
+
42
+ return (
43
+ <>
44
+ <StyledButton isActive={ isActive } disabled={ disabled } size="small" { ...bindTrigger( popupState ) }>
45
+ { optionLabelOverrides[ value ] ?? value }
46
+ </StyledButton>
47
+
48
+ <Menu MenuListProps={ { dense: true } } { ...bindMenu( popupState ) }>
49
+ { options.map( ( option ) => (
50
+ <MenuListItem
51
+ key={ option }
52
+ onClick={ () => handleMenuItemClick( option ) }
53
+ { ...menuItemsAttributes?.[ option ] }
54
+ primaryTypographyProps={ {
55
+ variant: 'caption',
56
+ sx: {
57
+ ...menuItemContentStyles,
58
+ lineHeight: '1',
59
+ },
60
+ } }
61
+ menuItemTextProps={ {
62
+ sx: menuItemContentStyles,
63
+ } }
64
+ >
65
+ { optionLabelOverrides[ option ] ?? option.toUpperCase() }
66
+ </MenuListItem>
67
+ ) ) }
68
+ </Menu>
69
+ </>
70
+ );
71
+ };
72
+
73
+ const StyledButton = styled( Button, {
74
+ shouldForwardProp: ( prop ) => prop !== 'isActive',
75
+ } )( ( { isActive, theme } ) => ( {
76
+ color: isActive ? theme.palette.text.primary : theme.palette.text.tertiary,
77
+ font: 'inherit',
78
+ minWidth: 'initial',
79
+ textTransform: 'uppercase',
80
+ } ) );