@elementor/editor-controls 4.4.0-1131 → 4.4.0-1132
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 +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +1851 -1686
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1542 -1377
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -16
- package/src/controls/image-control.tsx +25 -18
- package/src/controls/image-optimize-trigger.tsx +215 -0
- package/src/controls/inline-editing-control.tsx +100 -80
- package/src/controls/notice-control.tsx +2 -2
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.4.0-
|
|
4
|
+
"version": "4.4.0-1132",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,23 +40,23 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-current-user": "4.4.0-
|
|
44
|
-
"@elementor/editor-elements": "4.4.0-
|
|
45
|
-
"@elementor/editor-props": "4.4.0-
|
|
46
|
-
"@elementor/editor-responsive": "4.4.0-
|
|
47
|
-
"@elementor/editor-ui": "4.4.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "4.4.0-
|
|
49
|
-
"@elementor/env": "4.4.0-
|
|
50
|
-
"@elementor/events": "4.4.0-
|
|
51
|
-
"@elementor/http-client": "4.4.0-
|
|
43
|
+
"@elementor/editor-current-user": "4.4.0-1132",
|
|
44
|
+
"@elementor/editor-elements": "4.4.0-1132",
|
|
45
|
+
"@elementor/editor-props": "4.4.0-1132",
|
|
46
|
+
"@elementor/editor-responsive": "4.4.0-1132",
|
|
47
|
+
"@elementor/editor-ui": "4.4.0-1132",
|
|
48
|
+
"@elementor/editor-v1-adapters": "4.4.0-1132",
|
|
49
|
+
"@elementor/env": "4.4.0-1132",
|
|
50
|
+
"@elementor/events": "4.4.0-1132",
|
|
51
|
+
"@elementor/http-client": "4.4.0-1132",
|
|
52
52
|
"@elementor/icons": "~1.78.1",
|
|
53
|
-
"@elementor/locations": "4.4.0-
|
|
54
|
-
"@elementor/query": "4.4.0-
|
|
55
|
-
"@elementor/schema": "4.4.0-
|
|
56
|
-
"@elementor/session": "4.4.0-
|
|
53
|
+
"@elementor/locations": "4.4.0-1132",
|
|
54
|
+
"@elementor/query": "4.4.0-1132",
|
|
55
|
+
"@elementor/schema": "4.4.0-1132",
|
|
56
|
+
"@elementor/session": "4.4.0-1132",
|
|
57
57
|
"@elementor/ui": "1.41.1",
|
|
58
|
-
"@elementor/utils": "4.4.0-
|
|
59
|
-
"@elementor/wp-media": "4.4.0-
|
|
58
|
+
"@elementor/utils": "4.4.0-1132",
|
|
59
|
+
"@elementor/wp-media": "4.4.0-1132",
|
|
60
60
|
"@monaco-editor/react": "^4.7.0",
|
|
61
61
|
"@tanstack/react-virtual": "^3.13.3",
|
|
62
62
|
"@tiptap/extension-bold": "^3.11.1",
|
|
@@ -10,33 +10,40 @@ import { ControlLabel } from '../components/control-label';
|
|
|
10
10
|
import { createControl } from '../create-control';
|
|
11
11
|
import { useUnfilteredFilesUpload } from '../hooks/use-unfiltered-files-upload';
|
|
12
12
|
import { ImageMediaControl } from './image-media-control';
|
|
13
|
+
import { ImageOptimizeTrigger, type ImagePromotion } from './image-optimize-trigger';
|
|
13
14
|
import { SelectControl } from './select-control';
|
|
14
15
|
|
|
15
16
|
type ImageControlProps = {
|
|
16
17
|
sizes: { label: string; value: string }[];
|
|
17
18
|
label?: string;
|
|
19
|
+
promotion?: ImagePromotion;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
|
-
export const ImageControl = createControl(
|
|
21
|
-
|
|
22
|
+
export const ImageControl = createControl(
|
|
23
|
+
( { sizes, promotion, label = __( 'Image', 'elementor' ) }: ImageControlProps ) => {
|
|
24
|
+
const propContext = useBoundProp( imagePropTypeUtil );
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
return (
|
|
27
|
+
<PropProvider { ...propContext }>
|
|
28
|
+
<Stack gap={ 1.5 }>
|
|
29
|
+
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
30
|
+
<ControlLabel>{ label }</ControlLabel>
|
|
31
|
+
<ImageOptimizeTrigger promotion={ promotion } />
|
|
32
|
+
</Stack>
|
|
33
|
+
<ImageSrcControl label={ label } />
|
|
34
|
+
<Grid container gap={ 1.5 } alignItems="center" flexWrap="nowrap">
|
|
35
|
+
<Grid item xs={ 6 }>
|
|
36
|
+
<ControlFormLabel>{ __( 'Resolution', 'elementor' ) }</ControlFormLabel>
|
|
37
|
+
</Grid>
|
|
38
|
+
<Grid item xs={ 6 } sx={ { overflow: 'hidden' } }>
|
|
39
|
+
<ImageSizeControl sizes={ sizes } />
|
|
40
|
+
</Grid>
|
|
34
41
|
</Grid>
|
|
35
|
-
</
|
|
36
|
-
</
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
</Stack>
|
|
43
|
+
</PropProvider>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
);
|
|
40
47
|
|
|
41
48
|
const ImageSrcControl = ( { label }: { label: string } ) => {
|
|
42
49
|
const { data: allowSvgUpload } = useUnfilteredFilesUpload();
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { ajax } from '@elementor/editor-v1-adapters';
|
|
4
|
+
import { BulbIcon } from '@elementor/icons';
|
|
5
|
+
import { Box, Button, CloseButton, Infotip, Stack, Typography, useTheme } from '@elementor/ui';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
|
|
8
|
+
import { isNoticeDismissed, markNoticeAsDismissedInSession } from './notice-control';
|
|
9
|
+
|
|
10
|
+
const POPOVER_WIDTH = 296;
|
|
11
|
+
const POPOVER_OFFSET: [ number, number ] = [ -24, 12 ];
|
|
12
|
+
|
|
13
|
+
type InfotipWithPopperProps = React.ComponentProps< typeof Infotip > & {
|
|
14
|
+
PopperProps?: {
|
|
15
|
+
modifiers?: Array< { name: string; options?: { offset: [ number, number ] } } >;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const OptimizeInfotip = Infotip as React.FC< InfotipWithPopperProps >;
|
|
20
|
+
|
|
21
|
+
export type ImagePromotion = {
|
|
22
|
+
label?: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
content: string;
|
|
25
|
+
buttonText?: string;
|
|
26
|
+
buttonUrl?: string;
|
|
27
|
+
dismissible?: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type PreviewWindow = Window & {
|
|
31
|
+
elementor?: {
|
|
32
|
+
$preview?: ArrayLike< { contentDocument?: Document | null } >;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const isEventInside = ( target: EventTarget | null, anchor: HTMLElement | null ) => {
|
|
37
|
+
if ( ! ( target instanceof Element ) ) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return !! anchor?.contains( target ) || !! target.closest( '[data-image-optimize-popover], .MuiTooltip-popper' );
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const ImageOptimizeTrigger = ( { promotion }: { promotion?: ImagePromotion } ) => {
|
|
45
|
+
const [ open, setOpen ] = useState( false );
|
|
46
|
+
const [ dismissed, setDismissed ] = useState( () => isNoticeDismissed( promotion?.dismissible ) );
|
|
47
|
+
const anchorRef = useRef< HTMLButtonElement >( null );
|
|
48
|
+
const theme = useTheme();
|
|
49
|
+
const placement = 'rtl' === theme.direction ? 'left-start' : 'right-start';
|
|
50
|
+
|
|
51
|
+
useEffect( () => {
|
|
52
|
+
if ( ! open ) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const closeOnPointerDown = ( event: Event ) => {
|
|
57
|
+
if ( isEventInside( event.target, anchorRef.current ) ) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setOpen( false );
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const closeOnEscape = ( event: KeyboardEvent ) => {
|
|
65
|
+
if ( 'Escape' !== event.key ) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
event.stopPropagation();
|
|
71
|
+
event.stopImmediatePropagation();
|
|
72
|
+
|
|
73
|
+
if ( 'keydown' === event.type ) {
|
|
74
|
+
setOpen( false );
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const iframeDocument = ( window as PreviewWindow ).elementor?.$preview?.[ 0 ]?.contentDocument;
|
|
79
|
+
|
|
80
|
+
document.addEventListener( 'mousedown', closeOnPointerDown, true );
|
|
81
|
+
document.addEventListener( 'keydown', closeOnEscape, true );
|
|
82
|
+
document.addEventListener( 'keyup', closeOnEscape, true );
|
|
83
|
+
iframeDocument?.addEventListener( 'mousedown', closeOnPointerDown, true );
|
|
84
|
+
iframeDocument?.addEventListener( 'keydown', closeOnEscape, true );
|
|
85
|
+
iframeDocument?.addEventListener( 'keyup', closeOnEscape, true );
|
|
86
|
+
|
|
87
|
+
return () => {
|
|
88
|
+
document.removeEventListener( 'mousedown', closeOnPointerDown, true );
|
|
89
|
+
document.removeEventListener( 'keydown', closeOnEscape, true );
|
|
90
|
+
document.removeEventListener( 'keyup', closeOnEscape, true );
|
|
91
|
+
iframeDocument?.removeEventListener( 'mousedown', closeOnPointerDown, true );
|
|
92
|
+
iframeDocument?.removeEventListener( 'keydown', closeOnEscape, true );
|
|
93
|
+
iframeDocument?.removeEventListener( 'keyup', closeOnEscape, true );
|
|
94
|
+
};
|
|
95
|
+
}, [ open ] );
|
|
96
|
+
|
|
97
|
+
if ( dismissed || ! promotion?.content ) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const dismiss = () => {
|
|
102
|
+
setDismissed( true );
|
|
103
|
+
setOpen( false );
|
|
104
|
+
|
|
105
|
+
if ( ! promotion.dismissible ) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
markNoticeAsDismissedInSession( promotion.dismissible );
|
|
110
|
+
|
|
111
|
+
ajax.load( {
|
|
112
|
+
action: 'dismissed_editor_notices',
|
|
113
|
+
unique_id: `dismiss-editor-notice-${ promotion.dismissible }`,
|
|
114
|
+
data: { dismissId: promotion.dismissible },
|
|
115
|
+
} ).catch( () => {} );
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const hideForSession = () => {
|
|
119
|
+
setDismissed( true );
|
|
120
|
+
setOpen( false );
|
|
121
|
+
|
|
122
|
+
if ( promotion.dismissible ) {
|
|
123
|
+
markNoticeAsDismissedInSession( promotion.dismissible );
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<OptimizeInfotip
|
|
129
|
+
arrow
|
|
130
|
+
disableFocusListener
|
|
131
|
+
disableHoverListener
|
|
132
|
+
disableTouchListener
|
|
133
|
+
content={
|
|
134
|
+
<Box className="dialog-widget" data-image-optimize-popover="" sx={ { width: POPOVER_WIDTH } }>
|
|
135
|
+
<Stack direction="row" alignItems="center" gap={ 1 } py={ 1 } px={ 2 }>
|
|
136
|
+
<BulbIcon fontSize="small" color="info" />
|
|
137
|
+
<Typography variant="subtitle2">
|
|
138
|
+
{ promotion.title || __( 'Optimize your images', 'elementor' ) }
|
|
139
|
+
</Typography>
|
|
140
|
+
<CloseButton
|
|
141
|
+
edge="end"
|
|
142
|
+
sx={ { ml: 'auto' } }
|
|
143
|
+
slotProps={ { icon: { fontSize: 'small' } } }
|
|
144
|
+
onClick={ () => setOpen( false ) }
|
|
145
|
+
/>
|
|
146
|
+
</Stack>
|
|
147
|
+
<Stack px={ 2 }>
|
|
148
|
+
<Typography variant="body2" color="secondary" sx={ { pt: 0.5, pb: 1 } }>
|
|
149
|
+
{ promotion.content }
|
|
150
|
+
</Typography>
|
|
151
|
+
</Stack>
|
|
152
|
+
<Stack direction="row" alignItems="center" pt={ 1 } pb={ 1.5 } px={ 2 }>
|
|
153
|
+
<Button variant="text" size="small" color="secondary" onClick={ dismiss } sx={ { ml: -1 } }>
|
|
154
|
+
{ __( 'Dismiss', 'elementor' ) }
|
|
155
|
+
</Button>
|
|
156
|
+
{ promotion.buttonText && promotion.buttonUrl && (
|
|
157
|
+
<Button
|
|
158
|
+
variant="contained"
|
|
159
|
+
size="small"
|
|
160
|
+
color="info"
|
|
161
|
+
href={ promotion.buttonUrl }
|
|
162
|
+
target="_blank"
|
|
163
|
+
rel="noopener noreferrer"
|
|
164
|
+
onClick={ hideForSession }
|
|
165
|
+
sx={ { ml: 'auto' } }
|
|
166
|
+
>
|
|
167
|
+
{ promotion.buttonText }
|
|
168
|
+
</Button>
|
|
169
|
+
) }
|
|
170
|
+
</Stack>
|
|
171
|
+
</Box>
|
|
172
|
+
}
|
|
173
|
+
open={ open }
|
|
174
|
+
placement={ placement }
|
|
175
|
+
PopperProps={ {
|
|
176
|
+
modifiers: [
|
|
177
|
+
{
|
|
178
|
+
name: 'offset',
|
|
179
|
+
options: { offset: POPOVER_OFFSET },
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
} }
|
|
183
|
+
>
|
|
184
|
+
<Button
|
|
185
|
+
ref={ anchorRef }
|
|
186
|
+
variant="text"
|
|
187
|
+
size="small"
|
|
188
|
+
color="info"
|
|
189
|
+
aria-expanded={ open }
|
|
190
|
+
onClick={ () => setOpen( ( current ) => ! current ) }
|
|
191
|
+
startIcon={
|
|
192
|
+
<BulbIcon fontSize="tiny" sx={ { display: 'block', position: 'relative', top: '-3px' } } />
|
|
193
|
+
}
|
|
194
|
+
sx={ {
|
|
195
|
+
display: 'inline-flex',
|
|
196
|
+
alignItems: 'center',
|
|
197
|
+
minWidth: 0,
|
|
198
|
+
minHeight: 0,
|
|
199
|
+
px: 0.75,
|
|
200
|
+
py: 0.25,
|
|
201
|
+
lineHeight: 1,
|
|
202
|
+
fontWeight: 400,
|
|
203
|
+
'& .MuiButton-startIcon': {
|
|
204
|
+
display: 'inline-flex',
|
|
205
|
+
alignItems: 'center',
|
|
206
|
+
margin: 0,
|
|
207
|
+
mr: 0.5,
|
|
208
|
+
},
|
|
209
|
+
} }
|
|
210
|
+
>
|
|
211
|
+
{ promotion.label || __( 'Optimize', 'elementor' ) }
|
|
212
|
+
</Button>
|
|
213
|
+
</OptimizeInfotip>
|
|
214
|
+
);
|
|
215
|
+
};
|
|
@@ -1,109 +1,129 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type ComponentProps, useCallback, useState } from 'react';
|
|
3
3
|
import { escapedHtmlPropTypeUtil } from '@elementor/editor-props';
|
|
4
|
-
import { Box, type SxProps, type Theme } from '@elementor/ui';
|
|
4
|
+
import { Box, Stack, type SxProps, type Theme } from '@elementor/ui';
|
|
5
5
|
import { type Editor } from '@tiptap/react';
|
|
6
6
|
|
|
7
7
|
import { useBoundProp, usePropKeyContext } from '../bound-prop-context';
|
|
8
|
+
import { ControlLabel } from '../components/control-label';
|
|
8
9
|
import { InlineEditor } from '../components/inline-editor';
|
|
9
10
|
import { InlineEditorToolbar } from '../components/inline-editor-toolbar';
|
|
10
11
|
import ControlActions from '../control-actions/control-actions';
|
|
11
12
|
import { createControl } from '../create-control';
|
|
12
13
|
import { extractInlineHtmlContent } from '../utils/inline-editing';
|
|
13
14
|
import { type ControlProps } from '../utils/types';
|
|
15
|
+
import { ImageOptimizeTrigger, type ImagePromotion } from './image-optimize-trigger';
|
|
14
16
|
|
|
15
17
|
type Props = ControlProps< {
|
|
16
18
|
sx?: SxProps< Theme >;
|
|
17
19
|
attributes?: Record< string, string >;
|
|
18
20
|
props?: ComponentProps< 'div' >;
|
|
21
|
+
label?: string;
|
|
22
|
+
promotion?: ImagePromotion;
|
|
19
23
|
} >;
|
|
20
24
|
|
|
21
|
-
export const InlineEditingControl = createControl(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
export const InlineEditingControl = createControl(
|
|
26
|
+
( { sx, attributes, props, label, promotion, context: { elementId } }: Props ) => {
|
|
27
|
+
const { setValue, placeholder, value } = useBoundProp( escapedHtmlPropTypeUtil );
|
|
28
|
+
const { value: rawValue } = usePropKeyContext();
|
|
29
|
+
const content = value ?? extractInlineHtmlContent( rawValue );
|
|
30
|
+
const [ editor, setEditor ] = useState< Editor | null >( null );
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
const handleChange = useCallback(
|
|
33
|
+
( newValue: unknown ) => {
|
|
34
|
+
const html = ( newValue ?? '' ) as string;
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
setValue( html );
|
|
37
|
+
},
|
|
38
|
+
[ setValue ]
|
|
39
|
+
);
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
const editorField = (
|
|
42
|
+
<ControlActions>
|
|
43
|
+
<Box sx={ { position: 'relative' } }>
|
|
44
|
+
{ editor && editor.isEditable && (
|
|
45
|
+
<InlineEditorToolbar
|
|
46
|
+
editor={ editor }
|
|
47
|
+
elementId={ elementId }
|
|
48
|
+
sx={ ( theme: Theme ) => ( {
|
|
49
|
+
boxShadow: 'none',
|
|
50
|
+
border: '1px solid',
|
|
51
|
+
borderColor: theme.palette.text.secondary,
|
|
52
|
+
mb: 0.5,
|
|
53
|
+
} ) }
|
|
54
|
+
inControlPanel={ true }
|
|
55
|
+
/>
|
|
56
|
+
) }
|
|
57
|
+
<Box
|
|
43
58
|
sx={ ( theme: Theme ) => ( {
|
|
44
|
-
|
|
59
|
+
p: 0.8,
|
|
45
60
|
border: '1px solid',
|
|
46
61
|
borderColor: theme.palette.text.secondary,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
transition: 'border-color .2s ease, box-shadow .2s ease',
|
|
59
|
-
'&:hover': {
|
|
60
|
-
borderColor: theme.palette.text.primary,
|
|
61
|
-
},
|
|
62
|
-
'&:focus-within': {
|
|
63
|
-
borderColor: theme.palette.text.primary,
|
|
64
|
-
boxShadow: `0 0 0 1px ${ theme.palette.text.primary }`,
|
|
65
|
-
},
|
|
66
|
-
'& .ProseMirror:focus': {
|
|
67
|
-
outline: 'none',
|
|
68
|
-
},
|
|
69
|
-
'& .ProseMirror': {
|
|
70
|
-
minHeight: '100px',
|
|
71
|
-
fontSize: '12px',
|
|
72
|
-
'& a': {
|
|
73
|
-
color: 'inherit',
|
|
62
|
+
borderRadius: '8px',
|
|
63
|
+
transition: 'border-color .2s ease, box-shadow .2s ease',
|
|
64
|
+
'&:hover': {
|
|
65
|
+
borderColor: theme.palette.text.primary,
|
|
66
|
+
},
|
|
67
|
+
'&:focus-within': {
|
|
68
|
+
borderColor: theme.palette.text.primary,
|
|
69
|
+
boxShadow: `0 0 0 1px ${ theme.palette.text.primary }`,
|
|
70
|
+
},
|
|
71
|
+
'& .ProseMirror:focus': {
|
|
72
|
+
outline: 'none',
|
|
74
73
|
},
|
|
75
|
-
'& .
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
'& .ProseMirror': {
|
|
75
|
+
minHeight: '100px',
|
|
76
|
+
fontSize: '12px',
|
|
77
|
+
'& a': {
|
|
78
|
+
color: 'inherit',
|
|
79
|
+
},
|
|
80
|
+
'& .elementor-inline-editor-reset': {
|
|
81
|
+
margin: 0,
|
|
82
|
+
padding: 0,
|
|
83
|
+
},
|
|
84
|
+
'&.is-empty::before': {
|
|
85
|
+
content: 'attr(data-placeholder)',
|
|
86
|
+
color: 'text.tertiary',
|
|
87
|
+
pointerEvents: 'none',
|
|
88
|
+
position: 'absolute',
|
|
89
|
+
opacity: 0.6,
|
|
90
|
+
},
|
|
78
91
|
},
|
|
79
|
-
'
|
|
80
|
-
|
|
81
|
-
color: 'text.tertiary',
|
|
82
|
-
pointerEvents: 'none',
|
|
83
|
-
position: 'absolute',
|
|
84
|
-
opacity: 0.6,
|
|
92
|
+
'.strip-styles *': {
|
|
93
|
+
all: 'unset',
|
|
85
94
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
paddingBlockStart: 5,
|
|
103
|
-
} }
|
|
104
|
-
/>
|
|
95
|
+
...sx,
|
|
96
|
+
} ) }
|
|
97
|
+
{ ...attributes }
|
|
98
|
+
{ ...props }
|
|
99
|
+
>
|
|
100
|
+
<InlineEditor
|
|
101
|
+
value={ content }
|
|
102
|
+
setValue={ handleChange }
|
|
103
|
+
placeholder={ placeholder ?? null }
|
|
104
|
+
onEditorCreate={ setEditor }
|
|
105
|
+
onEditorDestroy={ () => setEditor( null ) }
|
|
106
|
+
sx={ {
|
|
107
|
+
paddingBlockStart: 5,
|
|
108
|
+
} }
|
|
109
|
+
/>
|
|
110
|
+
</Box>
|
|
105
111
|
</Box>
|
|
106
|
-
</
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
</ControlActions>
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if ( ! promotion ) {
|
|
116
|
+
return editorField;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<Stack gap={ 1 }>
|
|
121
|
+
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
122
|
+
<ControlLabel>{ label }</ControlLabel>
|
|
123
|
+
<ImageOptimizeTrigger promotion={ promotion } />
|
|
124
|
+
</Stack>
|
|
125
|
+
{ editorField }
|
|
126
|
+
</Stack>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
);
|
|
@@ -37,7 +37,7 @@ type ExtendedWindow = Window & {
|
|
|
37
37
|
};
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
const markNoticeAsDismissedInSession = ( dismissId: string ) => {
|
|
40
|
+
export const markNoticeAsDismissedInSession = ( dismissId: string ) => {
|
|
41
41
|
const dismissedNotices = ( window as ExtendedWindow ).elementor?.config?.user?.dismissed_editor_notices;
|
|
42
42
|
|
|
43
43
|
if ( dismissedNotices && ! dismissedNotices.includes( dismissId ) ) {
|
|
@@ -45,7 +45,7 @@ const markNoticeAsDismissedInSession = ( dismissId: string ) => {
|
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
const isNoticeDismissed = ( dismissId?: string ) => {
|
|
48
|
+
export const isNoticeDismissed = ( dismissId?: string ) => {
|
|
49
49
|
if ( ! dismissId ) {
|
|
50
50
|
return false;
|
|
51
51
|
}
|