@elementor/editor-components 4.0.0-666 → 4.0.0-668
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +191 -3870
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +184 -3904
- package/dist/index.mjs.map +1 -1
- package/package.json +23 -23
- package/src/init.ts +0 -13
- package/src/extended/components/component-introduction.tsx +0 -77
- package/src/extended/components/component-panel-header/component-badge.tsx +0 -73
- package/src/extended/components/component-panel-header/component-panel-header.tsx +0 -98
- package/src/extended/components/component-properties-panel/component-properties-panel-content.tsx +0 -176
- package/src/extended/components/component-properties-panel/component-properties-panel.tsx +0 -43
- package/src/extended/components/component-properties-panel/properties-empty-state.tsx +0 -51
- package/src/extended/components/component-properties-panel/properties-group.tsx +0 -196
- package/src/extended/components/component-properties-panel/property-item.tsx +0 -124
- package/src/extended/components/component-properties-panel/sortable.tsx +0 -92
- package/src/extended/components/component-properties-panel/use-current-editable-item.ts +0 -73
- package/src/extended/components/component-properties-panel/utils/generate-unique-label.ts +0 -21
- package/src/extended/components/component-properties-panel/utils/validate-group-label.ts +0 -24
- package/src/extended/components/components-tab/component-item.tsx +0 -180
- package/src/extended/components/components-tab/components.tsx +0 -58
- package/src/extended/components/components-tab/delete-confirmation-dialog.tsx +0 -26
- package/src/extended/components/create-component-form/create-component-form.tsx +0 -281
- package/src/extended/components/create-component-form/hooks/use-form.ts +0 -72
- package/src/extended/components/create-component-form/utils/get-component-event-data.ts +0 -54
- package/src/extended/components/edit-component/component-modal.tsx +0 -133
- package/src/extended/components/edit-component/edit-component.tsx +0 -166
- package/src/extended/components/edit-component/use-canvas-document.ts +0 -9
- package/src/extended/components/edit-component/use-element-rect.ts +0 -81
- package/src/extended/components/instance-editing-panel/instance-editing-panel.tsx +0 -60
- package/src/extended/components/overridable-props/indicator.tsx +0 -83
- package/src/extended/components/overridable-props/overridable-prop-control.tsx +0 -127
- package/src/extended/components/overridable-props/overridable-prop-form.tsx +0 -135
- package/src/extended/components/overridable-props/overridable-prop-indicator.tsx +0 -138
- package/src/extended/components/overridable-props/utils/validate-prop-label.ts +0 -38
- package/src/extended/consts.ts +0 -3
- package/src/extended/hooks/use-navigate-back.ts +0 -24
- package/src/extended/init.ts +0 -108
- package/src/extended/mcp/index.ts +0 -14
- package/src/extended/mcp/save-as-component-tool.ts +0 -436
- package/src/extended/shortcuts/create-component-shortcut.ts +0 -121
- package/src/extended/store/actions/add-overridable-group.ts +0 -53
- package/src/extended/store/actions/archive-component.ts +0 -18
- package/src/extended/store/actions/create-unpublished-component.ts +0 -99
- package/src/extended/store/actions/delete-overridable-group.ts +0 -32
- package/src/extended/store/actions/delete-overridable-prop.ts +0 -64
- package/src/extended/store/actions/rename-component.ts +0 -48
- package/src/extended/store/actions/rename-overridable-group.ts +0 -33
- package/src/extended/store/actions/reorder-group-props.ts +0 -37
- package/src/extended/store/actions/reorder-overridable-groups.ts +0 -24
- package/src/extended/store/actions/reset-sanitized-components.ts +0 -5
- package/src/extended/store/actions/set-overridable-prop.ts +0 -109
- package/src/extended/store/actions/update-component-sanitized-attribute.ts +0 -7
- package/src/extended/store/actions/update-current-component.ts +0 -12
- package/src/extended/store/actions/update-overridable-prop-params.ts +0 -52
- package/src/extended/store/utils/groups-transformers.ts +0 -187
- package/src/extended/sync/before-save.ts +0 -52
- package/src/extended/sync/cleanup-overridable-props-on-delete.ts +0 -78
- package/src/extended/sync/create-components-before-save.ts +0 -111
- package/src/extended/sync/handle-component-edit-mode-container.ts +0 -114
- package/src/extended/sync/prevent-non-atomic-nesting.ts +0 -198
- package/src/extended/sync/revert-overridables-on-copy-or-duplicate.ts +0 -66
- package/src/extended/sync/sanitize-overridable-props.ts +0 -32
- package/src/extended/sync/set-component-overridable-props-settings-before-save.ts +0 -22
- package/src/extended/sync/update-archived-component-before-save.ts +0 -31
- package/src/extended/sync/update-component-title-before-save.ts +0 -18
- package/src/extended/utils/component-form-schema.ts +0 -32
- package/src/extended/utils/component-name-validation.ts +0 -25
- package/src/extended/utils/create-component-model.ts +0 -28
- package/src/extended/utils/get-container-for-new-element.ts +0 -49
- package/src/extended/utils/is-editing-component.ts +0 -5
- package/src/extended/utils/replace-element-with-component.ts +0 -11
- package/src/extended/utils/revert-overridable-settings.ts +0 -207
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-components",
|
|
3
3
|
"description": "Elementor editor components",
|
|
4
|
-
"version": "4.0.0-
|
|
4
|
+
"version": "4.0.0-668",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,31 +40,31 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor": "4.0.0-
|
|
44
|
-
"@elementor/editor-canvas": "4.0.0-
|
|
45
|
-
"@elementor/editor-controls": "4.0.0-
|
|
46
|
-
"@elementor/editor-documents": "4.0.0-
|
|
47
|
-
"@elementor/editor-editing-panel": "4.0.0-
|
|
48
|
-
"@elementor/editor-elements": "4.0.0-
|
|
49
|
-
"@elementor/editor-elements-panel": "4.0.0-
|
|
50
|
-
"@elementor/editor-mcp": "4.0.0-
|
|
51
|
-
"@elementor/editor-templates": "4.0.0-
|
|
52
|
-
"@elementor/editor-panels": "4.0.0-
|
|
53
|
-
"@elementor/editor-props": "4.0.0-
|
|
54
|
-
"@elementor/editor-styles-repository": "4.0.0-
|
|
55
|
-
"@elementor/editor-ui": "4.0.0-
|
|
56
|
-
"@elementor/editor-v1-adapters": "4.0.0-
|
|
57
|
-
"@elementor/http-client": "4.0.0-
|
|
43
|
+
"@elementor/editor": "4.0.0-668",
|
|
44
|
+
"@elementor/editor-canvas": "4.0.0-668",
|
|
45
|
+
"@elementor/editor-controls": "4.0.0-668",
|
|
46
|
+
"@elementor/editor-documents": "4.0.0-668",
|
|
47
|
+
"@elementor/editor-editing-panel": "4.0.0-668",
|
|
48
|
+
"@elementor/editor-elements": "4.0.0-668",
|
|
49
|
+
"@elementor/editor-elements-panel": "4.0.0-668",
|
|
50
|
+
"@elementor/editor-mcp": "4.0.0-668",
|
|
51
|
+
"@elementor/editor-templates": "4.0.0-668",
|
|
52
|
+
"@elementor/editor-panels": "4.0.0-668",
|
|
53
|
+
"@elementor/editor-props": "4.0.0-668",
|
|
54
|
+
"@elementor/editor-styles-repository": "4.0.0-668",
|
|
55
|
+
"@elementor/editor-ui": "4.0.0-668",
|
|
56
|
+
"@elementor/editor-v1-adapters": "4.0.0-668",
|
|
57
|
+
"@elementor/http-client": "4.0.0-668",
|
|
58
58
|
"@elementor/icons": "^1.68.0",
|
|
59
|
-
"@elementor/events": "4.0.0-
|
|
60
|
-
"@elementor/query": "4.0.0-
|
|
61
|
-
"@elementor/schema": "4.0.0-
|
|
62
|
-
"@elementor/store": "4.0.0-
|
|
59
|
+
"@elementor/events": "4.0.0-668",
|
|
60
|
+
"@elementor/query": "4.0.0-668",
|
|
61
|
+
"@elementor/schema": "4.0.0-668",
|
|
62
|
+
"@elementor/store": "4.0.0-668",
|
|
63
63
|
"@elementor/ui": "1.36.17",
|
|
64
|
-
"@elementor/utils": "4.0.0-
|
|
64
|
+
"@elementor/utils": "4.0.0-668",
|
|
65
65
|
"@wordpress/i18n": "^5.13.0",
|
|
66
|
-
"@elementor/editor-notifications": "4.0.0-
|
|
67
|
-
"@elementor/editor-current-user": "4.0.0-
|
|
66
|
+
"@elementor/editor-notifications": "4.0.0-668",
|
|
67
|
+
"@elementor/editor-current-user": "4.0.0-668"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"react": "^18.3.1",
|
package/src/init.ts
CHANGED
|
@@ -11,7 +11,6 @@ import { injectTab } from '@elementor/editor-elements-panel';
|
|
|
11
11
|
import { stylesRepository } from '@elementor/editor-styles-repository';
|
|
12
12
|
import { registerDataHook } from '@elementor/editor-v1-adapters';
|
|
13
13
|
import { __registerSlice as registerSlice } from '@elementor/store';
|
|
14
|
-
import { isProAtLeast } from '@elementor/utils';
|
|
15
14
|
import { __ } from '@wordpress/i18n';
|
|
16
15
|
|
|
17
16
|
import { componentInstanceTransformer } from './component-instance-transformer';
|
|
@@ -23,8 +22,6 @@ import { openEditModeDialog } from './components/in-edit-mode';
|
|
|
23
22
|
import { InstanceEditingPanel } from './components/instance-editing-panel/instance-editing-panel';
|
|
24
23
|
import { LoadTemplateComponents } from './components/load-template-components';
|
|
25
24
|
import { COMPONENT_WIDGET_TYPE, createComponentType } from './create-component-type';
|
|
26
|
-
import { initExtended } from './extended/init';
|
|
27
|
-
import { initCreateComponentShortcut } from './extended/shortcuts/create-component-shortcut';
|
|
28
25
|
import { PopulateStore } from './populate-store';
|
|
29
26
|
import { initCircularNestingPrevention } from './prevent-circular-nesting';
|
|
30
27
|
import { loadComponentsAssets } from './store/actions/load-components-assets';
|
|
@@ -35,8 +32,6 @@ import { beforeSave } from './sync/before-save';
|
|
|
35
32
|
import { initLoadComponentDataAfterInstanceAdded } from './sync/load-component-data-after-instance-added';
|
|
36
33
|
import { type ExtendedWindow } from './types';
|
|
37
34
|
|
|
38
|
-
const PRO_EXTENDED_MIGRATION_VERSION = '4.0.0';
|
|
39
|
-
|
|
40
35
|
export function init() {
|
|
41
36
|
stylesRepository.register( componentsStylesProvider );
|
|
42
37
|
|
|
@@ -92,12 +87,4 @@ export function init() {
|
|
|
92
87
|
initCircularNestingPrevention();
|
|
93
88
|
|
|
94
89
|
initLoadComponentDataAfterInstanceAdded();
|
|
95
|
-
|
|
96
|
-
if ( !! window.elementorPro && ! isProAtLeast( PRO_EXTENDED_MIGRATION_VERSION ) ) {
|
|
97
|
-
initExtended();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if ( !! window.elementorPro ) {
|
|
101
|
-
initCreateComponentShortcut();
|
|
102
|
-
}
|
|
103
90
|
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { PopoverContent } from '@elementor/editor-controls';
|
|
3
|
-
import { PopoverHeader } from '@elementor/editor-ui';
|
|
4
|
-
import { Box, Button, Image, Link, Popover, Stack, Typography } from '@elementor/ui';
|
|
5
|
-
import { __ } from '@wordpress/i18n';
|
|
6
|
-
|
|
7
|
-
export const ComponentIntroduction = ( {
|
|
8
|
-
anchorRef,
|
|
9
|
-
shouldShowIntroduction,
|
|
10
|
-
onClose,
|
|
11
|
-
}: {
|
|
12
|
-
anchorRef: React.RefObject< HTMLElement >;
|
|
13
|
-
shouldShowIntroduction: boolean;
|
|
14
|
-
onClose: () => void;
|
|
15
|
-
} ) => {
|
|
16
|
-
if ( ! anchorRef.current || ! shouldShowIntroduction ) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<Popover
|
|
22
|
-
anchorEl={ anchorRef.current }
|
|
23
|
-
open={ shouldShowIntroduction }
|
|
24
|
-
anchorOrigin={ {
|
|
25
|
-
vertical: 'top',
|
|
26
|
-
horizontal: 'right',
|
|
27
|
-
} }
|
|
28
|
-
transformOrigin={ {
|
|
29
|
-
vertical: 'top',
|
|
30
|
-
horizontal: -30,
|
|
31
|
-
} }
|
|
32
|
-
onClose={ onClose }
|
|
33
|
-
>
|
|
34
|
-
<Box sx={ { width: '296px' } }>
|
|
35
|
-
<PopoverHeader title={ __( 'Add your first property', 'elementor' ) } onClose={ onClose } />
|
|
36
|
-
<Image
|
|
37
|
-
sx={ { width: '296px', height: '160px' } }
|
|
38
|
-
src={ 'https://assets.elementor.com/packages/v1/images/components-properties-intro.png' }
|
|
39
|
-
alt={ '' }
|
|
40
|
-
/>
|
|
41
|
-
<PopoverContent>
|
|
42
|
-
<Stack sx={ { p: 2 } }>
|
|
43
|
-
<Typography variant={ 'body2' }>
|
|
44
|
-
{ __( 'Properties make instances flexible.', 'elementor' ) }
|
|
45
|
-
</Typography>
|
|
46
|
-
<Typography variant={ 'body2' }>
|
|
47
|
-
{ __(
|
|
48
|
-
'Select any Element, then in the General tab, click next to any setting you want users to customize - like text, images, or links.',
|
|
49
|
-
'elementor'
|
|
50
|
-
) }
|
|
51
|
-
</Typography>
|
|
52
|
-
<Typography variant={ 'body2' } sx={ { mt: 2 } }>
|
|
53
|
-
{ __(
|
|
54
|
-
'Your properties will appear in the Properties panel, where you can organize and manage them anytime.',
|
|
55
|
-
'elementor'
|
|
56
|
-
) }
|
|
57
|
-
</Typography>
|
|
58
|
-
<Link
|
|
59
|
-
href="http://go.elementor.com/components-guide"
|
|
60
|
-
target="_blank"
|
|
61
|
-
sx={ { mt: 2 } }
|
|
62
|
-
color="info.main"
|
|
63
|
-
variant="body2"
|
|
64
|
-
>
|
|
65
|
-
{ __( 'Learn more', 'elementor' ) }
|
|
66
|
-
</Link>
|
|
67
|
-
<Stack direction="row" alignItems="center" justifyContent="flex-end" sx={ { pt: 1 } }>
|
|
68
|
-
<Button size="medium" variant="contained" onClick={ onClose }>
|
|
69
|
-
{ __( 'Got it', 'elementor' ) }
|
|
70
|
-
</Button>
|
|
71
|
-
</Stack>
|
|
72
|
-
</Stack>
|
|
73
|
-
</PopoverContent>
|
|
74
|
-
</Box>
|
|
75
|
-
</Popover>
|
|
76
|
-
);
|
|
77
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useEffect, useRef } from 'react';
|
|
3
|
-
import { ComponentPropListIcon } from '@elementor/icons';
|
|
4
|
-
import { Badge, Box, keyframes, styled, ToggleButton, Tooltip } from '@elementor/ui';
|
|
5
|
-
import { __ } from '@wordpress/i18n';
|
|
6
|
-
|
|
7
|
-
export const ComponentsBadge = React.forwardRef<
|
|
8
|
-
HTMLDivElement,
|
|
9
|
-
{ overridablePropsCount: number; onClick: () => void }
|
|
10
|
-
>( ( { overridablePropsCount, onClick }, ref ) => {
|
|
11
|
-
const prevCount = usePrevious( overridablePropsCount );
|
|
12
|
-
|
|
13
|
-
const isFirstExposedProperty = prevCount === 0 && overridablePropsCount === 1;
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<StyledBadge
|
|
17
|
-
ref={ ref }
|
|
18
|
-
color="primary"
|
|
19
|
-
key={ overridablePropsCount }
|
|
20
|
-
invisible={ overridablePropsCount === 0 }
|
|
21
|
-
animate={ isFirstExposedProperty }
|
|
22
|
-
anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
|
|
23
|
-
badgeContent={
|
|
24
|
-
<Box sx={ { animation: ! isFirstExposedProperty ? `${ slideUp } 300ms ease-out` : 'none' } }>
|
|
25
|
-
{ overridablePropsCount }
|
|
26
|
-
</Box>
|
|
27
|
-
}
|
|
28
|
-
>
|
|
29
|
-
<Tooltip title={ __( 'Component properties', 'elementor' ) }>
|
|
30
|
-
<ToggleButton
|
|
31
|
-
value="exposed properties"
|
|
32
|
-
size="tiny"
|
|
33
|
-
onClick={ onClick }
|
|
34
|
-
aria-label={ __( 'Component properties', 'elementor' ) }
|
|
35
|
-
>
|
|
36
|
-
<ComponentPropListIcon fontSize="tiny" />
|
|
37
|
-
</ToggleButton>
|
|
38
|
-
</Tooltip>
|
|
39
|
-
</StyledBadge>
|
|
40
|
-
);
|
|
41
|
-
} );
|
|
42
|
-
|
|
43
|
-
const StyledBadge = styled( Badge, { shouldForwardProp: ( prop ) => prop !== 'animate' } )(
|
|
44
|
-
( { theme, animate } ) => ( {
|
|
45
|
-
'& .MuiBadge-badge': {
|
|
46
|
-
minWidth: theme.spacing( 2 ),
|
|
47
|
-
height: theme.spacing( 2 ),
|
|
48
|
-
minHeight: theme.spacing( 2 ),
|
|
49
|
-
maxWidth: theme.spacing( 2 ),
|
|
50
|
-
fontSize: theme.typography.caption.fontSize as string,
|
|
51
|
-
animation: animate ? `${ bounceIn } 300ms ease-out` : 'none',
|
|
52
|
-
},
|
|
53
|
-
} )
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
function usePrevious< T >( value: T ) {
|
|
57
|
-
const ref = useRef< T >( value );
|
|
58
|
-
useEffect( () => {
|
|
59
|
-
ref.current = value;
|
|
60
|
-
}, [ value ] );
|
|
61
|
-
return ref.current;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const bounceIn = keyframes`
|
|
65
|
-
0% { transform: scale(0) translate(50%, 50%); opacity: 0; }
|
|
66
|
-
70% { transform: scale(1.1) translate(50%, -50%); opacity: 1; }
|
|
67
|
-
100% { transform: scale(1) translate(50%, -50%); opacity: 1; }
|
|
68
|
-
`;
|
|
69
|
-
|
|
70
|
-
const slideUp = keyframes`
|
|
71
|
-
from { transform: translateY(100%); opacity: 0; }
|
|
72
|
-
to { transform: translateY(0); opacity: 1; }
|
|
73
|
-
`;
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useSuppressedMessage } from '@elementor/editor-current-user';
|
|
3
|
-
import { getV1DocumentsManager } from '@elementor/editor-documents';
|
|
4
|
-
import { PanelHeader } from '@elementor/editor-panels';
|
|
5
|
-
import { EllipsisWithTooltip } from '@elementor/editor-ui';
|
|
6
|
-
import { ArrowLeftIcon, ComponentsFilledIcon } from '@elementor/icons';
|
|
7
|
-
import { __getState as getState } from '@elementor/store';
|
|
8
|
-
import { Box, Divider, IconButton, Tooltip, Typography } from '@elementor/ui';
|
|
9
|
-
import { __ } from '@wordpress/i18n';
|
|
10
|
-
|
|
11
|
-
import { useSanitizeOverridableProps } from '../../../hooks/use-sanitize-overridable-props';
|
|
12
|
-
import { type ComponentsSlice, SLICE_NAME, useCurrentComponent } from '../../../store/store';
|
|
13
|
-
import { trackComponentEvent } from '../../../utils/tracking';
|
|
14
|
-
import { useNavigateBack } from '../../hooks/use-navigate-back';
|
|
15
|
-
import { ComponentIntroduction } from '../component-introduction';
|
|
16
|
-
import { usePanelActions } from '../component-properties-panel/component-properties-panel';
|
|
17
|
-
import { ComponentsBadge } from './component-badge';
|
|
18
|
-
|
|
19
|
-
const MESSAGE_KEY = 'components-properties-introduction';
|
|
20
|
-
|
|
21
|
-
export const ComponentPanelHeader = () => {
|
|
22
|
-
const { id: currentComponentId, uid: componentUid } = useCurrentComponent() ?? { id: null, uid: null };
|
|
23
|
-
const overridableProps = useSanitizeOverridableProps( currentComponentId );
|
|
24
|
-
const onBack = useNavigateBack();
|
|
25
|
-
const componentName = getComponentName();
|
|
26
|
-
const [ isMessageSuppressed, suppressMessage ] = useSuppressedMessage( MESSAGE_KEY );
|
|
27
|
-
const [ shouldShowIntroduction, setShouldShowIntroduction ] = React.useState( ! isMessageSuppressed );
|
|
28
|
-
|
|
29
|
-
const { open: openPropertiesPanel } = usePanelActions();
|
|
30
|
-
|
|
31
|
-
const overridablePropsCount = overridableProps ? Object.keys( overridableProps.props ).length : 0;
|
|
32
|
-
const anchorRef = React.useRef< HTMLDivElement >( null );
|
|
33
|
-
|
|
34
|
-
if ( ! currentComponentId ) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const handleCloseIntroduction = () => {
|
|
39
|
-
suppressMessage();
|
|
40
|
-
setShouldShowIntroduction( false );
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const handleOpenPropertiesPanel = () => {
|
|
44
|
-
openPropertiesPanel();
|
|
45
|
-
|
|
46
|
-
trackComponentEvent( {
|
|
47
|
-
action: 'propertiesPanelOpened',
|
|
48
|
-
source: 'user',
|
|
49
|
-
component_uid: componentUid,
|
|
50
|
-
properties_count: overridablePropsCount,
|
|
51
|
-
} );
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<Box data-testid="component-panel-header">
|
|
56
|
-
<PanelHeader sx={ { justifyContent: 'start', px: 2 } }>
|
|
57
|
-
<Tooltip title={ __( 'Back', 'elementor' ) }>
|
|
58
|
-
<IconButton size="tiny" onClick={ onBack } aria-label={ __( 'Back', 'elementor' ) }>
|
|
59
|
-
<ArrowLeftIcon fontSize="tiny" />
|
|
60
|
-
</IconButton>
|
|
61
|
-
</Tooltip>
|
|
62
|
-
<ComponentsFilledIcon fontSize="tiny" stroke="currentColor" />
|
|
63
|
-
<EllipsisWithTooltip
|
|
64
|
-
title={ componentName }
|
|
65
|
-
as={ Typography }
|
|
66
|
-
variant="caption"
|
|
67
|
-
sx={ { fontWeight: 500, flexGrow: 1 } }
|
|
68
|
-
/>
|
|
69
|
-
<ComponentsBadge
|
|
70
|
-
overridablePropsCount={ overridablePropsCount }
|
|
71
|
-
ref={ anchorRef }
|
|
72
|
-
onClick={ handleOpenPropertiesPanel }
|
|
73
|
-
/>
|
|
74
|
-
</PanelHeader>
|
|
75
|
-
<Divider />
|
|
76
|
-
<ComponentIntroduction
|
|
77
|
-
anchorRef={ anchorRef }
|
|
78
|
-
shouldShowIntroduction={ shouldShowIntroduction }
|
|
79
|
-
onClose={ handleCloseIntroduction }
|
|
80
|
-
/>
|
|
81
|
-
</Box>
|
|
82
|
-
);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
function getComponentName(): string {
|
|
86
|
-
const state = getState() as ComponentsSlice;
|
|
87
|
-
const path = state[ SLICE_NAME ].path;
|
|
88
|
-
const { instanceTitle } = path.at( -1 ) ?? {};
|
|
89
|
-
|
|
90
|
-
if ( instanceTitle ) {
|
|
91
|
-
return instanceTitle;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const documentsManager = getV1DocumentsManager();
|
|
95
|
-
const currentDocument = documentsManager.getCurrent();
|
|
96
|
-
|
|
97
|
-
return currentDocument?.container?.settings?.get( 'post_title' ) ?? '';
|
|
98
|
-
}
|
package/src/extended/components/component-properties-panel/component-properties-panel-content.tsx
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { setDocumentModifiedStatus } from '@elementor/editor-documents';
|
|
4
|
-
import { PanelBody, PanelHeader, PanelHeaderTitle } from '@elementor/editor-panels';
|
|
5
|
-
import { ComponentPropListIcon, FolderPlusIcon, XIcon } from '@elementor/icons';
|
|
6
|
-
import { Divider, IconButton, List, Stack, Tooltip } from '@elementor/ui';
|
|
7
|
-
import { generateUniqueId } from '@elementor/utils';
|
|
8
|
-
import { __ } from '@wordpress/i18n';
|
|
9
|
-
|
|
10
|
-
import { useSanitizeOverridableProps } from '../../../hooks/use-sanitize-overridable-props';
|
|
11
|
-
import { useCurrentComponentId } from '../../../store/store';
|
|
12
|
-
import { addOverridableGroup } from '../../store/actions/add-overridable-group';
|
|
13
|
-
import { deleteOverridableGroup } from '../../store/actions/delete-overridable-group';
|
|
14
|
-
import { deleteOverridableProp } from '../../store/actions/delete-overridable-prop';
|
|
15
|
-
import { reorderGroupProps } from '../../store/actions/reorder-group-props';
|
|
16
|
-
import { reorderOverridableGroups } from '../../store/actions/reorder-overridable-groups';
|
|
17
|
-
import { updateOverridablePropParams } from '../../store/actions/update-overridable-prop-params';
|
|
18
|
-
import { PropertiesEmptyState } from './properties-empty-state';
|
|
19
|
-
import { PropertiesGroup } from './properties-group';
|
|
20
|
-
import { SortableItem, SortableProvider } from './sortable';
|
|
21
|
-
import { useCurrentEditableItem } from './use-current-editable-item';
|
|
22
|
-
import { generateUniqueLabel } from './utils/generate-unique-label';
|
|
23
|
-
|
|
24
|
-
type Props = {
|
|
25
|
-
onClose: () => void;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export function ComponentPropertiesPanelContent( { onClose }: Props ) {
|
|
29
|
-
const currentComponentId = useCurrentComponentId();
|
|
30
|
-
const overridableProps = useSanitizeOverridableProps( currentComponentId );
|
|
31
|
-
const [ isAddingGroup, setIsAddingGroup ] = useState( false );
|
|
32
|
-
const introductionRef = useRef< HTMLButtonElement >( null );
|
|
33
|
-
const groupLabelEditable = useCurrentEditableItem();
|
|
34
|
-
|
|
35
|
-
const groups = useMemo( () => {
|
|
36
|
-
if ( ! overridableProps ) {
|
|
37
|
-
return [];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return overridableProps.groups.order
|
|
41
|
-
.map( ( groupId ) => overridableProps.groups.items[ groupId ] ?? null )
|
|
42
|
-
.filter( Boolean );
|
|
43
|
-
}, [ overridableProps ] );
|
|
44
|
-
|
|
45
|
-
const allGroupsForSelect = useMemo(
|
|
46
|
-
() => groups.map( ( group ) => ( { value: group.id, label: group.label } ) ),
|
|
47
|
-
[ groups ]
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
if ( ! currentComponentId || ! overridableProps ) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const hasGroups = groups.length > 0;
|
|
55
|
-
const showEmptyState = ! hasGroups && ! isAddingGroup;
|
|
56
|
-
const groupIds = overridableProps.groups.order;
|
|
57
|
-
|
|
58
|
-
const handleAddGroupClick = () => {
|
|
59
|
-
if ( isAddingGroup ) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const newGroupId = generateUniqueId( 'group' );
|
|
64
|
-
const newLabel = generateUniqueLabel( groups );
|
|
65
|
-
|
|
66
|
-
addOverridableGroup( {
|
|
67
|
-
componentId: currentComponentId,
|
|
68
|
-
groupId: newGroupId,
|
|
69
|
-
label: newLabel,
|
|
70
|
-
source: 'user',
|
|
71
|
-
} );
|
|
72
|
-
setDocumentModifiedStatus( true );
|
|
73
|
-
setIsAddingGroup( false );
|
|
74
|
-
|
|
75
|
-
groupLabelEditable.setEditingGroupId( newGroupId );
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const handleGroupsReorder = ( newOrder: string[] ) => {
|
|
79
|
-
reorderOverridableGroups( { componentId: currentComponentId, newOrder } );
|
|
80
|
-
setDocumentModifiedStatus( true );
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const handlePropsReorder = ( groupId: string, newPropsOrder: string[] ) => {
|
|
84
|
-
reorderGroupProps( { componentId: currentComponentId, groupId, newPropsOrder } );
|
|
85
|
-
setDocumentModifiedStatus( true );
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const handlePropertyDelete = ( propKey: string ) => {
|
|
89
|
-
deleteOverridableProp( { componentId: currentComponentId, propKey, source: 'user' } );
|
|
90
|
-
setDocumentModifiedStatus( true );
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const handlePropertyUpdate = ( overrideKey: string, data: { label: string; group: string | null } ) => {
|
|
94
|
-
updateOverridablePropParams( {
|
|
95
|
-
componentId: currentComponentId,
|
|
96
|
-
overrideKey,
|
|
97
|
-
label: data.label,
|
|
98
|
-
groupId: data.group,
|
|
99
|
-
} );
|
|
100
|
-
setDocumentModifiedStatus( true );
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const handleGroupDelete = ( groupId: string ) => {
|
|
104
|
-
deleteOverridableGroup( { componentId: currentComponentId, groupId } );
|
|
105
|
-
setDocumentModifiedStatus( true );
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
return (
|
|
109
|
-
<>
|
|
110
|
-
<PanelHeader sx={ { justifyContent: 'start', pl: 1.5, pr: 1, py: 1 } }>
|
|
111
|
-
<Stack direction="row" alignItems="center" gap={ 0.5 } flexGrow={ 1 }>
|
|
112
|
-
<ComponentPropListIcon fontSize="tiny" />
|
|
113
|
-
<PanelHeaderTitle variant="subtitle2">
|
|
114
|
-
{ __( 'Component properties', 'elementor' ) }
|
|
115
|
-
</PanelHeaderTitle>
|
|
116
|
-
</Stack>
|
|
117
|
-
|
|
118
|
-
{ ! showEmptyState && (
|
|
119
|
-
<Tooltip title={ __( 'Add new group', 'elementor' ) }>
|
|
120
|
-
<IconButton
|
|
121
|
-
size="tiny"
|
|
122
|
-
aria-label={ __( 'Add new group', 'elementor' ) }
|
|
123
|
-
onClick={ handleAddGroupClick }
|
|
124
|
-
>
|
|
125
|
-
<FolderPlusIcon fontSize="tiny" />
|
|
126
|
-
</IconButton>
|
|
127
|
-
</Tooltip>
|
|
128
|
-
) }
|
|
129
|
-
|
|
130
|
-
<Tooltip title={ __( 'Close panel', 'elementor' ) }>
|
|
131
|
-
<IconButton
|
|
132
|
-
ref={ introductionRef }
|
|
133
|
-
size="tiny"
|
|
134
|
-
aria-label={ __( 'Close panel', 'elementor' ) }
|
|
135
|
-
onClick={ onClose }
|
|
136
|
-
>
|
|
137
|
-
<XIcon fontSize="tiny" />
|
|
138
|
-
</IconButton>
|
|
139
|
-
</Tooltip>
|
|
140
|
-
</PanelHeader>
|
|
141
|
-
|
|
142
|
-
<Divider />
|
|
143
|
-
|
|
144
|
-
<PanelBody>
|
|
145
|
-
{ showEmptyState ? (
|
|
146
|
-
<PropertiesEmptyState introductionRef={ introductionRef } />
|
|
147
|
-
) : (
|
|
148
|
-
<List sx={ { p: 2, display: 'flex', flexDirection: 'column', gap: 2 } }>
|
|
149
|
-
<SortableProvider value={ groupIds } onChange={ handleGroupsReorder }>
|
|
150
|
-
{ groups.map( ( group ) => (
|
|
151
|
-
<SortableItem key={ group.id } id={ group.id }>
|
|
152
|
-
{ ( { triggerProps, triggerStyle, isDragPlaceholder } ) => (
|
|
153
|
-
<PropertiesGroup
|
|
154
|
-
group={ group }
|
|
155
|
-
props={ overridableProps.props }
|
|
156
|
-
allGroups={ allGroupsForSelect }
|
|
157
|
-
allGroupsRecord={ overridableProps.groups.items }
|
|
158
|
-
sortableTriggerProps={ { ...triggerProps, style: triggerStyle } }
|
|
159
|
-
isDragPlaceholder={ isDragPlaceholder }
|
|
160
|
-
setIsAddingGroup={ setIsAddingGroup }
|
|
161
|
-
onPropsReorder={ ( newOrder ) => handlePropsReorder( group.id, newOrder ) }
|
|
162
|
-
onPropertyDelete={ handlePropertyDelete }
|
|
163
|
-
onPropertyUpdate={ handlePropertyUpdate }
|
|
164
|
-
editableLabelProps={ groupLabelEditable }
|
|
165
|
-
onGroupDelete={ handleGroupDelete }
|
|
166
|
-
/>
|
|
167
|
-
) }
|
|
168
|
-
</SortableItem>
|
|
169
|
-
) ) }
|
|
170
|
-
</SortableProvider>
|
|
171
|
-
</List>
|
|
172
|
-
) }
|
|
173
|
-
</PanelBody>
|
|
174
|
-
</>
|
|
175
|
-
);
|
|
176
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { usePanelActions as useEditingPanelActions } from '@elementor/editor-editing-panel';
|
|
3
|
-
import { __createPanel as createPanel, Panel } from '@elementor/editor-panels';
|
|
4
|
-
import { ThemeProvider } from '@elementor/editor-ui';
|
|
5
|
-
import { Alert, Box, ErrorBoundary } from '@elementor/ui';
|
|
6
|
-
import { __ } from '@wordpress/i18n';
|
|
7
|
-
|
|
8
|
-
import { ComponentPropertiesPanelContent } from './component-properties-panel-content';
|
|
9
|
-
|
|
10
|
-
const id = 'component-properties-panel';
|
|
11
|
-
|
|
12
|
-
export const { panel, usePanelActions } = createPanel( {
|
|
13
|
-
id,
|
|
14
|
-
component: ComponentPropertiesPanel,
|
|
15
|
-
} );
|
|
16
|
-
|
|
17
|
-
function ComponentPropertiesPanel() {
|
|
18
|
-
const { close: closePanel } = usePanelActions();
|
|
19
|
-
const { open: openEditingPanel } = useEditingPanelActions();
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<ThemeProvider>
|
|
23
|
-
<ErrorBoundary fallback={ <ErrorBoundaryFallback /> }>
|
|
24
|
-
<Panel>
|
|
25
|
-
<ComponentPropertiesPanelContent
|
|
26
|
-
onClose={ () => {
|
|
27
|
-
closePanel();
|
|
28
|
-
openEditingPanel();
|
|
29
|
-
} }
|
|
30
|
-
/>
|
|
31
|
-
</Panel>
|
|
32
|
-
</ErrorBoundary>
|
|
33
|
-
</ThemeProvider>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const ErrorBoundaryFallback = () => (
|
|
38
|
-
<Box role="alert" sx={ { minHeight: '100%', p: 2 } }>
|
|
39
|
-
<Alert severity="error" sx={ { mb: 2, maxWidth: 400, textAlign: 'center' } }>
|
|
40
|
-
<strong>{ __( 'Something went wrong', 'elementor' ) }</strong>
|
|
41
|
-
</Alert>
|
|
42
|
-
</Box>
|
|
43
|
-
);
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { ComponentPropListIcon } from '@elementor/icons';
|
|
4
|
-
import { Link, Stack, Typography } from '@elementor/ui';
|
|
5
|
-
import { __ } from '@wordpress/i18n';
|
|
6
|
-
|
|
7
|
-
import { ComponentIntroduction } from '../component-introduction';
|
|
8
|
-
|
|
9
|
-
export function PropertiesEmptyState( { introductionRef }: { introductionRef: React.RefObject< HTMLButtonElement > } ) {
|
|
10
|
-
const [ isOpen, setIsOpen ] = useState( false );
|
|
11
|
-
return (
|
|
12
|
-
<>
|
|
13
|
-
<Stack
|
|
14
|
-
alignItems="center"
|
|
15
|
-
justifyContent="flex-start"
|
|
16
|
-
height="100%"
|
|
17
|
-
color="text.secondary"
|
|
18
|
-
sx={ { px: 2.5, pt: 10, pb: 5.5 } }
|
|
19
|
-
gap={ 1 }
|
|
20
|
-
>
|
|
21
|
-
<ComponentPropListIcon fontSize="large" />
|
|
22
|
-
|
|
23
|
-
<Typography align="center" variant="subtitle2">
|
|
24
|
-
{ __( 'Add your first property', 'elementor' ) }
|
|
25
|
-
</Typography>
|
|
26
|
-
|
|
27
|
-
<Typography align="center" variant="caption">
|
|
28
|
-
{ __( 'Make instances flexible while keeping design synced.', 'elementor' ) }
|
|
29
|
-
</Typography>
|
|
30
|
-
|
|
31
|
-
<Typography align="center" variant="caption">
|
|
32
|
-
{ __( 'Select any element, then click + next to a setting to expose it.', 'elementor' ) }
|
|
33
|
-
</Typography>
|
|
34
|
-
|
|
35
|
-
<Link
|
|
36
|
-
variant="caption"
|
|
37
|
-
color="secondary"
|
|
38
|
-
sx={ { textDecorationLine: 'underline' } }
|
|
39
|
-
onClick={ () => setIsOpen( true ) }
|
|
40
|
-
>
|
|
41
|
-
{ __( 'Learn more', 'elementor' ) }
|
|
42
|
-
</Link>
|
|
43
|
-
</Stack>
|
|
44
|
-
<ComponentIntroduction
|
|
45
|
-
anchorRef={ introductionRef }
|
|
46
|
-
shouldShowIntroduction={ isOpen }
|
|
47
|
-
onClose={ () => setIsOpen( false ) }
|
|
48
|
-
/>
|
|
49
|
-
</>
|
|
50
|
-
);
|
|
51
|
-
}
|