@elementor/editor-controls 3.33.0-99 → 3.34.3
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 +264 -74
- package/dist/index.d.ts +264 -74
- package/dist/index.js +2541 -1861
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2344 -1660
- package/dist/index.mjs.map +1 -1
- package/package.json +31 -17
- package/src/bound-prop-context/prop-context.tsx +8 -1
- package/src/bound-prop-context/use-bound-prop.ts +19 -5
- package/src/components/autocomplete.tsx +34 -3
- package/src/components/conditional-control-infotip.tsx +64 -0
- package/src/components/{unstable-repeater → control-repeater}/actions/disable-item-action.tsx +2 -2
- package/src/components/{unstable-repeater → control-repeater}/actions/duplicate-item-action.tsx +10 -4
- package/src/components/{unstable-repeater → control-repeater}/actions/remove-item-action.tsx +2 -2
- package/src/components/control-repeater/context/item-context.tsx +8 -0
- package/src/components/{unstable-repeater → control-repeater}/context/repeater-context.tsx +24 -15
- package/src/components/control-repeater/control-repeater.tsx +29 -0
- package/src/components/{unstable-repeater → control-repeater}/index.ts +1 -2
- package/src/components/{unstable-repeater → control-repeater}/items/edit-item-popover.tsx +6 -20
- package/src/components/control-repeater/items/item.tsx +75 -0
- package/src/components/{unstable-repeater → control-repeater}/items/items-container.tsx +8 -13
- package/src/components/{unstable-repeater → control-repeater}/locations.ts +0 -4
- package/src/components/{unstable-repeater → control-repeater}/types.ts +1 -2
- package/src/components/control-toggle-button-group.tsx +79 -69
- package/src/components/enable-unfiltered-modal.tsx +1 -26
- package/src/components/icon-buttons/clear-icon-button.tsx +23 -0
- package/src/components/inline-editor-toolbar.tsx +137 -0
- package/src/components/inline-editor.tsx +111 -0
- package/src/components/item-selector.tsx +10 -4
- package/src/components/{unstable-repeater/header/header.tsx → repeater/repeater-header.tsx} +4 -12
- package/src/components/repeater/repeater-popover.tsx +19 -0
- package/src/components/repeater/repeater-tag.tsx +16 -0
- package/src/components/repeater/repeater.tsx +405 -0
- package/src/components/{sortable.tsx → repeater/sortable.tsx} +1 -1
- package/src/components/size-control/size-input.tsx +20 -14
- package/src/components/size-control/text-field-inner-selection.tsx +15 -2
- package/src/control-adornments/control-adornments-context.tsx +5 -4
- package/src/control-replacements.tsx +3 -43
- package/src/controls/background-control/background-control.tsx +43 -12
- package/src/controls/background-control/background-gradient-color-control.tsx +5 -8
- package/src/controls/background-control/background-overlay/background-image-overlay/background-image-overlay-position.tsx +18 -13
- package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +25 -16
- package/src/controls/box-shadow-repeater-control.tsx +38 -21
- package/src/controls/color-control.tsx +3 -1
- package/src/controls/date-time-control.tsx +108 -0
- package/src/controls/filter-control/drop-shadow/drop-shadow-item-content.tsx +1 -0
- package/src/controls/filter-control/drop-shadow/drop-shadow-item-label.tsx +10 -6
- package/src/controls/filter-control/filter-content.tsx +1 -1
- package/src/controls/filter-control/filter-repeater-control.tsx +24 -21
- package/src/controls/filter-control/single-size/single-size-item-content.tsx +1 -1
- package/src/controls/filter-control/single-size/single-size-item-label.tsx +2 -1
- package/src/controls/font-family-control/font-family-control.tsx +66 -55
- package/src/controls/html-tag-control.tsx +90 -0
- package/src/controls/image-media-control.tsx +2 -2
- package/src/controls/inline-editing-control.tsx +18 -0
- package/src/controls/key-value-control.tsx +8 -2
- package/src/controls/link-control.tsx +23 -123
- package/src/controls/linked-dimensions-control.tsx +71 -33
- package/src/controls/query-control.tsx +168 -0
- package/src/controls/repeatable-control.tsx +62 -27
- package/src/controls/select-control-wrapper.tsx +57 -0
- package/src/controls/select-control.tsx +9 -5
- package/src/controls/selection-size-control.tsx +13 -2
- package/src/controls/size-control.tsx +32 -59
- package/src/controls/svg-media-control.tsx +33 -10
- package/src/controls/text-area-control.tsx +5 -1
- package/src/controls/text-control.tsx +5 -0
- package/src/controls/toggle-control.tsx +11 -2
- package/src/controls/transform-control/functions/axis-row.tsx +1 -0
- package/src/controls/transform-control/transform-icon.tsx +2 -2
- package/src/controls/transform-control/transform-label.tsx +15 -32
- package/src/controls/transform-control/transform-repeater-control.tsx +42 -36
- package/src/controls/transform-control/{transform-base-control.tsx → transform-settings-control.tsx} +2 -2
- package/src/controls/transform-control/use-transform-tabs-history.tsx +1 -1
- package/src/controls/transition-control/data.ts +16 -1
- package/src/controls/transition-control/trainsition-events.ts +2 -2
- package/src/controls/transition-control/transition-repeater-control.tsx +137 -13
- package/src/controls/transition-control/transition-selector.tsx +37 -14
- package/src/controls/url-control.tsx +21 -16
- package/src/hooks/use-filtered-items-list.ts +3 -2
- package/src/hooks/use-repeatable-control-context.ts +3 -0
- package/src/hooks/use-sync-external-state.tsx +0 -1
- package/src/index.ts +21 -5
- package/src/utils/convert-toggle-options-to-atomic.tsx +33 -0
- package/src/utils/escape-html-attr.ts +11 -0
- package/src/components/css-code-editor/css-editor.styles.ts +0 -52
- package/src/components/css-code-editor/css-editor.tsx +0 -142
- package/src/components/css-code-editor/css-validation.ts +0 -75
- package/src/components/css-code-editor/resize-handle.tsx +0 -55
- package/src/components/css-code-editor/visual-content-change-protection.ts +0 -69
- package/src/components/repeater.tsx +0 -343
- package/src/components/unstable-repeater/items/item.tsx +0 -77
- package/src/components/unstable-repeater/unstable-repeater.tsx +0 -26
- /package/src/components/{unstable-repeater → control-repeater}/actions/tooltip-add-item-action.tsx +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
+
import { useCurrentUserCapabilities } from '@elementor/editor-current-user';
|
|
3
4
|
import { imageSrcPropTypeUtil } from '@elementor/editor-props';
|
|
4
5
|
import { UploadIcon } from '@elementor/icons';
|
|
5
|
-
import { Button, Card, CardMedia, CardOverlay, CircularProgress, Stack, styled } from '@elementor/ui';
|
|
6
|
+
import { Button, Card, CardMedia, CardOverlay, CircularProgress, Stack, styled, ThemeProvider } from '@elementor/ui';
|
|
6
7
|
import { type OpenOptions, useWpMediaAttachment, useWpMediaFrame } from '@elementor/wp-media';
|
|
7
8
|
import { __ } from '@wordpress/i18n';
|
|
8
9
|
|
|
9
10
|
import { useBoundProp } from '../bound-prop-context';
|
|
11
|
+
import { ConditionalControlInfotip } from '../components/conditional-control-infotip';
|
|
10
12
|
import { EnableUnfilteredModal } from '../components/enable-unfiltered-modal';
|
|
11
13
|
import ControlActions from '../control-actions/control-actions';
|
|
12
14
|
import { createControl } from '../create-control';
|
|
@@ -47,6 +49,8 @@ export const SvgMediaControl = createControl( () => {
|
|
|
47
49
|
const src = attachment?.url ?? url?.value ?? null;
|
|
48
50
|
const { data: allowSvgUpload } = useUnfilteredFilesUpload();
|
|
49
51
|
const [ unfilteredModalOpenState, setUnfilteredModalOpenState ] = useState( false );
|
|
52
|
+
const { canUser } = useCurrentUserCapabilities();
|
|
53
|
+
const canManageOptions = canUser( 'manage_options' );
|
|
50
54
|
|
|
51
55
|
const { open } = useWpMediaFrame( {
|
|
52
56
|
mediaTypes: [ 'svg' ],
|
|
@@ -79,6 +83,18 @@ export const SvgMediaControl = createControl( () => {
|
|
|
79
83
|
}
|
|
80
84
|
};
|
|
81
85
|
|
|
86
|
+
const infotipProps = {
|
|
87
|
+
title: __( "Sorry, you can't upload that file yet.", 'elementor' ),
|
|
88
|
+
description: (
|
|
89
|
+
<>
|
|
90
|
+
{ __( 'To upload them anyway, ask the site administrator to enable unfiltered', 'elementor' ) }
|
|
91
|
+
<br />
|
|
92
|
+
{ __( 'file uploads.', 'elementor' ) }
|
|
93
|
+
</>
|
|
94
|
+
),
|
|
95
|
+
isEnabled: ! canManageOptions,
|
|
96
|
+
};
|
|
97
|
+
|
|
82
98
|
return (
|
|
83
99
|
<Stack gap={ 1 }>
|
|
84
100
|
<EnableUnfilteredModal open={ unfilteredModalOpenState } onClose={ onCloseUnfilteredModal } />
|
|
@@ -112,15 +128,22 @@ export const SvgMediaControl = createControl( () => {
|
|
|
112
128
|
>
|
|
113
129
|
{ __( 'Select SVG', 'elementor' ) }
|
|
114
130
|
</Button>
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
<ConditionalControlInfotip { ...infotipProps }>
|
|
132
|
+
<span>
|
|
133
|
+
<ThemeProvider colorScheme={ canManageOptions ? 'light' : 'dark' }>
|
|
134
|
+
<Button
|
|
135
|
+
size="tiny"
|
|
136
|
+
variant="text"
|
|
137
|
+
color="inherit"
|
|
138
|
+
startIcon={ <UploadIcon /> }
|
|
139
|
+
disabled={ canManageOptions ? false : true }
|
|
140
|
+
onClick={ () => canManageOptions && handleClick( MODE_UPLOAD ) }
|
|
141
|
+
>
|
|
142
|
+
{ __( 'Upload', 'elementor' ) }
|
|
143
|
+
</Button>
|
|
144
|
+
</ThemeProvider>
|
|
145
|
+
</span>
|
|
146
|
+
</ConditionalControlInfotip>
|
|
124
147
|
</Stack>
|
|
125
148
|
</CardOverlay>
|
|
126
149
|
</StyledCard>
|
|
@@ -8,9 +8,10 @@ import { createControl } from '../create-control';
|
|
|
8
8
|
|
|
9
9
|
type Props = {
|
|
10
10
|
placeholder?: string;
|
|
11
|
+
ariaLabel?: string;
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
export const TextAreaControl = createControl( ( { placeholder }: Props ) => {
|
|
14
|
+
export const TextAreaControl = createControl( ( { placeholder, ariaLabel }: Props ) => {
|
|
14
15
|
const { value, setValue, disabled } = useBoundProp( stringPropTypeUtil );
|
|
15
16
|
|
|
16
17
|
const handleChange = ( event: React.ChangeEvent< HTMLInputElement > ) => {
|
|
@@ -28,6 +29,9 @@ export const TextAreaControl = createControl( ( { placeholder }: Props ) => {
|
|
|
28
29
|
value={ value ?? '' }
|
|
29
30
|
onChange={ handleChange }
|
|
30
31
|
placeholder={ placeholder }
|
|
32
|
+
inputProps={ {
|
|
33
|
+
...( ariaLabel ? { 'aria-label': ariaLabel } : {} ),
|
|
34
|
+
} }
|
|
31
35
|
/>
|
|
32
36
|
</ControlActions>
|
|
33
37
|
);
|
|
@@ -14,6 +14,7 @@ export const TextControl = createControl(
|
|
|
14
14
|
inputDisabled,
|
|
15
15
|
helperText,
|
|
16
16
|
sx,
|
|
17
|
+
ariaLabel,
|
|
17
18
|
}: {
|
|
18
19
|
placeholder?: string;
|
|
19
20
|
error?: boolean;
|
|
@@ -21,6 +22,7 @@ export const TextControl = createControl(
|
|
|
21
22
|
inputDisabled?: boolean;
|
|
22
23
|
helperText?: string;
|
|
23
24
|
sx?: SxProps;
|
|
25
|
+
ariaLabel?: string;
|
|
24
26
|
} ) => {
|
|
25
27
|
const { value, setValue, disabled } = useBoundProp( stringPropTypeUtil );
|
|
26
28
|
const handleChange = ( event: React.ChangeEvent< HTMLInputElement > ) => setValue( event.target.value );
|
|
@@ -37,6 +39,9 @@ export const TextControl = createControl(
|
|
|
37
39
|
error={ error }
|
|
38
40
|
helperText={ helperText }
|
|
39
41
|
sx={ sx }
|
|
42
|
+
inputProps={ {
|
|
43
|
+
...( ariaLabel ? { 'aria-label': ariaLabel } : {} ),
|
|
44
|
+
} }
|
|
40
45
|
/>
|
|
41
46
|
</ControlActions>
|
|
42
47
|
);
|
|
@@ -5,6 +5,7 @@ import { type ToggleButtonProps } from '@elementor/ui';
|
|
|
5
5
|
import { useBoundProp } from '../bound-prop-context';
|
|
6
6
|
import { ControlToggleButtonGroup, type ToggleButtonGroupItem } from '../components/control-toggle-button-group';
|
|
7
7
|
import { createControl } from '../create-control';
|
|
8
|
+
import { convertToggleOptionsToAtomic, type DynamicToggleOption } from '../utils/convert-toggle-options-to-atomic';
|
|
8
9
|
|
|
9
10
|
export type ToggleControlProps< T extends PropValue > = {
|
|
10
11
|
options: Array< ToggleButtonGroupItem< T > & { exclusive?: boolean } >;
|
|
@@ -12,6 +13,7 @@ export type ToggleControlProps< T extends PropValue > = {
|
|
|
12
13
|
size?: ToggleButtonProps[ 'size' ];
|
|
13
14
|
exclusive?: boolean;
|
|
14
15
|
maxItems?: number;
|
|
16
|
+
convertOptions?: boolean;
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
export const ToggleControl = createControl(
|
|
@@ -21,10 +23,17 @@ export const ToggleControl = createControl(
|
|
|
21
23
|
size = 'tiny',
|
|
22
24
|
exclusive = true,
|
|
23
25
|
maxItems,
|
|
26
|
+
convertOptions = false,
|
|
24
27
|
}: ToggleControlProps< StringPropValue[ 'value' ] > ) => {
|
|
25
28
|
const { value, setValue, placeholder, disabled } = useBoundProp( stringPropTypeUtil );
|
|
26
29
|
|
|
27
|
-
const
|
|
30
|
+
const processedOptions = convertOptions
|
|
31
|
+
? convertToggleOptionsToAtomic( options as DynamicToggleOption[] )
|
|
32
|
+
: ( options as Array< ToggleButtonGroupItem< StringPropValue[ 'value' ] > & { exclusive?: boolean } > );
|
|
33
|
+
|
|
34
|
+
const exclusiveValues = processedOptions
|
|
35
|
+
.filter( ( option ) => option.exclusive )
|
|
36
|
+
.map( ( option ) => option.value );
|
|
28
37
|
|
|
29
38
|
const handleNonExclusiveToggle = ( selectedValues: StringPropValue[ 'value' ][] ) => {
|
|
30
39
|
const newSelectedValue = selectedValues[ selectedValues.length - 1 ];
|
|
@@ -38,7 +47,7 @@ export const ToggleControl = createControl(
|
|
|
38
47
|
};
|
|
39
48
|
|
|
40
49
|
const toggleButtonGroupProps = {
|
|
41
|
-
items:
|
|
50
|
+
items: processedOptions,
|
|
42
51
|
maxItems,
|
|
43
52
|
fullWidth,
|
|
44
53
|
size,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type TransformFunctionsItemPropValue } from '@elementor/editor-props';
|
|
3
|
-
import {
|
|
3
|
+
import { ArrowAutofitHeightIcon, ArrowsMaximizeIcon, RotateClockwise2Icon, SkewXIcon } from '@elementor/icons';
|
|
4
4
|
|
|
5
5
|
import { TransformFunctionKeys } from './initial-values';
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ export const TransformIcon = ( { value }: { value: TransformFunctionsItemPropVal
|
|
|
9
9
|
case TransformFunctionKeys.move:
|
|
10
10
|
return <ArrowsMaximizeIcon fontSize="tiny" />;
|
|
11
11
|
case TransformFunctionKeys.scale:
|
|
12
|
-
return <
|
|
12
|
+
return <ArrowAutofitHeightIcon fontSize="tiny" />;
|
|
13
13
|
case TransformFunctionKeys.rotate:
|
|
14
14
|
return <RotateClockwise2Icon fontSize="tiny" />;
|
|
15
15
|
case TransformFunctionKeys.skew:
|
|
@@ -3,53 +3,36 @@ import type { TransformFunctionsItemPropValue } from '@elementor/editor-props';
|
|
|
3
3
|
import { Box } from '@elementor/ui';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
|
+
import { CUSTOM_SIZE_LABEL } from '../size-control';
|
|
6
7
|
import { defaultValues, TransformFunctionKeys } from './initial-values';
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
-
Object.values( value )
|
|
9
|
+
const formatLabel = ( value: TransformFunctionsItemPropValue[ 'value' ], functionType: keyof typeof defaultValues ) => {
|
|
10
|
+
return Object.values( value )
|
|
10
11
|
.map( ( axis ) => {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
if ( functionType === 'scale' ) {
|
|
13
|
+
return axis?.value || defaultValues[ functionType ];
|
|
14
|
+
}
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const transformScaleValue = ( value: TransformFunctionsItemPropValue[ 'value' ] ) =>
|
|
19
|
-
Object.values( value )
|
|
20
|
-
.map( ( axis ) => axis?.value || defaultValues.scale )
|
|
21
|
-
.join( ', ' );
|
|
22
|
-
|
|
23
|
-
const transformRotateValue = ( value: TransformFunctionsItemPropValue[ 'value' ] ) =>
|
|
24
|
-
Object.values( value )
|
|
25
|
-
.map( ( axis ) => {
|
|
26
|
-
const size = axis?.value?.size ?? defaultValues.rotate.size;
|
|
27
|
-
const unit = axis?.value?.unit ?? defaultValues.rotate.unit;
|
|
16
|
+
const defaults = defaultValues[ functionType ];
|
|
17
|
+
const size = axis?.value?.size ?? defaults.size;
|
|
18
|
+
const unit = axis?.value?.unit ?? defaults.unit;
|
|
28
19
|
|
|
29
|
-
return `${ size }${ unit }`;
|
|
30
|
-
} )
|
|
31
|
-
.join( ', ' );
|
|
32
|
-
const transformSkewValue = ( value: TransformFunctionsItemPropValue[ 'value' ] ) =>
|
|
33
|
-
Object.values( value )
|
|
34
|
-
.map( ( axis ) => {
|
|
35
|
-
const size = axis?.value?.size ?? defaultValues.skew.size;
|
|
36
|
-
const unit = axis?.value?.unit ?? defaultValues.skew.unit;
|
|
37
|
-
|
|
38
|
-
return `${ size }${ unit }`;
|
|
20
|
+
return unit === 'custom' ? size || CUSTOM_SIZE_LABEL : `${ size }${ unit }`;
|
|
39
21
|
} )
|
|
40
22
|
.join( ', ' );
|
|
23
|
+
};
|
|
41
24
|
|
|
42
25
|
export const TransformLabel = ( props: { value: TransformFunctionsItemPropValue } ) => {
|
|
43
26
|
const { $$type, value } = props.value;
|
|
44
27
|
switch ( $$type ) {
|
|
45
28
|
case TransformFunctionKeys.move:
|
|
46
|
-
return <Label label={ __( 'Move', 'elementor' ) } value={
|
|
29
|
+
return <Label label={ __( 'Move', 'elementor' ) } value={ formatLabel( value, 'move' ) } />;
|
|
47
30
|
case TransformFunctionKeys.scale:
|
|
48
|
-
return <Label label={ __( 'Scale', 'elementor' ) } value={
|
|
31
|
+
return <Label label={ __( 'Scale', 'elementor' ) } value={ formatLabel( value, 'scale' ) } />;
|
|
49
32
|
case TransformFunctionKeys.rotate:
|
|
50
|
-
return <Label label={ __( 'Rotate', 'elementor' ) } value={
|
|
33
|
+
return <Label label={ __( 'Rotate', 'elementor' ) } value={ formatLabel( value, 'rotate' ) } />;
|
|
51
34
|
case TransformFunctionKeys.skew:
|
|
52
|
-
return <Label label={ __( 'Skew', 'elementor' ) } value={
|
|
35
|
+
return <Label label={ __( 'Skew', 'elementor' ) } value={ formatLabel( value, 'skew' ) } />;
|
|
53
36
|
default:
|
|
54
37
|
return '';
|
|
55
38
|
}
|
|
@@ -2,28 +2,22 @@ import * as React from 'react';
|
|
|
2
2
|
import { useRef } from 'react';
|
|
3
3
|
import { type PropType, transformFunctionsPropTypeUtil, transformPropTypeUtil } from '@elementor/editor-props';
|
|
4
4
|
import { AdjustmentsIcon, InfoCircleFilledIcon } from '@elementor/icons';
|
|
5
|
-
import { bindTrigger, Box, IconButton, type PopupState, Typography, usePopupState } from '@elementor/ui';
|
|
5
|
+
import { bindTrigger, Box, IconButton, type PopupState, Tooltip, Typography, usePopupState } from '@elementor/ui';
|
|
6
6
|
import { __ } from '@wordpress/i18n';
|
|
7
7
|
|
|
8
8
|
import { PropKeyProvider, PropProvider, useBoundProp } from '../../bound-prop-context';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
UnstableRepeater,
|
|
15
|
-
} from '../../components/unstable-repeater';
|
|
16
|
-
import { DisableItemAction } from '../../components/unstable-repeater/actions/disable-item-action';
|
|
17
|
-
import { RemoveItemAction } from '../../components/unstable-repeater/actions/remove-item-action';
|
|
18
|
-
import { EditItemPopover } from '../../components/unstable-repeater/items/edit-item-popover';
|
|
19
|
-
import { injectIntoRepeaterHeaderActions } from '../../components/unstable-repeater/locations';
|
|
9
|
+
import { ControlRepeater, Item, ItemsContainer, TooltipAddItemAction } from '../../components/control-repeater';
|
|
10
|
+
import { DisableItemAction } from '../../components/control-repeater/actions/disable-item-action';
|
|
11
|
+
import { RemoveItemAction } from '../../components/control-repeater/actions/remove-item-action';
|
|
12
|
+
import { EditItemPopover } from '../../components/control-repeater/items/edit-item-popover';
|
|
13
|
+
import { RepeaterHeader } from '../../components/repeater/repeater-header';
|
|
20
14
|
import { ControlAdornments } from '../../control-adornments/control-adornments';
|
|
21
15
|
import { createControl } from '../../create-control';
|
|
22
16
|
import { initialRotateValue, initialScaleValue, initialSkewValue, initialTransformValue } from './initial-values';
|
|
23
|
-
import { TransformBaseControl } from './transform-base-control';
|
|
24
17
|
import { TransformContent } from './transform-content';
|
|
25
18
|
import { TransformIcon } from './transform-icon';
|
|
26
19
|
import { TransformLabel } from './transform-label';
|
|
20
|
+
import { TransformSettingsControl } from './transform-settings-control';
|
|
27
21
|
|
|
28
22
|
const SIZE = 'tiny';
|
|
29
23
|
|
|
@@ -32,19 +26,11 @@ export const TransformRepeaterControl = createControl( () => {
|
|
|
32
26
|
const headerRef = useRef< HTMLDivElement >( null );
|
|
33
27
|
const popupState = usePopupState( { variant: 'popover' } );
|
|
34
28
|
|
|
35
|
-
const repeaterBindKey = 'transform-functions';
|
|
36
|
-
|
|
37
|
-
injectIntoRepeaterHeaderActions( {
|
|
38
|
-
id: 'transform-base-control',
|
|
39
|
-
component: () => <TransformBasePopoverTrigger popupState={ popupState } repeaterBindKey={ repeaterBindKey } />,
|
|
40
|
-
options: { overwrite: true },
|
|
41
|
-
} );
|
|
42
|
-
|
|
43
29
|
return (
|
|
44
30
|
<PropProvider { ...context }>
|
|
45
|
-
<
|
|
46
|
-
<PropKeyProvider bind={
|
|
47
|
-
<Repeater headerRef={ headerRef } propType={ context.propType } />
|
|
31
|
+
<TransformSettingsControl popupState={ popupState } anchorRef={ headerRef } />
|
|
32
|
+
<PropKeyProvider bind={ 'transform-functions' }>
|
|
33
|
+
<Repeater headerRef={ headerRef } propType={ context.propType } popupState={ popupState } />
|
|
48
34
|
</PropKeyProvider>
|
|
49
35
|
</PropProvider>
|
|
50
36
|
);
|
|
@@ -63,10 +49,18 @@ const ToolTip = (
|
|
|
63
49
|
</Box>
|
|
64
50
|
);
|
|
65
51
|
|
|
66
|
-
const Repeater = ( {
|
|
52
|
+
const Repeater = ( {
|
|
53
|
+
headerRef,
|
|
54
|
+
propType,
|
|
55
|
+
popupState,
|
|
56
|
+
}: {
|
|
57
|
+
headerRef: React.RefObject< HTMLDivElement >;
|
|
58
|
+
propType: PropType;
|
|
59
|
+
popupState: PopupState;
|
|
60
|
+
} ) => {
|
|
67
61
|
const transformFunctionsContext = useBoundProp( transformFunctionsPropTypeUtil );
|
|
68
62
|
const availableValues = [ initialTransformValue, initialScaleValue, initialRotateValue, initialSkewValue ];
|
|
69
|
-
const { value: transformValues } = transformFunctionsContext;
|
|
63
|
+
const { value: transformValues, bind } = transformFunctionsContext;
|
|
70
64
|
|
|
71
65
|
const getInitialValue = () => {
|
|
72
66
|
return availableValues.find( ( value ) => ! transformValues?.some( ( item ) => item.$$type === value.$$type ) );
|
|
@@ -76,30 +70,39 @@ const Repeater = ( { headerRef, propType }: { headerRef: React.RefObject< HTMLDi
|
|
|
76
70
|
|
|
77
71
|
return (
|
|
78
72
|
<PropProvider { ...transformFunctionsContext }>
|
|
79
|
-
<
|
|
73
|
+
<ControlRepeater
|
|
80
74
|
initial={ getInitialValue() ?? initialTransformValue }
|
|
81
75
|
propTypeUtil={ transformFunctionsPropTypeUtil }
|
|
82
76
|
>
|
|
83
|
-
<
|
|
77
|
+
<RepeaterHeader
|
|
84
78
|
label={ __( 'Transform', 'elementor' ) }
|
|
85
79
|
adornment={ () => <ControlAdornments customContext={ { path: [ 'transform' ], propType } } /> }
|
|
86
80
|
ref={ headerRef }
|
|
87
81
|
>
|
|
82
|
+
<TransformBasePopoverTrigger popupState={ popupState } repeaterBindKey={ bind } />
|
|
88
83
|
<TooltipAddItemAction
|
|
89
84
|
disabled={ shouldDisableAddItem }
|
|
90
85
|
tooltipContent={ ToolTip }
|
|
91
86
|
enableTooltip={ shouldDisableAddItem }
|
|
92
87
|
ariaLabel={ 'transform' }
|
|
93
88
|
/>
|
|
94
|
-
</
|
|
95
|
-
<ItemsContainer
|
|
96
|
-
<
|
|
97
|
-
|
|
89
|
+
</RepeaterHeader>
|
|
90
|
+
<ItemsContainer>
|
|
91
|
+
<Item
|
|
92
|
+
Icon={ TransformIcon }
|
|
93
|
+
Label={ TransformLabel }
|
|
94
|
+
actions={
|
|
95
|
+
<>
|
|
96
|
+
<DisableItemAction />
|
|
97
|
+
<RemoveItemAction />
|
|
98
|
+
</>
|
|
99
|
+
}
|
|
100
|
+
/>
|
|
98
101
|
</ItemsContainer>
|
|
99
102
|
<EditItemPopover>
|
|
100
103
|
<TransformContent />
|
|
101
104
|
</EditItemPopover>
|
|
102
|
-
</
|
|
105
|
+
</ControlRepeater>
|
|
103
106
|
</PropProvider>
|
|
104
107
|
);
|
|
105
108
|
};
|
|
@@ -112,10 +115,13 @@ const TransformBasePopoverTrigger = ( {
|
|
|
112
115
|
repeaterBindKey: string;
|
|
113
116
|
} ) => {
|
|
114
117
|
const { bind } = useBoundProp();
|
|
118
|
+
const titleLabel = __( 'Transform settings', 'elementor' );
|
|
115
119
|
|
|
116
120
|
return bind !== repeaterBindKey ? null : (
|
|
117
|
-
<
|
|
118
|
-
<
|
|
119
|
-
|
|
121
|
+
<Tooltip title={ titleLabel } placement="top">
|
|
122
|
+
<IconButton size={ SIZE } aria-label={ titleLabel } { ...bindTrigger( popupState ) }>
|
|
123
|
+
<AdjustmentsIcon fontSize={ SIZE } />
|
|
124
|
+
</IconButton>
|
|
125
|
+
</Tooltip>
|
|
120
126
|
);
|
|
121
127
|
};
|
package/src/controls/transform-control/{transform-base-control.tsx → transform-settings-control.tsx}
RENAMED
|
@@ -11,7 +11,7 @@ import { TransformOriginControl } from './transform-base-controls/transform-orig
|
|
|
11
11
|
|
|
12
12
|
const SIZE = 'tiny';
|
|
13
13
|
|
|
14
|
-
export const
|
|
14
|
+
export const TransformSettingsControl = ( {
|
|
15
15
|
popupState,
|
|
16
16
|
anchorRef,
|
|
17
17
|
}: {
|
|
@@ -38,7 +38,7 @@ export const TransformBaseControl = ( {
|
|
|
38
38
|
{ ...popupProps }
|
|
39
39
|
>
|
|
40
40
|
<PopoverHeader
|
|
41
|
-
title={ __( '
|
|
41
|
+
title={ __( 'Transform settings', 'elementor' ) }
|
|
42
42
|
onClose={ popupState.close }
|
|
43
43
|
icon={ <AdjustmentsIcon fontSize={ SIZE } /> }
|
|
44
44
|
/>
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { useTabs } from '@elementor/ui';
|
|
14
14
|
|
|
15
15
|
import { useBoundProp } from '../../bound-prop-context';
|
|
16
|
-
import { useRepeaterContext } from '../../components/
|
|
16
|
+
import { useRepeaterContext } from '../../components/control-repeater/context/repeater-context';
|
|
17
17
|
import { type TransformFunction, TransformFunctionKeys } from './initial-values';
|
|
18
18
|
|
|
19
19
|
type InitialTransformValues = {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { type KeyValuePropValue, type SizePropValue } from '@elementor/editor-props';
|
|
1
2
|
import { __ } from '@wordpress/i18n';
|
|
2
3
|
|
|
3
4
|
export type TransitionProperty = {
|
|
4
5
|
label: string;
|
|
5
6
|
value: string;
|
|
6
7
|
unavailable?: boolean;
|
|
8
|
+
isDisabled?: boolean;
|
|
7
9
|
};
|
|
8
10
|
|
|
9
11
|
export type TransitionCategory = {
|
|
@@ -12,7 +14,20 @@ export type TransitionCategory = {
|
|
|
12
14
|
properties: TransitionProperty[];
|
|
13
15
|
};
|
|
14
16
|
|
|
15
|
-
export
|
|
17
|
+
export type TransitionValue = {
|
|
18
|
+
selection: KeyValuePropValue;
|
|
19
|
+
size: SizePropValue;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type TransitionItem = {
|
|
23
|
+
$$type: 'selection-size';
|
|
24
|
+
value: {
|
|
25
|
+
$$type: 'key-value';
|
|
26
|
+
value: TransitionValue;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const initialTransitionValue: TransitionValue = {
|
|
16
31
|
selection: {
|
|
17
32
|
$$type: 'key-value',
|
|
18
33
|
value: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSelectedElements } from '@elementor/editor-elements';
|
|
2
|
-
import {
|
|
2
|
+
import { trackEvent } from '@elementor/mixpanel';
|
|
3
3
|
|
|
4
4
|
import { eventBus } from '../../services/event-bus';
|
|
5
5
|
import { type initialTransitionValue } from './data';
|
|
@@ -19,7 +19,7 @@ export function subscribeToTransitionEvent() {
|
|
|
19
19
|
const value = payload?.itemValue?.selection?.value?.value?.value;
|
|
20
20
|
const selectedElements = getSelectedElements();
|
|
21
21
|
const widgetType = selectedElements[ 0 ]?.type ?? null;
|
|
22
|
-
|
|
22
|
+
trackEvent( {
|
|
23
23
|
transition_type: value ?? 'unknown',
|
|
24
24
|
...transitionRepeaterMixpanelEvent,
|
|
25
25
|
widget_type: widgetType,
|