@elementor/editor-editing-panel 1.1.0 → 1.3.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 +53 -0
- package/dist/index.js +868 -444
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +851 -403
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -14
- package/src/components/css-class-selector.tsx +131 -0
- package/src/components/multi-combobox/multi-combobox.tsx +34 -32
- package/src/components/multi-combobox/types.ts +2 -0
- package/src/components/multi-combobox/use-combobox-actions.ts +4 -4
- package/src/components/style-sections/border-section/border-radius-field.tsx +4 -4
- package/src/components/style-sections/border-section/border-width-field.tsx +4 -4
- package/src/components/style-sections/layout-section/align-items-field.tsx +72 -0
- package/src/components/style-sections/layout-section/align-self-child-field.tsx +72 -0
- package/src/components/style-sections/layout-section/flex-direction-field.tsx +64 -0
- package/src/components/style-sections/layout-section/flex-order-field.tsx +120 -0
- package/src/components/style-sections/layout-section/flex-size-field.tsx +164 -0
- package/src/components/style-sections/layout-section/justify-content-field.tsx +62 -62
- package/src/components/style-sections/layout-section/layout-section.tsx +27 -3
- package/src/components/style-sections/layout-section/utils/rotated-icon.tsx +52 -0
- package/src/components/style-sections/layout-section/wrap-field.tsx +52 -0
- package/src/components/style-sections/position-section/position-section.tsx +3 -3
- package/src/components/style-sections/typography-section/line-height-field.tsx +21 -0
- package/src/components/style-sections/typography-section/text-stroke-field.tsx +41 -6
- package/src/components/style-sections/typography-section/text-style-field.tsx +31 -8
- package/src/components/style-sections/typography-section/typography-section.tsx +3 -1
- package/src/components/style-tab.tsx +2 -2
- package/src/controls-registry/controls-registry.tsx +4 -0
- package/src/dynamics/components/dynamic-selection-control.tsx +8 -5
- package/src/dynamics/components/dynamic-selection.tsx +10 -8
- package/src/dynamics/dynamic-control.tsx +9 -11
- package/src/dynamics/utils.ts +20 -3
- package/src/components/css-class-selector-section.tsx +0 -76
- package/src/components/style-sections/layout-section/utils/rotate-flex-icon.ts +0 -12
|
@@ -1,16 +1,51 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { StrokeControl } from '@elementor/editor-controls';
|
|
3
3
|
import { __ } from '@wordpress/i18n';
|
|
4
4
|
|
|
5
5
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
6
|
-
import {
|
|
6
|
+
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
7
|
+
import { AddOrRemoveContent } from '../../add-or-remove-content';
|
|
8
|
+
|
|
9
|
+
const initTextStroke = {
|
|
10
|
+
$$type: 'stroke',
|
|
11
|
+
value: {
|
|
12
|
+
color: {
|
|
13
|
+
$$type: 'color',
|
|
14
|
+
value: '#000000',
|
|
15
|
+
},
|
|
16
|
+
width: {
|
|
17
|
+
$$type: 'size',
|
|
18
|
+
value: {
|
|
19
|
+
unit: 'px',
|
|
20
|
+
size: 1,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
7
25
|
|
|
8
26
|
export const TextStrokeField = () => {
|
|
27
|
+
const [ textStroke, setTextStroke ] = useStylesField( '-webkit-text-stroke' );
|
|
28
|
+
|
|
29
|
+
const addTextStroke = () => {
|
|
30
|
+
setTextStroke( initTextStroke );
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const removeTextStroke = () => {
|
|
34
|
+
setTextStroke( null );
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const hasTextStroke = Boolean( textStroke );
|
|
38
|
+
|
|
9
39
|
return (
|
|
10
|
-
<
|
|
11
|
-
|
|
40
|
+
<AddOrRemoveContent
|
|
41
|
+
label={ __( 'Text Stroke', 'elementor' ) }
|
|
42
|
+
isAdded={ hasTextStroke }
|
|
43
|
+
onAdd={ addTextStroke }
|
|
44
|
+
onRemove={ removeTextStroke }
|
|
45
|
+
>
|
|
46
|
+
<StylesField bind={ '-webkit-text-stroke' }>
|
|
12
47
|
<StrokeControl />
|
|
13
|
-
</
|
|
14
|
-
</
|
|
48
|
+
</StylesField>
|
|
49
|
+
</AddOrRemoveContent>
|
|
15
50
|
);
|
|
16
51
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ControlLabel } from '@elementor/editor-controls';
|
|
3
|
+
import { type StringPropValue } from '@elementor/editor-props';
|
|
3
4
|
import { ItalicIcon, StrikethroughIcon, UnderlineIcon } from '@elementor/icons';
|
|
4
5
|
import { Grid, ToggleButton as ToggleButtonBase, ToggleButtonGroup, type ToggleButtonProps } from '@elementor/ui';
|
|
5
6
|
import { __ } from '@wordpress/i18n';
|
|
@@ -9,10 +10,32 @@ import { useStylesField } from '../../../hooks/use-styles-field';
|
|
|
9
10
|
const buttonSize = 'tiny';
|
|
10
11
|
|
|
11
12
|
export const TextStyleField = () => {
|
|
12
|
-
const [ fontStyle, setFontStyle ] = useStylesField<
|
|
13
|
-
const [ textDecoration, setTextDecoration ] = useStylesField<
|
|
13
|
+
const [ fontStyle, setFontStyle ] = useStylesField< StringPropValue | null >( 'font-style' );
|
|
14
|
+
const [ textDecoration, setTextDecoration ] = useStylesField< StringPropValue | null >( 'text-decoration' );
|
|
14
15
|
|
|
15
|
-
const formats = [ fontStyle, ...( textDecoration || '' ).split( ' ' ) ];
|
|
16
|
+
const formats = [ fontStyle?.value, ...( textDecoration?.value || '' ).split( ' ' ) ];
|
|
17
|
+
|
|
18
|
+
const handleSetFontStyle = ( newValue: string | null ) => {
|
|
19
|
+
if ( newValue === null ) {
|
|
20
|
+
return setFontStyle( null );
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setFontStyle( {
|
|
24
|
+
$$type: 'string',
|
|
25
|
+
value: newValue,
|
|
26
|
+
} );
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const handleSetTextDecoration = ( newValue: string | null ) => {
|
|
30
|
+
if ( newValue === null ) {
|
|
31
|
+
return setTextDecoration( null );
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setTextDecoration( {
|
|
35
|
+
$$type: 'string',
|
|
36
|
+
value: newValue,
|
|
37
|
+
} );
|
|
38
|
+
};
|
|
16
39
|
|
|
17
40
|
return (
|
|
18
41
|
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
@@ -23,7 +46,7 @@ export const TextStyleField = () => {
|
|
|
23
46
|
<ToggleButtonGroup value={ formats }>
|
|
24
47
|
<ToggleButton
|
|
25
48
|
value="italic"
|
|
26
|
-
onChange={ ( v ) =>
|
|
49
|
+
onChange={ ( v ) => handleSetFontStyle( fontStyle?.value === v ? null : v ) }
|
|
27
50
|
aria-label="italic"
|
|
28
51
|
sx={ { marginLeft: 'auto' } }
|
|
29
52
|
>
|
|
@@ -31,16 +54,16 @@ export const TextStyleField = () => {
|
|
|
31
54
|
</ToggleButton>
|
|
32
55
|
<ShorthandControl
|
|
33
56
|
value="line-through"
|
|
34
|
-
currentValues={ textDecoration || '' }
|
|
35
|
-
updateValues={
|
|
57
|
+
currentValues={ textDecoration?.value || '' }
|
|
58
|
+
updateValues={ handleSetTextDecoration }
|
|
36
59
|
aria-label="line-through"
|
|
37
60
|
>
|
|
38
61
|
<StrikethroughIcon fontSize={ buttonSize } />
|
|
39
62
|
</ShorthandControl>
|
|
40
63
|
<ShorthandControl
|
|
41
64
|
value="underline"
|
|
42
|
-
currentValues={ textDecoration || '' }
|
|
43
|
-
updateValues={
|
|
65
|
+
currentValues={ textDecoration?.value || '' }
|
|
66
|
+
updateValues={ handleSetTextDecoration }
|
|
44
67
|
aria-label="underline"
|
|
45
68
|
>
|
|
46
69
|
<UnderlineIcon fontSize={ buttonSize } />
|
|
@@ -6,6 +6,7 @@ import { FontFamilyField } from './font-family-field';
|
|
|
6
6
|
import { FontSizeField } from './font-size-field';
|
|
7
7
|
import { FontWeightField } from './font-weight-field';
|
|
8
8
|
import { LetterSpacingField } from './letter-spacing-field';
|
|
9
|
+
import { LineHeightField } from './line-height-field';
|
|
9
10
|
import { TextAlignmentField } from './text-alignment-field';
|
|
10
11
|
import { TextColorField } from './text-color-field';
|
|
11
12
|
import { TextDirectionField } from './text-direction-field';
|
|
@@ -21,13 +22,14 @@ export const TypographySection = () => {
|
|
|
21
22
|
<FontWeightField />
|
|
22
23
|
<FontSizeField />
|
|
23
24
|
<Divider />
|
|
25
|
+
<TextAlignmentField />
|
|
24
26
|
<TextColorField />
|
|
25
27
|
<CollapsibleContent>
|
|
26
28
|
<Stack gap={ 1.5 } sx={ { pt: 1.5 } }>
|
|
29
|
+
<LineHeightField />
|
|
27
30
|
<LetterSpacingField />
|
|
28
31
|
<WordSpacingField />
|
|
29
32
|
<Divider />
|
|
30
|
-
<TextAlignmentField />
|
|
31
33
|
<TextStyleField />
|
|
32
34
|
<TransformField />
|
|
33
35
|
<TextDirectionField />
|
|
@@ -10,7 +10,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
10
10
|
import { ClassesPropProvider } from '../contexts/classes-prop-context';
|
|
11
11
|
import { useElement } from '../contexts/element-context';
|
|
12
12
|
import { StyleProvider } from '../contexts/style-context';
|
|
13
|
-
import {
|
|
13
|
+
import { CssClassSelector } from './css-class-selector';
|
|
14
14
|
import { Section } from './section';
|
|
15
15
|
import { SectionsList } from './sections-list';
|
|
16
16
|
import { BackgroundSection } from './style-sections/background-section/background-section';
|
|
@@ -32,7 +32,7 @@ export const StyleTab = () => {
|
|
|
32
32
|
return (
|
|
33
33
|
<ClassesPropProvider prop={ currentClassesProp }>
|
|
34
34
|
<StyleProvider meta={ { breakpoint, state: null } } id={ activeStyleDefId } setId={ setActiveStyleDefId }>
|
|
35
|
-
<
|
|
35
|
+
<CssClassSelector />
|
|
36
36
|
<Divider />
|
|
37
37
|
<SectionsList>
|
|
38
38
|
<Section title={ __( 'Layout', 'elementor' ) }>
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ControlComponent,
|
|
3
3
|
ImageControl,
|
|
4
|
+
LinkControl,
|
|
4
5
|
SelectControl,
|
|
5
6
|
SizeControl,
|
|
6
7
|
TextAreaControl,
|
|
7
8
|
TextControl,
|
|
9
|
+
UrlControl,
|
|
8
10
|
} from '@elementor/editor-controls';
|
|
9
11
|
|
|
10
12
|
export type ControlLayout = 'full' | 'two-columns';
|
|
@@ -17,6 +19,8 @@ const controlTypes = {
|
|
|
17
19
|
textarea: { component: TextAreaControl, layout: 'full' },
|
|
18
20
|
size: { component: SizeControl, layout: 'two-columns' },
|
|
19
21
|
select: { component: SelectControl, layout: 'two-columns' },
|
|
22
|
+
link: { component: LinkControl, layout: 'full' },
|
|
23
|
+
url: { component: UrlControl, layout: 'full' },
|
|
20
24
|
} as const satisfies ControlRegistry;
|
|
21
25
|
|
|
22
26
|
export type ControlType = keyof typeof controlTypes;
|
|
@@ -27,15 +27,17 @@ import { type ControlType, getControlByType } from '../../controls-registry/cont
|
|
|
27
27
|
import { usePropValueHistory } from '../../hooks/use-prop-value-history';
|
|
28
28
|
import { DynamicControl } from '../dynamic-control';
|
|
29
29
|
import { useDynamicTag } from '../hooks/use-dynamic-tag';
|
|
30
|
-
import { type
|
|
30
|
+
import { type DynamicTag } from '../types';
|
|
31
|
+
import { dynamicPropTypeUtil } from '../utils';
|
|
31
32
|
import { DynamicSelection } from './dynamic-selection';
|
|
32
33
|
|
|
33
34
|
const SIZE = 'tiny';
|
|
34
35
|
|
|
35
36
|
export const DynamicSelectionControl = () => {
|
|
36
|
-
const {
|
|
37
|
+
const { setValue: setAnyValue } = useBoundProp();
|
|
38
|
+
const { bind, value } = useBoundProp( dynamicPropTypeUtil );
|
|
37
39
|
const { getPropValue: getPropValueFromHistory } = usePropValueHistory();
|
|
38
|
-
const { name: tagName = '' } = value
|
|
40
|
+
const { name: tagName = '' } = value;
|
|
39
41
|
|
|
40
42
|
const selectionPopoverId = useId();
|
|
41
43
|
const selectionPopoverState = usePopupState( { variant: 'popover', popupId: selectionPopoverId } );
|
|
@@ -43,8 +45,9 @@ export const DynamicSelectionControl = () => {
|
|
|
43
45
|
const dynamicTag = useDynamicTag( bind, tagName );
|
|
44
46
|
|
|
45
47
|
const removeDynamicTag = () => {
|
|
46
|
-
const propValue = getPropValueFromHistory
|
|
47
|
-
|
|
48
|
+
const propValue = getPropValueFromHistory( bind );
|
|
49
|
+
|
|
50
|
+
setAnyValue( propValue ?? null );
|
|
48
51
|
};
|
|
49
52
|
|
|
50
53
|
if ( ! dynamicTag ) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Fragment, useState } from 'react';
|
|
3
3
|
import { useBoundProp } from '@elementor/editor-controls';
|
|
4
|
-
import { type PropKey
|
|
4
|
+
import { type PropKey } from '@elementor/editor-props';
|
|
5
5
|
import { PhotoIcon, SearchIcon } from '@elementor/icons';
|
|
6
6
|
import {
|
|
7
7
|
Box,
|
|
@@ -20,8 +20,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
20
20
|
import { usePropValueHistory } from '../../hooks/use-prop-value-history';
|
|
21
21
|
import { usePropDynamicTags } from '../hooks/use-prop-dynamic-tags';
|
|
22
22
|
import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
|
|
23
|
-
import {
|
|
24
|
-
import { isDynamicPropValue } from '../utils';
|
|
23
|
+
import { dynamicPropTypeUtil } from '../utils';
|
|
25
24
|
|
|
26
25
|
type Option = {
|
|
27
26
|
label: string;
|
|
@@ -39,10 +38,13 @@ export type DynamicSelectionProps = {
|
|
|
39
38
|
export const DynamicSelection = ( { onSelect }: DynamicSelectionProps ) => {
|
|
40
39
|
const [ searchValue, setSearchValue ] = useState( '' );
|
|
41
40
|
const { groups: dynamicGroups } = getAtomicDynamicTags() || {};
|
|
42
|
-
|
|
41
|
+
|
|
42
|
+
const { value: anyValue } = useBoundProp();
|
|
43
|
+
const { bind, value: dynamicvalue, setValue } = useBoundProp( dynamicPropTypeUtil );
|
|
44
|
+
|
|
43
45
|
const { setPropValue: updatePropValueHistory } = usePropValueHistory();
|
|
44
46
|
|
|
45
|
-
const isCurrentValueDynamic =
|
|
47
|
+
const isCurrentValueDynamic = !! dynamicvalue;
|
|
46
48
|
|
|
47
49
|
const options = useFilteredOptions( bind, searchValue );
|
|
48
50
|
|
|
@@ -52,10 +54,10 @@ export const DynamicSelection = ( { onSelect }: DynamicSelectionProps ) => {
|
|
|
52
54
|
|
|
53
55
|
const handleSetDynamicTag = ( value: string ) => {
|
|
54
56
|
if ( ! isCurrentValueDynamic ) {
|
|
55
|
-
updatePropValueHistory( bind,
|
|
57
|
+
updatePropValueHistory( bind, anyValue );
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
setValue( {
|
|
60
|
+
setValue( { name: value, settings: {} } );
|
|
59
61
|
|
|
60
62
|
onSelect?.();
|
|
61
63
|
};
|
|
@@ -88,7 +90,7 @@ export const DynamicSelection = ( { onSelect }: DynamicSelectionProps ) => {
|
|
|
88
90
|
{ dynamicGroups?.[ category ]?.title || category }
|
|
89
91
|
</ListSubheader>
|
|
90
92
|
{ items.map( ( { value, label: tagLabel } ) => {
|
|
91
|
-
const isSelected = isCurrentValueDynamic && value ===
|
|
93
|
+
const isSelected = isCurrentValueDynamic && value === dynamicvalue?.name;
|
|
92
94
|
|
|
93
95
|
return (
|
|
94
96
|
<MenuItem
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { BoundPropProvider, useBoundProp } from '@elementor/editor-controls';
|
|
3
|
-
import { type PropKey, type PropValue } from '@elementor/editor-props';
|
|
3
|
+
import { isTransformable, type PropKey, type PropValue } from '@elementor/editor-props';
|
|
4
4
|
|
|
5
5
|
import { useDynamicTag } from './hooks/use-dynamic-tag';
|
|
6
|
-
import {
|
|
6
|
+
import { dynamicPropTypeUtil } from './utils';
|
|
7
7
|
|
|
8
8
|
export type DynamicControlProps = React.PropsWithChildren< {
|
|
9
9
|
bind: PropKey;
|
|
10
10
|
} >;
|
|
11
11
|
|
|
12
12
|
export const DynamicControl = ( { bind, children }: DynamicControlProps ) => {
|
|
13
|
-
const { value, setValue, bind: propName } = useBoundProp
|
|
14
|
-
const { name = '', settings } = value
|
|
13
|
+
const { value, setValue, bind: propName } = useBoundProp( dynamicPropTypeUtil );
|
|
14
|
+
const { name = '', settings } = value ?? {};
|
|
15
15
|
|
|
16
16
|
const dynamicTag = useDynamicTag( propName, name );
|
|
17
17
|
|
|
@@ -24,13 +24,11 @@ export const DynamicControl = ( { bind, children }: DynamicControlProps ) => {
|
|
|
24
24
|
|
|
25
25
|
const setDynamicValue = ( newValue: PropValue ) => {
|
|
26
26
|
setValue( {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
[ bind ]: newValue,
|
|
33
|
-
},
|
|
27
|
+
name,
|
|
28
|
+
settings: {
|
|
29
|
+
...settings,
|
|
30
|
+
// The value inside the dynamic is not a transformable value, so we need to store the whole object.
|
|
31
|
+
[ bind ]: isTransformable( newValue ) ? newValue.value : newValue,
|
|
34
32
|
},
|
|
35
33
|
} );
|
|
36
34
|
};
|
package/src/dynamics/utils.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createPropUtils,
|
|
3
|
+
isTransformable,
|
|
4
|
+
type PropType,
|
|
5
|
+
type PropValue,
|
|
6
|
+
type TransformablePropType,
|
|
7
|
+
} from '@elementor/editor-props';
|
|
8
|
+
import { z } from '@elementor/schema';
|
|
2
9
|
|
|
3
|
-
import { type DynamicPropType
|
|
10
|
+
import { type DynamicPropType } from './types';
|
|
4
11
|
|
|
5
|
-
const DYNAMIC_PROP_TYPE_KEY = 'dynamic';
|
|
12
|
+
export const DYNAMIC_PROP_TYPE_KEY = 'dynamic';
|
|
6
13
|
|
|
7
14
|
export const isDynamicPropType = ( prop: TransformablePropType ): prop is DynamicPropType =>
|
|
8
15
|
prop.key === DYNAMIC_PROP_TYPE_KEY;
|
|
@@ -20,3 +27,13 @@ export const isDynamicPropValue = ( prop: PropValue ): prop is DynamicPropValue
|
|
|
20
27
|
export const supportsDynamic = ( propType: PropType ): boolean => {
|
|
21
28
|
return !! getDynamicPropType( propType );
|
|
22
29
|
};
|
|
30
|
+
|
|
31
|
+
export const dynamicPropTypeUtil = createPropUtils(
|
|
32
|
+
DYNAMIC_PROP_TYPE_KEY,
|
|
33
|
+
z.strictObject( {
|
|
34
|
+
name: z.string(),
|
|
35
|
+
settings: z.record( z.any() ).optional(),
|
|
36
|
+
} )
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export type DynamicPropValue = z.infer< typeof dynamicPropTypeUtil.schema >;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useElementSetting, useElementStyles } from '@elementor/editor-elements';
|
|
3
|
-
import { type ClassesPropValue } from '@elementor/editor-props';
|
|
4
|
-
import { Chip, Stack, Typography } from '@elementor/ui';
|
|
5
|
-
import { __ } from '@wordpress/i18n';
|
|
6
|
-
|
|
7
|
-
import { useClassesProp } from '../contexts/classes-prop-context';
|
|
8
|
-
import { useElement } from '../contexts/element-context';
|
|
9
|
-
import { useStyle } from '../contexts/style-context';
|
|
10
|
-
import { MultiCombobox, type Option } from './multi-combobox';
|
|
11
|
-
|
|
12
|
-
const ID = 'elementor-css-class-selector';
|
|
13
|
-
const TAGS_LIMIT = 8;
|
|
14
|
-
|
|
15
|
-
export function CssClassSelectorSection() {
|
|
16
|
-
const options = useOptions();
|
|
17
|
-
|
|
18
|
-
const { id: activeId, setId: setActiveId } = useStyle();
|
|
19
|
-
const appliedIds = useAppliedClassesIds();
|
|
20
|
-
|
|
21
|
-
const applied = options.filter( ( option ) => appliedIds.includes( option.value ) );
|
|
22
|
-
const active = options.find( ( option ) => option.value === activeId ) || null;
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<Stack gap={ 1 } p={ 2 }>
|
|
26
|
-
<Typography component="label" variant="caption" htmlFor={ ID }>
|
|
27
|
-
{ __( 'CSS Classes', 'elementor' ) }
|
|
28
|
-
</Typography>
|
|
29
|
-
<MultiCombobox
|
|
30
|
-
id={ ID }
|
|
31
|
-
size="tiny"
|
|
32
|
-
options={ options }
|
|
33
|
-
selected={ applied }
|
|
34
|
-
limitTags={ TAGS_LIMIT }
|
|
35
|
-
optionsLabel={ __( 'Global CSS Classes', 'elementor' ) }
|
|
36
|
-
renderTags={ ( tagValue, getTagProps ) =>
|
|
37
|
-
tagValue.map( ( option, index ) => {
|
|
38
|
-
const chipProps = getTagProps( { index } );
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<Chip
|
|
42
|
-
{ ...chipProps }
|
|
43
|
-
key={ chipProps.key }
|
|
44
|
-
size="small"
|
|
45
|
-
label={ option.label }
|
|
46
|
-
variant={ option.value === active?.value ? 'filled' : 'standard' }
|
|
47
|
-
color={ option.color ?? 'default' }
|
|
48
|
-
onClick={ () => setActiveId( option.value ) }
|
|
49
|
-
onDelete={ null }
|
|
50
|
-
/>
|
|
51
|
-
);
|
|
52
|
-
} )
|
|
53
|
-
}
|
|
54
|
-
/>
|
|
55
|
-
</Stack>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function useAppliedClassesIds() {
|
|
60
|
-
const { element } = useElement();
|
|
61
|
-
const currentClassesProp = useClassesProp();
|
|
62
|
-
|
|
63
|
-
return useElementSetting< ClassesPropValue >( element.id, currentClassesProp )?.value || [];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function useOptions() {
|
|
67
|
-
const { element } = useElement();
|
|
68
|
-
|
|
69
|
-
const styleDefs = useElementStyles( element.id );
|
|
70
|
-
|
|
71
|
-
return Object.values( styleDefs ).map< Option >( ( styleDef ) => ( {
|
|
72
|
-
label: styleDef.label,
|
|
73
|
-
value: styleDef.id,
|
|
74
|
-
color: 'primary',
|
|
75
|
-
} ) );
|
|
76
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export function rotateFlexIcon( direction: string | null = 'row', initValue: number ) {
|
|
2
|
-
const rotationIndexMap: Record< string, number > = {
|
|
3
|
-
row: 0,
|
|
4
|
-
column: 1,
|
|
5
|
-
'row-reverse': 2,
|
|
6
|
-
'column-reverse': 3,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const rotationIndex = initValue + ( rotationIndexMap[ direction || 'row' ] ?? 0 );
|
|
10
|
-
|
|
11
|
-
return `rotate(calc(90deg * ${ rotationIndex }))`;
|
|
12
|
-
}
|