@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.
Files changed (120) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/index.d.mts +10 -19
  3. package/dist/index.d.ts +10 -19
  4. package/dist/index.js +1539 -1754
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1534 -1723
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +13 -13
  9. package/src/components/add-or-remove-content.tsx +3 -3
  10. package/src/components/collapse-icon.tsx +12 -0
  11. package/src/components/collapsible-content.tsx +5 -14
  12. package/src/components/collapsible-field.tsx +5 -3
  13. package/src/components/css-class-selector.tsx +131 -0
  14. package/src/components/editing-panel-hooks.tsx +2 -0
  15. package/src/components/editing-panel-tabs.tsx +23 -13
  16. package/src/components/editing-panel.tsx +9 -6
  17. package/src/components/multi-combobox/index.ts +3 -0
  18. package/src/components/multi-combobox/multi-combobox.tsx +122 -0
  19. package/src/components/multi-combobox/types.ts +28 -0
  20. package/src/components/multi-combobox/use-combobox-actions.ts +62 -0
  21. package/src/components/section.tsx +37 -0
  22. package/src/components/sections-list.tsx +6 -0
  23. package/src/components/settings-tab.tsx +11 -11
  24. package/src/components/style-sections/background-section/background-color-field.tsx +4 -4
  25. package/src/components/style-sections/background-section/background-section.tsx +9 -7
  26. package/src/components/style-sections/border-section/border-color-field.tsx +4 -4
  27. package/src/components/style-sections/border-section/border-field.tsx +4 -3
  28. package/src/components/style-sections/border-section/border-radius-field.tsx +4 -3
  29. package/src/components/style-sections/border-section/border-section.tsx +7 -10
  30. package/src/components/style-sections/border-section/border-style-field.tsx +4 -4
  31. package/src/components/style-sections/border-section/border-width-field.tsx +4 -3
  32. package/src/components/style-sections/effects-section/effects-section.tsx +7 -10
  33. package/src/components/style-sections/layout-section/align-items-field.tsx +92 -0
  34. package/src/components/style-sections/layout-section/display-field.tsx +32 -0
  35. package/src/components/style-sections/layout-section/flex-direction-field.tsx +64 -0
  36. package/src/components/style-sections/layout-section/flex-order-field.tsx +114 -0
  37. package/src/components/style-sections/layout-section/justify-content-field.tsx +109 -0
  38. package/src/components/style-sections/layout-section/layout-section.tsx +36 -0
  39. package/src/components/style-sections/layout-section/wrap-field.tsx +52 -0
  40. package/src/components/style-sections/position-section/dimensions-field.tsx +6 -6
  41. package/src/components/style-sections/position-section/position-field.tsx +4 -4
  42. package/src/components/style-sections/position-section/position-section.tsx +45 -15
  43. package/src/components/style-sections/position-section/z-index-field.tsx +4 -4
  44. package/src/components/style-sections/size-section/overflow-field.tsx +8 -8
  45. package/src/components/style-sections/size-section/size-section.tsx +33 -26
  46. package/src/components/style-sections/spacing-section/spacing-section.tsx +11 -13
  47. package/src/components/style-sections/typography-section/font-family-field.tsx +40 -0
  48. package/src/components/style-sections/typography-section/font-size-field.tsx +4 -4
  49. package/src/components/style-sections/typography-section/font-weight-field.tsx +4 -4
  50. package/src/components/style-sections/typography-section/letter-spacing-field.tsx +4 -4
  51. package/src/components/style-sections/typography-section/text-alignment-field.tsx +9 -9
  52. package/src/components/style-sections/typography-section/text-color-field.tsx +4 -4
  53. package/src/components/style-sections/typography-section/text-direction-field.tsx +7 -7
  54. package/src/components/style-sections/typography-section/text-stroke-field.tsx +42 -7
  55. package/src/components/style-sections/typography-section/text-style-field.tsx +5 -4
  56. package/src/components/style-sections/typography-section/transform-field.tsx +23 -9
  57. package/src/components/style-sections/typography-section/typography-section.tsx +26 -27
  58. package/src/components/style-sections/typography-section/word-spacing-field.tsx +4 -4
  59. package/src/components/style-tab.tsx +67 -31
  60. package/src/contexts/classes-prop-context.tsx +1 -1
  61. package/src/contexts/element-context.tsx +2 -2
  62. package/src/contexts/style-context.tsx +6 -5
  63. package/src/control-replacement.tsx +1 -1
  64. package/src/controls-actions.ts +3 -2
  65. package/src/controls-registry/control-type-container.tsx +3 -2
  66. package/src/controls-registry/control.tsx +2 -1
  67. package/src/controls-registry/controls-registry.tsx +8 -1
  68. package/src/controls-registry/settings-field.tsx +5 -4
  69. package/src/controls-registry/styles-field.tsx +3 -2
  70. package/src/dynamics/components/dynamic-selection-control.tsx +15 -14
  71. package/src/dynamics/components/dynamic-selection.tsx +9 -8
  72. package/src/dynamics/dynamic-control.tsx +4 -4
  73. package/src/dynamics/hooks/use-dynamic-tag.ts +3 -2
  74. package/src/dynamics/hooks/use-prop-dynamic-action.tsx +6 -5
  75. package/src/dynamics/hooks/use-prop-dynamic-tags.ts +3 -2
  76. package/src/dynamics/init.ts +5 -3
  77. package/src/dynamics/sync/get-elementor-config.ts +1 -1
  78. package/src/dynamics/types.ts +2 -2
  79. package/src/dynamics/utils.ts +3 -2
  80. package/src/hooks/use-close-editor-panel.ts +23 -0
  81. package/src/hooks/use-direction.ts +13 -0
  82. package/src/hooks/use-open-editor-panel.ts +4 -3
  83. package/src/hooks/use-prop-value-history.ts +45 -0
  84. package/src/hooks/use-style-prop-history.ts +75 -0
  85. package/src/hooks/use-styles-field.ts +25 -4
  86. package/src/index.ts +1 -1
  87. package/src/init.ts +5 -4
  88. package/src/panel.ts +1 -0
  89. package/src/popover-action.tsx +1 -1
  90. package/src/sync/enqueue-font.ts +7 -0
  91. package/src/sync/get-elementor-config.ts +7 -0
  92. package/src/sync/{should-use-v2-panel.ts → is-atomic-widget-selected.ts} +1 -1
  93. package/src/sync/types.ts +20 -21
  94. package/src/components/accordion-section.tsx +0 -26
  95. package/src/components/control-label.tsx +0 -10
  96. package/src/controls/bound-prop-context.tsx +0 -30
  97. package/src/controls/components/control-toggle-button-group.tsx +0 -68
  98. package/src/controls/components/repeater.tsx +0 -197
  99. package/src/controls/components/text-field-inner-selection.tsx +0 -75
  100. package/src/controls/control-actions/control-actions-context.tsx +0 -27
  101. package/src/controls/control-actions/control-actions-menu.ts +0 -7
  102. package/src/controls/control-actions/control-actions.tsx +0 -31
  103. package/src/controls/controls/box-shadow-repeater-control.tsx +0 -210
  104. package/src/controls/controls/color-control.tsx +0 -25
  105. package/src/controls/controls/equal-unequal-sizes-control.tsx +0 -196
  106. package/src/controls/controls/image-control.tsx +0 -58
  107. package/src/controls/controls/image-media-control.tsx +0 -64
  108. package/src/controls/controls/linked-dimensions-control.tsx +0 -139
  109. package/src/controls/controls/number-control.tsx +0 -29
  110. package/src/controls/controls/select-control.tsx +0 -30
  111. package/src/controls/controls/size-control.tsx +0 -71
  112. package/src/controls/controls/stroke-control.tsx +0 -105
  113. package/src/controls/controls/text-area-control.tsx +0 -31
  114. package/src/controls/controls/text-control.tsx +0 -17
  115. package/src/controls/controls/toggle-control.tsx +0 -26
  116. package/src/controls/create-control-replacement.tsx +0 -53
  117. package/src/controls/create-control.tsx +0 -40
  118. package/src/controls/hooks/use-sync-external-state.tsx +0 -51
  119. package/src/controls/index.ts +0 -24
  120. package/src/dynamics/hooks/use-prop-value-history.ts +0 -26
