@elementor/editor-editing-panel 1.46.0 → 1.48.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 +85 -0
- package/dist/index.d.mts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +1094 -889
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +979 -780
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -18
- package/src/components/popover-scrollable-content.tsx +12 -0
- package/src/components/section-content.tsx +6 -16
- package/src/components/section.tsx +8 -4
- package/src/components/settings-tab.tsx +5 -2
- package/src/components/style-sections/background-section/background-section.tsx +4 -1
- package/src/components/style-sections/border-section/border-color-field.tsx +10 -16
- package/src/components/style-sections/border-section/border-field.tsx +14 -7
- package/src/components/style-sections/border-section/border-radius-field.tsx +4 -2
- package/src/components/style-sections/border-section/border-style-field.tsx +11 -16
- package/src/components/style-sections/border-section/border-width-field.tsx +4 -2
- package/src/components/style-sections/effects-section/effects-section.tsx +29 -6
- package/src/components/style-sections/layout-section/align-content-field.tsx +11 -12
- package/src/components/style-sections/layout-section/align-items-field.tsx +8 -11
- package/src/components/style-sections/layout-section/align-self-child-field.tsx +11 -16
- package/src/components/style-sections/layout-section/display-field.tsx +6 -6
- package/src/components/style-sections/layout-section/flex-direction-field.tsx +11 -14
- package/src/components/style-sections/layout-section/flex-order-field.tsx +23 -20
- package/src/components/style-sections/layout-section/flex-size-field.tsx +42 -64
- package/src/components/style-sections/layout-section/gap-control-field.tsx +5 -6
- package/src/components/style-sections/layout-section/justify-content-field.tsx +11 -12
- package/src/components/style-sections/layout-section/layout-section.tsx +9 -2
- package/src/components/style-sections/layout-section/opacity-control-field.tsx +9 -13
- package/src/components/style-sections/layout-section/utils/rotated-icon.tsx +6 -1
- package/src/components/style-sections/layout-section/wrap-field.tsx +10 -14
- package/src/components/style-sections/position-section/dimensions-field.tsx +4 -4
- package/src/components/style-sections/position-section/offset-field.tsx +12 -14
- package/src/components/style-sections/position-section/position-field.tsx +7 -11
- package/src/components/style-sections/position-section/position-section.tsx +19 -8
- package/src/components/style-sections/position-section/z-index-field.tsx +7 -11
- package/src/components/style-sections/size-section/object-fit-field.tsx +7 -11
- package/src/components/style-sections/size-section/object-position-field.tsx +4 -1
- package/src/components/style-sections/size-section/overflow-field.tsx +7 -11
- package/src/components/style-sections/size-section/size-section.tsx +13 -8
- package/src/components/style-sections/spacing-section/spacing-section.tsx +7 -4
- package/src/components/style-sections/typography-section/column-count-field.tsx +7 -11
- package/src/components/style-sections/typography-section/column-gap-field.tsx +9 -13
- package/src/components/style-sections/typography-section/font-family-field.tsx +9 -11
- package/src/components/style-sections/typography-section/font-size-field.tsx +9 -13
- package/src/components/style-sections/typography-section/font-style-field.tsx +13 -13
- package/src/components/style-sections/typography-section/font-weight-field.tsx +7 -11
- package/src/components/style-sections/typography-section/letter-spacing-field.tsx +9 -13
- package/src/components/style-sections/typography-section/line-height-field.tsx +9 -13
- package/src/components/style-sections/typography-section/text-alignment-field.tsx +11 -14
- package/src/components/style-sections/typography-section/text-color-field.tsx +7 -11
- package/src/components/style-sections/typography-section/text-decoration-field.tsx +7 -11
- package/src/components/style-sections/typography-section/text-direction-field.tsx +7 -11
- package/src/components/style-sections/typography-section/text-stroke-field.tsx +7 -3
- package/src/components/style-sections/typography-section/transform-field.tsx +7 -11
- package/src/components/style-sections/typography-section/typography-section.tsx +6 -1
- package/src/components/style-sections/typography-section/word-spacing-field.tsx +9 -13
- package/src/components/style-tab.tsx +1 -1
- package/src/components/styles-field-layout.tsx +50 -0
- package/src/contexts/section-context.tsx +14 -0
- package/src/controls-registry/control-type-container.tsx +6 -2
- package/src/controls-registry/controls-registry.tsx +1 -1
- package/src/controls-registry/settings-field.tsx +85 -10
- package/src/controls-registry/styles-field.tsx +15 -5
- package/src/dynamics/components/dynamic-selection-control.tsx +10 -4
- package/src/dynamics/components/dynamic-selection.tsx +18 -14
- package/src/hooks/use-default-panel-settings.ts +4 -0
- package/src/hooks/use-styles-field.ts +3 -4
- package/src/hooks/use-styles-fields.ts +141 -73
- package/src/index.ts +4 -0
- package/src/init.ts +0 -6
- package/src/popover-action.tsx +8 -1
- package/src/styles-inheritance/components/styles-inheritance-indicator.tsx +4 -1
- package/src/styles-inheritance/components/styles-inheritance-infotip.tsx +9 -19
- package/src/sync/experiments-flags.ts +1 -0
- package/src/components/popover-content.tsx +0 -15
|
@@ -24,8 +24,12 @@ const initTextStroke = {
|
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
const TEXT_STROKE_LABEL = __( 'Text stroke', 'elementor' );
|
|
28
|
+
|
|
27
29
|
export const TextStrokeField = () => {
|
|
28
|
-
const { value, setValue, canEdit } = useStylesField( 'stroke'
|
|
30
|
+
const { value, setValue, canEdit } = useStylesField( 'stroke', {
|
|
31
|
+
history: { propDisplayName: TEXT_STROKE_LABEL },
|
|
32
|
+
} );
|
|
29
33
|
|
|
30
34
|
const addTextStroke = () => {
|
|
31
35
|
setValue( initTextStroke );
|
|
@@ -38,13 +42,13 @@ export const TextStrokeField = () => {
|
|
|
38
42
|
const hasTextStroke = Boolean( value );
|
|
39
43
|
|
|
40
44
|
return (
|
|
41
|
-
<StylesField bind={ 'stroke' }>
|
|
45
|
+
<StylesField bind={ 'stroke' } propDisplayName={ TEXT_STROKE_LABEL }>
|
|
42
46
|
<AddOrRemoveContent
|
|
43
47
|
isAdded={ hasTextStroke }
|
|
44
48
|
onAdd={ addTextStroke }
|
|
45
49
|
onRemove={ removeTextStroke }
|
|
46
50
|
disabled={ ! canEdit }
|
|
47
|
-
renderLabel={ () => <ControlLabel>{
|
|
51
|
+
renderLabel={ () => <ControlLabel>{ TEXT_STROKE_LABEL }</ControlLabel> }
|
|
48
52
|
>
|
|
49
53
|
<StrokeControl />
|
|
50
54
|
</AddOrRemoveContent>
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
|
|
3
3
|
import { LetterCaseIcon, LetterCaseLowerIcon, LetterCaseUpperIcon, MinusIcon } from '@elementor/icons';
|
|
4
|
-
import { Grid } from '@elementor/ui';
|
|
5
4
|
import { __ } from '@wordpress/i18n';
|
|
6
5
|
|
|
7
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
8
|
-
import {
|
|
7
|
+
import { StylesFieldLayout } from '../../styles-field-layout';
|
|
9
8
|
|
|
10
9
|
type Transforms = 'none' | 'capitalize' | 'uppercase' | 'lowercase';
|
|
11
10
|
|
|
11
|
+
const TEXT_TRANSFORM_LABEL = __( 'Text transform', 'elementor' );
|
|
12
|
+
|
|
12
13
|
const options: ToggleButtonGroupItem< Transforms >[] = [
|
|
13
14
|
{
|
|
14
15
|
value: 'none',
|
|
@@ -37,14 +38,9 @@ const options: ToggleButtonGroupItem< Transforms >[] = [
|
|
|
37
38
|
];
|
|
38
39
|
|
|
39
40
|
export const TransformField = () => (
|
|
40
|
-
<StylesField bind=
|
|
41
|
-
<
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
</Grid>
|
|
45
|
-
<Grid item xs={ 6 } display="flex" justifyContent="end">
|
|
46
|
-
<ToggleControl options={ options } />
|
|
47
|
-
</Grid>
|
|
48
|
-
</Grid>
|
|
41
|
+
<StylesField bind="text-transform" propDisplayName={ TEXT_TRANSFORM_LABEL }>
|
|
42
|
+
<StylesFieldLayout label={ TEXT_TRANSFORM_LABEL }>
|
|
43
|
+
<ToggleControl options={ options } />
|
|
44
|
+
</StylesFieldLayout>
|
|
49
45
|
</StylesField>
|
|
50
46
|
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { NumberPropValue } from '@elementor/editor-props';
|
|
3
3
|
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
4
5
|
|
|
5
6
|
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
6
7
|
import { PanelDivider } from '../../panel-divider';
|
|
@@ -22,8 +23,12 @@ import { TextStrokeField } from './text-stroke-field';
|
|
|
22
23
|
import { TransformField } from './transform-field';
|
|
23
24
|
import { WordSpacingField } from './word-spacing-field';
|
|
24
25
|
|
|
26
|
+
const COLUMN_COUNT_LABEL = __( 'Column count', 'elementor' );
|
|
27
|
+
|
|
25
28
|
export const TypographySection = () => {
|
|
26
|
-
const { value: columnCount } = useStylesField< NumberPropValue >( 'column-count'
|
|
29
|
+
const { value: columnCount } = useStylesField< NumberPropValue >( 'column-count', {
|
|
30
|
+
history: { propDisplayName: COLUMN_COUNT_LABEL },
|
|
31
|
+
} );
|
|
27
32
|
const hasMultiColumns = !! ( columnCount?.value && columnCount?.value > 1 );
|
|
28
33
|
|
|
29
34
|
const isVersion330Active = isExperimentActive( 'e_v_3_30' );
|
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useRef } from 'react';
|
|
3
3
|
import { SizeControl } from '@elementor/editor-controls';
|
|
4
|
-
import { Grid } from '@elementor/ui';
|
|
5
4
|
import { __ } from '@wordpress/i18n';
|
|
6
5
|
|
|
7
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
8
|
-
import {
|
|
7
|
+
import { StylesFieldLayout } from '../../styles-field-layout';
|
|
8
|
+
|
|
9
|
+
const WORD_SPACING_LABEL = __( 'Word spacing', 'elementor' );
|
|
9
10
|
|
|
10
11
|
export const WordSpacingField = () => {
|
|
11
|
-
const rowRef
|
|
12
|
+
const rowRef = useRef< HTMLDivElement >( null );
|
|
12
13
|
|
|
13
14
|
return (
|
|
14
|
-
<StylesField bind="word-spacing">
|
|
15
|
-
<
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
</Grid>
|
|
19
|
-
<Grid item xs={ 6 }>
|
|
20
|
-
<SizeControl anchorRef={ rowRef } />
|
|
21
|
-
</Grid>
|
|
22
|
-
</Grid>
|
|
15
|
+
<StylesField bind="word-spacing" propDisplayName={ WORD_SPACING_LABEL }>
|
|
16
|
+
<StylesFieldLayout label={ WORD_SPACING_LABEL } ref={ rowRef }>
|
|
17
|
+
<SizeControl anchorRef={ rowRef } />
|
|
18
|
+
</StylesFieldLayout>
|
|
23
19
|
</StylesField>
|
|
24
20
|
);
|
|
25
21
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Grid, Stack, type Theme } from '@elementor/ui';
|
|
3
|
+
|
|
4
|
+
import { ControlLabel } from './control-label';
|
|
5
|
+
|
|
6
|
+
type StylesFieldLayoutProps = {
|
|
7
|
+
label: string;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
direction?: 'row' | 'column';
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const StylesFieldLayout = React.forwardRef< HTMLDivElement, StylesFieldLayoutProps >( ( props, ref ) => {
|
|
13
|
+
const { direction = 'row', children, label } = props;
|
|
14
|
+
|
|
15
|
+
const LayoutComponent = direction === 'row' ? Row : Column;
|
|
16
|
+
|
|
17
|
+
return <LayoutComponent label={ label } ref={ ref } children={ children } />;
|
|
18
|
+
} );
|
|
19
|
+
|
|
20
|
+
const Row = React.forwardRef< HTMLDivElement, { label: string; children: React.ReactNode } >(
|
|
21
|
+
( { label, children }, ref ) => {
|
|
22
|
+
return (
|
|
23
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap" ref={ ref }>
|
|
24
|
+
<Grid item xs={ 6 }>
|
|
25
|
+
<ControlLabel>{ label }</ControlLabel>
|
|
26
|
+
</Grid>
|
|
27
|
+
<Grid
|
|
28
|
+
item
|
|
29
|
+
xs={ 6 }
|
|
30
|
+
sx={ ( theme: Theme ) => ( {
|
|
31
|
+
width: `calc(50% - ${ theme.spacing( 2 ) })`,
|
|
32
|
+
} ) }
|
|
33
|
+
>
|
|
34
|
+
{ children }
|
|
35
|
+
</Grid>
|
|
36
|
+
</Grid>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const Column = React.forwardRef< HTMLDivElement, { label: string; children: React.ReactNode } >(
|
|
42
|
+
( { label, children }, ref ) => {
|
|
43
|
+
return (
|
|
44
|
+
<Stack gap={ 0.75 } ref={ ref }>
|
|
45
|
+
<ControlLabel>{ label }</ControlLabel>
|
|
46
|
+
{ children }
|
|
47
|
+
</Stack>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import type { RefObject } from 'react';
|
|
3
|
+
|
|
4
|
+
const FALLBACK_SECTION_WIDTH = 320;
|
|
5
|
+
|
|
6
|
+
export const SectionRefContext = createContext< RefObject< HTMLElement > | null >( null );
|
|
7
|
+
|
|
8
|
+
const useSectionRef = () => useContext( SectionRefContext );
|
|
9
|
+
|
|
10
|
+
export const useSectionWidth = (): number => {
|
|
11
|
+
const sectionRef = useSectionRef();
|
|
12
|
+
|
|
13
|
+
return sectionRef?.current?.offsetWidth ?? FALLBACK_SECTION_WIDTH;
|
|
14
|
+
};
|
|
@@ -3,6 +3,10 @@ import { type ControlLayout } from '@elementor/editor-elements';
|
|
|
3
3
|
import { Box, type BoxProps, styled } from '@elementor/ui';
|
|
4
4
|
|
|
5
5
|
export const ControlTypeContainer = ( { children, layout }: React.PropsWithChildren< { layout?: ControlLayout } > ) => {
|
|
6
|
+
if ( layout === 'custom' ) {
|
|
7
|
+
return children;
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
return <StyledContainer layout={ layout }>{ children }</StyledContainer>;
|
|
7
11
|
};
|
|
8
12
|
|
|
@@ -14,10 +18,10 @@ const StyledContainer = styled( Box, {
|
|
|
14
18
|
...getGridLayout( layout ),
|
|
15
19
|
} ) );
|
|
16
20
|
|
|
17
|
-
const getGridLayout = ( layout: ControlLayout ) => ( {
|
|
21
|
+
const getGridLayout = ( layout: Omit< ControlLayout, 'custom' > ) => ( {
|
|
18
22
|
justifyContent: 'space-between',
|
|
19
23
|
gridTemplateColumns: {
|
|
20
24
|
full: 'minmax(0, 1fr)',
|
|
21
25
|
'two-columns': 'repeat(2, minmax(0, 1fr))',
|
|
22
|
-
}[ layout ],
|
|
26
|
+
}[ layout as string ],
|
|
23
27
|
} );
|
|
@@ -37,7 +37,7 @@ const controlTypes = {
|
|
|
37
37
|
textarea: { component: TextAreaControl, layout: 'full', propTypeUtil: stringPropTypeUtil },
|
|
38
38
|
size: { component: SizeControl, layout: 'two-columns', propTypeUtil: sizePropTypeUtil },
|
|
39
39
|
select: { component: SelectControl, layout: 'two-columns', propTypeUtil: stringPropTypeUtil },
|
|
40
|
-
link: { component: LinkControl, layout: '
|
|
40
|
+
link: { component: LinkControl, layout: 'custom', propTypeUtil: linkPropTypeUtil },
|
|
41
41
|
url: { component: UrlControl, layout: 'full', propTypeUtil: stringPropTypeUtil },
|
|
42
42
|
switch: { component: SwitchControl, layout: 'two-columns', propTypeUtil: booleanPropTypeUtil },
|
|
43
43
|
repeatable: { component: RepeatableControl, layout: 'full', propTypeUtil: undefined },
|
|
@@ -1,35 +1,110 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { useMemo } from 'react';
|
|
2
3
|
import { PropKeyProvider, PropProvider } from '@elementor/editor-controls';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { setDocumentModifiedStatus } from '@elementor/editor-documents';
|
|
5
|
+
import {
|
|
6
|
+
type ElementID,
|
|
7
|
+
getElementLabel,
|
|
8
|
+
getElementSetting,
|
|
9
|
+
updateElementSettings,
|
|
10
|
+
useElementSettings,
|
|
11
|
+
} from '@elementor/editor-elements';
|
|
12
|
+
import { type PropKey, type PropType, type PropValue, shouldApplyEffect } from '@elementor/editor-props';
|
|
13
|
+
import { isExperimentActive, undoable } from '@elementor/editor-v1-adapters';
|
|
14
|
+
import { __ } from '@wordpress/i18n';
|
|
5
15
|
|
|
6
16
|
import { useElement } from '../contexts/element-context';
|
|
17
|
+
import { EXPERIMENTAL_FEATURES } from '../sync/experiments-flags';
|
|
7
18
|
import { createTopLevelOjectType } from './create-top-level-object-type';
|
|
8
19
|
|
|
9
20
|
type Props = {
|
|
10
21
|
bind: PropKey;
|
|
22
|
+
propDisplayName: string;
|
|
11
23
|
children: React.ReactNode;
|
|
12
24
|
};
|
|
13
25
|
|
|
14
|
-
export const SettingsField = ( { bind, children }: Props ) => {
|
|
26
|
+
export const SettingsField = ( { bind, children, propDisplayName }: Props ) => {
|
|
15
27
|
const { element, elementType } = useElement();
|
|
16
28
|
|
|
17
|
-
const
|
|
29
|
+
const elementSettingValues = useElementSettings< PropValue >( element.id, Object.keys( elementType.propsSchema ) );
|
|
18
30
|
|
|
19
|
-
const value = { [ bind ]:
|
|
31
|
+
const value = { [ bind ]: elementSettingValues?.[ bind ] };
|
|
20
32
|
|
|
21
33
|
const propType = createTopLevelOjectType( { schema: elementType.propsSchema } );
|
|
22
34
|
|
|
35
|
+
const undoableUpdateElementProp = useUndoableUpdateElementProp( {
|
|
36
|
+
propKey: bind,
|
|
37
|
+
elementId: element.id,
|
|
38
|
+
propDisplayName,
|
|
39
|
+
} );
|
|
40
|
+
|
|
23
41
|
const setValue = ( newValue: Record< string, PropValue > ) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
const isVersion331Active = isExperimentActive( EXPERIMENTAL_FEATURES.V_3_31 );
|
|
43
|
+
|
|
44
|
+
if ( isVersion331Active ) {
|
|
45
|
+
undoableUpdateElementProp( { newValue } );
|
|
46
|
+
} else {
|
|
47
|
+
updateElementSettings( { id: element.id, props: newValue } );
|
|
48
|
+
}
|
|
28
49
|
};
|
|
29
50
|
|
|
51
|
+
const isDisabled = ( prop: PropType ) => getDisableState( prop, elementSettingValues );
|
|
52
|
+
|
|
30
53
|
return (
|
|
31
|
-
<PropProvider propType={ propType } value={ value } setValue={ setValue }>
|
|
54
|
+
<PropProvider propType={ propType } value={ value } setValue={ setValue } isDisabled={ isDisabled }>
|
|
32
55
|
<PropKeyProvider bind={ bind }>{ children }</PropKeyProvider>
|
|
33
56
|
</PropProvider>
|
|
34
57
|
);
|
|
35
58
|
};
|
|
59
|
+
|
|
60
|
+
function getDisableState( propType: PropType, elementValues: PropValue ): boolean | undefined {
|
|
61
|
+
const disablingDependencies = propType.dependencies?.filter( ( { effect } ) => effect === 'disable' ) || [];
|
|
62
|
+
|
|
63
|
+
if ( ! disablingDependencies.length ) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if ( disablingDependencies.length > 1 ) {
|
|
68
|
+
throw new Error( 'Multiple disabling dependencies are not supported.' );
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return shouldApplyEffect( disablingDependencies[ 0 ], elementValues );
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type UndoableUpdateElementSettingsArgs = {
|
|
75
|
+
newValue: Record< string, PropValue >;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
function useUndoableUpdateElementProp( {
|
|
79
|
+
propKey,
|
|
80
|
+
elementId,
|
|
81
|
+
propDisplayName,
|
|
82
|
+
}: {
|
|
83
|
+
propKey: PropKey;
|
|
84
|
+
elementId: ElementID;
|
|
85
|
+
propDisplayName: string;
|
|
86
|
+
} ) {
|
|
87
|
+
return useMemo( () => {
|
|
88
|
+
return undoable(
|
|
89
|
+
{
|
|
90
|
+
do: ( { newValue }: UndoableUpdateElementSettingsArgs ) => {
|
|
91
|
+
const prevPropValue = getElementSetting( elementId, propKey ) as PropValue;
|
|
92
|
+
|
|
93
|
+
updateElementSettings( { id: elementId, props: { ...newValue }, withHistory: false } );
|
|
94
|
+
setDocumentModifiedStatus( true );
|
|
95
|
+
|
|
96
|
+
return { [ propKey ]: prevPropValue };
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
undo: ( {}, prevProps ) => {
|
|
100
|
+
updateElementSettings( { id: elementId, props: prevProps, withHistory: false } );
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
title: getElementLabel( elementId ),
|
|
105
|
+
// translators: %s is the name of the property that was edited.
|
|
106
|
+
subtitle: __( '%s edited', 'elementor' ).replace( '%s', propDisplayName ),
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
}, [ propKey, elementId, propDisplayName ] );
|
|
110
|
+
}
|
|
@@ -2,7 +2,9 @@ import * as React from 'react';
|
|
|
2
2
|
import { ControlAdornmentsProvider, PropKeyProvider, PropProvider } from '@elementor/editor-controls';
|
|
3
3
|
import { type PropKey, type PropValue } from '@elementor/editor-props';
|
|
4
4
|
import { getStylesSchema } from '@elementor/editor-styles';
|
|
5
|
+
import { isExperimentActive } from '@elementor/editor-v1-adapters';
|
|
5
6
|
|
|
7
|
+
import { useStylesInheritanceChain } from '../contexts/styles-inheritance-context';
|
|
6
8
|
import { useStylesField } from '../hooks/use-styles-field';
|
|
7
9
|
import { StylesInheritanceIndicator } from '../styles-inheritance/components/styles-inheritance-indicator';
|
|
8
10
|
import { createTopLevelOjectType } from './create-top-level-object-type';
|
|
@@ -11,18 +13,26 @@ export type StylesFieldProps = {
|
|
|
11
13
|
bind: PropKey;
|
|
12
14
|
placeholder?: PropValue;
|
|
13
15
|
children: React.ReactNode;
|
|
16
|
+
propDisplayName: string;
|
|
14
17
|
};
|
|
15
18
|
|
|
16
|
-
export const StylesField = ( { bind, placeholder, children }: StylesFieldProps ) => {
|
|
17
|
-
const { value, setValue, canEdit } = useStylesField( bind
|
|
19
|
+
export const StylesField = ( { bind, placeholder, propDisplayName, children }: StylesFieldProps ) => {
|
|
20
|
+
const { value, setValue, canEdit } = useStylesField( bind, {
|
|
21
|
+
history: { propDisplayName },
|
|
22
|
+
} );
|
|
23
|
+
|
|
24
|
+
const isVersion331Active = isExperimentActive( 'e_v_3_31' );
|
|
25
|
+
const stylesInheritanceChain = useStylesInheritanceChain( [ bind ] );
|
|
18
26
|
|
|
19
27
|
const stylesSchema = getStylesSchema();
|
|
20
28
|
|
|
21
29
|
const propType = createTopLevelOjectType( { schema: stylesSchema } );
|
|
22
30
|
|
|
23
31
|
const values = { [ bind ]: value };
|
|
24
|
-
const
|
|
25
|
-
|
|
32
|
+
const [ actualValue ] = stylesInheritanceChain;
|
|
33
|
+
const placeholderValues = {
|
|
34
|
+
[ bind ]: isVersion331Active ? actualValue?.value : placeholder,
|
|
35
|
+
};
|
|
26
36
|
const setValues = ( newValue: Record< string, PropValue > ) => {
|
|
27
37
|
setValue( newValue[ bind ] );
|
|
28
38
|
};
|
|
@@ -41,7 +51,7 @@ export const StylesField = ( { bind, placeholder, children }: StylesFieldProps )
|
|
|
41
51
|
value={ values }
|
|
42
52
|
setValue={ setValues }
|
|
43
53
|
placeholder={ placeholderValues }
|
|
44
|
-
|
|
54
|
+
isDisabled={ () => ! canEdit }
|
|
45
55
|
>
|
|
46
56
|
<PropKeyProvider bind={ bind }>{ children }</PropKeyProvider>
|
|
47
57
|
</PropProvider>
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
} from '@elementor/ui';
|
|
22
22
|
import { __ } from '@wordpress/i18n';
|
|
23
23
|
|
|
24
|
-
import { PopoverContent } from '../../components/popover-content';
|
|
25
24
|
import { Control as BaseControl } from '../../controls-registry/control';
|
|
26
25
|
import { type ControlType, getControl } from '../../controls-registry/controls-registry';
|
|
27
26
|
import { usePersistDynamicValue } from '../../hooks/use-persist-dynamic-value';
|
|
@@ -76,7 +75,11 @@ export const DynamicSelectionControl = () => {
|
|
|
76
75
|
<Popover
|
|
77
76
|
disablePortal
|
|
78
77
|
disableScrollLock
|
|
79
|
-
anchorOrigin={ { vertical: 'bottom', horizontal: '
|
|
78
|
+
anchorOrigin={ { vertical: 'bottom', horizontal: 'right' } }
|
|
79
|
+
transformOrigin={ { vertical: 'top', horizontal: 'right' } }
|
|
80
|
+
PaperProps={ {
|
|
81
|
+
sx: { my: 1 },
|
|
82
|
+
} }
|
|
80
83
|
{ ...bindPopover( selectionPopoverState ) }
|
|
81
84
|
>
|
|
82
85
|
<Stack>
|
|
@@ -105,6 +108,9 @@ export const DynamicSettingsPopover = ( { dynamicTag }: { dynamicTag: DynamicTag
|
|
|
105
108
|
disablePortal
|
|
106
109
|
disableScrollLock
|
|
107
110
|
anchorOrigin={ { vertical: 'bottom', horizontal: 'center' } }
|
|
111
|
+
PaperProps={ {
|
|
112
|
+
sx: { my: 0.5 },
|
|
113
|
+
} }
|
|
108
114
|
{ ...bindPopover( popupState ) }
|
|
109
115
|
>
|
|
110
116
|
<PopoverHeader
|
|
@@ -139,14 +145,14 @@ const DynamicSettings = ( { controls }: { controls: DynamicTag[ 'atomic_controls
|
|
|
139
145
|
{ tabs.map( ( { value }, index ) => {
|
|
140
146
|
return (
|
|
141
147
|
<TabPanel key={ index } sx={ { flexGrow: 1, py: 0 } } { ...getTabPanelProps( index ) }>
|
|
142
|
-
<
|
|
148
|
+
<Stack p={ 2 } gap={ 2 }>
|
|
143
149
|
{ value.items.map( ( item ) => {
|
|
144
150
|
if ( item.type === 'control' ) {
|
|
145
151
|
return <Control key={ item.value.bind } control={ item.value } />;
|
|
146
152
|
}
|
|
147
153
|
return null;
|
|
148
154
|
} ) }
|
|
149
|
-
</
|
|
155
|
+
</Stack>
|
|
150
156
|
</TabPanel>
|
|
151
157
|
);
|
|
152
158
|
} ) }
|
|
@@ -6,6 +6,7 @@ import { DatabaseIcon } from '@elementor/icons';
|
|
|
6
6
|
import { Box, Divider, Link, Stack, Typography, useTheme } from '@elementor/ui';
|
|
7
7
|
import { __ } from '@wordpress/i18n';
|
|
8
8
|
|
|
9
|
+
import { PopoverScrollableContent } from '../../components/popover-scrollable-content';
|
|
9
10
|
import { usePersistDynamicValue } from '../../hooks/use-persist-dynamic-value';
|
|
10
11
|
import { usePropDynamicTags } from '../hooks/use-prop-dynamic-tags';
|
|
11
12
|
import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
|
|
@@ -91,19 +92,23 @@ export const DynamicSelection = ( { close: closePopover }: DynamicSelectionProps
|
|
|
91
92
|
onSearch={ handleSearch }
|
|
92
93
|
placeholder={ __( 'Search dynamic tags…', 'elementor' ) }
|
|
93
94
|
/>
|
|
95
|
+
|
|
94
96
|
<Divider />
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
97
|
+
|
|
98
|
+
<PopoverScrollableContent>
|
|
99
|
+
<PopoverMenuList
|
|
100
|
+
items={ virtualizedItems }
|
|
101
|
+
onSelect={ handleSetDynamicTag }
|
|
102
|
+
onClose={ closePopover }
|
|
103
|
+
selectedValue={ dynamicValue?.name }
|
|
104
|
+
itemStyle={ ( item ) =>
|
|
105
|
+
item.type === 'item' ? { paddingInlineStart: theme.spacing( 3.5 ) } : {}
|
|
106
|
+
}
|
|
107
|
+
noResultsComponent={
|
|
108
|
+
<NoResults searchValue={ searchValue } onClear={ () => setSearchValue( '' ) } />
|
|
109
|
+
}
|
|
110
|
+
/>
|
|
111
|
+
</PopoverScrollableContent>
|
|
107
112
|
</Fragment>
|
|
108
113
|
) }
|
|
109
114
|
</Stack>
|
|
@@ -127,9 +132,8 @@ const NoResults = ( { searchValue, onClear }: NoResultsProps ) => (
|
|
|
127
132
|
<br />
|
|
128
133
|
“{ searchValue }”.
|
|
129
134
|
</Typography>
|
|
130
|
-
<Typography align="center" variant="caption">
|
|
135
|
+
<Typography align="center" variant="caption" sx={ { display: 'flex', flexDirection: 'column' } }>
|
|
131
136
|
{ __( 'Try something else.', 'elementor' ) }
|
|
132
|
-
|
|
133
137
|
<Link color="text.secondary" variant="caption" component="button" onClick={ onClear }>
|
|
134
138
|
{ __( 'Clear & try again', 'elementor' ) }
|
|
135
139
|
</Link>
|
|
@@ -24,6 +24,10 @@ const defaultPanelSettingsContext = createContext< Record< string, Defaults | un
|
|
|
24
24
|
defaultSectionsExpanded: fallbackEditorSettings.defaultSectionsExpanded,
|
|
25
25
|
defaultTab: 'style',
|
|
26
26
|
},
|
|
27
|
+
'e-divider': {
|
|
28
|
+
defaultSectionsExpanded: fallbackEditorSettings.defaultSectionsExpanded,
|
|
29
|
+
defaultTab: 'style',
|
|
30
|
+
},
|
|
27
31
|
} );
|
|
28
32
|
|
|
29
33
|
export const useDefaultPanelSettings = () => {
|
|
@@ -3,7 +3,8 @@ import type { PropKey, PropValue } from '@elementor/editor-props';
|
|
|
3
3
|
import { useStylesFields } from './use-styles-fields';
|
|
4
4
|
|
|
5
5
|
export function useStylesField< T extends PropValue >(
|
|
6
|
-
propName: PropKey
|
|
6
|
+
propName: PropKey,
|
|
7
|
+
meta: { history: { propDisplayName: string } }
|
|
7
8
|
): {
|
|
8
9
|
value: T;
|
|
9
10
|
setValue: ( newValue: T ) => void;
|
|
@@ -14,9 +15,7 @@ export function useStylesField< T extends PropValue >(
|
|
|
14
15
|
const value = values?.[ propName ] ?? null;
|
|
15
16
|
|
|
16
17
|
const setValue = ( newValue: T ) => {
|
|
17
|
-
setValues( {
|
|
18
|
-
[ propName ]: newValue,
|
|
19
|
-
} );
|
|
18
|
+
setValues( { [ propName ]: newValue }, meta );
|
|
20
19
|
};
|
|
21
20
|
|
|
22
21
|
return { value: value as T, setValue, canEdit };
|