@elementor/editor-editing-panel 1.48.0 → 3.32.0-20
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/CHANGELOG.md +21 -0
- package/dist/index.d.mts +78 -47
- package/dist/index.d.ts +78 -47
- package/dist/index.js +1770 -1406
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1550 -1157
- package/dist/index.mjs.map +1 -1
- package/package.json +22 -22
- package/src/components/css-classes/css-class-convert-local.tsx +77 -0
- package/src/components/css-classes/css-class-item.tsx +18 -3
- package/src/components/css-classes/css-class-menu.tsx +10 -3
- package/src/components/css-classes/css-class-selector.tsx +10 -2
- package/src/components/css-classes/local-class-sub-menu.tsx +23 -0
- package/src/components/css-classes/use-apply-and-unapply-class.ts +7 -50
- package/src/components/css-classes/use-can-convert-local-class-to-global.ts +22 -0
- package/src/components/custom-css.tsx +21 -0
- package/src/components/editing-panel-tabs.tsx +1 -5
- package/src/components/popover-body.tsx +12 -0
- package/src/components/section.tsx +1 -5
- package/src/components/settings-tab.tsx +6 -15
- package/src/components/style-sections/effects-section/effects-section.tsx +32 -19
- package/src/components/style-sections/layout-section/display-field.tsx +11 -20
- package/src/components/style-sections/layout-section/flex-order-field.tsx +6 -1
- package/src/components/style-sections/layout-section/flex-size-field.tsx +86 -52
- package/src/components/style-sections/position-section/offset-field.tsx +2 -2
- package/src/components/style-sections/position-section/position-section.tsx +2 -8
- package/src/components/style-sections/size-section/size-section.tsx +16 -31
- package/src/components/style-sections/typography-section/typography-section.tsx +2 -19
- package/src/components/style-tab-collapsible-content.tsx +1 -5
- package/src/components/style-tab-section.tsx +1 -5
- package/src/components/style-tab.tsx +15 -2
- package/src/controls-actions.ts +1 -1
- package/src/controls-registry/conditional-field.tsx +26 -0
- package/src/controls-registry/control.tsx +2 -2
- package/src/controls-registry/controls-registry.tsx +44 -3
- package/src/controls-registry/settings-field.tsx +33 -45
- package/src/controls-registry/styles-field.tsx +14 -14
- package/src/dynamics/components/dynamic-selection-control.tsx +24 -16
- package/src/dynamics/components/dynamic-selection.tsx +32 -36
- package/src/errors.ts +10 -0
- package/src/hooks/use-custom-css.ts +184 -0
- package/src/hooks/use-state-by-element.ts +1 -4
- package/src/hooks/use-styles-fields.ts +129 -106
- package/src/index.ts +9 -10
- package/src/init.ts +2 -5
- package/src/popover-action.tsx +36 -15
- package/src/reset-style-props.tsx +2 -6
- package/src/styles-inheritance/components/infotip/value-component.tsx +1 -0
- package/src/styles-inheritance/components/styles-inheritance-indicator.tsx +6 -23
- package/src/styles-inheritance/components/styles-inheritance-infotip.tsx +18 -9
- package/src/styles-inheritance/consts.ts +0 -4
- package/src/styles-inheritance/init.ts +1 -4
- package/src/styles-inheritance/transformers/background-color-overlay-transformer.tsx +5 -1
- package/src/styles-inheritance/transformers/background-gradient-overlay-transformer.tsx +3 -3
- package/src/styles-inheritance/transformers/background-image-overlay-transformer.tsx +2 -1
- package/src/utils/get-styles-provider-color.ts +8 -0
- package/src/utils/prop-dependency-utils.ts +156 -0
- package/src/components/popover-scrollable-content.tsx +0 -12
- package/src/components/style-sections/size-section/object-position-field.tsx +0 -15
- package/src/sync/experiments-flags.ts +0 -5
- /package/src/components/style-sections/{layout-section → effects-section}/opacity-control-field.tsx +0 -0
|
@@ -1,44 +1,57 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
BoxShadowRepeaterControl,
|
|
4
|
+
FilterRepeaterControl,
|
|
5
|
+
TransformRepeaterControl,
|
|
6
|
+
TransitionRepeaterControl,
|
|
7
|
+
UnstableTransformRepeaterControl,
|
|
8
|
+
} from '@elementor/editor-controls';
|
|
9
|
+
import { EXPERIMENTAL_FEATURES, isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
10
|
import { __ } from '@wordpress/i18n';
|
|
5
11
|
|
|
6
12
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
|
-
import { EXPERIMENTAL_FEATURES } from '../../../sync/experiments-flags';
|
|
8
13
|
import { PanelDivider } from '../../panel-divider';
|
|
9
14
|
import { SectionContent } from '../../section-content';
|
|
10
|
-
import { OpacityControlField } from '
|
|
15
|
+
import { OpacityControlField } from './opacity-control-field';
|
|
11
16
|
|
|
12
17
|
const BOX_SHADOW_LABEL = __( 'Box shadow', 'elementor' );
|
|
13
|
-
const FILTER_LABEL = __( '
|
|
18
|
+
const FILTER_LABEL = __( 'Filters', 'elementor' );
|
|
14
19
|
const TRANSFORM_LABEL = __( 'Transform', 'elementor' );
|
|
20
|
+
const BACKDROP_FILTER_LABEL = __( 'Backdrop filters', 'elementor' );
|
|
21
|
+
const TRANSITIONS_LABEL = __( 'Transitions', 'elementor' );
|
|
15
22
|
|
|
16
23
|
export const EffectsSection = () => {
|
|
17
|
-
const
|
|
24
|
+
const shouldShowTransition = isExperimentActive( EXPERIMENTAL_FEATURES.TRANSITIONS );
|
|
25
|
+
|
|
26
|
+
const isUnstableRepeaterActive = isExperimentActive( EXPERIMENTAL_FEATURES.UNSTABLE_REPEATER );
|
|
18
27
|
|
|
19
28
|
return (
|
|
20
29
|
<SectionContent>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<OpacityControlField />
|
|
24
|
-
<PanelDivider />
|
|
25
|
-
</>
|
|
26
|
-
) }
|
|
30
|
+
<OpacityControlField />
|
|
31
|
+
<PanelDivider />
|
|
27
32
|
<StylesField bind="box-shadow" propDisplayName={ BOX_SHADOW_LABEL }>
|
|
28
33
|
<BoxShadowRepeaterControl />
|
|
29
34
|
</StylesField>
|
|
30
|
-
|
|
35
|
+
<PanelDivider />
|
|
36
|
+
<StylesField bind="transform" propDisplayName={ TRANSFORM_LABEL }>
|
|
37
|
+
{ isUnstableRepeaterActive ? <UnstableTransformRepeaterControl /> : <TransformRepeaterControl /> }
|
|
38
|
+
</StylesField>
|
|
39
|
+
{ shouldShowTransition && (
|
|
31
40
|
<>
|
|
32
41
|
<PanelDivider />
|
|
33
|
-
<StylesField bind="
|
|
34
|
-
<
|
|
35
|
-
</StylesField>
|
|
36
|
-
<PanelDivider />
|
|
37
|
-
<StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
|
|
38
|
-
<FilterRepeaterControl />
|
|
42
|
+
<StylesField bind="transition" propDisplayName={ TRANSITIONS_LABEL }>
|
|
43
|
+
<TransitionRepeaterControl />
|
|
39
44
|
</StylesField>
|
|
40
45
|
</>
|
|
41
46
|
) }
|
|
47
|
+
<PanelDivider />
|
|
48
|
+
<StylesField bind="filter" propDisplayName={ FILTER_LABEL }>
|
|
49
|
+
<FilterRepeaterControl />
|
|
50
|
+
</StylesField>
|
|
51
|
+
<PanelDivider />
|
|
52
|
+
<StylesField bind="backdrop-filter" propDisplayName={ BACKDROP_FILTER_LABEL }>
|
|
53
|
+
<FilterRepeaterControl filterPropName="backdrop-filter" />
|
|
54
|
+
</StylesField>
|
|
42
55
|
</SectionContent>
|
|
43
56
|
);
|
|
44
57
|
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
|
|
3
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
3
|
import { __ } from '@wordpress/i18n';
|
|
5
4
|
|
|
6
5
|
import { useStylesInheritanceChain } from '../../../contexts/styles-inheritance-context';
|
|
7
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
8
|
-
import { EXPERIMENTAL_FEATURES } from '../../../sync/experiments-flags';
|
|
9
7
|
import { StylesFieldLayout } from '../../styles-field-layout';
|
|
10
8
|
|
|
11
9
|
type Displays = 'block' | 'flex' | 'inline-block' | 'inline-flex' | 'none';
|
|
@@ -31,34 +29,27 @@ const displayFieldItems: ToggleButtonGroupItem< Displays >[] = [
|
|
|
31
29
|
label: __( 'Inline-block', 'elementor' ),
|
|
32
30
|
showTooltip: true,
|
|
33
31
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
items.push( {
|
|
42
|
-
value: 'none',
|
|
43
|
-
renderContent: () => __( 'None', 'elementor' ),
|
|
44
|
-
label: __( 'None', 'elementor' ),
|
|
45
|
-
showTooltip: true,
|
|
46
|
-
} );
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
items.push( {
|
|
32
|
+
{
|
|
33
|
+
value: 'none',
|
|
34
|
+
renderContent: () => __( 'None', 'elementor' ),
|
|
35
|
+
label: __( 'None', 'elementor' ),
|
|
36
|
+
showTooltip: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
50
39
|
value: 'inline-flex',
|
|
51
40
|
renderContent: () => __( 'In-flx', 'elementor' ),
|
|
52
41
|
label: __( 'Inline-flex', 'elementor' ),
|
|
53
42
|
showTooltip: true,
|
|
54
|
-
}
|
|
43
|
+
},
|
|
44
|
+
];
|
|
55
45
|
|
|
46
|
+
export const DisplayField = () => {
|
|
56
47
|
const placeholder = useDisplayPlaceholderValue();
|
|
57
48
|
|
|
58
49
|
return (
|
|
59
50
|
<StylesField bind="display" propDisplayName={ DISPLAY_LABEL } placeholder={ placeholder }>
|
|
60
51
|
<StylesFieldLayout label={ DISPLAY_LABEL } direction="column">
|
|
61
|
-
<ToggleControl options={
|
|
52
|
+
<ToggleControl options={ displayFieldItems } maxItems={ 4 } fullWidth={ true } />
|
|
62
53
|
</StylesFieldLayout>
|
|
63
54
|
</StylesField>
|
|
64
55
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useState } from 'react';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
3
|
import { ControlToggleButtonGroup, NumberControl, type ToggleButtonGroupItem } from '@elementor/editor-controls';
|
|
4
4
|
import { type NumberPropValue } from '@elementor/editor-props';
|
|
5
5
|
import { ArrowDownSmallIcon, ArrowUpSmallIcon, PencilIcon } from '@elementor/icons';
|
|
@@ -60,6 +60,11 @@ export const FlexOrderField = () => {
|
|
|
60
60
|
|
|
61
61
|
const [ groupControlValue, setGroupControlValue ] = useState( getGroupControlValue( order?.value || null ) );
|
|
62
62
|
|
|
63
|
+
useEffect( () => {
|
|
64
|
+
const newGroupControlValue = getGroupControlValue( order?.value || null );
|
|
65
|
+
setGroupControlValue( newGroupControlValue );
|
|
66
|
+
}, [ order?.value ] );
|
|
67
|
+
|
|
63
68
|
const handleToggleButtonChange = ( group: GroupControlItemOption | null ) => {
|
|
64
69
|
setGroupControlValue( group );
|
|
65
70
|
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import {
|
|
4
4
|
ControlToggleButtonGroup,
|
|
5
5
|
NumberControl,
|
|
6
|
+
PropKeyProvider,
|
|
7
|
+
PropProvider,
|
|
6
8
|
SizeControl,
|
|
7
9
|
type ToggleButtonGroupItem,
|
|
10
|
+
useBoundProp,
|
|
8
11
|
} from '@elementor/editor-controls';
|
|
9
|
-
import {
|
|
12
|
+
import { flexPropTypeUtil, type FlexPropValue, numberPropTypeUtil } from '@elementor/editor-props';
|
|
10
13
|
import { ExpandIcon, PencilIcon, ShrinkIcon } from '@elementor/icons';
|
|
11
14
|
import { __ } from '@wordpress/i18n';
|
|
12
15
|
|
|
13
16
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
14
|
-
import {
|
|
17
|
+
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
15
18
|
import { UiProviders } from '../../../styles-inheritance/components/ui-providers';
|
|
16
19
|
import { SectionContent } from '../../section-content';
|
|
17
20
|
import { StylesFieldLayout } from '../../styles-field-layout';
|
|
@@ -44,51 +47,44 @@ const items: ToggleButtonGroupItem< GroupItem >[] = [
|
|
|
44
47
|
];
|
|
45
48
|
|
|
46
49
|
export const FlexSizeField = () => {
|
|
47
|
-
const {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
|
|
50
|
+
const { value, setValue, canEdit } = useStylesField< FlexPropValue >( 'flex', {
|
|
51
|
+
history: { propDisplayName: FLEX_SIZE_LABEL },
|
|
52
|
+
} );
|
|
53
|
+
|
|
54
|
+
const flexValue = value as FlexPropValue | null;
|
|
55
|
+
const grow = flexValue?.value?.flexGrow?.value || null;
|
|
56
|
+
const shrink = flexValue?.value?.flexShrink?.value || null;
|
|
57
|
+
const basis = flexValue?.value?.flexBasis?.value || null;
|
|
58
|
+
|
|
59
|
+
const currentGroup = useMemo( () => getActiveGroup( { grow, shrink, basis } ), [ grow, shrink, basis ] );
|
|
60
|
+
const [ activeGroup, setActiveGroup ] = useState( currentGroup );
|
|
61
|
+
const [ customLocked, setCustomLocked ] = useState( false );
|
|
62
|
+
|
|
63
|
+
useEffect( () => {
|
|
64
|
+
if ( ! customLocked ) {
|
|
65
|
+
setActiveGroup( currentGroup );
|
|
66
|
+
}
|
|
67
|
+
}, [ currentGroup, customLocked ] );
|
|
56
68
|
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
useEffect( () => {
|
|
70
|
+
if ( value === null ) {
|
|
71
|
+
setCustomLocked( false );
|
|
72
|
+
}
|
|
73
|
+
}, [ value ] );
|
|
59
74
|
|
|
60
75
|
const onChangeGroup = ( group: GroupItem | null = null ) => {
|
|
61
76
|
setActiveGroup( group );
|
|
77
|
+
setCustomLocked( group === 'custom' );
|
|
62
78
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if ( ! group || group === 'custom' ) {
|
|
66
|
-
props = {
|
|
67
|
-
'flex-basis': null,
|
|
68
|
-
'flex-grow': null,
|
|
69
|
-
'flex-shrink': null,
|
|
70
|
-
};
|
|
71
|
-
} else if ( group === 'flex-grow' ) {
|
|
72
|
-
props = {
|
|
73
|
-
'flex-basis': null,
|
|
74
|
-
'flex-grow': numberPropTypeUtil.create( DEFAULT ),
|
|
75
|
-
'flex-shrink': null,
|
|
76
|
-
};
|
|
77
|
-
} else {
|
|
78
|
-
props = {
|
|
79
|
-
'flex-basis': null,
|
|
80
|
-
'flex-grow': null,
|
|
81
|
-
'flex-shrink': numberPropTypeUtil.create( DEFAULT ),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
79
|
+
const newFlexValue = createFlexValueForGroup( group, flexValue );
|
|
84
80
|
|
|
85
|
-
|
|
81
|
+
setValue( newFlexValue as FlexPropValue );
|
|
86
82
|
};
|
|
87
83
|
|
|
88
84
|
return (
|
|
89
85
|
<UiProviders>
|
|
90
86
|
<SectionContent>
|
|
91
|
-
<StylesField bind=
|
|
87
|
+
<StylesField bind="flex" propDisplayName={ FLEX_SIZE_LABEL }>
|
|
92
88
|
<StylesFieldLayout label={ FLEX_SIZE_LABEL }>
|
|
93
89
|
<ControlToggleButtonGroup
|
|
94
90
|
value={ activeGroup }
|
|
@@ -98,34 +94,72 @@ export const FlexSizeField = () => {
|
|
|
98
94
|
exclusive={ true }
|
|
99
95
|
/>
|
|
100
96
|
</StylesFieldLayout>
|
|
97
|
+
{ 'custom' === activeGroup && <FlexCustomField /> }
|
|
101
98
|
</StylesField>
|
|
102
|
-
{ 'custom' === activeGroup && <FlexCustomField /> }
|
|
103
99
|
</SectionContent>
|
|
104
100
|
</UiProviders>
|
|
105
101
|
);
|
|
106
102
|
};
|
|
107
103
|
|
|
104
|
+
const createFlexValueForGroup = ( group: GroupItem | null, flexValue: FlexPropValue | null ): FlexPropValue | null => {
|
|
105
|
+
if ( ! group ) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if ( group === 'flex-grow' ) {
|
|
110
|
+
return flexPropTypeUtil.create( {
|
|
111
|
+
flexGrow: numberPropTypeUtil.create( DEFAULT ),
|
|
112
|
+
flexShrink: null,
|
|
113
|
+
flexBasis: null,
|
|
114
|
+
} );
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if ( group === 'flex-shrink' ) {
|
|
118
|
+
return flexPropTypeUtil.create( {
|
|
119
|
+
flexGrow: null,
|
|
120
|
+
flexShrink: numberPropTypeUtil.create( DEFAULT ),
|
|
121
|
+
flexBasis: null,
|
|
122
|
+
} );
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if ( group === 'custom' ) {
|
|
126
|
+
if ( flexValue ) {
|
|
127
|
+
return flexValue;
|
|
128
|
+
}
|
|
129
|
+
return flexPropTypeUtil.create( {
|
|
130
|
+
flexGrow: null,
|
|
131
|
+
flexShrink: null,
|
|
132
|
+
flexBasis: null,
|
|
133
|
+
} );
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return null;
|
|
137
|
+
};
|
|
138
|
+
|
|
108
139
|
const FlexCustomField = () => {
|
|
109
140
|
const flexBasisRowRef = useRef< HTMLDivElement >( null );
|
|
141
|
+
const context = useBoundProp( flexPropTypeUtil );
|
|
110
142
|
|
|
111
143
|
return (
|
|
112
|
-
|
|
113
|
-
|
|
144
|
+
<PropProvider { ...context }>
|
|
145
|
+
<>
|
|
114
146
|
<StylesFieldLayout label={ __( 'Grow', 'elementor' ) }>
|
|
115
|
-
<
|
|
147
|
+
<PropKeyProvider bind="flexGrow">
|
|
148
|
+
<NumberControl min={ 0 } shouldForceInt={ true } />
|
|
149
|
+
</PropKeyProvider>
|
|
116
150
|
</StylesFieldLayout>
|
|
117
|
-
</StylesField>
|
|
118
|
-
<StylesField bind="flex-shrink" propDisplayName={ FLEX_SIZE_LABEL }>
|
|
119
151
|
<StylesFieldLayout label={ __( 'Shrink', 'elementor' ) }>
|
|
120
|
-
<
|
|
152
|
+
<PropKeyProvider bind="flexShrink">
|
|
153
|
+
<NumberControl min={ 0 } shouldForceInt={ true } />
|
|
154
|
+
</PropKeyProvider>
|
|
121
155
|
</StylesFieldLayout>
|
|
122
|
-
</StylesField>
|
|
123
|
-
<StylesField bind="flex-basis" propDisplayName={ FLEX_SIZE_LABEL }>
|
|
124
156
|
<StylesFieldLayout label={ __( 'Basis', 'elementor' ) } ref={ flexBasisRowRef }>
|
|
125
|
-
<
|
|
157
|
+
<PropKeyProvider bind="flexBasis">
|
|
158
|
+
<SizeControl extendedOptions={ [ 'auto' ] } anchorRef={ flexBasisRowRef } />
|
|
159
|
+
</PropKeyProvider>
|
|
126
160
|
</StylesFieldLayout>
|
|
127
|
-
|
|
128
|
-
|
|
161
|
+
</>
|
|
162
|
+
</PropProvider>
|
|
129
163
|
);
|
|
130
164
|
};
|
|
131
165
|
|
|
@@ -134,9 +168,9 @@ const getActiveGroup = ( {
|
|
|
134
168
|
shrink,
|
|
135
169
|
basis,
|
|
136
170
|
}: {
|
|
137
|
-
grow:
|
|
138
|
-
shrink:
|
|
139
|
-
basis:
|
|
171
|
+
grow: number | null;
|
|
172
|
+
shrink: number | null;
|
|
173
|
+
basis: { size: number; unit: string } | string | null;
|
|
140
174
|
} ): GroupItem | null => {
|
|
141
175
|
if ( null === grow && null === shrink && ! basis ) {
|
|
142
176
|
return null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useRef } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { type LengthUnit, SizeControl } from '@elementor/editor-controls';
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
|
|
6
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
@@ -8,7 +8,7 @@ import { StylesFieldLayout } from '../../styles-field-layout';
|
|
|
8
8
|
|
|
9
9
|
const OFFSET_LABEL = __( 'Anchor offset', 'elementor' );
|
|
10
10
|
|
|
11
|
-
const UNITS:
|
|
11
|
+
const UNITS: LengthUnit[] = [ 'px', 'em', 'rem', 'vw', 'vh' ];
|
|
12
12
|
|
|
13
13
|
export const OffsetField = () => {
|
|
14
14
|
const rowRef = useRef< HTMLDivElement >( null );
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type StringPropValue } from '@elementor/editor-props';
|
|
3
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
3
|
import { useSessionStorage } from '@elementor/session';
|
|
5
4
|
import { __ } from '@wordpress/i18n';
|
|
6
5
|
|
|
@@ -44,7 +43,6 @@ export const PositionSection = () => {
|
|
|
44
43
|
] );
|
|
45
44
|
|
|
46
45
|
const [ dimensionsValuesFromHistory, updateDimensionsHistory, clearDimensionsHistory ] = usePersistDimensions();
|
|
47
|
-
const isCssIdFeatureActive = isExperimentActive( 'e_v_3_30' );
|
|
48
46
|
|
|
49
47
|
const onPositionChange = ( newPosition: string | null, previousPosition: string | null | undefined ) => {
|
|
50
48
|
const meta = { history: { propDisplayName: DIMENSIONS_LABEL } };
|
|
@@ -82,12 +80,8 @@ export const PositionSection = () => {
|
|
|
82
80
|
</>
|
|
83
81
|
) : null }
|
|
84
82
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<PanelDivider />
|
|
88
|
-
<OffsetField />
|
|
89
|
-
</>
|
|
90
|
-
) }
|
|
83
|
+
<PanelDivider />
|
|
84
|
+
<OffsetField />
|
|
91
85
|
</SectionContent>
|
|
92
86
|
);
|
|
93
87
|
};
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type RefObject, useRef } from 'react';
|
|
3
|
-
import { AspectRatioControl, type ExtendedOption, SizeControl } from '@elementor/editor-controls';
|
|
4
|
-
import type { StringPropValue } from '@elementor/editor-props';
|
|
5
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
3
|
+
import { AspectRatioControl, type ExtendedOption, PositionControl, SizeControl } from '@elementor/editor-controls';
|
|
6
4
|
import { Grid, Stack } from '@elementor/ui';
|
|
7
5
|
import { __ } from '@wordpress/i18n';
|
|
8
6
|
|
|
9
7
|
import { StylesField, type StylesFieldProps } from '../../../controls-registry/styles-field';
|
|
10
|
-
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
11
8
|
import { ControlLabel } from '../../control-label';
|
|
12
9
|
import { PanelDivider } from '../../panel-divider';
|
|
13
10
|
import { SectionContent } from '../../section-content';
|
|
14
11
|
import { StyleTabCollapsibleContent } from '../../style-tab-collapsible-content';
|
|
15
12
|
import { ObjectFitField } from './object-fit-field';
|
|
16
|
-
import { ObjectPositionField } from './object-position-field';
|
|
17
13
|
import { OverflowField } from './overflow-field';
|
|
18
14
|
|
|
19
|
-
const EXPERIMENT_ID = 'e_v_3_30';
|
|
20
|
-
|
|
21
15
|
const CssSizeProps = [
|
|
22
16
|
[
|
|
23
17
|
{
|
|
@@ -52,17 +46,9 @@ const CssSizeProps = [
|
|
|
52
46
|
];
|
|
53
47
|
|
|
54
48
|
const ASPECT_RATIO_LABEL = __( 'Aspect Ratio', 'elementor' );
|
|
55
|
-
const OBJECT_FIT_LABEL = __( 'Object fit', 'elementor' );
|
|
56
49
|
|
|
57
50
|
export const SizeSection = () => {
|
|
58
|
-
const { value: fitValue } = useStylesField< StringPropValue >( 'object-fit', {
|
|
59
|
-
history: { propDisplayName: OBJECT_FIT_LABEL },
|
|
60
|
-
} );
|
|
61
|
-
|
|
62
|
-
const isNotFill = fitValue && fitValue?.value !== 'fill';
|
|
63
|
-
|
|
64
51
|
const gridRowRefs: RefObject< HTMLDivElement >[] = [ useRef( null ), useRef( null ), useRef( null ) ];
|
|
65
|
-
const isVersion330Active = isExperimentActive( EXPERIMENT_ID );
|
|
66
52
|
|
|
67
53
|
return (
|
|
68
54
|
<SectionContent>
|
|
@@ -79,22 +65,21 @@ export const SizeSection = () => {
|
|
|
79
65
|
<Stack>
|
|
80
66
|
<OverflowField />
|
|
81
67
|
</Stack>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
) }
|
|
68
|
+
|
|
69
|
+
<StyleTabCollapsibleContent fields={ [ 'aspect-ratio', 'object-fit' ] }>
|
|
70
|
+
<Stack gap={ 2 } pt={ 2 }>
|
|
71
|
+
<StylesField bind="aspect-ratio" propDisplayName={ ASPECT_RATIO_LABEL }>
|
|
72
|
+
<AspectRatioControl label={ ASPECT_RATIO_LABEL } />
|
|
73
|
+
</StylesField>
|
|
74
|
+
<PanelDivider />
|
|
75
|
+
<ObjectFitField />
|
|
76
|
+
<StylesField bind="object-position" propDisplayName={ __( 'Object position', 'elementor' ) }>
|
|
77
|
+
<Grid item xs={ 6 }>
|
|
78
|
+
<PositionControl />
|
|
79
|
+
</Grid>
|
|
80
|
+
</StylesField>
|
|
81
|
+
</Stack>
|
|
82
|
+
</StyleTabCollapsibleContent>
|
|
98
83
|
</SectionContent>
|
|
99
84
|
);
|
|
100
85
|
};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { NumberPropValue } from '@elementor/editor-props';
|
|
3
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
|
-
import { __ } from '@wordpress/i18n';
|
|
5
2
|
|
|
6
|
-
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
7
3
|
import { PanelDivider } from '../../panel-divider';
|
|
8
4
|
import { SectionContent } from '../../section-content';
|
|
9
5
|
import { StyleTabCollapsibleContent } from '../../style-tab-collapsible-content';
|
|
@@ -23,16 +19,7 @@ import { TextStrokeField } from './text-stroke-field';
|
|
|
23
19
|
import { TransformField } from './transform-field';
|
|
24
20
|
import { WordSpacingField } from './word-spacing-field';
|
|
25
21
|
|
|
26
|
-
const COLUMN_COUNT_LABEL = __( 'Column count', 'elementor' );
|
|
27
|
-
|
|
28
22
|
export const TypographySection = () => {
|
|
29
|
-
const { value: columnCount } = useStylesField< NumberPropValue >( 'column-count', {
|
|
30
|
-
history: { propDisplayName: COLUMN_COUNT_LABEL },
|
|
31
|
-
} );
|
|
32
|
-
const hasMultiColumns = !! ( columnCount?.value && columnCount?.value > 1 );
|
|
33
|
-
|
|
34
|
-
const isVersion330Active = isExperimentActive( 'e_v_3_30' );
|
|
35
|
-
|
|
36
23
|
return (
|
|
37
24
|
<SectionContent>
|
|
38
25
|
<FontFamilyField />
|
|
@@ -58,12 +45,8 @@ export const TypographySection = () => {
|
|
|
58
45
|
<LineHeightField />
|
|
59
46
|
<LetterSpacingField />
|
|
60
47
|
<WordSpacingField />
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<ColumnCountField />
|
|
64
|
-
{ hasMultiColumns && <ColumnGapField /> }
|
|
65
|
-
</>
|
|
66
|
-
) }
|
|
48
|
+
<ColumnCountField />
|
|
49
|
+
<ColumnGapField />
|
|
67
50
|
<PanelDivider />
|
|
68
51
|
<TextDecorationField />
|
|
69
52
|
<TransformField />
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type PropsWithChildren } from 'react';
|
|
3
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
3
|
|
|
5
4
|
import { StylesInheritanceSectionIndicators } from '../styles-inheritance/components/styles-inheritance-section-indicators';
|
|
6
|
-
import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
|
|
7
5
|
import { CollapsibleContent } from './collapsible-content';
|
|
8
6
|
type Props = PropsWithChildren< { fields?: string[] } >;
|
|
9
7
|
|
|
@@ -12,9 +10,7 @@ export const StyleTabCollapsibleContent = ( { fields = [], children }: Props ) =
|
|
|
12
10
|
};
|
|
13
11
|
|
|
14
12
|
export function getStylesInheritanceIndicators( fields: string[] ) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if ( fields.length === 0 || ! isUsingFieldsIndicators ) {
|
|
13
|
+
if ( fields.length === 0 ) {
|
|
18
14
|
return null;
|
|
19
15
|
}
|
|
20
16
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
3
2
|
|
|
4
3
|
import { useDefaultPanelSettings } from '../hooks/use-default-panel-settings';
|
|
5
|
-
import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
|
|
6
4
|
import { Section } from './section';
|
|
7
5
|
import { getStylesInheritanceIndicators } from './style-tab-collapsible-content';
|
|
8
6
|
|
|
@@ -18,9 +16,7 @@ export const StyleTabSection = ( { section, fields = [] }: Props ) => {
|
|
|
18
16
|
const { component, name, title } = section;
|
|
19
17
|
const tabDefaults = useDefaultPanelSettings();
|
|
20
18
|
const SectionComponent = component;
|
|
21
|
-
const isExpanded =
|
|
22
|
-
? tabDefaults.defaultSectionsExpanded.style?.includes( name )
|
|
23
|
-
: false;
|
|
19
|
+
const isExpanded = tabDefaults.defaultSectionsExpanded.style?.includes( name );
|
|
24
20
|
|
|
25
21
|
return (
|
|
26
22
|
<Section title={ title } defaultExpanded={ isExpanded } titleEnd={ getStylesInheritanceIndicators( fields ) }>
|
|
@@ -3,8 +3,9 @@ import { useState } from 'react';
|
|
|
3
3
|
import { CLASSES_PROP_KEY } from '@elementor/editor-props';
|
|
4
4
|
import { useActiveBreakpoint } from '@elementor/editor-responsive';
|
|
5
5
|
import { type StyleDefinitionID, type StyleDefinitionState } from '@elementor/editor-styles';
|
|
6
|
+
import { EXPERIMENTAL_FEATURES, isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
6
7
|
import { SessionStorageProvider } from '@elementor/session';
|
|
7
|
-
import { Divider, Stack } from '@elementor/ui';
|
|
8
|
+
import { Box, Divider, Stack } from '@elementor/ui';
|
|
8
9
|
import { __ } from '@wordpress/i18n';
|
|
9
10
|
|
|
10
11
|
import { ClassesPropProvider } from '../contexts/classes-prop-context';
|
|
@@ -14,6 +15,7 @@ import { StyleProvider } from '../contexts/style-context';
|
|
|
14
15
|
import { StyleInheritanceProvider } from '../contexts/styles-inheritance-context';
|
|
15
16
|
import { useActiveStyleDefId } from '../hooks/use-active-style-def-id';
|
|
16
17
|
import { CssClassSelector } from './css-classes/css-class-selector';
|
|
18
|
+
import { CustomCss } from './custom-css';
|
|
17
19
|
import { SectionsList } from './sections-list';
|
|
18
20
|
import { BackgroundSection } from './style-sections/background-section/background-section';
|
|
19
21
|
import { BorderSection } from './style-sections/border-section/border-section';
|
|
@@ -40,6 +42,7 @@ export const StyleTab = () => {
|
|
|
40
42
|
const [ activeStyleDefId, setActiveStyleDefId ] = useActiveStyleDefId( currentClassesProp );
|
|
41
43
|
const [ activeStyleState, setActiveStyleState ] = useState< StyleDefinitionState | null >( null );
|
|
42
44
|
const breakpoint = useActiveBreakpoint();
|
|
45
|
+
const shouldRenderCustomCss = isExperimentActive( EXPERIMENTAL_FEATURES.CUSTOM_CSS );
|
|
43
46
|
|
|
44
47
|
return (
|
|
45
48
|
<ClassesPropProvider prop={ currentClassesProp }>
|
|
@@ -155,9 +158,19 @@ export const StyleTab = () => {
|
|
|
155
158
|
name: 'Effects',
|
|
156
159
|
title: __( 'Effects', 'elementor' ),
|
|
157
160
|
} }
|
|
158
|
-
fields={ [ 'box-shadow' ] }
|
|
161
|
+
fields={ [ 'box-shadow', 'opacity', 'transform', 'filter', 'backdrop-filter' ] }
|
|
159
162
|
/>
|
|
163
|
+
{ shouldRenderCustomCss && (
|
|
164
|
+
<StyleTabSection
|
|
165
|
+
section={ {
|
|
166
|
+
component: CustomCss,
|
|
167
|
+
name: 'Custom CSS',
|
|
168
|
+
title: __( 'Custom CSS', 'elementor' ),
|
|
169
|
+
} }
|
|
170
|
+
/>
|
|
171
|
+
) }
|
|
160
172
|
</SectionsList>
|
|
173
|
+
<Box sx={ { height: '150px' } } />
|
|
161
174
|
</StyleInheritanceProvider>
|
|
162
175
|
</SessionStorageProvider>
|
|
163
176
|
</StyleProvider>
|
package/src/controls-actions.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useBoundProp } from '@elementor/editor-controls';
|
|
2
|
+
import { isDependency, isDependencyMet, type PropKey, type PropType } from '@elementor/editor-props';
|
|
3
|
+
|
|
4
|
+
import { useStylesFields } from '../hooks/use-styles-fields';
|
|
5
|
+
|
|
6
|
+
export const ConditionalField: React.FC< {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
} > = ( { children } ) => {
|
|
9
|
+
const { propType } = useBoundProp();
|
|
10
|
+
|
|
11
|
+
const depList = getDependencies( propType );
|
|
12
|
+
|
|
13
|
+
const { values: depValues } = useStylesFields( depList );
|
|
14
|
+
|
|
15
|
+
const isHidden = ! isDependencyMet( propType?.dependencies, depValues );
|
|
16
|
+
|
|
17
|
+
return isHidden ? null : children;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function getDependencies( propType?: PropType ): PropKey[] {
|
|
21
|
+
if ( ! propType?.dependencies?.terms.length ) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return propType.dependencies.terms.flatMap( ( term ) => ( ! isDependency( term ) ? term.path : [] ) );
|
|
26
|
+
}
|