@elementor/editor-editing-panel 1.0.0 → 1.2.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 +70 -0
- package/dist/index.d.mts +10 -19
- package/dist/index.d.ts +10 -19
- package/dist/index.js +1539 -1754
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1534 -1723
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
- package/src/components/add-or-remove-content.tsx +3 -3
- package/src/components/collapse-icon.tsx +12 -0
- package/src/components/collapsible-content.tsx +5 -14
- package/src/components/collapsible-field.tsx +5 -3
- package/src/components/css-class-selector.tsx +131 -0
- package/src/components/editing-panel-hooks.tsx +2 -0
- package/src/components/editing-panel-tabs.tsx +23 -13
- package/src/components/editing-panel.tsx +9 -6
- package/src/components/multi-combobox/index.ts +3 -0
- package/src/components/multi-combobox/multi-combobox.tsx +122 -0
- package/src/components/multi-combobox/types.ts +28 -0
- package/src/components/multi-combobox/use-combobox-actions.ts +62 -0
- package/src/components/section.tsx +37 -0
- package/src/components/sections-list.tsx +6 -0
- package/src/components/settings-tab.tsx +11 -11
- package/src/components/style-sections/background-section/background-color-field.tsx +4 -4
- package/src/components/style-sections/background-section/background-section.tsx +9 -7
- package/src/components/style-sections/border-section/border-color-field.tsx +4 -4
- package/src/components/style-sections/border-section/border-field.tsx +4 -3
- package/src/components/style-sections/border-section/border-radius-field.tsx +4 -3
- package/src/components/style-sections/border-section/border-section.tsx +7 -10
- package/src/components/style-sections/border-section/border-style-field.tsx +4 -4
- package/src/components/style-sections/border-section/border-width-field.tsx +4 -3
- package/src/components/style-sections/effects-section/effects-section.tsx +7 -10
- package/src/components/style-sections/layout-section/align-items-field.tsx +92 -0
- package/src/components/style-sections/layout-section/display-field.tsx +32 -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 +114 -0
- package/src/components/style-sections/layout-section/justify-content-field.tsx +109 -0
- package/src/components/style-sections/layout-section/layout-section.tsx +36 -0
- package/src/components/style-sections/layout-section/wrap-field.tsx +52 -0
- package/src/components/style-sections/position-section/dimensions-field.tsx +6 -6
- package/src/components/style-sections/position-section/position-field.tsx +4 -4
- package/src/components/style-sections/position-section/position-section.tsx +45 -15
- package/src/components/style-sections/position-section/z-index-field.tsx +4 -4
- package/src/components/style-sections/size-section/overflow-field.tsx +8 -8
- package/src/components/style-sections/size-section/size-section.tsx +33 -26
- package/src/components/style-sections/spacing-section/spacing-section.tsx +11 -13
- package/src/components/style-sections/typography-section/font-family-field.tsx +40 -0
- package/src/components/style-sections/typography-section/font-size-field.tsx +4 -4
- package/src/components/style-sections/typography-section/font-weight-field.tsx +4 -4
- package/src/components/style-sections/typography-section/letter-spacing-field.tsx +4 -4
- package/src/components/style-sections/typography-section/text-alignment-field.tsx +9 -9
- package/src/components/style-sections/typography-section/text-color-field.tsx +4 -4
- package/src/components/style-sections/typography-section/text-direction-field.tsx +7 -7
- package/src/components/style-sections/typography-section/text-stroke-field.tsx +42 -7
- package/src/components/style-sections/typography-section/text-style-field.tsx +5 -4
- package/src/components/style-sections/typography-section/transform-field.tsx +23 -9
- package/src/components/style-sections/typography-section/typography-section.tsx +26 -27
- package/src/components/style-sections/typography-section/word-spacing-field.tsx +4 -4
- package/src/components/style-tab.tsx +67 -31
- package/src/contexts/classes-prop-context.tsx +1 -1
- package/src/contexts/element-context.tsx +2 -2
- package/src/contexts/style-context.tsx +6 -5
- package/src/control-replacement.tsx +1 -1
- package/src/controls-actions.ts +3 -2
- package/src/controls-registry/control-type-container.tsx +3 -2
- package/src/controls-registry/control.tsx +2 -1
- package/src/controls-registry/controls-registry.tsx +8 -1
- package/src/controls-registry/settings-field.tsx +5 -4
- package/src/controls-registry/styles-field.tsx +3 -2
- package/src/dynamics/components/dynamic-selection-control.tsx +15 -14
- package/src/dynamics/components/dynamic-selection.tsx +9 -8
- package/src/dynamics/dynamic-control.tsx +4 -4
- package/src/dynamics/hooks/use-dynamic-tag.ts +3 -2
- package/src/dynamics/hooks/use-prop-dynamic-action.tsx +6 -5
- package/src/dynamics/hooks/use-prop-dynamic-tags.ts +3 -2
- package/src/dynamics/init.ts +5 -3
- package/src/dynamics/sync/get-elementor-config.ts +1 -1
- package/src/dynamics/types.ts +2 -2
- package/src/dynamics/utils.ts +3 -2
- package/src/hooks/use-close-editor-panel.ts +23 -0
- package/src/hooks/use-direction.ts +13 -0
- package/src/hooks/use-open-editor-panel.ts +4 -3
- package/src/hooks/use-prop-value-history.ts +45 -0
- package/src/hooks/use-style-prop-history.ts +75 -0
- package/src/hooks/use-styles-field.ts +25 -4
- package/src/index.ts +1 -1
- package/src/init.ts +5 -4
- package/src/panel.ts +1 -0
- package/src/popover-action.tsx +1 -1
- package/src/sync/enqueue-font.ts +7 -0
- package/src/sync/get-elementor-config.ts +7 -0
- package/src/sync/{should-use-v2-panel.ts → is-atomic-widget-selected.ts} +1 -1
- package/src/sync/types.ts +20 -21
- package/src/components/accordion-section.tsx +0 -26
- package/src/components/control-label.tsx +0 -10
- package/src/controls/bound-prop-context.tsx +0 -30
- package/src/controls/components/control-toggle-button-group.tsx +0 -68
- package/src/controls/components/repeater.tsx +0 -197
- package/src/controls/components/text-field-inner-selection.tsx +0 -75
- package/src/controls/control-actions/control-actions-context.tsx +0 -27
- package/src/controls/control-actions/control-actions-menu.ts +0 -7
- package/src/controls/control-actions/control-actions.tsx +0 -31
- package/src/controls/controls/box-shadow-repeater-control.tsx +0 -210
- package/src/controls/controls/color-control.tsx +0 -25
- package/src/controls/controls/equal-unequal-sizes-control.tsx +0 -196
- package/src/controls/controls/image-control.tsx +0 -58
- package/src/controls/controls/image-media-control.tsx +0 -64
- package/src/controls/controls/linked-dimensions-control.tsx +0 -139
- package/src/controls/controls/number-control.tsx +0 -29
- package/src/controls/controls/select-control.tsx +0 -30
- package/src/controls/controls/size-control.tsx +0 -71
- package/src/controls/controls/stroke-control.tsx +0 -105
- package/src/controls/controls/text-area-control.tsx +0 -31
- package/src/controls/controls/text-control.tsx +0 -17
- package/src/controls/controls/toggle-control.tsx +0 -26
- package/src/controls/create-control-replacement.tsx +0 -53
- package/src/controls/create-control.tsx +0 -40
- package/src/controls/hooks/use-sync-external-state.tsx +0 -51
- package/src/controls/index.ts +0 -24
- package/src/dynamics/hooks/use-prop-value-history.ts +0 -26
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ControlLabel } from '@elementor/editor-controls';
|
|
3
3
|
import { type Control } from '@elementor/editor-elements';
|
|
4
|
-
|
|
5
|
-
import {
|
|
4
|
+
|
|
5
|
+
import { useElement } from '../contexts/element-context';
|
|
6
6
|
import { Control as BaseControl } from '../controls-registry/control';
|
|
7
|
-
import { ControlType, getControlByType } from '../controls-registry/controls-registry';
|
|
8
7
|
import { ControlTypeContainer } from '../controls-registry/control-type-container';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { type ControlType, getControlByType } from '../controls-registry/controls-registry';
|
|
9
|
+
import { SettingsField } from '../controls-registry/settings-field';
|
|
10
|
+
import { Section } from './section';
|
|
11
|
+
import { SectionsList } from './sections-list';
|
|
11
12
|
|
|
12
13
|
export const SettingsTab = () => {
|
|
13
14
|
const { elementType } = useElement();
|
|
14
15
|
|
|
15
16
|
return (
|
|
16
|
-
<
|
|
17
|
+
<SectionsList>
|
|
17
18
|
{ elementType.controls.map( ( { type, value }, index ) => {
|
|
18
19
|
if ( type === 'control' ) {
|
|
19
20
|
return <Control key={ value.bind } control={ value } />;
|
|
@@ -21,7 +22,7 @@ export const SettingsTab = () => {
|
|
|
21
22
|
|
|
22
23
|
if ( type === 'section' ) {
|
|
23
24
|
return (
|
|
24
|
-
<
|
|
25
|
+
<Section title={ value.label } key={ type + '.' + index } defaultExpanded={ true }>
|
|
25
26
|
{ value.items?.map( ( item ) => {
|
|
26
27
|
if ( item.type === 'control' ) {
|
|
27
28
|
return <Control key={ item.value.bind } control={ item.value } />;
|
|
@@ -30,17 +31,16 @@ export const SettingsTab = () => {
|
|
|
30
31
|
// TODO: Handle 2nd level sections
|
|
31
32
|
return null;
|
|
32
33
|
} ) }
|
|
33
|
-
</
|
|
34
|
+
</Section>
|
|
34
35
|
);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
return null;
|
|
38
39
|
} ) }
|
|
39
|
-
</
|
|
40
|
+
</SectionsList>
|
|
40
41
|
);
|
|
41
42
|
};
|
|
42
43
|
|
|
43
|
-
// TODO: Create control wrapper by type for different layouts.
|
|
44
44
|
const Control = ( { control }: { control: Control[ 'value' ] } ) => {
|
|
45
45
|
if ( ! getControlByType( control.type as ControlType ) ) {
|
|
46
46
|
return null;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ColorControl, ControlLabel } from '@elementor/editor-controls';
|
|
3
3
|
import { Grid } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
4
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
5
|
-
import { ControlLabel } from '../../control-label';
|
|
6
|
-
import { ColorControl } from '../../../controls';
|
|
7
7
|
|
|
8
8
|
export const BackgroundColorField = () => {
|
|
9
9
|
return (
|
|
10
10
|
<StylesField bind="background-color">
|
|
11
|
-
<Grid container
|
|
11
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
12
12
|
<Grid item xs={ 6 }>
|
|
13
13
|
<ControlLabel>{ __( 'Color', 'elementor' ) }</ControlLabel>
|
|
14
14
|
</Grid>
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { BackgroundOverlayRepeaterControl } from '@elementor/editor-controls';
|
|
3
3
|
import { Stack } from '@elementor/ui';
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
import { StylesField } from '../../../controls-registry/styles-field';
|
|
5
6
|
import { BackgroundColorField } from './background-color-field';
|
|
6
7
|
|
|
7
8
|
export const BackgroundSection = () => {
|
|
8
9
|
return (
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
</
|
|
13
|
-
|
|
10
|
+
<Stack gap={ 1.5 }>
|
|
11
|
+
<StylesField bind="background-image">
|
|
12
|
+
<BackgroundOverlayRepeaterControl />
|
|
13
|
+
</StylesField>
|
|
14
|
+
<BackgroundColorField />
|
|
15
|
+
</Stack>
|
|
14
16
|
);
|
|
15
17
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ColorControl, ControlLabel } from '@elementor/editor-controls';
|
|
3
3
|
import { Grid } from '@elementor/ui';
|
|
4
|
-
import {
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
5
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
6
|
-
import { ControlLabel } from '../../control-label';
|
|
7
7
|
|
|
8
8
|
export const BorderColorField = () => {
|
|
9
9
|
return (
|
|
10
10
|
<StylesField bind={ 'border-color' }>
|
|
11
|
-
<Grid container
|
|
11
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
12
12
|
<Grid item xs={ 6 }>
|
|
13
13
|
<ControlLabel>{ __( 'Border Color', 'elementor' ) }</ControlLabel>
|
|
14
14
|
</Grid>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { __ } from '@wordpress/i18n';
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
5
|
+
import { AddOrRemoveContent } from '../../add-or-remove-content';
|
|
4
6
|
import { BorderColorField } from './border-color-field';
|
|
5
7
|
import { BorderStyleField } from './border-style-field';
|
|
6
|
-
import {
|
|
7
|
-
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
8
|
+
import { BorderWidthField } from './border-width-field';
|
|
8
9
|
|
|
9
10
|
const initialSize = { $$type: 'size', value: { size: 1, unit: 'px' } };
|
|
10
11
|
const initialBorderWidth = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { type EqualUnequalItems, EqualUnequalSizesControl } from '@elementor/editor-controls';
|
|
3
|
+
import type { BorderRadiusPropValue } from '@elementor/editor-props';
|
|
3
4
|
import {
|
|
4
5
|
BorderCornersIcon,
|
|
5
6
|
RadiusBottomLeftIcon,
|
|
@@ -7,8 +8,8 @@ import {
|
|
|
7
8
|
RadiusTopLeftIcon,
|
|
8
9
|
RadiusTopRightIcon,
|
|
9
10
|
} from '@elementor/icons';
|
|
10
|
-
import
|
|
11
|
-
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
|
|
12
13
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
13
14
|
|
|
14
15
|
const corners: EqualUnequalItems< BorderRadiusPropValue[ '$$type' ], BorderRadiusPropValue > = [
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { AccordionSection } from '../../accordion-section';
|
|
3
2
|
import { Divider, Stack } from '@elementor/ui';
|
|
4
|
-
|
|
5
|
-
import { BorderRadiusField } from './border-radius-field';
|
|
3
|
+
|
|
6
4
|
import { BorderField } from './border-field';
|
|
5
|
+
import { BorderRadiusField } from './border-radius-field';
|
|
7
6
|
|
|
8
7
|
export const BorderSection = () => (
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</Stack>
|
|
15
|
-
</AccordionSection>
|
|
8
|
+
<Stack gap={ 1.5 }>
|
|
9
|
+
<BorderRadiusField />
|
|
10
|
+
<Divider />
|
|
11
|
+
<BorderField />
|
|
12
|
+
</Stack>
|
|
16
13
|
);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { SelectControl } from '../../../controls';
|
|
2
|
+
import { ControlLabel, SelectControl } from '@elementor/editor-controls';
|
|
4
3
|
import { Grid } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
5
6
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
6
|
-
import { ControlLabel } from '../../control-label';
|
|
7
7
|
|
|
8
8
|
const borderStyles = [
|
|
9
9
|
{ value: 'none', label: __( 'None', 'elementor' ) },
|
|
@@ -19,7 +19,7 @@ const borderStyles = [
|
|
|
19
19
|
export const BorderStyleField = () => {
|
|
20
20
|
return (
|
|
21
21
|
<StylesField bind={ 'border-style' }>
|
|
22
|
-
<Grid container
|
|
22
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
23
23
|
<Grid item xs={ 6 }>
|
|
24
24
|
<ControlLabel>{ __( 'Border Type', 'elementor' ) }</ControlLabel>
|
|
25
25
|
</Grid>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { type EqualUnequalItems, EqualUnequalSizesControl } from '@elementor/editor-controls';
|
|
3
|
+
import { type BorderWidthPropValue } from '@elementor/editor-props';
|
|
4
|
+
import { SideAllIcon, SideBottomIcon, SideLeftIcon, SideRightIcon, SideTopIcon } from '@elementor/icons';
|
|
3
5
|
import { __ } from '@wordpress/i18n';
|
|
4
|
-
|
|
5
|
-
import { EqualUnequalItems, EqualUnequalSizesControl } from '../../../controls/controls/equal-unequal-sizes-control';
|
|
6
|
+
|
|
6
7
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
8
|
|
|
8
9
|
const edges: EqualUnequalItems< BorderWidthPropValue[ '$$type' ], BorderWidthPropValue > = [
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { BoxShadowRepeaterControl } from '@elementor/editor-controls';
|
|
3
3
|
import { Stack } from '@elementor/ui';
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import { StylesField } from '../../../controls-registry/styles-field';
|
|
6
|
-
import { BoxShadowRepeaterControl } from '../../../controls';
|
|
7
6
|
|
|
8
7
|
export const EffectsSection = () => {
|
|
9
8
|
return (
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
</Stack>
|
|
16
|
-
</AccordionSection>
|
|
9
|
+
<Stack gap={ 1.5 }>
|
|
10
|
+
<StylesField bind="box-shadow">
|
|
11
|
+
<BoxShadowRepeaterControl />
|
|
12
|
+
</StylesField>
|
|
13
|
+
</Stack>
|
|
17
14
|
);
|
|
18
15
|
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { JSX } from 'react';
|
|
3
|
+
import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
|
|
4
|
+
import {
|
|
5
|
+
LayoutAlignCenterIcon as CenterIcon,
|
|
6
|
+
LayoutAlignLeftIcon,
|
|
7
|
+
LayoutAlignRightIcon,
|
|
8
|
+
LayoutDistributeVerticalIcon as JustifyIcon,
|
|
9
|
+
} from '@elementor/icons';
|
|
10
|
+
import { DirectionProvider, Grid, ThemeProvider, type ToggleButtonProps, useTheme, withDirection } from '@elementor/ui';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
|
|
13
|
+
import { StylesField } from '../../../controls-registry/styles-field';
|
|
14
|
+
import { useDirection } from '../../../hooks/use-direction';
|
|
15
|
+
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
16
|
+
import { type FlexDirection } from './flex-direction-field';
|
|
17
|
+
|
|
18
|
+
type AlignItems = 'start' | 'center' | 'end' | 'justify';
|
|
19
|
+
|
|
20
|
+
export const AlignItemsField = () => {
|
|
21
|
+
const options = useOptions(),
|
|
22
|
+
{ isSiteRtl } = useDirection();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<DirectionProvider rtl={ isSiteRtl }>
|
|
26
|
+
<ThemeProvider>
|
|
27
|
+
<StylesField bind="align-items">
|
|
28
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
29
|
+
<Grid item xs={ 6 }>
|
|
30
|
+
<ControlLabel>{ __( 'Align Items', 'elementor' ) }</ControlLabel>
|
|
31
|
+
</Grid>
|
|
32
|
+
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
|
|
33
|
+
<ToggleControl options={ options } />
|
|
34
|
+
</Grid>
|
|
35
|
+
</Grid>
|
|
36
|
+
</StylesField>
|
|
37
|
+
</ThemeProvider>
|
|
38
|
+
</DirectionProvider>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const useOptions = (): ToggleButtonGroupItem< AlignItems >[] => {
|
|
43
|
+
const StartIcon = withDirection( LayoutAlignLeftIcon ),
|
|
44
|
+
EndIcon = withDirection( LayoutAlignRightIcon );
|
|
45
|
+
|
|
46
|
+
return [
|
|
47
|
+
{
|
|
48
|
+
value: 'start',
|
|
49
|
+
label: __( 'Start', 'elementor' ),
|
|
50
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ StartIcon } size={ size } />,
|
|
51
|
+
showTooltip: true,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
value: 'center',
|
|
55
|
+
label: __( 'Center', 'elementor' ),
|
|
56
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ CenterIcon } size={ size } />,
|
|
57
|
+
showTooltip: true,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
value: 'end',
|
|
61
|
+
label: __( 'End', 'elementor' ),
|
|
62
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ EndIcon } size={ size } />,
|
|
63
|
+
showTooltip: true,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
value: 'justify',
|
|
67
|
+
label: __( 'Justify', 'elementor' ),
|
|
68
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ JustifyIcon } size={ size } />,
|
|
69
|
+
showTooltip: true,
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const RotatedIcon = ( { icon: Icon, size }: { icon: JSX.ElementType; size: ToggleButtonProps[ 'size' ] } ) => {
|
|
75
|
+
const [ direction ] = useStylesField< FlexDirection >( 'flex-direction' ),
|
|
76
|
+
isRtl = 'rtl' === useTheme().direction,
|
|
77
|
+
rotationMultiplier = isRtl ? -1 : 1;
|
|
78
|
+
|
|
79
|
+
const rotationAngelMap: Record< FlexDirection, number > = {
|
|
80
|
+
row: 90,
|
|
81
|
+
column: 0,
|
|
82
|
+
'row-reverse': -90,
|
|
83
|
+
'column-reverse': -180,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<Icon
|
|
88
|
+
fontSize={ size }
|
|
89
|
+
sx={ { transition: '.3s', rotate: `${ rotationAngelMap[ direction || 'row' ] * rotationMultiplier }deg` } }
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
|
|
3
|
+
import { Stack } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
import { StylesField } from '../../../controls-registry/styles-field';
|
|
7
|
+
|
|
8
|
+
type Displays = 'block' | 'flex';
|
|
9
|
+
|
|
10
|
+
export const DisplayField = () => {
|
|
11
|
+
const options: ToggleButtonGroupItem< Displays >[] = [
|
|
12
|
+
{
|
|
13
|
+
value: 'block',
|
|
14
|
+
renderContent: () => __( 'Block', 'elementor' ),
|
|
15
|
+
label: __( 'Block', 'elementor' ),
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
value: 'flex',
|
|
19
|
+
renderContent: () => __( 'Flex', 'elementor' ),
|
|
20
|
+
label: __( 'Flex', 'elementor' ),
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<StylesField bind="display">
|
|
26
|
+
<Stack gap={ 1 }>
|
|
27
|
+
<ControlLabel>{ __( 'Display', 'elementor' ) }</ControlLabel>
|
|
28
|
+
<ToggleControl options={ options } fullWidth={ true } />
|
|
29
|
+
</Stack>
|
|
30
|
+
</StylesField>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
|
|
3
|
+
import { ArrowDownSmallIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpSmallIcon } from '@elementor/icons';
|
|
4
|
+
import { DirectionProvider, Grid, ThemeProvider, withDirection } from '@elementor/ui';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
|
|
7
|
+
import { StylesField } from '../../../controls-registry/styles-field';
|
|
8
|
+
import { useDirection } from '../../../hooks/use-direction';
|
|
9
|
+
|
|
10
|
+
export type FlexDirection = 'row' | 'row-reverse' | 'column' | 'column-reverse';
|
|
11
|
+
|
|
12
|
+
const options: ToggleButtonGroupItem< FlexDirection >[] = [
|
|
13
|
+
{
|
|
14
|
+
value: 'row',
|
|
15
|
+
label: __( 'Row', 'elementor' ),
|
|
16
|
+
renderContent: ( { size } ) => {
|
|
17
|
+
const StartIcon = withDirection( ArrowRightIcon );
|
|
18
|
+
return <StartIcon fontSize={ size } />;
|
|
19
|
+
},
|
|
20
|
+
showTooltip: true,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
value: 'column',
|
|
24
|
+
label: __( 'Column', 'elementor' ),
|
|
25
|
+
renderContent: ( { size } ) => <ArrowDownSmallIcon fontSize={ size } />,
|
|
26
|
+
showTooltip: true,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
value: 'row-reverse',
|
|
30
|
+
label: __( 'Row reverse', 'elementor' ),
|
|
31
|
+
renderContent: ( { size } ) => {
|
|
32
|
+
const EndIcon = withDirection( ArrowLeftIcon );
|
|
33
|
+
return <EndIcon fontSize={ size } />;
|
|
34
|
+
},
|
|
35
|
+
showTooltip: true,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
value: 'column-reverse',
|
|
39
|
+
label: __( 'Column reverse', 'elementor' ),
|
|
40
|
+
renderContent: ( { size } ) => <ArrowUpSmallIcon fontSize={ size } />,
|
|
41
|
+
showTooltip: true,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
export const FlexDirectionField = () => {
|
|
46
|
+
const { isSiteRtl } = useDirection();
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<DirectionProvider rtl={ isSiteRtl }>
|
|
50
|
+
<ThemeProvider>
|
|
51
|
+
<StylesField bind="flex-direction">
|
|
52
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
53
|
+
<Grid item xs={ 6 }>
|
|
54
|
+
<ControlLabel>{ __( 'Direction', 'elementor' ) }</ControlLabel>
|
|
55
|
+
</Grid>
|
|
56
|
+
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
|
|
57
|
+
<ToggleControl options={ options } />
|
|
58
|
+
</Grid>
|
|
59
|
+
</Grid>
|
|
60
|
+
</StylesField>
|
|
61
|
+
</ThemeProvider>
|
|
62
|
+
</DirectionProvider>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
ControlLabel,
|
|
5
|
+
ControlToggleButtonGroup,
|
|
6
|
+
NumberControl,
|
|
7
|
+
type ToggleButtonGroupItem,
|
|
8
|
+
} from '@elementor/editor-controls';
|
|
9
|
+
import { ArrowDownSmallIcon, ArrowUpSmallIcon, PencilIcon } from '@elementor/icons';
|
|
10
|
+
import { DirectionProvider, Grid, Stack, ThemeProvider } from '@elementor/ui';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
|
|
13
|
+
import { StylesField } from '../../../controls-registry/styles-field';
|
|
14
|
+
import { useDirection } from '../../../hooks/use-direction';
|
|
15
|
+
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
16
|
+
|
|
17
|
+
type GroupControlItemOption = 'first' | 'last' | 'custom';
|
|
18
|
+
|
|
19
|
+
export const FIRST_DEFAULT_VALUE = -99999,
|
|
20
|
+
LAST_DEFAULT_VALUE = 99999,
|
|
21
|
+
FIRST = 'first',
|
|
22
|
+
LAST = 'last',
|
|
23
|
+
CUSTOM = 'custom';
|
|
24
|
+
|
|
25
|
+
const items: ToggleButtonGroupItem< GroupControlItemOption >[] = [
|
|
26
|
+
{
|
|
27
|
+
value: FIRST,
|
|
28
|
+
label: __( 'First', 'elementor' ),
|
|
29
|
+
renderContent: ( { size } ) => <ArrowUpSmallIcon fontSize={ size } />,
|
|
30
|
+
showTooltip: true,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
value: LAST,
|
|
34
|
+
label: __( 'Last', 'elementor' ),
|
|
35
|
+
renderContent: ( { size } ) => <ArrowDownSmallIcon fontSize={ size } />,
|
|
36
|
+
showTooltip: true,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
value: CUSTOM,
|
|
40
|
+
label: __( 'Custom', 'elementor' ),
|
|
41
|
+
renderContent: ( { size } ) => <PencilIcon fontSize={ size } />,
|
|
42
|
+
showTooltip: true,
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
export const FlexOrderField = () => {
|
|
47
|
+
const { isSiteRtl } = useDirection(),
|
|
48
|
+
[ order, setOrder ] = useStylesField< number | null >( 'order' );
|
|
49
|
+
|
|
50
|
+
const [ groupControlValue, setGroupControlValue ] = useState( getGroupControlValue( order ) );
|
|
51
|
+
|
|
52
|
+
const handleToggleButtonChange = ( group: GroupControlItemOption | null ) => {
|
|
53
|
+
setGroupControlValue( group );
|
|
54
|
+
|
|
55
|
+
const orderValueMap = {
|
|
56
|
+
[ FIRST ]: FIRST_DEFAULT_VALUE,
|
|
57
|
+
[ LAST ]: LAST_DEFAULT_VALUE,
|
|
58
|
+
[ CUSTOM ]: null,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
setOrder( group ? orderValueMap[ group ] : null );
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<DirectionProvider rtl={ isSiteRtl }>
|
|
66
|
+
<ThemeProvider>
|
|
67
|
+
<Stack gap={ 2 }>
|
|
68
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
69
|
+
<Grid item xs={ 6 }>
|
|
70
|
+
<ControlLabel>{ __( 'Order', 'elementor' ) }</ControlLabel>
|
|
71
|
+
</Grid>
|
|
72
|
+
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
|
|
73
|
+
<ControlToggleButtonGroup
|
|
74
|
+
items={ items }
|
|
75
|
+
value={ groupControlValue }
|
|
76
|
+
onChange={ handleToggleButtonChange }
|
|
77
|
+
exclusive={ true }
|
|
78
|
+
/>
|
|
79
|
+
</Grid>
|
|
80
|
+
</Grid>
|
|
81
|
+
|
|
82
|
+
{ CUSTOM === groupControlValue && (
|
|
83
|
+
<StylesField bind={ 'order' }>
|
|
84
|
+
<Grid container gap={ 2 } alignItems="center" flexWrap="nowrap">
|
|
85
|
+
<Grid item xs={ 6 }>
|
|
86
|
+
<ControlLabel>{ __( 'Custom order', 'elementor' ) }</ControlLabel>
|
|
87
|
+
</Grid>
|
|
88
|
+
<Grid item xs={ 6 } sx={ { display: 'flex', justifyContent: 'end' } }>
|
|
89
|
+
<NumberControl
|
|
90
|
+
min={ FIRST_DEFAULT_VALUE + 1 }
|
|
91
|
+
max={ LAST_DEFAULT_VALUE - 1 }
|
|
92
|
+
shouldForceInt={ true }
|
|
93
|
+
/>
|
|
94
|
+
</Grid>
|
|
95
|
+
</Grid>
|
|
96
|
+
</StylesField>
|
|
97
|
+
) }
|
|
98
|
+
</Stack>
|
|
99
|
+
</ThemeProvider>
|
|
100
|
+
</DirectionProvider>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const getGroupControlValue = ( order: number | null ): GroupControlItemOption | null => {
|
|
105
|
+
if ( LAST_DEFAULT_VALUE === order ) {
|
|
106
|
+
return LAST;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if ( FIRST_DEFAULT_VALUE === order ) {
|
|
110
|
+
return FIRST;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return 0 === order || order ? CUSTOM : null;
|
|
114
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type JSX } from 'react';
|
|
3
|
+
import { ControlLabel, type ToggleButtonGroupItem, ToggleControl } from '@elementor/editor-controls';
|
|
4
|
+
import {
|
|
5
|
+
JustifyBottomIcon,
|
|
6
|
+
JustifyCenterIcon as CenterIcon,
|
|
7
|
+
JustifyDistributeVerticalIcon as EvenlyIcon,
|
|
8
|
+
JustifySpaceAroundVerticalIcon as AroundIcon,
|
|
9
|
+
JustifySpaceBetweenVerticalIcon as BetweenIcon,
|
|
10
|
+
JustifyTopIcon,
|
|
11
|
+
} from '@elementor/icons';
|
|
12
|
+
import {
|
|
13
|
+
DirectionProvider,
|
|
14
|
+
Stack,
|
|
15
|
+
ThemeProvider,
|
|
16
|
+
type ToggleButtonProps,
|
|
17
|
+
useTheme,
|
|
18
|
+
withDirection,
|
|
19
|
+
} from '@elementor/ui';
|
|
20
|
+
import { __ } from '@wordpress/i18n';
|
|
21
|
+
|
|
22
|
+
import { StylesField } from '../../../controls-registry/styles-field';
|
|
23
|
+
import { useDirection } from '../../../hooks/use-direction';
|
|
24
|
+
import { useStylesField } from '../../../hooks/use-styles-field';
|
|
25
|
+
import { type FlexDirection } from './flex-direction-field';
|
|
26
|
+
|
|
27
|
+
type JustifyContent = 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly';
|
|
28
|
+
|
|
29
|
+
export const JustifyContentField = () => {
|
|
30
|
+
const options = useOptions(),
|
|
31
|
+
{ isSiteRtl } = useDirection();
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<DirectionProvider rtl={ isSiteRtl }>
|
|
35
|
+
<ThemeProvider>
|
|
36
|
+
<StylesField bind="justify-content">
|
|
37
|
+
<Stack gap={ 1 }>
|
|
38
|
+
<ControlLabel>{ __( 'Justify Content', 'elementor' ) }</ControlLabel>
|
|
39
|
+
<ToggleControl options={ options } fullWidth={ true } />
|
|
40
|
+
</Stack>
|
|
41
|
+
</StylesField>
|
|
42
|
+
</ThemeProvider>
|
|
43
|
+
</DirectionProvider>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const useOptions = (): ToggleButtonGroupItem< JustifyContent >[] => {
|
|
48
|
+
const StartIcon = withDirection( JustifyTopIcon ),
|
|
49
|
+
EndIcon = withDirection( JustifyBottomIcon );
|
|
50
|
+
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
value: 'start',
|
|
54
|
+
label: __( 'Start', 'elementor' ),
|
|
55
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ StartIcon } size={ size } />,
|
|
56
|
+
showTooltip: true,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
value: 'center',
|
|
60
|
+
label: __( 'Center', 'elementor' ),
|
|
61
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ CenterIcon } size={ size } />,
|
|
62
|
+
showTooltip: true,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
value: 'end',
|
|
66
|
+
label: __( 'End', 'elementor' ),
|
|
67
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ EndIcon } size={ size } />,
|
|
68
|
+
showTooltip: true,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
value: 'space-between',
|
|
72
|
+
label: __( 'Space between', 'elementor' ),
|
|
73
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ BetweenIcon } size={ size } />,
|
|
74
|
+
showTooltip: true,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
value: 'space-around',
|
|
78
|
+
label: __( 'Space around', 'elementor' ),
|
|
79
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ AroundIcon } size={ size } />,
|
|
80
|
+
showTooltip: true,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
value: 'space-evenly',
|
|
84
|
+
label: __( 'Space evenly', 'elementor' ),
|
|
85
|
+
renderContent: ( { size } ) => <RotatedIcon icon={ EvenlyIcon } size={ size } />,
|
|
86
|
+
showTooltip: true,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const RotatedIcon = ( { icon: Icon, size }: { icon: JSX.ElementType; size: ToggleButtonProps[ 'size' ] } ) => {
|
|
92
|
+
const [ direction ] = useStylesField< FlexDirection >( 'flex-direction' ),
|
|
93
|
+
isRtl = 'rtl' === useTheme().direction,
|
|
94
|
+
rotationMultiplier = isRtl ? -1 : 1;
|
|
95
|
+
|
|
96
|
+
const rotationAngelMap: Record< FlexDirection, number > = {
|
|
97
|
+
row: -90,
|
|
98
|
+
column: 0,
|
|
99
|
+
'row-reverse': 90,
|
|
100
|
+
'column-reverse': 180,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Icon
|
|
105
|
+
fontSize={ size }
|
|
106
|
+
sx={ { transition: '.3s', rotate: `${ rotationAngelMap[ direction || 'row' ] * rotationMultiplier }deg` } }
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
};
|