@elementor/editor-editing-panel 1.10.0 → 1.11.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 +73 -0
- package/dist/index.js +680 -685
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +632 -641
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -15
- package/src/components/css-classes/css-class-item.tsx +130 -0
- package/src/components/css-classes/css-class-menu.tsx +151 -0
- package/src/components/{css-class-selector.tsx → css-classes/css-class-selector.tsx} +23 -154
- package/src/components/style-sections/layout-section/display-field.tsx +9 -1
- package/src/components/style-sections/layout-section/flex-order-field.tsx +5 -5
- package/src/components/style-sections/layout-section/flex-size-field.tsx +1 -1
- package/src/components/style-sections/layout-section/gap-control-field.tsx +0 -2
- package/src/components/style-sections/position-section/dimensions-field.tsx +1 -1
- package/src/components/style-sections/position-section/position-section.tsx +1 -1
- package/src/components/style-sections/typography-section/font-weight-field.tsx +9 -5
- package/src/components/style-sections/typography-section/text-alignment-field.tsx +16 -8
- package/src/components/style-sections/typography-section/transform-field.tsx +12 -3
- package/src/components/style-tab.tsx +1 -1
- package/src/controls-registry/controls-registry.tsx +3 -1
- package/src/controls-registry/settings-field.tsx +8 -1
- package/src/dynamics/components/dynamic-selection.tsx +1 -1
- package/src/dynamics/dynamic-control.tsx +1 -1
- package/src/dynamics/types.ts +2 -2
- package/src/dynamics/utils.ts +2 -2
- package/src/hooks/use-persist-dynamic-value.ts +1 -1
- package/src/hooks/use-styles-fields.ts +113 -9
- package/src/index.ts +1 -1
- package/src/init.ts +2 -2
- package/src/sync/types.ts +4 -3
- package/src/components/collapsible-field.tsx +0 -36
- package/src/components/css-class-menu.tsx +0 -101
- package/src/components/editable-field.tsx +0 -166
- package/src/hooks/use-session-storage.ts +0 -46
- package/src/sync/enqueue-font.ts +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-editing-panel",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -39,26 +39,29 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "0.
|
|
43
|
-
"@elementor/editor-controls": "0.
|
|
44
|
-
"@elementor/editor-elements": "0.5.
|
|
45
|
-
"@elementor/
|
|
46
|
-
"@elementor/editor-props": "0.
|
|
47
|
-
"@elementor/editor-
|
|
48
|
-
"@elementor/editor-
|
|
49
|
-
"@elementor/editor-styles": "0.
|
|
50
|
-
"@elementor/editor-
|
|
51
|
-
"@elementor/editor-
|
|
52
|
-
"@elementor/
|
|
53
|
-
"@elementor/icons": "1.26.0",
|
|
42
|
+
"@elementor/editor": "0.18.0",
|
|
43
|
+
"@elementor/editor-controls": "0.9.0",
|
|
44
|
+
"@elementor/editor-elements": "0.5.2",
|
|
45
|
+
"@elementor/editor-panels": "0.11.0",
|
|
46
|
+
"@elementor/editor-props": "0.9.0",
|
|
47
|
+
"@elementor/editor-responsive": "0.13.0",
|
|
48
|
+
"@elementor/editor-styles": "0.5.5",
|
|
49
|
+
"@elementor/editor-styles-repository": "0.7.0",
|
|
50
|
+
"@elementor/editor-ui": "0.2.0",
|
|
51
|
+
"@elementor/editor-v1-adapters": "0.10.0",
|
|
52
|
+
"@elementor/icons": "1.31.0",
|
|
54
53
|
"@elementor/locations": "0.7.6",
|
|
54
|
+
"@elementor/menus": "0.1.3",
|
|
55
55
|
"@elementor/schema": "0.1.2",
|
|
56
56
|
"@elementor/session": "0.1.0",
|
|
57
|
-
"@elementor/ui": "1.
|
|
58
|
-
"@elementor/utils": "0.3.
|
|
57
|
+
"@elementor/ui": "1.26.0",
|
|
58
|
+
"@elementor/utils": "0.3.1",
|
|
59
59
|
"@wordpress/i18n": "^5.13.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"react": "^18.3.1"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"tsup": "^8.3.5"
|
|
63
66
|
}
|
|
64
67
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { stylesRepository } from '@elementor/editor-styles-repository';
|
|
4
|
+
import { EditableField, EllipsisWithTooltip, useEditable } from '@elementor/editor-ui';
|
|
5
|
+
import { DotsVerticalIcon } from '@elementor/icons';
|
|
6
|
+
import {
|
|
7
|
+
type AutocompleteRenderGetTagProps,
|
|
8
|
+
bindTrigger,
|
|
9
|
+
Chip,
|
|
10
|
+
type ChipOwnProps,
|
|
11
|
+
Stack,
|
|
12
|
+
Typography,
|
|
13
|
+
UnstableChipGroup,
|
|
14
|
+
usePopupState,
|
|
15
|
+
} from '@elementor/ui';
|
|
16
|
+
import { __ } from '@wordpress/i18n';
|
|
17
|
+
|
|
18
|
+
import { useStyle } from '../../contexts/style-context';
|
|
19
|
+
import { CssClassMenu } from './css-class-menu';
|
|
20
|
+
|
|
21
|
+
type CssClassItemProps = {
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
provider: string;
|
|
25
|
+
isActive: boolean;
|
|
26
|
+
color: ChipOwnProps[ 'color' ];
|
|
27
|
+
chipProps: ReturnType< AutocompleteRenderGetTagProps >;
|
|
28
|
+
onClickActive: ( id: string ) => void;
|
|
29
|
+
renameLabel: ( newLabel: string ) => void;
|
|
30
|
+
validateLabel?: ( newLabel: string ) => string | undefined | null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const CHIP_SIZE = 'tiny';
|
|
34
|
+
|
|
35
|
+
export function CssClassItem( {
|
|
36
|
+
id,
|
|
37
|
+
label,
|
|
38
|
+
provider,
|
|
39
|
+
isActive,
|
|
40
|
+
color: colorProp,
|
|
41
|
+
chipProps,
|
|
42
|
+
onClickActive,
|
|
43
|
+
renameLabel,
|
|
44
|
+
}: CssClassItemProps ) {
|
|
45
|
+
const { meta } = useStyle();
|
|
46
|
+
const popupState = usePopupState( { variant: 'popover' } );
|
|
47
|
+
const [ chipRef, setChipRef ] = useState< HTMLElement | null >( null );
|
|
48
|
+
const { onDelete, ...chipGroupProps } = chipProps;
|
|
49
|
+
|
|
50
|
+
const {
|
|
51
|
+
ref,
|
|
52
|
+
isEditing,
|
|
53
|
+
openEditMode,
|
|
54
|
+
error,
|
|
55
|
+
getProps: getEditableProps,
|
|
56
|
+
} = useEditable( {
|
|
57
|
+
value: label,
|
|
58
|
+
onSubmit: renameLabel,
|
|
59
|
+
validation: validateLabel,
|
|
60
|
+
} );
|
|
61
|
+
|
|
62
|
+
const color = error ? 'error' : colorProp;
|
|
63
|
+
|
|
64
|
+
const providerActions = stylesRepository.getProviderByKey( provider )?.actions;
|
|
65
|
+
const allowRename = Boolean( providerActions?.update );
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<>
|
|
69
|
+
<UnstableChipGroup ref={ setChipRef } { ...chipGroupProps } aria-label={ `Edit ${ label }` } role="group">
|
|
70
|
+
<Chip
|
|
71
|
+
size={ CHIP_SIZE }
|
|
72
|
+
label={
|
|
73
|
+
isEditing ? (
|
|
74
|
+
<EditableField ref={ ref } error={ error } { ...getEditableProps() } />
|
|
75
|
+
) : (
|
|
76
|
+
<EllipsisWithTooltip maxWidth="10ch" title={ label } as="div" />
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
variant={ isActive && ! meta.state ? 'filled' : 'standard' }
|
|
80
|
+
color={ color }
|
|
81
|
+
onClick={ () => {
|
|
82
|
+
if ( isActive && allowRename ) {
|
|
83
|
+
openEditMode();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
onClickActive( id );
|
|
87
|
+
} }
|
|
88
|
+
aria-pressed={ isActive }
|
|
89
|
+
sx={ {
|
|
90
|
+
'&.Mui-focusVisible': {
|
|
91
|
+
boxShadow: 'none !important',
|
|
92
|
+
},
|
|
93
|
+
} }
|
|
94
|
+
/>
|
|
95
|
+
{ ! isEditing && (
|
|
96
|
+
<Chip
|
|
97
|
+
size={ CHIP_SIZE }
|
|
98
|
+
label={
|
|
99
|
+
<Stack direction="row" gap={ 0.5 } alignItems="center">
|
|
100
|
+
{ isActive && meta.state && <Typography variant="inherit">{ meta.state }</Typography> }
|
|
101
|
+
<DotsVerticalIcon fontSize="inherit" />
|
|
102
|
+
</Stack>
|
|
103
|
+
}
|
|
104
|
+
variant="filled"
|
|
105
|
+
color={ color }
|
|
106
|
+
{ ...bindTrigger( popupState ) }
|
|
107
|
+
aria-label={ __( 'Open CSS Class Menu', 'elementor' ) }
|
|
108
|
+
/>
|
|
109
|
+
) }
|
|
110
|
+
</UnstableChipGroup>
|
|
111
|
+
<CssClassMenu
|
|
112
|
+
styleId={ id }
|
|
113
|
+
popupState={ popupState }
|
|
114
|
+
provider={ provider }
|
|
115
|
+
handleRename={ openEditMode }
|
|
116
|
+
anchorEl={ chipRef }
|
|
117
|
+
/>
|
|
118
|
+
</>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const validateLabel = ( newLabel: string ) => {
|
|
123
|
+
if ( ! stylesRepository.isLabelValid( newLabel ) ) {
|
|
124
|
+
return __( 'Format is not valid', 'elementor' );
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if ( stylesRepository.isLabelExist( newLabel ) ) {
|
|
128
|
+
return __( 'Existing name', 'elementor' );
|
|
129
|
+
}
|
|
130
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type StyleDefinitionState } from '@elementor/editor-styles';
|
|
3
|
+
import { stylesRepository } from '@elementor/editor-styles-repository';
|
|
4
|
+
import { bindMenu, Divider, ListSubheader, Menu, MenuItem, type PopupState } from '@elementor/ui';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
|
|
7
|
+
import { useStyle } from '../../contexts/style-context';
|
|
8
|
+
import { useUnapplyClass } from '../../hooks/use-unapply-class';
|
|
9
|
+
|
|
10
|
+
const STATES: NonNullable< StyleDefinitionState >[] = [ 'hover', 'focus', 'active' ];
|
|
11
|
+
|
|
12
|
+
type CssClassMenuProps = {
|
|
13
|
+
styleId: string;
|
|
14
|
+
provider: string;
|
|
15
|
+
popupState: PopupState;
|
|
16
|
+
handleRename: () => void;
|
|
17
|
+
anchorEl: HTMLElement | null;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function CssClassMenu( { styleId, provider, popupState, handleRename, anchorEl }: CssClassMenuProps ) {
|
|
21
|
+
const handleKeyDown = ( e: React.KeyboardEvent< HTMLElement > ) => {
|
|
22
|
+
e.stopPropagation();
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Menu
|
|
27
|
+
MenuListProps={ { dense: true } }
|
|
28
|
+
{ ...bindMenu( popupState ) }
|
|
29
|
+
anchorEl={ anchorEl }
|
|
30
|
+
anchorOrigin={ {
|
|
31
|
+
vertical: 'bottom',
|
|
32
|
+
horizontal: 'left',
|
|
33
|
+
} }
|
|
34
|
+
transformOrigin={ {
|
|
35
|
+
horizontal: 'left',
|
|
36
|
+
vertical: -4,
|
|
37
|
+
} }
|
|
38
|
+
onKeyDown={ handleKeyDown }
|
|
39
|
+
>
|
|
40
|
+
{ /* It has to be an array since MUI menu doesn't accept a Fragment as a child, and wrapping the items with an HTML element disrupts keyboard navigation */ }
|
|
41
|
+
{ getMenuItemsByProvider( { provider, styleId, handleRename, closeMenu: popupState.close } ) }
|
|
42
|
+
<ListSubheader sx={ { typography: 'caption', color: 'text.secondary', pb: 0.5, pt: 1 } }>
|
|
43
|
+
{ __( 'Pseudo selector', 'elementor' ) }
|
|
44
|
+
</ListSubheader>
|
|
45
|
+
{ STATES.map( ( state ) => {
|
|
46
|
+
return <StateMenuItem key={ state } state={ state } styleId={ styleId } />;
|
|
47
|
+
} ) }
|
|
48
|
+
</Menu>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getMenuItemsByProvider( {
|
|
53
|
+
provider,
|
|
54
|
+
styleId,
|
|
55
|
+
handleRename,
|
|
56
|
+
closeMenu,
|
|
57
|
+
}: {
|
|
58
|
+
provider: string;
|
|
59
|
+
styleId: string;
|
|
60
|
+
handleRename: () => void;
|
|
61
|
+
closeMenu: () => void;
|
|
62
|
+
} ) {
|
|
63
|
+
const providerInstance = stylesRepository.getProviderByKey( provider );
|
|
64
|
+
const providerActions = providerInstance?.actions;
|
|
65
|
+
|
|
66
|
+
const [ canUpdate, canDelete ] = [ providerActions?.update, providerActions?.delete ];
|
|
67
|
+
|
|
68
|
+
const actions = [
|
|
69
|
+
canUpdate && <RenameClassMenuItem key="rename-class" handleRename={ handleRename } closeMenu={ closeMenu } />,
|
|
70
|
+
canDelete && <UnapplyClassMenuItem key="unapply-class" styleId={ styleId } />,
|
|
71
|
+
].filter( Boolean );
|
|
72
|
+
|
|
73
|
+
if ( actions.length ) {
|
|
74
|
+
actions.unshift(
|
|
75
|
+
<ListSubheader
|
|
76
|
+
key="provider-label"
|
|
77
|
+
sx={ { typography: 'caption', color: 'text.secondary', pb: 0.5, pt: 1 } }
|
|
78
|
+
>
|
|
79
|
+
{ providerInstance?.labels?.singular }
|
|
80
|
+
</ListSubheader>
|
|
81
|
+
);
|
|
82
|
+
actions.push( <Divider key="provider-actions-divider" /> );
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return actions;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type StateMenuItemProps = {
|
|
89
|
+
state: StyleDefinitionState;
|
|
90
|
+
styleId: string;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function StateMenuItem( { state, styleId, ...props }: StateMenuItemProps ) {
|
|
94
|
+
const { id: activeId, setId: setActiveId, setMetaState: setActiveMetaState, meta } = useStyle();
|
|
95
|
+
const { state: activeState } = meta;
|
|
96
|
+
|
|
97
|
+
const isActive = styleId === activeId;
|
|
98
|
+
const isSelected = state === activeState && isActive;
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<StyledMenuItem
|
|
102
|
+
{ ...props }
|
|
103
|
+
selected={ isSelected }
|
|
104
|
+
sx={ { textTransform: 'capitalize' } }
|
|
105
|
+
onClick={ () => {
|
|
106
|
+
if ( ! isActive ) {
|
|
107
|
+
setActiveId( styleId );
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
setActiveMetaState( state );
|
|
111
|
+
} }
|
|
112
|
+
>
|
|
113
|
+
{ state }
|
|
114
|
+
</StyledMenuItem>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function UnapplyClassMenuItem( { styleId, ...props }: { styleId: string } ) {
|
|
119
|
+
const unapplyClass = useUnapplyClass( styleId );
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<StyledMenuItem { ...props } onClick={ unapplyClass }>
|
|
123
|
+
{ __( 'Remove', 'elementor' ) }
|
|
124
|
+
</StyledMenuItem>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function RenameClassMenuItem( {
|
|
129
|
+
handleRename,
|
|
130
|
+
closeMenu,
|
|
131
|
+
...props
|
|
132
|
+
}: {
|
|
133
|
+
handleRename: () => void;
|
|
134
|
+
closeMenu: () => void;
|
|
135
|
+
} ) {
|
|
136
|
+
return (
|
|
137
|
+
<StyledMenuItem
|
|
138
|
+
{ ...props }
|
|
139
|
+
onClick={ () => {
|
|
140
|
+
closeMenu();
|
|
141
|
+
handleRename();
|
|
142
|
+
} }
|
|
143
|
+
>
|
|
144
|
+
{ __( 'Rename', 'elementor' ) }
|
|
145
|
+
</StyledMenuItem>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const StyledMenuItem = ( { ...props } ) => (
|
|
150
|
+
<MenuItem { ...props } sx={ { ...( props.sx ?? {} ), typography: 'caption', color: 'text.primary' } } />
|
|
151
|
+
);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useId, useRef } from 'react';
|
|
3
2
|
import { getElementSetting, updateElementSettings, useElementSetting } from '@elementor/editor-elements';
|
|
4
3
|
import { classesPropTypeUtil, type ClassesPropValue } from '@elementor/editor-props';
|
|
5
4
|
import { type StyleDefinitionID } from '@elementor/editor-styles';
|
|
@@ -11,27 +10,15 @@ import {
|
|
|
11
10
|
useCreateActionsByProvider,
|
|
12
11
|
useProviders,
|
|
13
12
|
} from '@elementor/editor-styles-repository';
|
|
14
|
-
import { EllipsisWithTooltip } from '@elementor/editor-ui';
|
|
15
|
-
import { DotsVerticalIcon } from '@elementor/icons';
|
|
16
13
|
import { createLocation } from '@elementor/locations';
|
|
17
|
-
import {
|
|
18
|
-
type AutocompleteRenderGetTagProps,
|
|
19
|
-
bindTrigger,
|
|
20
|
-
Chip,
|
|
21
|
-
type ChipOwnProps,
|
|
22
|
-
Stack,
|
|
23
|
-
Typography,
|
|
24
|
-
UnstableChipGroup,
|
|
25
|
-
usePopupState,
|
|
26
|
-
} from '@elementor/ui';
|
|
14
|
+
import { Chip, Stack, Typography } from '@elementor/ui';
|
|
27
15
|
import { __ } from '@wordpress/i18n';
|
|
28
16
|
|
|
29
|
-
import { useClassesProp } from '
|
|
30
|
-
import { useElement } from '
|
|
31
|
-
import { useStyle } from '
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import { type Action, MultiCombobox, type Option } from './multi-combobox';
|
|
17
|
+
import { useClassesProp } from '../../contexts/classes-prop-context';
|
|
18
|
+
import { useElement } from '../../contexts/element-context';
|
|
19
|
+
import { useStyle } from '../../contexts/style-context';
|
|
20
|
+
import { type Action, MultiCombobox, type Option } from '../multi-combobox';
|
|
21
|
+
import { CssClassItem } from './css-class-item';
|
|
35
22
|
|
|
36
23
|
const ID = 'elementor-css-class-selector';
|
|
37
24
|
const TAGS_LIMIT = 8;
|
|
@@ -101,30 +88,19 @@ export function CssClassSelector() {
|
|
|
101
88
|
};
|
|
102
89
|
|
|
103
90
|
return (
|
|
104
|
-
<
|
|
91
|
+
<CssClassItem
|
|
105
92
|
key={ chipProps.key }
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
label={ value.label }
|
|
118
|
-
id={ value.value }
|
|
119
|
-
isActive={ isActive }
|
|
120
|
-
isFixed={ value.fixed }
|
|
121
|
-
color={ isActive && value.color ? value.color : 'default' }
|
|
122
|
-
chipProps={ chipProps }
|
|
123
|
-
// There is only a single local style, which might not exist, so setting it to
|
|
124
|
-
// `null` will either return the actual style or the fallback one.
|
|
125
|
-
onClickActive={ () => setActiveId( isElementsProvider ? null : value.value ) }
|
|
126
|
-
/>
|
|
127
|
-
</EditableFieldProvider>
|
|
93
|
+
label={ value.label }
|
|
94
|
+
provider={ value.provider }
|
|
95
|
+
id={ value.value }
|
|
96
|
+
isActive={ isActive }
|
|
97
|
+
color={ isActive && value.color ? value.color : 'default' }
|
|
98
|
+
chipProps={ chipProps }
|
|
99
|
+
// There is only a single local style, which might not exist, so setting it to
|
|
100
|
+
// `null` will either return the actual style or the fallback one.
|
|
101
|
+
onClickActive={ () => setActiveId( isElementsProvider ? null : value.value ) }
|
|
102
|
+
renameLabel={ renameLabel }
|
|
103
|
+
/>
|
|
128
104
|
);
|
|
129
105
|
} )
|
|
130
106
|
}
|
|
@@ -133,91 +109,6 @@ export function CssClassSelector() {
|
|
|
133
109
|
);
|
|
134
110
|
}
|
|
135
111
|
|
|
136
|
-
type CssClassItemProps = {
|
|
137
|
-
id: string;
|
|
138
|
-
label: string;
|
|
139
|
-
isActive: boolean;
|
|
140
|
-
isFixed?: boolean;
|
|
141
|
-
color: ChipOwnProps[ 'color' ];
|
|
142
|
-
chipProps: ReturnType< AutocompleteRenderGetTagProps >;
|
|
143
|
-
onClickActive: ( id: string ) => void;
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
const CHIP_SIZE = 'tiny';
|
|
147
|
-
|
|
148
|
-
export function CssClassItem( {
|
|
149
|
-
id,
|
|
150
|
-
label,
|
|
151
|
-
isActive,
|
|
152
|
-
isFixed = false,
|
|
153
|
-
color: colorProp,
|
|
154
|
-
chipProps,
|
|
155
|
-
onClickActive,
|
|
156
|
-
}: CssClassItemProps ) {
|
|
157
|
-
const { meta } = useStyle();
|
|
158
|
-
// TODO - resolve the useId issue with invalid characters upon CSS selectors (EDS-1089)
|
|
159
|
-
const popupId = useId().replace( /:/g, '_' );
|
|
160
|
-
const popupState = usePopupState( { variant: 'popover', popupId } );
|
|
161
|
-
const chipRef = useRef< Element >( null );
|
|
162
|
-
const { onDelete, ...chipGroupProps } = chipProps;
|
|
163
|
-
const { isEditing, openEditMode, error, submitting } = useEditableField();
|
|
164
|
-
|
|
165
|
-
const color = error ? 'error' : colorProp;
|
|
166
|
-
|
|
167
|
-
return (
|
|
168
|
-
<>
|
|
169
|
-
<UnstableChipGroup ref={ chipRef } { ...chipGroupProps } aria-label={ `Edit ${ label }` } role="group">
|
|
170
|
-
<Chip
|
|
171
|
-
disabled={ submitting }
|
|
172
|
-
size={ CHIP_SIZE }
|
|
173
|
-
label={
|
|
174
|
-
<EditableField
|
|
175
|
-
onDoubleClick={ () => {
|
|
176
|
-
if ( ! isActive ) {
|
|
177
|
-
openEditMode();
|
|
178
|
-
}
|
|
179
|
-
} }
|
|
180
|
-
onClick={ () => {
|
|
181
|
-
if ( isActive ) {
|
|
182
|
-
openEditMode();
|
|
183
|
-
}
|
|
184
|
-
} }
|
|
185
|
-
>
|
|
186
|
-
<EllipsisWithTooltip maxWidth="10ch" title={ label } />
|
|
187
|
-
</EditableField>
|
|
188
|
-
}
|
|
189
|
-
variant={ isActive && ! meta.state ? 'filled' : 'standard' }
|
|
190
|
-
color={ color }
|
|
191
|
-
onClick={ () => onClickActive( id ) }
|
|
192
|
-
aria-pressed={ isActive }
|
|
193
|
-
sx={ {
|
|
194
|
-
'&.Mui-focusVisible': {
|
|
195
|
-
boxShadow: 'none !important',
|
|
196
|
-
},
|
|
197
|
-
} }
|
|
198
|
-
/>
|
|
199
|
-
{ ! isEditing && (
|
|
200
|
-
<Chip
|
|
201
|
-
disabled={ submitting }
|
|
202
|
-
size={ CHIP_SIZE }
|
|
203
|
-
label={
|
|
204
|
-
<Stack direction="row" gap={ 0.5 } alignItems="center">
|
|
205
|
-
{ isActive && meta.state && <Typography variant="inherit">{ meta.state }</Typography> }
|
|
206
|
-
<DotsVerticalIcon fontSize="inherit" />
|
|
207
|
-
</Stack>
|
|
208
|
-
}
|
|
209
|
-
variant="filled"
|
|
210
|
-
color={ color }
|
|
211
|
-
{ ...bindTrigger( popupState ) }
|
|
212
|
-
aria-label={ __( 'Open CSS Class Menu', 'elementor' ) }
|
|
213
|
-
/>
|
|
214
|
-
) }
|
|
215
|
-
</UnstableChipGroup>
|
|
216
|
-
<CssClassMenu styleId={ id } popupState={ popupState } isFixed={ isFixed } />
|
|
217
|
-
</>
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
112
|
const updateClassByProvider = ( provider: string, data: UpdateActionPayload ) => {
|
|
222
113
|
const providerInstance = stylesRepository.getProviderByKey( provider );
|
|
223
114
|
|
|
@@ -228,28 +119,6 @@ const updateClassByProvider = ( provider: string, data: UpdateActionPayload ) =>
|
|
|
228
119
|
return providerInstance.actions.update?.( data );
|
|
229
120
|
};
|
|
230
121
|
|
|
231
|
-
const VALID_SELECTOR_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
232
|
-
|
|
233
|
-
const renameValidation = ( newLabel: string, options: Option[] ) => {
|
|
234
|
-
if ( isNameExist( newLabel, options ) ) {
|
|
235
|
-
return __( 'Existing name', 'elementor' );
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if ( isCharactersNotSupported( newLabel ) ) {
|
|
239
|
-
return __( 'Format is not valid', 'elementor' );
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
const isNameExist = ( newLabel: string, options: Option[] ) => {
|
|
244
|
-
if ( ! options?.length ) {
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return options.some( ( option ) => option.label.toLowerCase() === newLabel.toLowerCase() );
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
const isCharactersNotSupported = ( newLabel: string ) => ! VALID_SELECTOR_REGEX.test( newLabel );
|
|
252
|
-
|
|
253
122
|
function useOptions() {
|
|
254
123
|
const { element } = useElement();
|
|
255
124
|
|
|
@@ -290,15 +159,15 @@ function useCreateActions( {
|
|
|
290
159
|
return {
|
|
291
160
|
// translators: %s is the label of the new class.
|
|
292
161
|
label: ( value ) => __( 'Create new "%s"', 'elementor' ).replace( '%s', value ),
|
|
293
|
-
apply:
|
|
294
|
-
const
|
|
162
|
+
apply: ( label ) => {
|
|
163
|
+
const createdId = create( label );
|
|
295
164
|
|
|
296
|
-
if ( !
|
|
165
|
+
if ( ! createdId ) {
|
|
297
166
|
return;
|
|
298
167
|
}
|
|
299
168
|
|
|
300
|
-
pushAppliedId(
|
|
301
|
-
setActiveId(
|
|
169
|
+
pushAppliedId( createdId );
|
|
170
|
+
setActiveId( createdId );
|
|
302
171
|
},
|
|
303
172
|
condition: ( options, inputValue ) => {
|
|
304
173
|
const isUniqueLabel = ! options.some(
|
|
@@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
|
|
6
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
7
|
|
|
8
|
-
type Displays = 'block' | 'flex';
|
|
8
|
+
type Displays = 'block' | 'flex' | 'inline-block';
|
|
9
9
|
|
|
10
10
|
export const DisplayField = () => {
|
|
11
11
|
const options: ToggleButtonGroupItem< Displays >[] = [
|
|
@@ -13,11 +13,19 @@ export const DisplayField = () => {
|
|
|
13
13
|
value: 'block',
|
|
14
14
|
renderContent: () => __( 'Block', 'elementor' ),
|
|
15
15
|
label: __( 'Block', 'elementor' ),
|
|
16
|
+
showTooltip: true,
|
|
16
17
|
},
|
|
17
18
|
{
|
|
18
19
|
value: 'flex',
|
|
19
20
|
renderContent: () => __( 'Flex', 'elementor' ),
|
|
20
21
|
label: __( 'Flex', 'elementor' ),
|
|
22
|
+
showTooltip: true,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
value: 'inline-block',
|
|
26
|
+
renderContent: () => __( 'In-blk', 'elementor' ),
|
|
27
|
+
label: __( 'Inline-block', 'elementor' ),
|
|
28
|
+
showTooltip: true,
|
|
21
29
|
},
|
|
22
30
|
];
|
|
23
31
|
|
|
@@ -17,11 +17,11 @@ import { useStylesField } from '../../../hooks/use-styles-field';
|
|
|
17
17
|
|
|
18
18
|
type GroupControlItemOption = 'first' | 'last' | 'custom';
|
|
19
19
|
|
|
20
|
-
export const FIRST_DEFAULT_VALUE = -99999
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
export const FIRST_DEFAULT_VALUE = -99999;
|
|
21
|
+
export const LAST_DEFAULT_VALUE = 99999;
|
|
22
|
+
const FIRST = 'first';
|
|
23
|
+
const LAST = 'last';
|
|
24
|
+
const CUSTOM = 'custom';
|
|
25
25
|
|
|
26
26
|
const orderValueMap = {
|
|
27
27
|
[ FIRST ]: FIRST_DEFAULT_VALUE,
|
|
@@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
6
6
|
|
|
7
7
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
type Side = 'left' | 'right' | 'top' | 'bottom';
|
|
10
10
|
|
|
11
11
|
const sideIcons = {
|
|
12
12
|
left: <SideLeftIcon fontSize={ 'tiny' } />,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { type StringPropValue } from '@elementor/editor-props';
|
|
3
|
+
import { useSessionStorage } from '@elementor/session';
|
|
3
4
|
import { Stack } from '@elementor/ui';
|
|
4
5
|
|
|
5
6
|
import { useStyle } from '../../../contexts/style-context';
|
|
6
|
-
import { useSessionStorage } from '../../../hooks/use-session-storage';
|
|
7
7
|
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
8
8
|
import { useStylesFields } from '../../../hooks/use-styles-fields';
|
|
9
9
|
import { DimensionsField } from './dimensions-field';
|
|
@@ -6,11 +6,15 @@ import { __ } from '@wordpress/i18n';
|
|
|
6
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
7
|
|
|
8
8
|
const fontWeightOptions = [
|
|
9
|
-
{ label: __( '
|
|
10
|
-
{ label: __( '
|
|
11
|
-
{ label: __( '
|
|
12
|
-
{ label: __( '
|
|
13
|
-
{ label: __( '
|
|
9
|
+
{ value: '100', label: __( '100 - Thin', 'elementor' ) },
|
|
10
|
+
{ value: '200', label: __( '200 - Extra Light', 'elementor' ) },
|
|
11
|
+
{ value: '300', label: __( '300 - Light', 'elementor' ) },
|
|
12
|
+
{ value: '400', label: __( '400 - Normal', 'elementor' ) },
|
|
13
|
+
{ value: '500', label: __( '500 - Medium', 'elementor' ) },
|
|
14
|
+
{ value: '600', label: __( '600 - Semi Bold', 'elementor' ) },
|
|
15
|
+
{ value: '700', label: __( '700 - Bold', 'elementor' ) },
|
|
16
|
+
{ value: '800', label: __( '800 - Extra Bold', 'elementor' ) },
|
|
17
|
+
{ value: '900', label: __( '900 - Black', 'elementor' ) },
|
|
14
18
|
];
|
|
15
19
|
|
|
16
20
|
export const FontWeightField = () => {
|