@elementor/editor-editing-panel 1.15.0 → 1.17.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 +58 -0
- package/dist/index.js +306 -232
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +211 -137
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
- package/src/components/css-classes/css-class-menu.tsx +1 -1
- package/src/components/css-classes/css-class-selector.tsx +1 -1
- package/src/components/editing-panel.tsx +2 -0
- package/src/components/style-sections/border-section/border-radius-field.tsx +1 -0
- package/src/components/style-sections/border-section/border-width-field.tsx +19 -10
- package/src/components/style-sections/layout-section/flex-size-field.tsx +1 -1
- package/src/components/style-sections/position-section/dimensions-field.tsx +24 -12
- package/src/components/style-sections/position-section/position-section.tsx +12 -12
- package/src/components/style-sections/position-section/z-index-field.tsx +1 -1
- package/src/components/style-sections/size-section/size-section.tsx +18 -9
- package/src/components/style-sections/spacing-section/spacing-section.tsx +9 -2
- package/src/components/style-sections/typography-section/font-family-field.tsx +34 -2
- package/src/components/style-sections/typography-section/font-weight-field.tsx +3 -3
- package/src/components/style-sections/typography-section/text-direction-field.tsx +4 -2
- package/src/dynamics/components/dynamic-selection-control.tsx +1 -1
- package/src/dynamics/components/dynamic-selection.tsx +19 -12
- package/src/dynamics/hooks/use-prop-dynamic-action.tsx +1 -1
- package/src/styles-inheritance/create-snapshots-manager.ts +179 -0
- package/src/styles-inheritance/create-styles-inheritance.ts +50 -0
- package/src/styles-inheritance/types.ts +42 -0
- package/src/styles-inheritance/utils.ts +10 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { type BreakpointId, type BreakpointNode } from '@elementor/editor-responsive';
|
|
2
|
+
import { type StyleDefinitionState } from '@elementor/editor-styles';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
type BreakpointsInheritancePath,
|
|
6
|
+
type BreakpointsStatesSnapshotsMapping,
|
|
7
|
+
type BreakpointStatesSlotsMapping,
|
|
8
|
+
type SnapshotPropValue,
|
|
9
|
+
type StyleInheritanceMetaProps,
|
|
10
|
+
type StylesInheritanceSnapshot,
|
|
11
|
+
type StylesInheritanceSnapshotGetter,
|
|
12
|
+
type StylesInheritanceSnapshotsSlot,
|
|
13
|
+
type StyleVariantWithId,
|
|
14
|
+
} from './types';
|
|
15
|
+
import { DEFAULT_STATE, getBreakpointKey, getStateKey } from './utils';
|
|
16
|
+
|
|
17
|
+
export function createSnapshotsManager(
|
|
18
|
+
getStylesByMeta: ( meta: StyleInheritanceMetaProps ) => StyleVariantWithId[],
|
|
19
|
+
breakpointsRoot: BreakpointNode
|
|
20
|
+
): StylesInheritanceSnapshotGetter {
|
|
21
|
+
const breakpointsInheritancePaths = makeBreakpointsInheritancePaths( breakpointsRoot );
|
|
22
|
+
const allBreakpointStatesSnapshots: BreakpointsStatesSnapshotsMapping = {};
|
|
23
|
+
|
|
24
|
+
const buildMissingSnapshotsForBreakpoint = (
|
|
25
|
+
currentBreakpointId: BreakpointId | null,
|
|
26
|
+
parentBreakpoint: BreakpointStatesSlotsMapping | undefined,
|
|
27
|
+
state: StyleDefinitionState
|
|
28
|
+
) => {
|
|
29
|
+
const currentBreakpointKey = getBreakpointKey( currentBreakpointId );
|
|
30
|
+
const stateKey = getStateKey( state );
|
|
31
|
+
|
|
32
|
+
if ( ! allBreakpointStatesSnapshots[ currentBreakpointKey ] ) {
|
|
33
|
+
allBreakpointStatesSnapshots[ currentBreakpointKey ] = {
|
|
34
|
+
[ DEFAULT_STATE ]: buildStateSnapshotSlot(
|
|
35
|
+
getStylesByMeta( { breakpoint: currentBreakpointId, state: null } ),
|
|
36
|
+
parentBreakpoint,
|
|
37
|
+
{},
|
|
38
|
+
null
|
|
39
|
+
),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if ( state && ! allBreakpointStatesSnapshots[ currentBreakpointKey ][ stateKey ] ) {
|
|
44
|
+
allBreakpointStatesSnapshots[ currentBreakpointKey ][ stateKey ] = buildStateSnapshotSlot(
|
|
45
|
+
getStylesByMeta( { breakpoint: currentBreakpointId, state } ),
|
|
46
|
+
parentBreakpoint,
|
|
47
|
+
allBreakpointStatesSnapshots[ currentBreakpointKey ],
|
|
48
|
+
state
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return ( meta: StyleInheritanceMetaProps ) => {
|
|
54
|
+
const { breakpoint, state } = meta;
|
|
55
|
+
|
|
56
|
+
const stateKey = getStateKey( state );
|
|
57
|
+
const breakpointKey = getBreakpointKey( breakpoint );
|
|
58
|
+
|
|
59
|
+
if ( allBreakpointStatesSnapshots[ breakpointKey ]?.[ stateKey ] ) {
|
|
60
|
+
// snapshot was already made for this breakpoint+state
|
|
61
|
+
return allBreakpointStatesSnapshots[ breakpointKey ][ stateKey ].snapshot;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const breakpointsChain = [ ...breakpointsInheritancePaths[ breakpointKey ], breakpoint ];
|
|
65
|
+
|
|
66
|
+
breakpointsChain.forEach( ( breakpointId, index ) => {
|
|
67
|
+
const parentBreakpointId = index > 0 ? breakpointsChain[ index - 1 ] : null;
|
|
68
|
+
|
|
69
|
+
buildMissingSnapshotsForBreakpoint(
|
|
70
|
+
breakpointId,
|
|
71
|
+
parentBreakpointId ? allBreakpointStatesSnapshots[ parentBreakpointId ] : undefined,
|
|
72
|
+
state
|
|
73
|
+
);
|
|
74
|
+
} );
|
|
75
|
+
|
|
76
|
+
return allBreakpointStatesSnapshots[ breakpointKey ]?.[ stateKey ]?.snapshot;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* builds a mapping of each breakpoint to its inheritance chain, e.g. -
|
|
82
|
+
* desktop: [],
|
|
83
|
+
* tablet: [ 'desktop' ],
|
|
84
|
+
* mobile: [ 'desktop', 'tablet' ]
|
|
85
|
+
* @param root
|
|
86
|
+
*/
|
|
87
|
+
function makeBreakpointsInheritancePaths( root: BreakpointNode ): BreakpointsInheritancePath {
|
|
88
|
+
const breakpoints: Partial< BreakpointsInheritancePath > = {};
|
|
89
|
+
|
|
90
|
+
const traverse = ( node: BreakpointNode, parent?: BreakpointId[] ) => {
|
|
91
|
+
const { id, children } = node;
|
|
92
|
+
|
|
93
|
+
breakpoints[ id ] = parent ? [ ...parent ] : [];
|
|
94
|
+
|
|
95
|
+
children?.forEach( ( child ) => {
|
|
96
|
+
traverse( child, [ ...( breakpoints[ id ] ?? [] ), id ] );
|
|
97
|
+
} );
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
traverse( root );
|
|
101
|
+
|
|
102
|
+
return breakpoints as BreakpointsInheritancePath;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// creates a snapshot slot for a specific breakpoint and state
|
|
106
|
+
function buildStateSnapshotSlot(
|
|
107
|
+
styles: StyleVariantWithId[],
|
|
108
|
+
parentBreakpoint: BreakpointStatesSlotsMapping | undefined,
|
|
109
|
+
currentBreakpoint: BreakpointStatesSlotsMapping,
|
|
110
|
+
state: StyleDefinitionState
|
|
111
|
+
): StylesInheritanceSnapshotsSlot {
|
|
112
|
+
const initialSlot = buildInitialSnapshotFromStyles( styles );
|
|
113
|
+
|
|
114
|
+
if ( ! state ) {
|
|
115
|
+
return {
|
|
116
|
+
snapshot: mergeSnapshots( [ initialSlot.snapshot, parentBreakpoint?.[ DEFAULT_STATE ]?.snapshot ] ),
|
|
117
|
+
stateSpecificSnapshot: undefined,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
snapshot: mergeSnapshots( [
|
|
123
|
+
initialSlot.snapshot,
|
|
124
|
+
parentBreakpoint?.[ state ]?.stateSpecificSnapshot,
|
|
125
|
+
currentBreakpoint[ DEFAULT_STATE ]?.snapshot,
|
|
126
|
+
] ),
|
|
127
|
+
stateSpecificSnapshot: mergeSnapshots( [
|
|
128
|
+
initialSlot.stateSpecificSnapshot,
|
|
129
|
+
parentBreakpoint?.[ state ]?.stateSpecificSnapshot,
|
|
130
|
+
] ),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// creates an initial snapshot based on the passed style variants only
|
|
135
|
+
function buildInitialSnapshotFromStyles( styles: StyleVariantWithId[] ): StylesInheritanceSnapshotsSlot {
|
|
136
|
+
const snapshot: StylesInheritanceSnapshot = {};
|
|
137
|
+
|
|
138
|
+
styles.forEach( ( styleVariantWithId ) => {
|
|
139
|
+
const {
|
|
140
|
+
styleVariant: { props },
|
|
141
|
+
} = styleVariantWithId;
|
|
142
|
+
|
|
143
|
+
Object.entries( props ).forEach( ( [ key, value ] ) => {
|
|
144
|
+
if ( ! snapshot[ key ] ) {
|
|
145
|
+
snapshot[ key ] = [];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const snapshotPropValue: SnapshotPropValue = {
|
|
149
|
+
...styleVariantWithId,
|
|
150
|
+
value,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
snapshot[ key ].push( snapshotPropValue );
|
|
154
|
+
} );
|
|
155
|
+
} );
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
snapshot,
|
|
159
|
+
stateSpecificSnapshot: snapshot,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// merge previous snapshot into the current one - first value of each prop is the strongest
|
|
164
|
+
function mergeSnapshots( snapshots: ( StylesInheritanceSnapshot | undefined )[] ) {
|
|
165
|
+
const snapshot: StylesInheritanceSnapshot = {};
|
|
166
|
+
|
|
167
|
+
snapshots.filter( Boolean ).forEach( ( currentSnapshot ) =>
|
|
168
|
+
Object.entries( currentSnapshot as StylesInheritanceSnapshot ).forEach( ( [ key, values ] ) => {
|
|
169
|
+
if ( ! snapshot[ key ] ) {
|
|
170
|
+
snapshot[ key ] = [];
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// concatenate the previous snapshot's prop values to the current ones
|
|
174
|
+
snapshot[ key ] = snapshot[ key ].concat( values );
|
|
175
|
+
} )
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
return snapshot;
|
|
179
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type BreakpointNode } from '@elementor/editor-responsive';
|
|
2
|
+
import { type StyleDefinition } from '@elementor/editor-styles';
|
|
3
|
+
|
|
4
|
+
import { createSnapshotsManager } from './create-snapshots-manager';
|
|
5
|
+
import { type BreakpointsStatesStyles, type StyleInheritanceMetaProps, type StylesInheritanceSnapshot } from './types';
|
|
6
|
+
import { getBreakpointKey, getStateKey } from './utils';
|
|
7
|
+
|
|
8
|
+
export function createStylesInheritance(
|
|
9
|
+
styleDefs: StyleDefinition[],
|
|
10
|
+
breakpointsRoot: BreakpointNode
|
|
11
|
+
): ( meta: StyleInheritanceMetaProps ) => StylesInheritanceSnapshot | undefined {
|
|
12
|
+
const styleVariantsByMeta = buildStyleVariantsByMetaMapping( styleDefs );
|
|
13
|
+
|
|
14
|
+
const getStyles = ( { breakpoint, state }: StyleInheritanceMetaProps ) =>
|
|
15
|
+
styleVariantsByMeta?.[ getBreakpointKey( breakpoint ) ]?.[ getStateKey( state ) ] ?? [];
|
|
16
|
+
|
|
17
|
+
return createSnapshotsManager( getStyles, breakpointsRoot );
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function buildStyleVariantsByMetaMapping( styleDefs: StyleDefinition[] ): BreakpointsStatesStyles {
|
|
21
|
+
const breakpointStateSlots: BreakpointsStatesStyles = {};
|
|
22
|
+
|
|
23
|
+
styleDefs.forEach( ( styleDef ) => {
|
|
24
|
+
// iterate over each style definition's variants and place them in the corresponding breakpoint's base or state styles
|
|
25
|
+
styleDef.variants.forEach( ( styleVariant ) => {
|
|
26
|
+
const { meta } = styleVariant;
|
|
27
|
+
const { state, breakpoint } = meta;
|
|
28
|
+
|
|
29
|
+
const breakpointKey = getBreakpointKey( breakpoint );
|
|
30
|
+
const stateKey = getStateKey( state );
|
|
31
|
+
|
|
32
|
+
if ( ! breakpointStateSlots[ breakpointKey ] ) {
|
|
33
|
+
breakpointStateSlots[ breakpointKey ] = {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const breakpointNode = breakpointStateSlots[ breakpointKey ];
|
|
37
|
+
|
|
38
|
+
if ( ! breakpointNode[ stateKey ] ) {
|
|
39
|
+
breakpointNode[ stateKey ] = [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
breakpointNode[ stateKey ].push( {
|
|
43
|
+
styleId: styleDef.id,
|
|
44
|
+
styleVariant,
|
|
45
|
+
} );
|
|
46
|
+
} );
|
|
47
|
+
} );
|
|
48
|
+
|
|
49
|
+
return breakpointStateSlots;
|
|
50
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type PropValue } from '@elementor/editor-props';
|
|
2
|
+
import { type BreakpointId } from '@elementor/editor-responsive';
|
|
3
|
+
import { type StyleDefinitionState, type StyleDefinitionVariant } from '@elementor/editor-styles';
|
|
4
|
+
|
|
5
|
+
export type StyleDefinitionStateWithNormal = NonNullable< StyleDefinitionState > | 'normal';
|
|
6
|
+
|
|
7
|
+
type StatesMapping< T > = Partial< Record< StyleDefinitionStateWithNormal, T > >;
|
|
8
|
+
|
|
9
|
+
export type StyleVariantWithId = {
|
|
10
|
+
styleId: string;
|
|
11
|
+
styleVariant: StyleDefinitionVariant;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type SnapshotPropValue = StyleVariantWithId & {
|
|
15
|
+
value: PropValue;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type StylesInheritanceSnapshot = Record< string, SnapshotPropValue[] >;
|
|
19
|
+
|
|
20
|
+
export type StylesInheritanceSnapshotsSlot = {
|
|
21
|
+
snapshot?: StylesInheritanceSnapshot;
|
|
22
|
+
stateSpecificSnapshot?: StylesInheritanceSnapshot; // with only prop values of the current state, used for inheritance - e.g. mobile-hover inherits first from tablet-hover specific snapshot
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type BreakpointStatesSlotsMapping = StatesMapping< StylesInheritanceSnapshotsSlot >;
|
|
26
|
+
|
|
27
|
+
export type BreakpointsStatesSnapshotsMapping = Partial< Record< BreakpointId, BreakpointStatesSlotsMapping > >;
|
|
28
|
+
|
|
29
|
+
type BreakpointStatesStyles = StatesMapping< StyleVariantWithId[] >;
|
|
30
|
+
|
|
31
|
+
export type BreakpointsStatesStyles = Partial< Record< BreakpointId, Partial< BreakpointStatesStyles > > >;
|
|
32
|
+
|
|
33
|
+
export type BreakpointsInheritancePath = Record< BreakpointId, BreakpointId[] >;
|
|
34
|
+
|
|
35
|
+
export type StyleInheritanceMetaProps = {
|
|
36
|
+
breakpoint: BreakpointId | null;
|
|
37
|
+
state: StyleDefinitionState;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type StylesInheritanceSnapshotGetter = (
|
|
41
|
+
meta: StyleInheritanceMetaProps
|
|
42
|
+
) => StylesInheritanceSnapshot | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type BreakpointId } from '@elementor/editor-responsive';
|
|
2
|
+
import { type StyleDefinitionState } from '@elementor/editor-styles';
|
|
3
|
+
|
|
4
|
+
export const DEFAULT_STATE = 'normal';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_BREAKPOINT = 'desktop';
|
|
7
|
+
|
|
8
|
+
export const getStateKey = ( state: StyleDefinitionState ) => state ?? DEFAULT_STATE;
|
|
9
|
+
|
|
10
|
+
export const getBreakpointKey = ( breakpoint: BreakpointId | null ): BreakpointId => breakpoint ?? DEFAULT_BREAKPOINT;
|