@@ -1,7 +1,8 @@
1
1
  import { useMemo } from 'react';
2
- import { PropKey } from '@elementor/editor-props';
3
- import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
2
+ import { type PropKey } from '@elementor/editor-props';
3
+
4
4
  import { useElement } from '../../contexts/element-context';
5
+ import { getAtomicDynamicTags } from '../sync/get-atomic-dynamic-tags';
5
6
  import { getDynamicPropType } from '../utils';
6
7
 
7
8
  export const usePropDynamicTags = ( propName: PropKey ) => {
@@ -1,8 +1,10 @@
1
+ import { replaceControl } from '../control-replacement';
2
+ import { controlActionsMenu } from '../controls-actions';
1
3
  import { DynamicSelectionControl } from './components/dynamic-selection-control';
2
- import { isDynamicPropValue } from './utils';
3
4
  import { usePropDynamicAction } from './hooks/use-prop-dynamic-action';
4
- import { replaceControl } from '../control-replacement';
5
- import { registerPopoverAction } from '../controls-actions';
5
+ import { isDynamicPropValue } from './utils';
6
+
7
+ const { registerPopoverAction } = controlActionsMenu;
6
8
 
7
9
  export const init = () => {
8
10
  replaceControl( {
@@ -1,4 +1,4 @@
1
- import { ExtendedWindow } from '../types';
1
+ import { type ExtendedWindow } from '../types';
2
2
 
3
3
  export const getElementorConfig = () => {
4
4
  const extendedWindow = window as unknown as ExtendedWindow;
@@ -1,5 +1,5 @@
1
- import { TransformablePropType, TransformablePropValue } from '@elementor/editor-props';
2
- import { ControlItem, PropsSchema } from '@elementor/editor-elements';
1
+ import { type ControlItem, type PropsSchema } from '@elementor/editor-elements';
2
+ import { type TransformablePropType, type TransformablePropValue } from '@elementor/editor-props';
3
3
 
4
4
  export type ExtendedWindow = Window & {
5
5
  elementor?: {
@@ -1,5 +1,6 @@
1
- import { isTransformable, PropType, PropValue, TransformablePropType } from '@elementor/editor-props';
2
- import { DynamicPropType, DynamicPropValue } from './types';
1
+ import { isTransformable, type PropType, type PropValue, type TransformablePropType } from '@elementor/editor-props';
2
+
3
+ import { type DynamicPropType, type DynamicPropValue } from './types';
3
4
 
4
5
  const DYNAMIC_PROP_TYPE_KEY = 'dynamic';
5
6
 
@@ -0,0 +1,23 @@
1
+ import { useEffect } from 'react';
2
+ import { getSelectedElements, isElementInContainer, type V1Element } from '@elementor/editor-elements';
3
+ import { __privateListenTo as listenTo, type CommandEvent, commandStartEvent } from '@elementor/editor-v1-adapters';
4
+
5
+ import { usePanelActions } from '../panel';
6
+ import { isAtomicWidgetSelected } from '../sync/is-atomic-widget-selected';
7
+
8
+ export const useCloseEditorPanel = () => {
9
+ const { close } = usePanelActions();
10
+
11
+ return useEffect( () => {
12
+ return listenTo( commandStartEvent( 'document/elements/delete' ), ( e ) => {
13
+ const selectedElement = getSelectedElements()[ 0 ];
14
+ const { container: deletedContainer } = ( e as CommandEvent< { container: V1Element } > )?.args;
15
+ const isSelectedElementInDeletedContainer =
16
+ deletedContainer && selectedElement && isElementInContainer( selectedElement, deletedContainer );
17
+
18
+ if ( isSelectedElementInDeletedContainer && isAtomicWidgetSelected() ) {
19
+ close();
20
+ }
21
+ } );
22
+ }, [] ); // eslint-disable-line react-hooks/exhaustive-deps
23
+ };
@@ -0,0 +1,13 @@
1
+ import { useTheme } from '@elementor/ui';
2
+
3
+ import { type ExtendedWindow } from '../sync/types';
4
+
5
+ export function useDirection() {
6
+ const theme = useTheme(),
7
+ extendedWindow: ExtendedWindow = window;
8
+
9
+ const isUiRtl = 'rtl' === theme.direction,
10
+ isSiteRtl = !! extendedWindow.elementorFrontend?.config?.is_rtl;
11
+
12
+ return { isSiteRtl, isUiRtl };
13
+ }
@@ -1,14 +1,15 @@
1
1
  import { useEffect } from 'react';
2
- import { commandStartEvent, __privateListenTo as listenTo } from '@elementor/editor-v1-adapters';
2
+ import { __privateListenTo as listenTo, commandStartEvent } from '@elementor/editor-v1-adapters';
3
+
3
4
  import { usePanelActions } from '../panel';
4
- import { shouldUseV2Panel } from '../sync/should-use-v2-panel';
5
+ import { isAtomicWidgetSelected } from '../sync/is-atomic-widget-selected';
5
6
 
6
7
  export const useOpenEditorPanel = () => {
7
8
  const { open } = usePanelActions();
8
9
 
9
10
  useEffect( () => {
10
11
  return listenTo( commandStartEvent( 'panel/editor/open' ), () => {
11
- if ( shouldUseV2Panel() ) {
12
+ if ( isAtomicWidgetSelected() ) {
12
13
  open();
13
14
  }
14
15
  } );
@@ -0,0 +1,45 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { getSessionStorageItem, setSessionStorageItem } from '@elementor/utils';
3
+
4
+ import { useElement } from '../contexts/element-context';
5
+
6
+ export const PROPS_VALUES_HISTORY_PREFIX = 'elementor/editor-editing-panel/prop-value-history';
7
+
8
+ export const usePropValueHistory = () => {
9
+ const { element } = useElement();
10
+ const elementKey = `${ PROPS_VALUES_HISTORY_PREFIX }/${ element.id }`;
11
+
12
+ const getElementPropsHistory = useCallback( () => {
13
+ return getSessionStorageItem< Record< string, unknown > >( elementKey );
14
+ }, [ elementKey ] );
15
+
16
+ const getPropValue = useCallback(
17
+ < T >( propKey: string ) => {
18
+ const elementPropValues = getElementPropsHistory();
19
+ return ( elementPropValues?.[ propKey ] ?? null ) as T | null;
20
+ },
21
+ [ getElementPropsHistory ]
22
+ );
23
+
24
+ const setPropValue = useCallback(
25
+ ( propKey: string, propValue: unknown ) => {
26
+ const elementPropValues = getElementPropsHistory();
27
+ const updatedElementPropValues = { ...elementPropValues, [ propKey ]: propValue };
28
+ setSessionStorageItem( elementKey, updatedElementPropValues );
29
+ },
30
+ [ getElementPropsHistory, elementKey ]
31
+ );
32
+
33
+ const removeProp = useCallback(
34
+ ( propKey: string ) => {
35
+ const elementPropValues = getElementPropsHistory();
36
+ const updatedElementPropValues = Object.fromEntries(
37
+ Object.entries( elementPropValues || {} ).filter( ( [ key ] ) => key !== propKey )
38
+ );
39
+ setSessionStorageItem( elementKey, updatedElementPropValues );
40
+ },
41
+ [ getElementPropsHistory, elementKey ]
42
+ );
43
+
44
+ return useMemo( () => ( { getPropValue, setPropValue, removeProp } ), [ getPropValue, removeProp, setPropValue ] );
45
+ };
@@ -0,0 +1,75 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { getElementStyles, getVariantByMeta, updateStyle } from '@elementor/editor-elements';
3
+ import { type PropKey } from '@elementor/editor-props';
4
+
5
+ import { useElement } from '../contexts/element-context';
6
+ import { useStyle } from '../contexts/style-context';
7
+ import { usePropValueHistory } from './use-prop-value-history';
8
+
9
+ export const useStylePropsHistory = ( props: PropKey[] ) => {
10
+ const { element } = useElement();
11
+ const { id: styleDefID, meta } = useStyle();
12
+ const { getPropValue, setPropValue, removeProp } = usePropValueHistory();
13
+
14
+ const styleDef = getElementStyles( element.id )?.[ styleDefID ];
15
+ const styleVariant = styleDef ? getVariantByMeta( styleDef, meta ) : null;
16
+ const styleVariantPath = `${ styleDefID }-${ styleVariant?.meta.breakpoint }-${ styleVariant?.meta.state }`;
17
+
18
+ const saveStylePropsHistory = useCallback( () => {
19
+ props.forEach( ( propKey ) => {
20
+ const propValue = styleVariant?.props[ propKey ];
21
+
22
+ if ( propValue ) {
23
+ const propPath = `${ styleVariantPath }-${ propKey }`;
24
+ setPropValue( propPath, propValue );
25
+ }
26
+ } );
27
+ }, [ props, setPropValue, styleVariant?.props, styleVariantPath ] );
28
+
29
+ const updateStylePropsFromHistory = useCallback( () => {
30
+ const propValuesFromHistory = props.reduce( ( allProps, currentPropKey ) => {
31
+ const propPath = `${ styleVariantPath }-${ currentPropKey }`;
32
+ const propHistory = getPropValue( propPath );
33
+
34
+ if ( propHistory ) {
35
+ removeProp( propPath );
36
+ return { ...allProps, [ currentPropKey ]: propHistory };
37
+ }
38
+
39
+ return allProps;
40
+ }, {} );
41
+
42
+ if ( Object.keys( propValuesFromHistory ).length ) {
43
+ updateStyle( {
44
+ elementID: element.id,
45
+ styleDefID,
46
+ meta,
47
+ props: propValuesFromHistory,
48
+ bind: 'classes',
49
+ } );
50
+ }
51
+ }, [ element.id, getPropValue, meta, props, removeProp, styleDefID, styleVariantPath ] );
52
+
53
+ const clearCurrentStyleProps = useCallback( () => {
54
+ const resetValues = props.reduce(
55
+ ( allProps, currentPropKey ) => ( {
56
+ ...allProps,
57
+ [ currentPropKey ]: undefined,
58
+ } ),
59
+ {}
60
+ );
61
+
62
+ updateStyle( {
63
+ elementID: element.id,
64
+ styleDefID,
65
+ meta,
66
+ props: resetValues,
67
+ bind: 'classes',
68
+ } );
69
+ }, [ element.id, meta, props, styleDefID ] );
70
+
71
+ return useMemo(
72
+ () => ( { saveStylePropsHistory, updateStylePropsFromHistory, clearCurrentStyleProps } ),
73
+ [ saveStylePropsHistory, updateStylePropsFromHistory, clearCurrentStyleProps ]
74
+ );
75
+ };
@@ -1,13 +1,23 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { updateStyle, useElementStyleProp } from '@elementor/editor-elements';
1
3
  import type { PropKey, PropValue } from '@elementor/editor-props';
2
- import { useElementStyleProp, updateStyle } from '@elementor/editor-elements';
3
- import { useStyle } from '../contexts/style-context';
4
+
4
5
  import { useClassesProp } from '../contexts/classes-prop-context';
5
6
  import { useElement } from '../contexts/element-context';
7
+ import { useStyle } from '../contexts/style-context';
6
8
 
7
- export const useStylesField = < T extends PropValue >( propName: PropKey ) => {
9
+ export const useStylesField = < T extends PropValue >(
10
+ propName: PropKey
11
+ ): [
12
+ T | null,
13
+ ( newValue: T ) => void,
14
+ ( callback: ( newValue: T | null, previousValue: T | null ) => void ) => void,
15
+ ] => {
8
16
  const { element } = useElement();
9
17
  const { id, meta } = useStyle();
10
18
  const classesProp = useClassesProp();
19
+ const previousValue = useRef< T | null >( null );
20
+ const onChangeCallbacks = useRef< Set< ( newValue: T | null, previousValue: T | null ) => void > >( new Set() );
11
21
 
12
22
  const value = useElementStyleProp< T >( {
13
23
  elementID: element.id,
@@ -26,5 +36,16 @@ export const useStylesField = < T extends PropValue >( propName: PropKey ) => {
26
36
  } );
27
37
  };
28
38
 
29
- return [ value, setValue ] as const;
39
+ const registerChangeListener = ( callback: ( newValue: T | null, previousValue: T | null ) => void ) => {
40
+ onChangeCallbacks.current.add( callback );
41
+ };
42
+
43
+ useEffect( () => {
44
+ onChangeCallbacks.current.forEach( ( cb ) => {
45
+ cb( value, previousValue.current );
46
+ } );
47
+ previousValue.current = value;
48
+ }, [ value ] );
49
+
50
+ return [ value, setValue, registerChangeListener ];
30
51
  };
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
+ export { useBoundProp } from '@elementor/editor-controls';
1
2
  export type { PopoverActionProps } from './popover-action';
2
3
  export { replaceControl } from './control-replacement';
3
- export { useBoundProp } from './controls';
4
4
 
5
5
  import init from './init';
6
6
 
package/src/init.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { panel } from './panel';
2
1
  import { injectIntoLogic } from '@elementor/editor';
3
- import { shouldUseV2Panel } from './sync/should-use-v2-panel';
4
- import { EditingPanelHooks } from './components/editing-panel-hooks';
5
2
  import { __registerPanel as registerPanel } from '@elementor/editor-panels';
6
3
  import { __privateBlockDataCommand as blockDataCommand } from '@elementor/editor-v1-adapters';
4
+
5
+ import { EditingPanelHooks } from './components/editing-panel-hooks';
7
6
  import { init as initDynamics } from './dynamics/init';
7
+ import { panel } from './panel';
8
+ import { isAtomicWidgetSelected } from './sync/is-atomic-widget-selected';
8
9
 
9
10
  export default function init() {
10
11
  registerPanel( panel );
@@ -22,6 +23,6 @@ export default function init() {
22
23
  const blockV1Panel = () => {
23
24
  blockDataCommand( {
24
25
  command: 'panel/editor/open',
25
- condition: shouldUseV2Panel,
26
+ condition: isAtomicWidgetSelected,
26
27
  } );
27
28
  };
package/src/panel.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { __createPanel as createPanel } from '@elementor/editor-panels';
2
+
2
3
  import { EditingPanel } from './components/editing-panel';
3
4
 
4
5
  export const { panel, usePanelActions, usePanelStatus } = createPanel( {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { ComponentType, ElementType as ReactElementType, useId } from 'react';
2
+ import { type ComponentType, type ElementType as ReactElementType, useId } from 'react';
3
3
  import { XIcon } from '@elementor/icons';
4
4
  import { bindPopover, bindToggle, IconButton, Popover, Stack, Tooltip, Typography, usePopupState } from '@elementor/ui';
5
5
 
@@ -0,0 +1,7 @@
1
+ import { type EnqueueFont, type ExtendedWindow } from './types';
2
+
3
+ export const enqueueFont: EnqueueFont = ( fontFamily, context = 'editor' ) => {
4
+ const extendedWindow = window as unknown as ExtendedWindow;
5
+
6
+ return extendedWindow.elementor?.helpers?.enqueueFont( fontFamily, context ) ?? null;
7
+ };
@@ -0,0 +1,7 @@
1
+ import { type ExtendedWindow } from './types';
2
+
3
+ export const getElementorConfig = () => {
4
+ const extendedWindow = window as unknown as ExtendedWindow;
5
+
6
+ return extendedWindow.elementor?.config ?? {};
7
+ };
@@ -1,6 +1,6 @@
1
1
  import { getSelectedElements, getWidgetsCache } from '@elementor/editor-elements';
2
2
 
3
- export const shouldUseV2Panel = () => {
3
+ export const isAtomicWidgetSelected = () => {
4
4
  const selectedElements = getSelectedElements();
5
5
  const widgetCache = getWidgetsCache();
6
6
 
package/src/sync/types.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { ControlItem, PropsSchema } from '@elementor/editor-elements';
2
- import { PropValue } from '@elementor/editor-props';
3
- import { StyleDefinition, StyleDefinitionID } from '@elementor/editor-styles';
1
+ import { type ControlItem, type PropsSchema, type V1Element } from '@elementor/editor-elements';
2
+
3
+ export type SupportedFonts = 'system' | 'googlefonts' | 'customfonts';
4
+
5
+ export type EnqueueFont = ( fontFamily: string, context?: 'preview' | 'editor' ) => void;
4
6
 
5
7
  export type ExtendedWindow = Window & {
6
8
  elementor?: {
@@ -17,23 +19,20 @@ export type ExtendedWindow = Window & {
17
19
  }
18
20
  >;
19
21
  getContainer?: ( id: string ) => V1Element;
22
+ helpers?: {
23
+ enqueueFont: EnqueueFont;
24
+ };
25
+ config?: {
26
+ controls?: {
27
+ font?: {
28
+ options?: Record< string, SupportedFonts >;
29
+ };
30
+ };
31
+ };
32
+ };
33
+ elementorFrontend?: {
34
+ config?: {
35
+ is_rtl?: boolean;
36
+ };
20
37
  };
21
- };
22
-
23
- export type V1Element = {
24
- model: V1Model< V1ElementModelProps >;
25
- settings?: V1Model< V1ElementSettingsProps >;
26
- };
27
-
28
- export type V1ElementModelProps = {
29
- widgetType?: string;
30
- elType: string;
31
- id: string;
32
- styles?: Record< StyleDefinitionID, StyleDefinition >;
33
- };
34
-
35
- export type V1ElementSettingsProps = Record< string, PropValue >;
36
-
37
- type V1Model< T > = {
38
- get: < K extends keyof T >( key: K ) => T[ K ];
39
38
  };
@@ -1,26 +0,0 @@
1
- import * as React from 'react';
2
- import { useId } from 'react';
3
- import { Accordion, AccordionSummary, AccordionDetails, AccordionSummaryText, Stack } from '@elementor/ui';
4
-
5
- export type AccordionSectionProps = React.PropsWithChildren< {
6
- title: React.ReactNode;
7
- defaultExpanded?: boolean;
8
- } >;
9
-
10
- export const AccordionSection = ( { title, children, defaultExpanded = false }: AccordionSectionProps ) => {
11
- const uid = useId();
12
- const labelId = `label-${ uid }`;
13
- const contentId = `content-${ uid }`;
14
-
15
- // TODO: Change to collapsible list item
16
- return (
17
- <Accordion disableGutters defaultExpanded={ defaultExpanded }>
18
- <AccordionSummary aria-controls={ contentId } id={ labelId }>
19
- <AccordionSummaryText primaryTypographyProps={ { variant: 'caption' } }>{ title }</AccordionSummaryText>
20
- </AccordionSummary>
21
- <AccordionDetails id={ contentId } aria-labelledby={ labelId }>
22
- <Stack gap={ 2.5 }>{ children }</Stack>
23
- </AccordionDetails>
24
- </Accordion>
25
- );
26
- };
@@ -1,10 +0,0 @@
1
- import * as React from 'react';
2
- import { Typography } from '@elementor/ui';
3
-
4
- export const ControlLabel = ( { children }: { children: React.ReactNode } ) => {
5
- return (
6
- <Typography component="label" variant="caption" color="text.secondary">
7
- { children }
8
- </Typography>
9
- );
10
- };
@@ -1,30 +0,0 @@
1
- import * as React from 'react';
2
- import { PropKey, PropValue } from '@elementor/editor-props';
3
- import { createContext, useContext } from 'react';
4
-
5
- export type BoundPropContext< T extends PropValue > = {
6
- bind: PropKey;
7
- setValue: ( value: T | undefined ) => void;
8
- value: T | undefined;
9
- };
10
-
11
- export type BoundPropProviderProps< T extends PropValue > = BoundPropContext< T > & {
12
- children: React.ReactNode;
13
- };
14
-
15
- const BoundPropContext = createContext< BoundPropContext< PropValue > | null >( null );
16
- export const BoundPropProvider = ( { children, value, setValue, bind }: BoundPropProviderProps< PropValue > ) => {
17
- return <BoundPropContext.Provider value={ { value, setValue, bind } }>{ children }</BoundPropContext.Provider>;
18
- };
19
-
20
- export function useBoundProp< T extends PropValue >(): BoundPropContext< T | undefined >;
21
- export function useBoundProp< T extends PropValue >( defaultValue: T ): BoundPropContext< T >;
22
- export function useBoundProp< T extends PropValue >( defaultValue?: T ) {
23
- const boundPropContext = useContext< BoundPropContext< T > >( BoundPropContext as never );
24
-
25
- if ( ! boundPropContext ) {
26
- throw new Error( 'useBoundProp must be used within a BoundPropContext' );
27
- }
28
-
29
- return { ...boundPropContext, value: boundPropContext.value ?? defaultValue };
30
- }
@@ -1,68 +0,0 @@
1
- import * as React from 'react';
2
- import { JSX } from 'react';
3
- import { StackProps, styled, ToggleButton, ToggleButtonGroup, Tooltip } from '@elementor/ui';
4
-
5
- export type ToggleButtonGroupItem< TValue > = {
6
- value: TValue;
7
- label: string;
8
- icon: JSX.ElementType;
9
- showTooltip?: boolean;
10
- };
11
-
12
- const StyledToggleButtonGroup = styled( ToggleButtonGroup )`
13
- ${ ( { justify } ) => `justify-content: ${ justify };` }
14
- `;
15
-
16
- type ExclusiveValue< TValue > = TValue | null;
17
- type NonExclusiveValue< TValue > = TValue[];
18
-
19
- type Props< TValue > = {
20
- justify?: StackProps[ 'justifyContent' ];
21
- size?: 'tiny' | 'small' | 'medium' | 'large';
22
- items: ToggleButtonGroupItem< TValue >[];
23
- } & (
24
- | {
25
- exclusive?: false;
26
- value: NonExclusiveValue< TValue >;
27
- onChange: ( value: NonExclusiveValue< TValue > ) => void;
28
- }
29
- | {
30
- exclusive: true;
31
- value: ExclusiveValue< TValue >;
32
- onChange: ( value: ExclusiveValue< TValue > ) => void;
33
- }
34
- );
35
-
36
- export const ControlToggleButtonGroup = < TValue, >( {
37
- justify = 'end',
38
- size = 'tiny',
39
- value,
40
- onChange,
41
- items,
42
- exclusive = false,
43
- }: Props< TValue > ) => {
44
- const handleChange = (
45
- _: React.MouseEvent< HTMLElement >,
46
- newValue: typeof exclusive extends true ? ExclusiveValue< TValue > : NonExclusiveValue< TValue >
47
- ) => {
48
- onChange( newValue as never );
49
- };
50
-
51
- return (
52
- <StyledToggleButtonGroup justify={ justify } value={ value } onChange={ handleChange } exclusive={ exclusive }>
53
- { items.map( ( { label: label, value: buttonValue, icon: Icon, showTooltip: showTooltip } ) =>
54
- showTooltip ? (
55
- <Tooltip title={ label } disableFocusListener={ true } placement="top" key={ buttonValue }>
56
- <ToggleButton value={ buttonValue } aria-label={ label } size={ size }>
57
- <Icon fontSize={ size } />
58
- </ToggleButton>
59
- </Tooltip>
60
- ) : (
61
- <ToggleButton key={ buttonValue } value={ buttonValue } aria-label={ label } size={ size }>
62
- <Icon fontSize={ size } />
63
- </ToggleButton>
64
- )
65
- ) }
66
- </StyledToggleButtonGroup>
67
- );
68
- };