@elementor/editor-editing-panel 1.45.0 → 1.46.0
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 +42 -0
- package/dist/index.d.mts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +702 -688
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +587 -573
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -13
- package/src/components/css-classes/css-class-menu.tsx +6 -8
- package/src/components/css-classes/css-class-selector.tsx +17 -11
- package/src/components/settings-tab.tsx +25 -2
- package/src/components/style-indicator.tsx +19 -15
- package/src/components/style-sections/border-section/border-field.tsx +4 -6
- package/src/components/style-sections/effects-section/effects-section.tsx +6 -0
- package/src/components/style-sections/layout-section/flex-order-field.tsx +1 -3
- package/src/components/style-sections/layout-section/flex-size-field.tsx +7 -10
- package/src/components/style-sections/layout-section/layout-section.tsx +2 -2
- package/src/components/style-sections/layout-section/opacity-control-field.tsx +25 -0
- package/src/components/style-sections/layout-section/utils/rotated-icon.tsx +1 -1
- package/src/components/style-sections/position-section/position-section.tsx +6 -6
- package/src/components/style-sections/size-section/object-position-field.tsx +2 -24
- package/src/components/style-sections/size-section/size-section.tsx +1 -1
- package/src/components/style-sections/typography-section/text-stroke-field.tsx +4 -6
- package/src/components/style-sections/typography-section/typography-section.tsx +4 -2
- package/src/controls-registry/controls-registry.tsx +30 -10
- package/src/controls-registry/styles-field.tsx +1 -3
- package/src/dynamics/components/dynamic-selection-control.tsx +10 -18
- package/src/dynamics/components/dynamic-selection.tsx +58 -77
- package/src/dynamics/hooks/use-prop-dynamic-action.tsx +1 -1
- package/src/hooks/use-styles-field.ts +9 -3
- package/src/hooks/use-styles-fields.ts +4 -4
- package/src/index.ts +1 -0
- package/src/popover-action.tsx +3 -5
- package/src/provider-colors-registry.ts +20 -0
- package/src/styles-inheritance/components/infotip/label-chip.tsx +4 -5
- package/src/styles-inheritance/components/styles-inheritance-indicator.tsx +32 -40
- package/src/styles-inheritance/components/styles-inheritance-infotip.tsx +1 -5
- package/src/styles-inheritance/components/styles-inheritance-section-indicators.tsx +29 -44
- package/src/styles-inheritance/hooks/use-normalized-inheritance-chain-items.tsx +1 -17
- package/src/styles-inheritance/types.ts +0 -2
- package/src/styles-inheritance/utils.ts +17 -1
- package/src/utils/get-styles-provider-color.ts +28 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-editing-panel",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -39,31 +39,32 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "0.
|
|
43
|
-
"@elementor/editor-canvas": "0.
|
|
44
|
-
"@elementor/editor-controls": "1.
|
|
42
|
+
"@elementor/editor": "0.20.0",
|
|
43
|
+
"@elementor/editor-canvas": "0.24.0",
|
|
44
|
+
"@elementor/editor-controls": "1.1.0",
|
|
45
45
|
"@elementor/editor-current-user": "0.5.0",
|
|
46
|
-
"@elementor/editor-documents": "0.13.
|
|
47
|
-
"@elementor/editor-elements": "0.8.
|
|
48
|
-
"@elementor/editor-panels": "0.
|
|
49
|
-
"@elementor/editor-props": "0.
|
|
46
|
+
"@elementor/editor-documents": "0.13.7",
|
|
47
|
+
"@elementor/editor-elements": "0.8.6",
|
|
48
|
+
"@elementor/editor-panels": "0.16.0",
|
|
49
|
+
"@elementor/editor-props": "0.14.0",
|
|
50
50
|
"@elementor/editor-responsive": "0.13.5",
|
|
51
|
-
"@elementor/editor-styles": "0.6.
|
|
52
|
-
"@elementor/editor-styles-repository": "0.10.
|
|
53
|
-
"@elementor/editor-ui": "0.
|
|
51
|
+
"@elementor/editor-styles": "0.6.10",
|
|
52
|
+
"@elementor/editor-styles-repository": "0.10.3",
|
|
53
|
+
"@elementor/editor-ui": "0.12.0",
|
|
54
54
|
"@elementor/editor-v1-adapters": "0.12.0",
|
|
55
55
|
"@elementor/icons": "1.44.0",
|
|
56
56
|
"@elementor/locations": "0.8.0",
|
|
57
57
|
"@elementor/menus": "0.1.5",
|
|
58
58
|
"@elementor/schema": "0.1.2",
|
|
59
59
|
"@elementor/session": "0.1.0",
|
|
60
|
-
"@elementor/ui": "1.
|
|
60
|
+
"@elementor/ui": "1.35.5",
|
|
61
61
|
"@elementor/utils": "0.4.0",
|
|
62
62
|
"@elementor/wp-media": "0.6.0",
|
|
63
63
|
"@wordpress/i18n": "^5.13.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"react": "^18.3.1"
|
|
66
|
+
"react": "^18.3.1",
|
|
67
|
+
"react-dom": "^18.3.1"
|
|
67
68
|
},
|
|
68
69
|
"devDependencies": {
|
|
69
70
|
"tsup": "^8.3.5"
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type StyleDefinitionState } from '@elementor/editor-styles';
|
|
3
|
-
import {
|
|
4
|
-
isElementsStylesProvider,
|
|
5
|
-
stylesRepository,
|
|
6
|
-
useUserStylesCapability,
|
|
7
|
-
} from '@elementor/editor-styles-repository';
|
|
3
|
+
import { stylesRepository, useUserStylesCapability } from '@elementor/editor-styles-repository';
|
|
8
4
|
import { MenuItemInfotip, MenuListItem } from '@elementor/editor-ui';
|
|
9
5
|
import { bindMenu, Divider, Menu, MenuSubheader, type PopupState, Stack } from '@elementor/ui';
|
|
10
6
|
import { __ } from '@wordpress/i18n';
|
|
11
7
|
|
|
12
8
|
import { useStyle } from '../../contexts/style-context';
|
|
13
9
|
import { type StyleDefinitionStateWithNormal } from '../../styles-inheritance/types';
|
|
10
|
+
import { getStylesProviderThemeColor } from '../../utils/get-styles-provider-color';
|
|
14
11
|
import { StyleIndicator } from '../style-indicator';
|
|
15
12
|
import { useCssClass } from './css-class-context';
|
|
16
13
|
import { useUnapplyClass } from './use-apply-and-unapply-class';
|
|
@@ -135,8 +132,6 @@ function StateMenuItem( { state, closeMenu, ...props }: StateMenuItemProps ) {
|
|
|
135
132
|
|
|
136
133
|
const isUpdateAllowed = ! state || userCan( provider ?? '' ).updateProps;
|
|
137
134
|
|
|
138
|
-
const indicatorVariant = ! provider || isElementsStylesProvider( provider ) ? 'local' : 'global';
|
|
139
|
-
|
|
140
135
|
const isStyled = modifiedStates[ state ?? 'normal' ] ?? false;
|
|
141
136
|
const disabled = ! isUpdateAllowed && ! isStyled;
|
|
142
137
|
const isActive = styleId === activeId;
|
|
@@ -164,7 +159,10 @@ function StateMenuItem( { state, closeMenu, ...props }: StateMenuItemProps ) {
|
|
|
164
159
|
>
|
|
165
160
|
<Stack gap={ 0.75 } direction="row" alignItems="center">
|
|
166
161
|
{ isStyled && (
|
|
167
|
-
<StyleIndicator
|
|
162
|
+
<StyleIndicator
|
|
163
|
+
aria-label={ __( 'Has style', 'elementor' ) }
|
|
164
|
+
getColor={ getStylesProviderThemeColor( provider ?? '' ) }
|
|
165
|
+
/>
|
|
168
166
|
) }
|
|
169
167
|
{ state ?? 'normal' }
|
|
170
168
|
</Stack>
|
|
@@ -14,12 +14,22 @@ import {
|
|
|
14
14
|
import { InfoAlert, WarningInfotip } from '@elementor/editor-ui';
|
|
15
15
|
import { ColorSwatchIcon, MapPinIcon } from '@elementor/icons';
|
|
16
16
|
import { createLocation } from '@elementor/locations';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
type AutocompleteChangeReason,
|
|
19
|
+
Box,
|
|
20
|
+
Chip,
|
|
21
|
+
type ChipOwnProps,
|
|
22
|
+
FormLabel,
|
|
23
|
+
Link,
|
|
24
|
+
Stack,
|
|
25
|
+
Typography,
|
|
26
|
+
} from '@elementor/ui';
|
|
18
27
|
import { __ } from '@wordpress/i18n';
|
|
19
28
|
|
|
20
29
|
import { useClassesProp } from '../../contexts/classes-prop-context';
|
|
21
30
|
import { useElement } from '../../contexts/element-context';
|
|
22
31
|
import { useStyle } from '../../contexts/style-context';
|
|
32
|
+
import { getStylesProviderColorName } from '../../utils/get-styles-provider-color';
|
|
23
33
|
import {
|
|
24
34
|
CreatableAutocomplete,
|
|
25
35
|
type CreatableAutocompleteProps,
|
|
@@ -34,7 +44,7 @@ const ID = 'elementor-css-class-selector';
|
|
|
34
44
|
const TAGS_LIMIT = 50;
|
|
35
45
|
|
|
36
46
|
type StyleDefOption = Option & {
|
|
37
|
-
color: '
|
|
47
|
+
color: ChipOwnProps[ 'color' ];
|
|
38
48
|
icon: ReactElement | null;
|
|
39
49
|
provider: string | null;
|
|
40
50
|
};
|
|
@@ -141,13 +151,9 @@ export function CssClassSelector() {
|
|
|
141
151
|
/>
|
|
142
152
|
</WarningInfotip>
|
|
143
153
|
{ ! canEdit && (
|
|
144
|
-
<InfoAlert
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
'elementor'
|
|
148
|
-
) }
|
|
149
|
-
sx={ { mt: 1 } }
|
|
150
|
-
/>
|
|
154
|
+
<InfoAlert sx={ { mt: 1 } }>
|
|
155
|
+
{ __( 'With your current role, you can use existing classes but can’t modify them.', 'elementor' ) }
|
|
156
|
+
</InfoAlert>
|
|
151
157
|
) }
|
|
152
158
|
</Stack>
|
|
153
159
|
);
|
|
@@ -205,7 +211,7 @@ function useOptions() {
|
|
|
205
211
|
const isElements = isElementsStylesProvider( provider.getKey() );
|
|
206
212
|
const styleDefs = provider.actions.all( { elementId: element.id } );
|
|
207
213
|
|
|
208
|
-
// Add empty local option for elements, as fallback.
|
|
214
|
+
// Add an empty local option for elements, as fallback.
|
|
209
215
|
if ( isElements && styleDefs.length === 0 ) {
|
|
210
216
|
return [ EMPTY_OPTION ];
|
|
211
217
|
}
|
|
@@ -215,7 +221,7 @@ function useOptions() {
|
|
|
215
221
|
label: styleDef.label,
|
|
216
222
|
value: styleDef.id,
|
|
217
223
|
fixed: isElements,
|
|
218
|
-
color:
|
|
224
|
+
color: getStylesProviderColorName( provider.getKey() ),
|
|
219
225
|
icon: isElements ? <MapPinIcon /> : null,
|
|
220
226
|
provider: provider.getKey(),
|
|
221
227
|
};
|
|
@@ -8,7 +8,12 @@ import { Divider } from '@elementor/ui';
|
|
|
8
8
|
import { useElement } from '../contexts/element-context';
|
|
9
9
|
import { Control as BaseControl } from '../controls-registry/control';
|
|
10
10
|
import { ControlTypeContainer } from '../controls-registry/control-type-container';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
type ControlType,
|
|
13
|
+
getControl,
|
|
14
|
+
getDefaultLayout,
|
|
15
|
+
getPropTypeUtil,
|
|
16
|
+
} from '../controls-registry/controls-registry';
|
|
12
17
|
import { SettingsField } from '../controls-registry/settings-field';
|
|
13
18
|
import { useDefaultPanelSettings } from '../hooks/use-default-panel-settings';
|
|
14
19
|
import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
|
|
@@ -64,14 +69,32 @@ const Control = ( { control }: { control: Control[ 'value' ] } ) => {
|
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
const layout = control.meta?.layout || getDefaultLayout( control.type as ControlType );
|
|
72
|
+
const controlProps = populateChildControlProps( control.props );
|
|
67
73
|
|
|
68
74
|
return (
|
|
69
75
|
<SettingsField bind={ control.bind }>
|
|
70
76
|
{ control.meta?.topDivider && <Divider /> }
|
|
71
77
|
<ControlTypeContainer layout={ layout }>
|
|
72
78
|
{ control.label ? <ControlFormLabel>{ control.label }</ControlFormLabel> : null }
|
|
73
|
-
<BaseControl type={ control.type as ControlType } props={
|
|
79
|
+
<BaseControl type={ control.type as ControlType } props={ controlProps } />
|
|
74
80
|
</ControlTypeContainer>
|
|
75
81
|
</SettingsField>
|
|
76
82
|
);
|
|
77
83
|
};
|
|
84
|
+
|
|
85
|
+
function populateChildControlProps( props: Record< string, unknown > ) {
|
|
86
|
+
if ( props.childControlType ) {
|
|
87
|
+
const childComponent = getControl( props.childControlType as ControlType );
|
|
88
|
+
const childPropType = getPropTypeUtil( props.childControlType as ControlType );
|
|
89
|
+
props = {
|
|
90
|
+
...props,
|
|
91
|
+
childControlConfig: {
|
|
92
|
+
component: childComponent,
|
|
93
|
+
props: props.childControlProps || {},
|
|
94
|
+
propTypeUtil: childPropType,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return props;
|
|
100
|
+
}
|
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
import { styled } from '@elementor/ui';
|
|
2
|
-
|
|
3
|
-
type StyleIndicatorVariant = 'overridden' | 'local' | 'global';
|
|
1
|
+
import { styled, type Theme } from '@elementor/ui';
|
|
4
2
|
|
|
5
3
|
export const StyleIndicator = styled( 'div', {
|
|
6
|
-
shouldForwardProp: ( prop ) =>
|
|
7
|
-
} )<
|
|
4
|
+
shouldForwardProp: ( prop: string ) => ! [ 'isOverridden', 'getColor' ].includes( prop ),
|
|
5
|
+
} )<
|
|
6
|
+
| {
|
|
7
|
+
isOverridden?: boolean;
|
|
8
|
+
getColor?: never;
|
|
9
|
+
}
|
|
10
|
+
| {
|
|
11
|
+
isOverridden?: boolean;
|
|
12
|
+
getColor?: ( ( theme: Theme ) => string ) | null;
|
|
13
|
+
}
|
|
14
|
+
>`
|
|
8
15
|
width: 5px;
|
|
9
16
|
height: 5px;
|
|
10
17
|
border-radius: 50%;
|
|
11
|
-
background-color: ${ ( { theme,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return theme.palette.warning.light;
|
|
15
|
-
case 'global':
|
|
16
|
-
return theme.palette.global.dark;
|
|
17
|
-
case 'local':
|
|
18
|
-
return theme.palette.accent.main;
|
|
19
|
-
default:
|
|
20
|
-
return theme.palette.text.disabled;
|
|
18
|
+
background-color: ${ ( { theme, isOverridden, getColor } ) => {
|
|
19
|
+
if ( isOverridden ) {
|
|
20
|
+
return theme.palette.warning.light;
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
const providerColor = getColor?.( theme );
|
|
24
|
+
|
|
25
|
+
return providerColor ?? theme.palette.text.disabled;
|
|
22
26
|
} };
|
|
23
27
|
`;
|
|
@@ -2,7 +2,6 @@ import * as React from 'react';
|
|
|
2
2
|
import { ControlFormLabel } from '@elementor/editor-controls';
|
|
3
3
|
import { __ } from '@wordpress/i18n';
|
|
4
4
|
|
|
5
|
-
import { useStyle } from '../../../contexts/style-context';
|
|
6
5
|
import { useStylesFields } from '../../../hooks/use-styles-fields';
|
|
7
6
|
import { AddOrRemoveContent } from '../../add-or-remove-content';
|
|
8
7
|
import { BorderColorField } from './border-color-field';
|
|
@@ -16,22 +15,21 @@ const initialBorder = {
|
|
|
16
15
|
};
|
|
17
16
|
|
|
18
17
|
export const BorderField = () => {
|
|
19
|
-
const { canEdit } =
|
|
20
|
-
const [ border, setBorder ] = useStylesFields( Object.keys( initialBorder ) );
|
|
18
|
+
const { values, setValues, canEdit } = useStylesFields( Object.keys( initialBorder ) );
|
|
21
19
|
|
|
22
20
|
const addBorder = () => {
|
|
23
|
-
|
|
21
|
+
setValues( initialBorder );
|
|
24
22
|
};
|
|
25
23
|
|
|
26
24
|
const removeBorder = () => {
|
|
27
|
-
|
|
25
|
+
setValues( {
|
|
28
26
|
'border-width': null,
|
|
29
27
|
'border-color': null,
|
|
30
28
|
'border-style': null,
|
|
31
29
|
} );
|
|
32
30
|
};
|
|
33
31
|
|
|
34
|
-
const hasBorder = Object.values(
|
|
32
|
+
const hasBorder = Object.values( values ?? {} ).some( Boolean );
|
|
35
33
|
|
|
36
34
|
return (
|
|
37
35
|
<AddOrRemoveContent
|
|
@@ -2,11 +2,17 @@ import * as React from 'react';
|
|
|
2
2
|
import { BoxShadowRepeaterControl } from '@elementor/editor-controls';
|
|
3
3
|
|
|
4
4
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
5
|
+
import { PanelDivider } from '../../panel-divider';
|
|
5
6
|
import { SectionContent } from '../../section-content';
|
|
7
|
+
import { OpacityControlField } from '../layout-section/opacity-control-field';
|
|
6
8
|
|
|
7
9
|
export const EffectsSection = () => {
|
|
8
10
|
return (
|
|
9
11
|
<SectionContent>
|
|
12
|
+
<StylesField bind="opacity">
|
|
13
|
+
<OpacityControlField />
|
|
14
|
+
</StylesField>
|
|
15
|
+
<PanelDivider />
|
|
10
16
|
<StylesField bind="box-shadow">
|
|
11
17
|
<BoxShadowRepeaterControl />
|
|
12
18
|
</StylesField>
|
|
@@ -6,7 +6,6 @@ import { ArrowDownSmallIcon, ArrowUpSmallIcon, PencilIcon } from '@elementor/ico
|
|
|
6
6
|
import { Grid } from '@elementor/ui';
|
|
7
7
|
import { __ } from '@wordpress/i18n';
|
|
8
8
|
|
|
9
|
-
import { useStyle } from '../../../contexts/style-context';
|
|
10
9
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
11
10
|
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
12
11
|
import { UiProviders } from '../../../styles-inheritance/components/ui-providers';
|
|
@@ -48,8 +47,7 @@ const items: ToggleButtonGroupItem< GroupControlItemOption >[] = [
|
|
|
48
47
|
];
|
|
49
48
|
|
|
50
49
|
export const FlexOrderField = () => {
|
|
51
|
-
const
|
|
52
|
-
const { canEdit } = useStyle();
|
|
50
|
+
const { value: order, setValue: setOrder, canEdit } = useStylesField< NumberPropValue | null >( 'order' );
|
|
53
51
|
|
|
54
52
|
const [ groupControlValue, setGroupControlValue ] = useState( getGroupControlValue( order?.value || null ) );
|
|
55
53
|
|
|
@@ -11,7 +11,6 @@ import { ExpandIcon, PencilIcon, ShrinkIcon } from '@elementor/icons';
|
|
|
11
11
|
import { Grid } from '@elementor/ui';
|
|
12
12
|
import { __ } from '@wordpress/i18n';
|
|
13
13
|
|
|
14
|
-
import { useStyle } from '../../../contexts/style-context';
|
|
15
14
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
16
15
|
import { useStylesFields } from '../../../hooks/use-styles-fields';
|
|
17
16
|
import { UiProviders } from '../../../styles-inheritance/components/ui-providers';
|
|
@@ -44,17 +43,15 @@ const items: ToggleButtonGroupItem< GroupItem >[] = [
|
|
|
44
43
|
];
|
|
45
44
|
|
|
46
45
|
export const FlexSizeField = () => {
|
|
47
|
-
const { canEdit } =
|
|
48
|
-
|
|
49
|
-
const [ fields, setFields ] = useStylesFields< {
|
|
46
|
+
const { values, setValues, canEdit } = useStylesFields< {
|
|
50
47
|
'flex-grow': NumberPropValue | null;
|
|
51
48
|
'flex-shrink': NumberPropValue | null;
|
|
52
49
|
'flex-basis': SizePropValue | null;
|
|
53
50
|
} >( [ 'flex-grow', 'flex-shrink', 'flex-basis' ] );
|
|
54
51
|
|
|
55
|
-
const grow =
|
|
56
|
-
const shrink =
|
|
57
|
-
const basis =
|
|
52
|
+
const grow = values?.[ 'flex-grow' ]?.value || null;
|
|
53
|
+
const shrink = values?.[ 'flex-shrink' ]?.value || null;
|
|
54
|
+
const basis = values?.[ 'flex-basis' ]?.value || null;
|
|
58
55
|
|
|
59
56
|
const currentGroup = useMemo( () => getActiveGroup( { grow, shrink, basis } ), [ grow, shrink, basis ] ),
|
|
60
57
|
[ activeGroup, setActiveGroup ] = useState( currentGroup );
|
|
@@ -63,7 +60,7 @@ export const FlexSizeField = () => {
|
|
|
63
60
|
setActiveGroup( group );
|
|
64
61
|
|
|
65
62
|
if ( ! group || group === 'custom' ) {
|
|
66
|
-
|
|
63
|
+
setValues( {
|
|
67
64
|
'flex-basis': null,
|
|
68
65
|
'flex-grow': null,
|
|
69
66
|
'flex-shrink': null,
|
|
@@ -73,7 +70,7 @@ export const FlexSizeField = () => {
|
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
if ( group === 'flex-grow' ) {
|
|
76
|
-
|
|
73
|
+
setValues( {
|
|
77
74
|
'flex-basis': null,
|
|
78
75
|
'flex-grow': numberPropTypeUtil.create( DEFAULT ),
|
|
79
76
|
'flex-shrink': null,
|
|
@@ -82,7 +79,7 @@ export const FlexSizeField = () => {
|
|
|
82
79
|
return;
|
|
83
80
|
}
|
|
84
81
|
|
|
85
|
-
|
|
82
|
+
setValues( {
|
|
86
83
|
'flex-basis': null,
|
|
87
84
|
'flex-grow': null,
|
|
88
85
|
'flex-shrink': numberPropTypeUtil.create( DEFAULT ),
|
|
@@ -21,7 +21,7 @@ import { JustifyContentField } from './justify-content-field';
|
|
|
21
21
|
import { WrapField } from './wrap-field';
|
|
22
22
|
|
|
23
23
|
export const LayoutSection = () => {
|
|
24
|
-
const
|
|
24
|
+
const { value: display } = useStylesField< StringPropValue >( 'display' );
|
|
25
25
|
const displayPlaceholder = useDisplayPlaceholderValue();
|
|
26
26
|
const isDisplayFlex = shouldDisplayFlexFields( display, displayPlaceholder as StringPropValue );
|
|
27
27
|
const { element } = useElement();
|
|
@@ -39,7 +39,7 @@ export const LayoutSection = () => {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
const FlexFields = () => {
|
|
42
|
-
const
|
|
42
|
+
const { value: flexWrap } = useStylesField< StringPropValue >( 'flex-wrap' );
|
|
43
43
|
|
|
44
44
|
return (
|
|
45
45
|
<>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MutableRefObject, useRef } from 'react';
|
|
3
|
+
import { SizeControl } from '@elementor/editor-controls';
|
|
4
|
+
import { Grid } from '@elementor/ui';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
|
|
7
|
+
import { StylesField } from '../../../controls-registry/styles-field';
|
|
8
|
+
import { ControlLabel } from '../../control-label';
|
|
9
|
+
|
|
10
|
+
export const OpacityControlField = () => {
|
|
11
|
+
const rowRef: MutableRefObject< HTMLElement | undefined > = useRef();
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<StylesField bind={ 'opacity' }>
|
|
15
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap" ref={ rowRef }>
|
|
16
|
+
<Grid item xs={ 6 }>
|
|
17
|
+
<ControlLabel>{ __( 'Opacity', 'elementor' ) }</ControlLabel>
|
|
18
|
+
</Grid>
|
|
19
|
+
<Grid item xs={ 6 }>
|
|
20
|
+
<SizeControl units={ [ '%' ] } anchorRef={ rowRef } defaultUnit="%" />
|
|
21
|
+
</Grid>
|
|
22
|
+
</Grid>
|
|
23
|
+
</StylesField>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
@@ -48,7 +48,7 @@ const useGetTargetAngle = (
|
|
|
48
48
|
disableRotationForReversed: boolean,
|
|
49
49
|
existingRef?: React.MutableRefObject< number >
|
|
50
50
|
) => {
|
|
51
|
-
const
|
|
51
|
+
const { value: direction } = useStylesField< StringPropValue >( 'flex-direction' );
|
|
52
52
|
const isRtl = 'rtl' === useTheme().direction;
|
|
53
53
|
const rotationMultiplier = isRtl ? -1 : 1;
|
|
54
54
|
const angleMap = isClockwise ? CLOCKWISE_ANGLES : COUNTER_CLOCKWISE_ANGLES;
|
|
@@ -29,8 +29,8 @@ type DimensionsValues = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export const PositionSection = () => {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
32
|
+
const { value: positionValue } = useStylesField< StringPropValue >( 'position' );
|
|
33
|
+
const { values: dimensions, setValues: setDimensions } = useStylesFields< DimensionsValues >( [
|
|
34
34
|
'inset-block-start',
|
|
35
35
|
'inset-block-end',
|
|
36
36
|
'inset-inline-start',
|
|
@@ -42,9 +42,9 @@ export const PositionSection = () => {
|
|
|
42
42
|
|
|
43
43
|
const onPositionChange = ( newPosition: string | null, previousPosition: string | null | undefined ) => {
|
|
44
44
|
if ( newPosition === 'static' ) {
|
|
45
|
-
if (
|
|
46
|
-
updateDimensionsHistory(
|
|
47
|
-
|
|
45
|
+
if ( dimensions ) {
|
|
46
|
+
updateDimensionsHistory( dimensions );
|
|
47
|
+
setDimensions( {
|
|
48
48
|
'inset-block-start': undefined,
|
|
49
49
|
'inset-block-end': undefined,
|
|
50
50
|
'inset-inline-start': undefined,
|
|
@@ -53,7 +53,7 @@ export const PositionSection = () => {
|
|
|
53
53
|
}
|
|
54
54
|
} else if ( previousPosition === 'static' ) {
|
|
55
55
|
if ( dimensionsValuesFromHistory ) {
|
|
56
|
-
|
|
56
|
+
setDimensions( dimensionsValuesFromHistory );
|
|
57
57
|
clearDimensionsHistory();
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -1,34 +1,12 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { Grid } from '@elementor/ui';
|
|
4
|
-
import { __ } from '@wordpress/i18n';
|
|
2
|
+
import { PositionControl } from '@elementor/editor-controls';
|
|
5
3
|
|
|
6
4
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
|
-
import { ControlLabel } from '../../control-label';
|
|
8
|
-
|
|
9
|
-
const positionOptions = [
|
|
10
|
-
{ label: __( 'Center center', 'elementor' ), value: 'center center' },
|
|
11
|
-
{ label: __( 'Center left', 'elementor' ), value: 'center left' },
|
|
12
|
-
{ label: __( 'Center right', 'elementor' ), value: 'center right' },
|
|
13
|
-
{ label: __( 'Top center', 'elementor' ), value: 'top center' },
|
|
14
|
-
{ label: __( 'Top left', 'elementor' ), value: 'top left' },
|
|
15
|
-
{ label: __( 'Top right', 'elementor' ), value: 'top right' },
|
|
16
|
-
{ label: __( 'Bottom center', 'elementor' ), value: 'bottom center' },
|
|
17
|
-
{ label: __( 'Bottom left', 'elementor' ), value: 'bottom left' },
|
|
18
|
-
{ label: __( 'Bottom right', 'elementor' ), value: 'bottom right' },
|
|
19
|
-
];
|
|
20
5
|
|
|
21
6
|
export const ObjectPositionField = () => {
|
|
22
7
|
return (
|
|
23
8
|
<StylesField bind="object-position">
|
|
24
|
-
<
|
|
25
|
-
<Grid item xs={ 6 }>
|
|
26
|
-
<ControlLabel>{ __( 'Object position', 'elementor' ) }</ControlLabel>
|
|
27
|
-
</Grid>
|
|
28
|
-
<Grid item xs={ 6 } sx={ { overflow: 'hidden' } }>
|
|
29
|
-
<SelectControl options={ positionOptions } />
|
|
30
|
-
</Grid>
|
|
31
|
-
</Grid>
|
|
9
|
+
<PositionControl />
|
|
32
10
|
</StylesField>
|
|
33
11
|
);
|
|
34
12
|
};
|
|
@@ -52,7 +52,7 @@ const CssSizeProps = [
|
|
|
52
52
|
];
|
|
53
53
|
|
|
54
54
|
export const SizeSection = () => {
|
|
55
|
-
const
|
|
55
|
+
const { value: fitValue } = useStylesField< StringPropValue >( 'object-fit' );
|
|
56
56
|
|
|
57
57
|
const isNotFill = fitValue && fitValue?.value !== 'fill';
|
|
58
58
|
|
|
@@ -2,7 +2,6 @@ import * as React from 'react';
|
|
|
2
2
|
import { StrokeControl } from '@elementor/editor-controls';
|
|
3
3
|
import { __ } from '@wordpress/i18n';
|
|
4
4
|
|
|
5
|
-
import { useStyle } from '../../../contexts/style-context';
|
|
6
5
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
6
|
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
8
7
|
import { AddOrRemoveContent } from '../../add-or-remove-content';
|
|
@@ -26,18 +25,17 @@ const initTextStroke = {
|
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
export const TextStrokeField = () => {
|
|
29
|
-
const { canEdit } =
|
|
30
|
-
const [ textStroke, setTextStroke ] = useStylesField( 'stroke' );
|
|
28
|
+
const { value, setValue, canEdit } = useStylesField( 'stroke' );
|
|
31
29
|
|
|
32
30
|
const addTextStroke = () => {
|
|
33
|
-
|
|
31
|
+
setValue( initTextStroke );
|
|
34
32
|
};
|
|
35
33
|
|
|
36
34
|
const removeTextStroke = () => {
|
|
37
|
-
|
|
35
|
+
setValue( null );
|
|
38
36
|
};
|
|
39
37
|
|
|
40
|
-
const hasTextStroke = Boolean(
|
|
38
|
+
const hasTextStroke = Boolean( value );
|
|
41
39
|
|
|
42
40
|
return (
|
|
43
41
|
<StylesField bind={ 'stroke' }>
|
|
@@ -23,9 +23,11 @@ import { TransformField } from './transform-field';
|
|
|
23
23
|
import { WordSpacingField } from './word-spacing-field';
|
|
24
24
|
|
|
25
25
|
export const TypographySection = () => {
|
|
26
|
-
const
|
|
27
|
-
const isVersion330Active = isExperimentActive( 'e_v_3_30' );
|
|
26
|
+
const { value: columnCount } = useStylesField< NumberPropValue >( 'column-count' );
|
|
28
27
|
const hasMultiColumns = !! ( columnCount?.value && columnCount?.value > 1 );
|
|
28
|
+
|
|
29
|
+
const isVersion330Active = isExperimentActive( 'e_v_3_30' );
|
|
30
|
+
|
|
29
31
|
return (
|
|
30
32
|
<SectionContent>
|
|
31
33
|
<FontFamilyField />
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ControlComponent,
|
|
3
3
|
ImageControl,
|
|
4
|
+
KeyValueControl,
|
|
4
5
|
LinkControl,
|
|
6
|
+
RepeatableControl,
|
|
5
7
|
SelectControl,
|
|
6
8
|
SizeControl,
|
|
7
9
|
SvgMediaControl,
|
|
@@ -11,19 +13,35 @@ import {
|
|
|
11
13
|
UrlControl,
|
|
12
14
|
} from '@elementor/editor-controls';
|
|
13
15
|
import { type ControlLayout } from '@elementor/editor-elements';
|
|
16
|
+
import {
|
|
17
|
+
booleanPropTypeUtil,
|
|
18
|
+
imagePropTypeUtil,
|
|
19
|
+
imageSrcPropTypeUtil,
|
|
20
|
+
keyValuePropTypeUtil,
|
|
21
|
+
linkPropTypeUtil,
|
|
22
|
+
type PropTypeUtil,
|
|
23
|
+
sizePropTypeUtil,
|
|
24
|
+
stringPropTypeUtil,
|
|
25
|
+
} from '@elementor/editor-props';
|
|
14
26
|
|
|
15
|
-
type ControlRegistry = Record<
|
|
27
|
+
type ControlRegistry = Record<
|
|
28
|
+
string,
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
{ component: ControlComponent; layout: ControlLayout; propTypeUtil?: PropTypeUtil< string, any > }
|
|
31
|
+
>;
|
|
16
32
|
|
|
17
33
|
const controlTypes = {
|
|
18
|
-
image: { component: ImageControl, layout: 'full' },
|
|
19
|
-
'svg-media': { component: SvgMediaControl, layout: 'full' },
|
|
20
|
-
text: { component: TextControl, layout: 'full' },
|
|
21
|
-
textarea: { component: TextAreaControl, layout: 'full' },
|
|
22
|
-
size: { component: SizeControl, layout: 'two-columns' },
|
|
23
|
-
select: { component: SelectControl, layout: 'two-columns' },
|
|
24
|
-
link: { component: LinkControl, layout: 'full' },
|
|
25
|
-
url: { component: UrlControl, layout: 'full' },
|
|
26
|
-
switch: { component: SwitchControl, layout: 'two-columns' },
|
|
34
|
+
image: { component: ImageControl, layout: 'full', propTypeUtil: imagePropTypeUtil },
|
|
35
|
+
'svg-media': { component: SvgMediaControl, layout: 'full', propTypeUtil: imageSrcPropTypeUtil },
|
|
36
|
+
text: { component: TextControl, layout: 'full', propTypeUtil: stringPropTypeUtil },
|
|
37
|
+
textarea: { component: TextAreaControl, layout: 'full', propTypeUtil: stringPropTypeUtil },
|
|
38
|
+
size: { component: SizeControl, layout: 'two-columns', propTypeUtil: sizePropTypeUtil },
|
|
39
|
+
select: { component: SelectControl, layout: 'two-columns', propTypeUtil: stringPropTypeUtil },
|
|
40
|
+
link: { component: LinkControl, layout: 'full', propTypeUtil: linkPropTypeUtil },
|
|
41
|
+
url: { component: UrlControl, layout: 'full', propTypeUtil: stringPropTypeUtil },
|
|
42
|
+
switch: { component: SwitchControl, layout: 'two-columns', propTypeUtil: booleanPropTypeUtil },
|
|
43
|
+
repeatable: { component: RepeatableControl, layout: 'full', propTypeUtil: undefined },
|
|
44
|
+
'key-value': { component: KeyValueControl, layout: 'full', propTypeUtil: keyValuePropTypeUtil },
|
|
27
45
|
} as const satisfies ControlRegistry;
|
|
28
46
|
|
|
29
47
|
export type ControlType = keyof typeof controlTypes;
|
|
@@ -35,3 +53,5 @@ export type ControlTypes = {
|
|
|
35
53
|
export const getControl = ( type: ControlType ) => controlTypes[ type ]?.component;
|
|
36
54
|
|
|
37
55
|
export const getDefaultLayout = ( type: ControlType ) => controlTypes[ type ].layout;
|
|
56
|
+
|
|
57
|
+
export const getPropTypeUtil = ( type: ControlType ) => controlTypes[ type ]?.propTypeUtil;
|
|
@@ -3,7 +3,6 @@ import { ControlAdornmentsProvider, PropKeyProvider, PropProvider } from '@eleme
|
|
|
3
3
|
import { type PropKey, type PropValue } from '@elementor/editor-props';
|
|
4
4
|
import { getStylesSchema } from '@elementor/editor-styles';
|
|
5
5
|
|
|
6
|
-
import { useStyle } from '../contexts/style-context';
|
|
7
6
|
import { useStylesField } from '../hooks/use-styles-field';
|
|
8
7
|
import { StylesInheritanceIndicator } from '../styles-inheritance/components/styles-inheritance-indicator';
|
|
9
8
|
import { createTopLevelOjectType } from './create-top-level-object-type';
|
|
@@ -15,8 +14,7 @@ export type StylesFieldProps = {
|
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
export const StylesField = ( { bind, placeholder, children }: StylesFieldProps ) => {
|
|
18
|
-
const
|
|
19
|
-
const { canEdit } = useStyle();
|
|
17
|
+
const { value, setValue, canEdit } = useStylesField( bind );
|
|
20
18
|
|
|
21
19
|
const stylesSchema = getStylesSchema();
|
|
22
20
|
|