@elementor/editor-editing-panel 1.6.0 → 1.7.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 +20 -0
- package/dist/index.js +354 -314
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +215 -171
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/components/css-class-selector.tsx +87 -26
- package/src/components/multi-combobox.tsx +184 -0
- package/src/components/style-sections/border-section/border-field.tsx +1 -5
- package/src/components/style-sections/position-section/position-field.tsx +1 -0
- package/src/components/style-tab.tsx +1 -1
- package/src/controls-registry/create-top-level-object-type.ts +14 -0
- package/src/controls-registry/settings-field.tsx +12 -14
- package/src/controls-registry/styles-field.tsx +17 -5
- package/src/dynamics/components/dynamic-selection-control.tsx +1 -1
- package/src/dynamics/components/dynamic-selection.tsx +3 -4
- package/src/dynamics/dynamic-control.tsx +16 -11
- package/src/dynamics/hooks/use-dynamic-tag.ts +2 -3
- package/src/dynamics/hooks/use-prop-dynamic-action.tsx +1 -4
- package/src/dynamics/hooks/use-prop-dynamic-tags.ts +3 -6
- package/src/dynamics/utils.ts +1 -1
- package/src/hooks/use-styles-fields.ts +1 -0
- package/src/components/multi-combobox/index.ts +0 -3
- package/src/components/multi-combobox/multi-combobox.tsx +0 -122
- package/src/components/multi-combobox/types.ts +0 -29
- package/src/components/multi-combobox/use-combobox-actions.ts +0 -62
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { useBoundProp } from '@elementor/editor-controls';
|
|
3
3
|
|
|
4
|
-
import { useElement } from '../../contexts/element-context';
|
|
5
4
|
import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
|
|
6
5
|
import { getDynamicPropType } from '../utils';
|
|
7
6
|
|
|
8
|
-
export const usePropDynamicTags = (
|
|
7
|
+
export const usePropDynamicTags = () => {
|
|
9
8
|
let categories: string[] = [];
|
|
10
9
|
|
|
11
|
-
const {
|
|
12
|
-
|
|
13
|
-
const propType = elementType.propsSchema?.[ propName ];
|
|
10
|
+
const { propType } = useBoundProp();
|
|
14
11
|
|
|
15
12
|
if ( propType ) {
|
|
16
13
|
const propDynamicType = getDynamicPropType( propType );
|
package/src/dynamics/utils.ts
CHANGED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Autocomplete,
|
|
4
|
-
type AutocompleteProps,
|
|
5
|
-
type AutocompleteRenderGroupParams,
|
|
6
|
-
Box,
|
|
7
|
-
Chip,
|
|
8
|
-
styled,
|
|
9
|
-
TextField,
|
|
10
|
-
} from '@elementor/ui';
|
|
11
|
-
import { type FilterOptionsState } from '@mui/base';
|
|
12
|
-
|
|
13
|
-
import { type ActionOption, type Actions, type Option } from './types';
|
|
14
|
-
import { useComboboxActions } from './use-combobox-actions';
|
|
15
|
-
|
|
16
|
-
type Props = Omit< AutocompleteProps< Option, true, true, true >, 'renderInput' | 'getLimitTagsText' | 'onSelect' > & {
|
|
17
|
-
actions?: Actions;
|
|
18
|
-
selected: Option[];
|
|
19
|
-
options: Option[];
|
|
20
|
-
optionsLabel?: string;
|
|
21
|
-
onSelect?: ( value: Option[] ) => void;
|
|
22
|
-
onCreate?: ( value: string ) => void;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const MultiCombobox = ( {
|
|
26
|
-
actions = {},
|
|
27
|
-
selected,
|
|
28
|
-
options,
|
|
29
|
-
optionsLabel,
|
|
30
|
-
onSelect,
|
|
31
|
-
onCreate,
|
|
32
|
-
...props
|
|
33
|
-
}: Props ) => {
|
|
34
|
-
const { action: actionProps, option: optionProps } = useComboboxActions(
|
|
35
|
-
selected,
|
|
36
|
-
actions,
|
|
37
|
-
// TODO: make the group mechanism more generic, allow passing list of groups.
|
|
38
|
-
optionsLabel,
|
|
39
|
-
onSelect
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<Autocomplete
|
|
44
|
-
{ ...props }
|
|
45
|
-
freeSolo
|
|
46
|
-
multiple
|
|
47
|
-
clearOnBlur
|
|
48
|
-
selectOnFocus
|
|
49
|
-
disableClearable
|
|
50
|
-
handleHomeEndKeys
|
|
51
|
-
value={ selected }
|
|
52
|
-
options={ options }
|
|
53
|
-
renderGroup={ renderGroup }
|
|
54
|
-
renderInput={ ( params ) => <TextField { ...params } /> }
|
|
55
|
-
// TODO: is it relevant for the combobox? or should be in the parent component?
|
|
56
|
-
getLimitTagsText={ ( more ) => <Chip size="tiny" variant="standard" label={ `+${ more }` } clickable /> }
|
|
57
|
-
onChange={ ( _, selectedOrTypedValue, reason ) => {
|
|
58
|
-
if ( reason === 'createOption' ) {
|
|
59
|
-
const typedValue = selectedOrTypedValue.find( ( option ) => typeof option === 'string' );
|
|
60
|
-
|
|
61
|
-
return typedValue && onCreate?.( typedValue );
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const action = selectedOrTypedValue.find( ( value ) => actionProps.is( value ) );
|
|
65
|
-
|
|
66
|
-
if ( reason === 'selectOption' && action ) {
|
|
67
|
-
return actionProps.onChange( action );
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const selectedValues = selectedOrTypedValue.filter( ( v ) => typeof v !== 'string' );
|
|
71
|
-
const fixedValues = options.filter( ( option ) => option.fixed );
|
|
72
|
-
|
|
73
|
-
optionProps.onChange( [ ...new Set( [ ...fixedValues, ...selectedValues ] ) ] );
|
|
74
|
-
} }
|
|
75
|
-
getOptionLabel={ ( option ) => {
|
|
76
|
-
if ( optionProps.is( option ) ) {
|
|
77
|
-
return optionProps.getLabel( option );
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if ( actionProps.is( option ) ) {
|
|
81
|
-
return actionProps.getLabel( option );
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return '';
|
|
85
|
-
} }
|
|
86
|
-
filterOptions={ ( optionList: Option[], params: FilterOptionsState< ActionOption | Option > ) => {
|
|
87
|
-
const filteredOptions = optionProps.getFilteredOptions( optionList, params );
|
|
88
|
-
|
|
89
|
-
const actionOptions = actionProps.getFilteredActions( optionList, params );
|
|
90
|
-
|
|
91
|
-
return [ ...actionOptions, ...filteredOptions ];
|
|
92
|
-
} }
|
|
93
|
-
groupBy={ ( option ) =>
|
|
94
|
-
( optionProps.is( option ) ? optionProps.groupBy() : actionProps.groupBy( option ) ) ?? ''
|
|
95
|
-
}
|
|
96
|
-
/>
|
|
97
|
-
);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const renderGroup = ( params: AutocompleteRenderGroupParams ) => (
|
|
101
|
-
<Group key={ params.key }>
|
|
102
|
-
<GroupHeader>{ params.group }</GroupHeader>
|
|
103
|
-
<GroupItems>{ params.children }</GroupItems>
|
|
104
|
-
</Group>
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
const Group = styled( 'li' )`
|
|
108
|
-
&:not( :last-of-type ) {
|
|
109
|
-
border-bottom: 1px solid ${ ( { theme } ) => theme.palette.divider };
|
|
110
|
-
}
|
|
111
|
-
`;
|
|
112
|
-
|
|
113
|
-
const GroupHeader = styled( Box )( ( { theme } ) => ( {
|
|
114
|
-
position: 'sticky',
|
|
115
|
-
top: '-8px',
|
|
116
|
-
padding: theme.spacing( 1, 2 ),
|
|
117
|
-
color: theme.palette.text.tertiary,
|
|
118
|
-
} ) );
|
|
119
|
-
|
|
120
|
-
const GroupItems = styled( 'ul' )`
|
|
121
|
-
padding: 0;
|
|
122
|
-
`;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export type Option = {
|
|
2
|
-
label: string;
|
|
3
|
-
value: string;
|
|
4
|
-
fixed?: boolean;
|
|
5
|
-
// TODO: Should be remove from here or use some kind of `meta`
|
|
6
|
-
color?: 'primary' | 'global';
|
|
7
|
-
provider?: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type Action = {
|
|
11
|
-
getLabel: ( inputValue: string ) => string;
|
|
12
|
-
apply: ( value: string ) => void;
|
|
13
|
-
condition: ( options: Option[], inputValue: string ) => boolean;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type ActionsGroup = {
|
|
17
|
-
label: string;
|
|
18
|
-
actions: Action[];
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type ActionOption = Option & {
|
|
22
|
-
action: {
|
|
23
|
-
groupLabel: string;
|
|
24
|
-
apply: Action[ 'apply' ];
|
|
25
|
-
getLabel: Action[ 'getLabel' ];
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type Actions = Record< string, ActionsGroup >;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { createFilterOptions } from '@elementor/ui';
|
|
2
|
-
import { type FilterOptionsState } from '@mui/base';
|
|
3
|
-
|
|
4
|
-
import { type Action, type ActionOption, type Actions, type Option } from './types';
|
|
5
|
-
|
|
6
|
-
export const useComboboxActions = (
|
|
7
|
-
applied: Option[],
|
|
8
|
-
actions: Actions,
|
|
9
|
-
optionsLabel?: string,
|
|
10
|
-
onSelect?: ( value: Option[] ) => void
|
|
11
|
-
) => ( {
|
|
12
|
-
action: {
|
|
13
|
-
is: ( opt: ActionOption | Option | string ): opt is ActionOption => typeof opt !== 'string' && 'action' in opt,
|
|
14
|
-
getLabel: ( option: ActionOption ) => option.action.getLabel( option.label ),
|
|
15
|
-
groupBy: ( option: ActionOption ) => option.action.groupLabel,
|
|
16
|
-
onChange: ( { action, label }: ActionOption ) => action?.apply( label ),
|
|
17
|
-
getFilteredActions: ( optionList: Option[], params: FilterOptionsState< ActionOption > ) => {
|
|
18
|
-
const actionGroups = Object.values( actions );
|
|
19
|
-
|
|
20
|
-
return actionGroups.reduce< Option[] >( ( groups, group ) => {
|
|
21
|
-
const actionOptions = group.actions.reduce< Option[] >( ( groupActions, action ) => {
|
|
22
|
-
const shouldShowAction = action.condition( optionList, params.inputValue );
|
|
23
|
-
|
|
24
|
-
if ( shouldShowAction ) {
|
|
25
|
-
const actionOption = createActionOption( group.label, action, params.inputValue );
|
|
26
|
-
groupActions.unshift( actionOption );
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return groupActions;
|
|
30
|
-
}, [] );
|
|
31
|
-
|
|
32
|
-
return [ ...groups, ...actionOptions ];
|
|
33
|
-
}, [] );
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
option: {
|
|
37
|
-
is: ( opt: ActionOption | Option | string ): opt is Option => typeof opt !== 'string' && ! ( 'action' in opt ),
|
|
38
|
-
getLabel: ( option: Option ) => option.label,
|
|
39
|
-
groupBy: () => optionsLabel ?? '',
|
|
40
|
-
onChange: ( optionValues: Option[] ) => onSelect?.( optionValues ),
|
|
41
|
-
getFilteredOptions: ( optionList: Option[], params: FilterOptionsState< Option > ) => {
|
|
42
|
-
const appliedValues = applied.map( ( option ) => option.value );
|
|
43
|
-
|
|
44
|
-
const optionsWithoutApplied = optionList.filter( ( option ) => ! appliedValues.includes( option.value ) );
|
|
45
|
-
|
|
46
|
-
return filter( optionsWithoutApplied, params );
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
} );
|
|
50
|
-
|
|
51
|
-
// Helper functions.
|
|
52
|
-
const filter = createFilterOptions< Option >();
|
|
53
|
-
|
|
54
|
-
const createActionOption = ( groupLabel: string, action: Action, inputValue: string ): ActionOption => ( {
|
|
55
|
-
value: '',
|
|
56
|
-
label: inputValue,
|
|
57
|
-
action: {
|
|
58
|
-
groupLabel,
|
|
59
|
-
apply: action.apply,
|
|
60
|
-
getLabel: action.getLabel,
|
|
61
|
-
},
|
|
62
|
-
} );
|