@elementor/editor-editing-panel 3.33.0-99 → 3.34.2
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 +419 -88
- package/dist/index.d.ts +419 -88
- package/dist/index.js +3361 -2421
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3299 -2347
- package/dist/index.mjs.map +1 -1
- package/package.json +22 -21
- package/src/apply-unapply-actions.ts +30 -0
- package/src/components/collapsible-content.tsx +1 -0
- package/src/components/css-classes/css-class-item.tsx +14 -4
- package/src/components/css-classes/css-class-menu.tsx +83 -11
- package/src/components/css-classes/css-class-selector.tsx +22 -1
- package/src/components/css-classes/use-apply-and-unapply-class.ts +4 -13
- package/src/components/custom-css-indicator.tsx +68 -1
- package/src/components/editing-panel-tabs.tsx +13 -2
- package/src/components/interactions-tab.tsx +15 -0
- package/src/components/section-content.tsx +3 -2
- package/src/components/section.tsx +2 -1
- package/src/components/settings-control.tsx +79 -0
- package/src/components/settings-tab.tsx +16 -46
- package/src/components/style-sections/border-section/border-section.tsx +6 -4
- package/src/components/style-sections/effects-section/blend-mode-field.tsx +44 -0
- package/src/components/style-sections/effects-section/effects-section.tsx +4 -1
- package/src/components/style-sections/layout-section/flex-size-field.tsx +10 -8
- package/src/components/style-sections/typography-section/font-family-field.tsx +5 -1
- package/src/components/style-sections/typography-section/font-size-field.tsx +1 -1
- package/src/components/style-sections/typography-section/letter-spacing-field.tsx +1 -1
- package/src/components/style-sections/typography-section/text-color-field.tsx +1 -1
- package/src/components/style-sections/typography-section/word-spacing-field.tsx +1 -1
- package/src/components/style-tab-section.tsx +2 -2
- package/src/components/style-tab.tsx +12 -17
- package/src/components/styles-field-layout.tsx +8 -1
- package/src/contexts/interaction-context.tsx +0 -0
- package/src/controls-registry/conditional-field.tsx +1 -1
- package/src/controls-registry/control-type-container.tsx +17 -5
- package/src/controls-registry/controls-registry.tsx +18 -5
- package/src/controls-registry/element-controls/get-element-by-type.ts +21 -0
- package/src/controls-registry/element-controls/registry.ts +16 -0
- package/src/controls-registry/element-controls/tabs-control/tabs-control.tsx +229 -0
- package/src/controls-registry/element-controls/tabs-control/use-actions.ts +248 -0
- package/src/controls-registry/settings-field.tsx +54 -10
- package/src/controls-registry/styles-field.tsx +2 -9
- package/src/dynamics/components/dynamic-conditional-control.tsx +62 -0
- package/src/dynamics/components/dynamic-selection-control.tsx +81 -25
- package/src/dynamics/components/dynamic-selection.tsx +3 -3
- package/src/dynamics/dynamic-control.tsx +10 -1
- package/src/dynamics/hooks/use-prop-dynamic-tags.ts +24 -6
- package/src/field-indicators-registry.ts +37 -0
- package/src/hooks/use-computed-style.ts +1 -4
- package/src/index.ts +16 -3
- package/src/init.ts +7 -0
- package/src/reset-style-props.tsx +21 -4
- package/src/styles-inheritance/components/infotip/value-component.tsx +2 -0
- package/src/styles-inheritance/components/styles-inheritance-indicator.tsx +1 -13
- package/src/styles-inheritance/components/styles-inheritance-infotip.tsx +5 -1
- package/src/styles-inheritance/hooks/use-normalized-inheritance-chain-items.tsx +18 -2
- package/src/styles-inheritance/init-styles-inheritance-transformers.ts +25 -4
- package/src/styles-inheritance/init.ts +9 -0
- package/src/styles-inheritance/transformers/{background-overlay-transformer.tsx → array-transformer.tsx} +2 -2
- package/src/styles-inheritance/transformers/background-color-overlay-transformer.tsx +0 -6
- package/src/styles-inheritance/transformers/box-shadow-transformer.tsx +32 -0
- package/src/styles-inheritance/transformers/color-transformer.tsx +32 -0
- package/src/styles-inheritance/transformers/repeater-to-items-transformer.tsx +27 -0
- package/src/utils/is-equal.ts +53 -0
- package/src/utils/prop-dependency-utils.ts +107 -19
- package/src/utils/tracking/subscribe.ts +7 -0
- package/src/components/custom-css-field.tsx +0 -20
- package/src/components/custom-css.tsx +0 -36
- package/src/components/style-sections/border-section/border-field.tsx +0 -54
|
@@ -33,6 +33,8 @@ import { DynamicSelection } from './dynamic-selection';
|
|
|
33
33
|
|
|
34
34
|
const SIZE = 'tiny';
|
|
35
35
|
|
|
36
|
+
const tagsWithoutTabs = [ 'popup' ];
|
|
37
|
+
|
|
36
38
|
export const DynamicSelectionControl = () => {
|
|
37
39
|
const { setValue: setAnyValue } = useBoundProp();
|
|
38
40
|
const { bind, value } = useBoundProp( dynamicPropTypeUtil );
|
|
@@ -83,7 +85,7 @@ export const DynamicSelectionControl = () => {
|
|
|
83
85
|
} }
|
|
84
86
|
{ ...bindPopover( selectionPopoverState ) }
|
|
85
87
|
>
|
|
86
|
-
<PopoverBody>
|
|
88
|
+
<PopoverBody aria-label={ __( 'Dynamic tags', 'elementor' ) }>
|
|
87
89
|
<DynamicSelection close={ selectionPopoverState.close } />
|
|
88
90
|
</PopoverBody>
|
|
89
91
|
</Popover>
|
|
@@ -102,7 +104,11 @@ export const DynamicSettingsPopover = ( { dynamicTag }: { dynamicTag: DynamicTag
|
|
|
102
104
|
|
|
103
105
|
return (
|
|
104
106
|
<>
|
|
105
|
-
<IconButton
|
|
107
|
+
<IconButton
|
|
108
|
+
size={ SIZE }
|
|
109
|
+
{ ...bindTrigger( popupState ) }
|
|
110
|
+
aria-label={ __( 'Dynamic settings', 'elementor' ) }
|
|
111
|
+
>
|
|
106
112
|
<SettingsIcon fontSize={ SIZE } />
|
|
107
113
|
</IconButton>
|
|
108
114
|
<Popover
|
|
@@ -115,20 +121,20 @@ export const DynamicSettingsPopover = ( { dynamicTag }: { dynamicTag: DynamicTag
|
|
|
115
121
|
} }
|
|
116
122
|
{ ...bindPopover( popupState ) }
|
|
117
123
|
>
|
|
118
|
-
<PopoverBody>
|
|
124
|
+
<PopoverBody aria-label={ __( 'Dynamic settings', 'elementor' ) }>
|
|
119
125
|
<PopoverHeader
|
|
120
126
|
title={ dynamicTag.label }
|
|
121
127
|
onClose={ popupState.close }
|
|
122
128
|
icon={ <DatabaseIcon fontSize={ SIZE } /> }
|
|
123
129
|
/>
|
|
124
|
-
<DynamicSettings controls={ dynamicTag.atomic_controls } />
|
|
130
|
+
<DynamicSettings controls={ dynamicTag.atomic_controls } tagName={ dynamicTag.name } />
|
|
125
131
|
</PopoverBody>
|
|
126
132
|
</Popover>
|
|
127
133
|
</>
|
|
128
134
|
);
|
|
129
135
|
};
|
|
130
136
|
|
|
131
|
-
const DynamicSettings = ( { controls }: { controls: DynamicTag[ 'atomic_controls' ] } ) => {
|
|
137
|
+
const DynamicSettings = ( { controls, tagName }: { controls: DynamicTag[ 'atomic_controls' ]; tagName: string } ) => {
|
|
132
138
|
const tabs = controls.filter( ( { type } ) => type === 'section' ) as ControlsSection[];
|
|
133
139
|
const { getTabsProps, getTabProps, getTabPanelProps } = useTabs< number >( 0 );
|
|
134
140
|
|
|
@@ -137,15 +143,31 @@ const DynamicSettings = ( { controls }: { controls: DynamicTag[ 'atomic_controls
|
|
|
137
143
|
return null;
|
|
138
144
|
}
|
|
139
145
|
|
|
146
|
+
if ( tagsWithoutTabs.includes( tagName ) ) {
|
|
147
|
+
const singleTab = tabs[ 0 ];
|
|
148
|
+
return (
|
|
149
|
+
<>
|
|
150
|
+
<Divider />
|
|
151
|
+
<ControlsItemsStack items={ singleTab.value.items } />
|
|
152
|
+
</>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
140
156
|
return (
|
|
141
157
|
<>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
158
|
+
{ tabs.length > 1 && (
|
|
159
|
+
<Tabs size="small" variant="fullWidth" { ...getTabsProps() }>
|
|
160
|
+
{ tabs.map( ( { value }, index ) => (
|
|
161
|
+
<Tab
|
|
162
|
+
key={ index }
|
|
163
|
+
label={ value.label }
|
|
164
|
+
sx={ { px: 1, py: 0.5 } }
|
|
165
|
+
{ ...getTabProps( index ) }
|
|
166
|
+
/>
|
|
167
|
+
) ) }
|
|
168
|
+
</Tabs>
|
|
169
|
+
) }
|
|
147
170
|
<Divider />
|
|
148
|
-
|
|
149
171
|
{ tabs.map( ( { value }, index ) => {
|
|
150
172
|
return (
|
|
151
173
|
<TabPanel
|
|
@@ -153,14 +175,7 @@ const DynamicSettings = ( { controls }: { controls: DynamicTag[ 'atomic_controls
|
|
|
153
175
|
sx={ { flexGrow: 1, py: 0, overflowY: 'auto' } }
|
|
154
176
|
{ ...getTabPanelProps( index ) }
|
|
155
177
|
>
|
|
156
|
-
<
|
|
157
|
-
{ value.items.map( ( item ) => {
|
|
158
|
-
if ( item.type === 'control' ) {
|
|
159
|
-
return <Control key={ item.value.bind } control={ item.value } />;
|
|
160
|
-
}
|
|
161
|
-
return null;
|
|
162
|
-
} ) }
|
|
163
|
-
</Stack>
|
|
178
|
+
<ControlsItemsStack items={ value.items } />
|
|
164
179
|
</TabPanel>
|
|
165
180
|
);
|
|
166
181
|
} ) }
|
|
@@ -170,9 +185,21 @@ const DynamicSettings = ( { controls }: { controls: DynamicTag[ 'atomic_controls
|
|
|
170
185
|
|
|
171
186
|
const LAYOUT_OVERRIDE_FIELDS = {
|
|
172
187
|
separator: 'two-columns',
|
|
188
|
+
action: 'full',
|
|
189
|
+
off_canvas: 'full',
|
|
190
|
+
type: 'two-columns',
|
|
191
|
+
} as const;
|
|
192
|
+
|
|
193
|
+
const DYNAMIC_TAG_LAYOUT_OVERRIDES = {
|
|
194
|
+
select: 'full',
|
|
173
195
|
} as const;
|
|
174
196
|
|
|
175
197
|
const getLayout = ( control: Control[ 'value' ] ): ControlLayout => {
|
|
198
|
+
const dynamicOverride = DYNAMIC_TAG_LAYOUT_OVERRIDES[ control.type as keyof typeof DYNAMIC_TAG_LAYOUT_OVERRIDES ];
|
|
199
|
+
if ( dynamicOverride ) {
|
|
200
|
+
return dynamicOverride;
|
|
201
|
+
}
|
|
202
|
+
|
|
176
203
|
return (
|
|
177
204
|
LAYOUT_OVERRIDE_FIELDS[ control.bind as keyof typeof LAYOUT_OVERRIDE_FIELDS ] ??
|
|
178
205
|
controlsRegistry.getLayout( control.type as ControlType )
|
|
@@ -186,22 +213,51 @@ const Control = ( { control }: { control: Control[ 'value' ] } ) => {
|
|
|
186
213
|
|
|
187
214
|
const layout = getLayout( control );
|
|
188
215
|
|
|
216
|
+
const shouldDisablePortal = control.type === 'select';
|
|
217
|
+
const baseControlProps = shouldDisablePortal
|
|
218
|
+
? {
|
|
219
|
+
...control.props,
|
|
220
|
+
MenuProps: {
|
|
221
|
+
...( control.props?.MenuProps ?? {} ),
|
|
222
|
+
disablePortal: true,
|
|
223
|
+
},
|
|
224
|
+
}
|
|
225
|
+
: { ...control.props };
|
|
226
|
+
const controlProps = {
|
|
227
|
+
...baseControlProps,
|
|
228
|
+
ariaLabel: control.label,
|
|
229
|
+
} as typeof baseControlProps & { ariaLabel?: string };
|
|
230
|
+
const isSwitchControl = control.type === 'switch';
|
|
231
|
+
const layoutStyleProps =
|
|
232
|
+
layout === 'two-columns'
|
|
233
|
+
? {
|
|
234
|
+
display: 'grid',
|
|
235
|
+
gridTemplateColumns: isSwitchControl ? 'minmax(0, 1fr) max-content' : '1fr 1fr',
|
|
236
|
+
}
|
|
237
|
+
: {};
|
|
238
|
+
|
|
189
239
|
return (
|
|
190
240
|
<DynamicControl bind={ control.bind }>
|
|
191
|
-
<Grid
|
|
192
|
-
container
|
|
193
|
-
gap={ 0.75 }
|
|
194
|
-
sx={ layout === 'two-columns' ? { display: 'grid', gridTemplateColumns: '1fr 1fr' } : {} }
|
|
195
|
-
>
|
|
241
|
+
<Grid container gap={ 0.75 } sx={ layoutStyleProps }>
|
|
196
242
|
{ control.label ? (
|
|
197
243
|
<Grid item xs={ 12 }>
|
|
198
244
|
<ControlFormLabel>{ control.label }</ControlFormLabel>
|
|
199
245
|
</Grid>
|
|
200
246
|
) : null }
|
|
201
247
|
<Grid item xs={ 12 }>
|
|
202
|
-
<BaseControl type={ control.type as ControlType } props={
|
|
248
|
+
<BaseControl type={ control.type as ControlType } props={ controlProps } />
|
|
203
249
|
</Grid>
|
|
204
250
|
</Grid>
|
|
205
251
|
</DynamicControl>
|
|
206
252
|
);
|
|
207
253
|
};
|
|
254
|
+
|
|
255
|
+
function ControlsItemsStack( { items }: { items: ControlsSection[ 'value' ][ 'items' ] } ) {
|
|
256
|
+
return (
|
|
257
|
+
<Stack p={ 2 } gap={ 2 } sx={ { overflowY: 'auto' } }>
|
|
258
|
+
{ items.map( ( item ) =>
|
|
259
|
+
item.type === 'control' ? <Control key={ item.value.bind } control={ item.value } /> : null
|
|
260
|
+
) }
|
|
261
|
+
</Stack>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment, useState } from 'react';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { useBoundProp } from '@elementor/editor-controls';
|
|
4
|
-
import { PopoverHeader, PopoverMenuList,
|
|
4
|
+
import { PopoverHeader, PopoverMenuList, SearchField } from '@elementor/editor-ui';
|
|
5
5
|
import { DatabaseIcon } from '@elementor/icons';
|
|
6
6
|
import { Divider, Link, Stack, Typography, useTheme } from '@elementor/ui';
|
|
7
7
|
import { __ } from '@wordpress/i18n';
|
|
@@ -76,7 +76,7 @@ export const DynamicSelection = ( { close: closePopover }: DynamicSelectionProps
|
|
|
76
76
|
] );
|
|
77
77
|
|
|
78
78
|
return (
|
|
79
|
-
<PopoverBody>
|
|
79
|
+
<PopoverBody aria-label={ __( 'Dynamic tags', 'elementor' ) }>
|
|
80
80
|
<PopoverHeader
|
|
81
81
|
title={ __( 'Dynamic tags', 'elementor' ) }
|
|
82
82
|
onClose={ closePopover }
|
|
@@ -86,7 +86,7 @@ export const DynamicSelection = ( { close: closePopover }: DynamicSelectionProps
|
|
|
86
86
|
<NoDynamicTags />
|
|
87
87
|
) : (
|
|
88
88
|
<Fragment>
|
|
89
|
-
<
|
|
89
|
+
<SearchField
|
|
90
90
|
value={ searchValue }
|
|
91
91
|
onSearch={ handleSearch }
|
|
92
92
|
placeholder={ __( 'Search dynamic tags…', 'elementor' ) }
|
|
@@ -3,6 +3,7 @@ import { PropKeyProvider, PropProvider, type SetValue, useBoundProp } from '@ele
|
|
|
3
3
|
import { type PropKey } from '@elementor/editor-props';
|
|
4
4
|
|
|
5
5
|
import { createTopLevelObjectType } from '../controls-registry/create-top-level-object-type';
|
|
6
|
+
import { DynamicConditionalControl } from './components/dynamic-conditional-control';
|
|
6
7
|
import { useDynamicTag } from './hooks/use-dynamic-tag';
|
|
7
8
|
import { dynamicPropTypeUtil, type DynamicPropValue } from './utils';
|
|
8
9
|
|
|
@@ -39,7 +40,15 @@ export const DynamicControl = ( { bind, children }: DynamicControlProps ) => {
|
|
|
39
40
|
|
|
40
41
|
return (
|
|
41
42
|
<PropProvider propType={ propType } setValue={ setDynamicValue } value={ { [ bind ]: dynamicValue } }>
|
|
42
|
-
<PropKeyProvider bind={ bind }>
|
|
43
|
+
<PropKeyProvider bind={ bind }>
|
|
44
|
+
<DynamicConditionalControl
|
|
45
|
+
propType={ dynamicPropType }
|
|
46
|
+
propsSchema={ dynamicTag.props_schema }
|
|
47
|
+
dynamicSettings={ settings }
|
|
48
|
+
>
|
|
49
|
+
{ children }
|
|
50
|
+
</DynamicConditionalControl>
|
|
51
|
+
</PropKeyProvider>
|
|
43
52
|
</PropProvider>
|
|
44
53
|
);
|
|
45
54
|
};
|
|
@@ -2,6 +2,7 @@ import { useMemo } from 'react';
|
|
|
2
2
|
import { useBoundProp } from '@elementor/editor-controls';
|
|
3
3
|
|
|
4
4
|
import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
|
|
5
|
+
import { type DynamicTag } from '../types';
|
|
5
6
|
import { getDynamicPropType } from '../utils';
|
|
6
7
|
|
|
7
8
|
export const usePropDynamicTags = () => {
|
|
@@ -15,21 +16,38 @@ export const usePropDynamicTags = () => {
|
|
|
15
16
|
categories = propDynamicType?.settings.categories || [];
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
// eslint-disable-next-line react-compiler/react-compiler
|
|
19
19
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
20
20
|
return useMemo( () => getDynamicTagsByCategories( categories ), [ categories.join() ] );
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const getDynamicTagsByCategories = ( categories: string[] ) => {
|
|
24
|
-
const
|
|
24
|
+
const { tags, groups } = getAtomicDynamicTags() || {};
|
|
25
25
|
|
|
26
|
-
if ( ! categories.length || !
|
|
26
|
+
if ( ! categories.length || ! tags || ! groups ) {
|
|
27
27
|
return [];
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const _categories = new Set( categories );
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const dynamicTags: DynamicTag[] = [];
|
|
33
|
+
const groupedFilteredTags: Record< string, DynamicTag[] > = {};
|
|
34
|
+
|
|
35
|
+
for ( const tag of Object.values( tags ) ) {
|
|
36
|
+
if ( ! tag.categories.some( ( category ) => _categories.has( category ) ) ) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if ( ! groupedFilteredTags[ tag.group ] ) {
|
|
41
|
+
groupedFilteredTags[ tag.group ] = [];
|
|
42
|
+
}
|
|
43
|
+
groupedFilteredTags[ tag.group ].push( tag );
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for ( const group in groups ) {
|
|
47
|
+
if ( groupedFilteredTags[ group ] ) {
|
|
48
|
+
dynamicTags.push( ...groupedFilteredTags[ group ] );
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return dynamicTags;
|
|
35
53
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type AdornmentComponent } from '@elementor/editor-controls';
|
|
2
|
+
|
|
3
|
+
type FieldType = 'settings' | 'styles';
|
|
4
|
+
|
|
5
|
+
type FieldIndicator = {
|
|
6
|
+
id: string;
|
|
7
|
+
indicator: AdornmentComponent;
|
|
8
|
+
|
|
9
|
+
// ordered from lowest to highest
|
|
10
|
+
priority: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const indicatorsRegistry: Record< FieldType, Map< string, FieldIndicator > > = {
|
|
14
|
+
settings: new Map(),
|
|
15
|
+
styles: new Map(),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const DEFAULT_PRIORITY = 10;
|
|
19
|
+
|
|
20
|
+
export const FIELD_TYPE = {
|
|
21
|
+
SETTINGS: 'settings',
|
|
22
|
+
STYLES: 'styles',
|
|
23
|
+
} satisfies Record< string, FieldType >;
|
|
24
|
+
|
|
25
|
+
export const registerFieldIndicator = ( {
|
|
26
|
+
fieldType,
|
|
27
|
+
id,
|
|
28
|
+
indicator,
|
|
29
|
+
priority = DEFAULT_PRIORITY,
|
|
30
|
+
}: FieldIndicator & { fieldType: FieldType } ) => {
|
|
31
|
+
indicatorsRegistry[ fieldType ].set( id, { id, indicator, priority } );
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const getFieldIndicators = ( fieldType: FieldType ): { id: string; Adornment: AdornmentComponent }[] =>
|
|
35
|
+
Array.from( indicatorsRegistry[ fieldType ].values() )
|
|
36
|
+
.sort( ( a, b ) => a.priority - b.priority )
|
|
37
|
+
.map( ( { id, indicator: Adornment } ) => ( { id, Adornment } ) );
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { __privateUseListenTo as useListenTo, commandEndEvent, windowEvent } from '@elementor/editor-v1-adapters';
|
|
2
2
|
|
|
3
|
-
import { type ExtendedWindow } from '../sync/types';
|
|
4
|
-
|
|
5
3
|
export function useComputedStyle( elementId: string | null ) {
|
|
6
4
|
return useListenTo(
|
|
7
5
|
[
|
|
@@ -15,8 +13,7 @@ export function useComputedStyle( elementId: string | null ) {
|
|
|
15
13
|
return null;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
const
|
|
19
|
-
const element = extendedWindow.elementor?.getContainer?.( elementId );
|
|
16
|
+
const element = window.elementor?.getContainer?.( elementId );
|
|
20
17
|
|
|
21
18
|
if ( ! element?.view?.el ) {
|
|
22
19
|
return null;
|
package/src/index.ts
CHANGED
|
@@ -2,17 +2,30 @@ export { useBoundProp } from '@elementor/editor-controls';
|
|
|
2
2
|
export { type ValidationEvent, type ValidationResult } from './components/creatable-autocomplete';
|
|
3
3
|
export { injectIntoCssClassConvert } from './components/css-classes/css-class-convert-local';
|
|
4
4
|
export { injectIntoClassSelectorActions } from './components/css-classes/css-class-selector';
|
|
5
|
+
export { CustomCssIndicator } from './components/custom-css-indicator';
|
|
5
6
|
export { PopoverBody } from './components/popover-body';
|
|
6
7
|
export { SectionContent } from './components/section-content';
|
|
7
|
-
export {
|
|
8
|
+
export { SettingsControl } from './components/settings-control';
|
|
9
|
+
export { StyleIndicator } from './components/style-indicator';
|
|
8
10
|
export { useFontFamilies } from './components/style-sections/typography-section/hooks/use-font-families';
|
|
9
|
-
export {
|
|
11
|
+
export { injectIntoStyleTab } from './components/style-tab';
|
|
12
|
+
export { StyleTabSection } from './components/style-tab-section';
|
|
13
|
+
export { useClassesProp } from './contexts/classes-prop-context';
|
|
14
|
+
export { useElement } from './contexts/element-context';
|
|
10
15
|
export { useSectionWidth } from './contexts/section-context';
|
|
16
|
+
export { useStyle } from './contexts/style-context';
|
|
11
17
|
export { registerControlReplacement } from './control-replacement';
|
|
12
18
|
export { controlActionsMenu } from './controls-actions';
|
|
19
|
+
export { controlsRegistry } from './controls-registry/controls-registry';
|
|
20
|
+
export { StylesProviderCannotUpdatePropsError } from './errors';
|
|
21
|
+
export { useCustomCss } from './hooks/use-custom-css';
|
|
22
|
+
export { getSubtitle, getTitle, HISTORY_DEBOUNCE_WAIT } from './hooks/use-styles-fields';
|
|
23
|
+
export { useStylesRerender } from './hooks/use-styles-rerender';
|
|
13
24
|
export { init } from './init';
|
|
14
25
|
export { usePanelActions, usePanelStatus } from './panel';
|
|
15
26
|
export type { PopoverActionProps } from './popover-action';
|
|
16
27
|
export { registerStyleProviderToColors } from './provider-colors-registry';
|
|
17
28
|
export { stylesInheritanceTransformersRegistry } from './styles-inheritance/styles-inheritance-transformers-registry';
|
|
18
|
-
export {
|
|
29
|
+
export { registerFieldIndicator, FIELD_TYPE } from './field-indicators-registry';
|
|
30
|
+
|
|
31
|
+
export { doApplyClasses, doGetAppliedClasses, doUnapplyClass } from './apply-unapply-actions';
|
package/src/init.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { injectIntoLogic } from '@elementor/editor';
|
|
2
|
+
import { initElementsMcp } from '@elementor/editor-elements';
|
|
2
3
|
import { __registerPanel as registerPanel } from '@elementor/editor-panels';
|
|
3
4
|
import { blockCommand } from '@elementor/editor-v1-adapters';
|
|
4
5
|
|
|
5
6
|
import { EditingPanelHooks } from './components/editing-panel-hooks';
|
|
7
|
+
import { registerElementControls } from './controls-registry/element-controls/registry';
|
|
6
8
|
import { init as initDynamics } from './dynamics/init';
|
|
7
9
|
import { panel } from './panel';
|
|
8
10
|
import { initResetStyleProps } from './reset-style-props';
|
|
@@ -13,6 +15,8 @@ export function init() {
|
|
|
13
15
|
registerPanel( panel );
|
|
14
16
|
blockV1Panel();
|
|
15
17
|
|
|
18
|
+
initElementsMcp();
|
|
19
|
+
|
|
16
20
|
injectIntoLogic( {
|
|
17
21
|
id: 'editing-panel-hooks',
|
|
18
22
|
component: EditingPanelHooks,
|
|
@@ -24,6 +28,9 @@ export function init() {
|
|
|
24
28
|
// TODO: Move it from here once we have styles-inheritance package.
|
|
25
29
|
initStylesInheritance();
|
|
26
30
|
|
|
31
|
+
// TODO: Move it from here once we have element-controls package.
|
|
32
|
+
registerElementControls();
|
|
33
|
+
|
|
27
34
|
initResetStyleProps();
|
|
28
35
|
}
|
|
29
36
|
|
|
@@ -4,6 +4,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
4
4
|
|
|
5
5
|
import { useIsStyle } from './contexts/style-context';
|
|
6
6
|
import { controlActionsMenu } from './controls-actions';
|
|
7
|
+
import { isEqual } from './utils/is-equal';
|
|
7
8
|
|
|
8
9
|
const { registerAction } = controlActionsMenu;
|
|
9
10
|
|
|
@@ -16,14 +17,30 @@ export function initResetStyleProps() {
|
|
|
16
17
|
|
|
17
18
|
export function useResetStyleValueProps() {
|
|
18
19
|
const isStyle = useIsStyle();
|
|
19
|
-
const { value,
|
|
20
|
+
const { value, resetValue, propType } = useBoundProp();
|
|
21
|
+
const hasValue = value !== null && value !== undefined;
|
|
22
|
+
const hasInitial = propType.initial_value !== undefined && propType.initial_value !== null;
|
|
23
|
+
const isRequired = !! propType.settings?.required;
|
|
24
|
+
const shouldHide = !! propType.settings?.hide_reset;
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
function calculateVisibility() {
|
|
27
|
+
if ( ! isStyle || ! hasValue || shouldHide ) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if ( hasInitial ) {
|
|
32
|
+
return ! isEqual( value, propType.initial_value );
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return ! isRequired;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const visible = calculateVisibility();
|
|
22
39
|
|
|
23
40
|
return {
|
|
24
|
-
visible
|
|
41
|
+
visible,
|
|
25
42
|
title: __( 'Clear', 'elementor' ),
|
|
26
43
|
icon: BrushBigIcon,
|
|
27
|
-
onClick: () =>
|
|
44
|
+
onClick: () => resetValue(),
|
|
28
45
|
};
|
|
29
46
|
}
|
|
@@ -12,9 +12,6 @@ import { getStylesProviderThemeColor } from '../../utils/get-styles-provider-col
|
|
|
12
12
|
import { type SnapshotPropValue } from '../types';
|
|
13
13
|
import { getValueFromInheritanceChain } from '../utils';
|
|
14
14
|
import { StylesInheritanceInfotip } from './styles-inheritance-infotip';
|
|
15
|
-
|
|
16
|
-
const disabledControls = [ 'box-shadow', 'background-overlay', 'filter', 'backdrop-filter', 'transform', 'transition' ];
|
|
17
|
-
|
|
18
15
|
export const StylesInheritanceIndicator = ( {
|
|
19
16
|
customContext,
|
|
20
17
|
}: {
|
|
@@ -28,16 +25,7 @@ export const StylesInheritanceIndicator = ( {
|
|
|
28
25
|
return null;
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<Indicator
|
|
35
|
-
inheritanceChain={ inheritanceChain }
|
|
36
|
-
path={ path }
|
|
37
|
-
propType={ propType }
|
|
38
|
-
isDisabled={ isDisabled }
|
|
39
|
-
/>
|
|
40
|
-
);
|
|
28
|
+
return <Indicator inheritanceChain={ inheritanceChain } path={ path } propType={ propType } />;
|
|
41
29
|
};
|
|
42
30
|
|
|
43
31
|
type IndicatorProps = {
|
|
@@ -122,7 +122,11 @@ export const StylesInheritanceInfotip = ( {
|
|
|
122
122
|
item.displayLabel
|
|
123
123
|
) }
|
|
124
124
|
>
|
|
125
|
-
<Box
|
|
125
|
+
<Box
|
|
126
|
+
display="flex"
|
|
127
|
+
gap={ 0.5 }
|
|
128
|
+
sx={ { flexWrap: 'wrap', width: '100%', alignItems: 'flex-start' } }
|
|
129
|
+
>
|
|
126
130
|
<BreakpointIcon breakpoint={ item.breakpoint } />
|
|
127
131
|
<LabelChip displayLabel={ item.displayLabel } provider={ item.provider } />
|
|
128
132
|
<ValueComponent index={ index } value={ item.value } />
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { isValidElement, type ReactNode, useEffect, useState } from 'react';
|
|
2
2
|
import { type PropsResolver } from '@elementor/editor-canvas';
|
|
3
3
|
import { type PropKey } from '@elementor/editor-props';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
isClassState,
|
|
6
|
+
isPseudoState,
|
|
7
|
+
type StyleDefinitionState,
|
|
8
|
+
type StyleDefinitionVariant,
|
|
9
|
+
} from '@elementor/editor-styles';
|
|
5
10
|
import { ELEMENTS_BASE_STYLES_PROVIDER_KEY } from '@elementor/editor-styles-repository';
|
|
6
11
|
import { __ } from '@wordpress/i18n';
|
|
7
12
|
|
|
@@ -65,7 +70,7 @@ export const normalizeInheritanceItem = async (
|
|
|
65
70
|
style: { label, id },
|
|
66
71
|
} = item;
|
|
67
72
|
|
|
68
|
-
const displayLabel =
|
|
73
|
+
const displayLabel = getLabel( { label, state } );
|
|
69
74
|
|
|
70
75
|
return {
|
|
71
76
|
id: id ? id + ( state ?? '' ) : index,
|
|
@@ -76,6 +81,17 @@ export const normalizeInheritanceItem = async (
|
|
|
76
81
|
};
|
|
77
82
|
};
|
|
78
83
|
|
|
84
|
+
function getLabel( { label, state }: { label: string; state: StyleDefinitionState } ) {
|
|
85
|
+
if ( isClassState( state ) ) {
|
|
86
|
+
return `${ label }.${ state }`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if ( isPseudoState( state ) ) {
|
|
90
|
+
return `${ label }:${ state }`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return label;
|
|
94
|
+
}
|
|
79
95
|
const getTransformedValue = async (
|
|
80
96
|
item: SnapshotPropValue,
|
|
81
97
|
bind: PropKey,
|
|
@@ -2,10 +2,13 @@ import { createTransformer, styleTransformersRegistry } from '@elementor/editor-
|
|
|
2
2
|
|
|
3
3
|
import { excludePropTypeTransformers } from './consts';
|
|
4
4
|
import { stylesInheritanceTransformersRegistry } from './styles-inheritance-transformers-registry';
|
|
5
|
+
import { arrayTransformer } from './transformers/array-transformer';
|
|
5
6
|
import { backgroundColorOverlayTransformer } from './transformers/background-color-overlay-transformer';
|
|
6
7
|
import { backgroundGradientOverlayTransformer } from './transformers/background-gradient-overlay-transformer';
|
|
7
8
|
import { backgroundImageOverlayTransformer } from './transformers/background-image-overlay-transformer';
|
|
8
|
-
import {
|
|
9
|
+
import { boxShadowTransformer } from './transformers/box-shadow-transformer';
|
|
10
|
+
import { colorTransformer } from './transformers/color-transformer';
|
|
11
|
+
import { createRepeaterToItemsTransformer } from './transformers/repeater-to-items-transformer';
|
|
9
12
|
|
|
10
13
|
export function initStylesInheritanceTransformers() {
|
|
11
14
|
const originalStyleTransformers = styleTransformersRegistry.all();
|
|
@@ -24,15 +27,33 @@ export function initStylesInheritanceTransformers() {
|
|
|
24
27
|
} )
|
|
25
28
|
);
|
|
26
29
|
|
|
27
|
-
registerCustomTransformers();
|
|
30
|
+
registerCustomTransformers( originalStyleTransformers );
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
function registerCustomTransformers() {
|
|
33
|
+
function registerCustomTransformers( originalStyleTransformers: ReturnType< typeof styleTransformersRegistry.all > ) {
|
|
34
|
+
stylesInheritanceTransformersRegistry.register( 'color', colorTransformer );
|
|
31
35
|
stylesInheritanceTransformersRegistry.register( 'background-color-overlay', backgroundColorOverlayTransformer );
|
|
32
36
|
stylesInheritanceTransformersRegistry.register(
|
|
33
37
|
'background-gradient-overlay',
|
|
34
38
|
backgroundGradientOverlayTransformer
|
|
35
39
|
);
|
|
36
40
|
stylesInheritanceTransformersRegistry.register( 'background-image-overlay', backgroundImageOverlayTransformer );
|
|
37
|
-
stylesInheritanceTransformersRegistry.register( '
|
|
41
|
+
stylesInheritanceTransformersRegistry.register( 'shadow', boxShadowTransformer );
|
|
42
|
+
|
|
43
|
+
stylesInheritanceTransformersRegistry.register(
|
|
44
|
+
'filter',
|
|
45
|
+
createRepeaterToItemsTransformer( originalStyleTransformers.filter )
|
|
46
|
+
);
|
|
47
|
+
stylesInheritanceTransformersRegistry.register(
|
|
48
|
+
'backdrop-filter',
|
|
49
|
+
createRepeaterToItemsTransformer( originalStyleTransformers[ 'backdrop-filter' ] )
|
|
50
|
+
);
|
|
51
|
+
stylesInheritanceTransformersRegistry.register(
|
|
52
|
+
'transition',
|
|
53
|
+
createRepeaterToItemsTransformer( originalStyleTransformers.transition, ', ' )
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
[ 'background-overlay', 'box-shadow', 'transform-functions' ].forEach( ( propType ) =>
|
|
57
|
+
stylesInheritanceTransformersRegistry.register( propType, arrayTransformer )
|
|
58
|
+
);
|
|
38
59
|
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import { FIELD_TYPE, registerFieldIndicator } from '../field-indicators-registry';
|
|
2
|
+
import { StylesInheritanceIndicator } from './components/styles-inheritance-indicator';
|
|
1
3
|
import { initStylesInheritanceTransformers } from './init-styles-inheritance-transformers';
|
|
2
4
|
|
|
3
5
|
export const init = () => {
|
|
4
6
|
initStylesInheritanceTransformers();
|
|
7
|
+
|
|
8
|
+
registerFieldIndicator( {
|
|
9
|
+
fieldType: FIELD_TYPE.STYLES,
|
|
10
|
+
id: 'styles-inheritance',
|
|
11
|
+
priority: 1,
|
|
12
|
+
indicator: StylesInheritanceIndicator,
|
|
13
|
+
} );
|
|
5
14
|
};
|
|
@@ -3,9 +3,9 @@ import { type ReactNode } from 'react';
|
|
|
3
3
|
import { createTransformer } from '@elementor/editor-canvas';
|
|
4
4
|
import { Stack } from '@elementor/ui';
|
|
5
5
|
|
|
6
|
-
type
|
|
6
|
+
type ArrayValues = ReactNode[];
|
|
7
7
|
|
|
8
|
-
export const
|
|
8
|
+
export const arrayTransformer = createTransformer( ( values: ArrayValues[] ) => {
|
|
9
9
|
if ( ! values || values.length === 0 ) {
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
@@ -8,16 +8,10 @@ export type Color = {
|
|
|
8
8
|
|
|
9
9
|
export const backgroundColorOverlayTransformer = createTransformer( ( value: Color ) => (
|
|
10
10
|
<Stack direction="row" gap={ 1 } alignItems="center">
|
|
11
|
-
<ItemIconColor value={ value } />
|
|
12
11
|
<ItemLabelColor value={ value } />
|
|
13
12
|
</Stack>
|
|
14
13
|
) );
|
|
15
14
|
|
|
16
|
-
const ItemIconColor = ( { value }: { value: Color } ) => {
|
|
17
|
-
const { color } = value;
|
|
18
|
-
return <StyledUnstableColorIndicator size="inherit" component="span" value={ color } />;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
15
|
const ItemLabelColor = ( { value: { color } }: { value: Color } ) => {
|
|
22
16
|
return <span>{ color }</span>;
|
|
23
17
|
};
|