@elementor/editor-controls 1.5.0 → 3.32.0-21

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 (71) hide show
  1. package/CHANGELOG.md +0 -22
  2. package/dist/index.d.mts +95 -25
  3. package/dist/index.d.ts +95 -25
  4. package/dist/index.js +2045 -1041
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1962 -964
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +18 -18
  9. package/src/components/control-toggle-button-group.tsx +78 -14
  10. package/src/components/floating-bar.tsx +45 -0
  11. package/src/components/{font-family-selector.tsx → item-selector.tsx} +62 -50
  12. package/src/components/repeater.tsx +1 -1
  13. package/src/components/restricted-link-infotip.tsx +76 -0
  14. package/src/components/size-control/size-input.tsx +8 -7
  15. package/src/components/size-control/text-field-inner-selection.tsx +60 -14
  16. package/src/components/text-field-popover.tsx +30 -7
  17. package/src/components/unstable-repeater/actions/add-item-action.tsx +50 -0
  18. package/src/components/unstable-repeater/actions/disable-item-action.tsx +39 -0
  19. package/src/components/unstable-repeater/actions/duplicate-item-action.tsx +32 -0
  20. package/src/components/unstable-repeater/actions/remove-item-action.tsx +27 -0
  21. package/src/components/unstable-repeater/context/repeater-context.tsx +137 -0
  22. package/src/components/unstable-repeater/header/header.tsx +23 -0
  23. package/src/components/unstable-repeater/index.ts +5 -0
  24. package/src/components/unstable-repeater/items/edit-item-popover.tsx +28 -0
  25. package/src/components/unstable-repeater/items/item.tsx +71 -0
  26. package/src/components/unstable-repeater/items/items-container.tsx +49 -0
  27. package/src/components/unstable-repeater/items/use-popover.tsx +26 -0
  28. package/src/{locations.ts → components/unstable-repeater/locations.ts} +9 -1
  29. package/src/components/unstable-repeater/types.ts +26 -0
  30. package/src/components/unstable-repeater/unstable-repeater.tsx +24 -0
  31. package/src/control-actions/control-actions.tsx +3 -20
  32. package/src/control-replacements.tsx +41 -0
  33. package/src/controls/background-control/background-control.tsx +1 -8
  34. package/src/controls/background-control/background-overlay/background-overlay-repeater-control.tsx +17 -16
  35. package/src/controls/equal-unequal-sizes-control.tsx +2 -9
  36. package/src/controls/filter-control/drop-shadow-item-content.tsx +4 -6
  37. package/src/controls/filter-control/drop-shadow-item-label.tsx +2 -2
  38. package/src/controls/filter-repeater-control.tsx +149 -110
  39. package/src/controls/font-family-control/font-family-control.tsx +22 -10
  40. package/src/controls/key-value-control.tsx +9 -6
  41. package/src/controls/link-control.tsx +8 -91
  42. package/src/controls/linked-dimensions-control.tsx +3 -16
  43. package/src/controls/number-control.tsx +10 -1
  44. package/src/controls/position-control.tsx +4 -16
  45. package/src/controls/repeatable-control.tsx +8 -5
  46. package/src/controls/select-control.tsx +7 -2
  47. package/src/controls/selection-size-control.tsx +74 -0
  48. package/src/controls/size-control.tsx +181 -126
  49. package/src/controls/stroke-control.tsx +2 -2
  50. package/src/controls/toggle-control.tsx +3 -2
  51. package/src/controls/transform-control/functions/axis-row.tsx +4 -2
  52. package/src/controls/transform-control/functions/move.tsx +2 -1
  53. package/src/controls/transform-control/functions/rotate.tsx +48 -0
  54. package/src/controls/transform-control/functions/scale-axis-row.tsx +32 -0
  55. package/src/controls/transform-control/functions/scale.tsx +45 -0
  56. package/src/controls/transform-control/functions/skew.tsx +43 -0
  57. package/src/controls/transform-control/transform-content.tsx +60 -23
  58. package/src/controls/transform-control/transform-icon.tsx +10 -2
  59. package/src/controls/transform-control/transform-label.tsx +39 -2
  60. package/src/controls/transform-control/transform-repeater-control.tsx +2 -10
  61. package/src/controls/transform-control/types.ts +58 -0
  62. package/src/controls/transform-control/use-transform-tabs-history.tsx +107 -0
  63. package/src/controls/transition-control/data.ts +34 -0
  64. package/src/controls/transition-control/transition-repeater-control.tsx +63 -0
  65. package/src/controls/transition-control/transition-selector.tsx +88 -0
  66. package/src/controls/unstable-transform-control/unstable-transform-repeater-control.tsx +35 -0
  67. package/src/hooks/use-filtered-items-list.ts +24 -0
  68. package/src/hooks/use-size-extended-options.ts +1 -6
  69. package/src/index.ts +13 -3
  70. package/src/utils/size-control.ts +12 -6
  71. package/src/hooks/use-filtered-font-families.ts +0 -24
@@ -0,0 +1,63 @@
1
+ import * as React from 'react';
2
+ import { selectionSizePropTypeUtil } from '@elementor/editor-props';
3
+ import { __ } from '@wordpress/i18n';
4
+
5
+ import { createControl } from '../../create-control';
6
+ import { RepeatableControl } from '../repeatable-control';
7
+ import { SelectionSizeControl } from '../selection-size-control';
8
+ import { initialTransitionValue, transitionProperties } from './data';
9
+ import { TransitionSelector } from './transition-selector';
10
+
11
+ const DURATION_CONFIG = {
12
+ variant: 'time',
13
+ units: [ 's', 'ms' ],
14
+ defaultUnit: 'ms',
15
+ };
16
+
17
+ // this config needs to be loaded at runtime/render since it's the transitionProperties object will be mutated by the pro plugin.
18
+ // See: https://elementor.atlassian.net/browse/ED-20285
19
+ const getSelectionSizeProps = () => {
20
+ return {
21
+ selectionLabel: __( 'Type', 'elementor' ),
22
+ sizeLabel: __( 'Duration', 'elementor' ),
23
+ selectionConfig: {
24
+ component: TransitionSelector,
25
+ props: {},
26
+ },
27
+ sizeConfigMap: {
28
+ ...transitionProperties.reduce(
29
+ ( acc, category ) => {
30
+ category.properties.forEach( ( property ) => {
31
+ acc[ property.value ] = DURATION_CONFIG;
32
+ } );
33
+ return acc;
34
+ },
35
+ {} as Record< string, typeof DURATION_CONFIG >
36
+ ),
37
+ },
38
+ };
39
+ };
40
+
41
+ function getChildControlConfig() {
42
+ return {
43
+ propTypeUtil: selectionSizePropTypeUtil,
44
+ component: SelectionSizeControl as unknown as React.ComponentType< Record< string, unknown > >,
45
+ props: getSelectionSizeProps(),
46
+ };
47
+ }
48
+
49
+ export const TransitionRepeaterControl = createControl( () => {
50
+ return (
51
+ <RepeatableControl
52
+ label={ __( 'Transitions', 'elementor' ) }
53
+ repeaterLabel={ __( 'Transitions', 'elementor' ) }
54
+ patternLabel="${value.selection.value.key.value}: ${value.size.value.size}${value.size.value.unit}"
55
+ placeholder={ __( 'Empty Transition', 'elementor' ) }
56
+ showDuplicate={ false }
57
+ showToggle={ true }
58
+ initialValues={ initialTransitionValue }
59
+ childControlConfig={ getChildControlConfig() }
60
+ propKey="transition"
61
+ />
62
+ );
63
+ } );
@@ -0,0 +1,88 @@
1
+ import * as React from 'react';
2
+ import { useRef } from 'react';
3
+ import { keyValuePropTypeUtil } from '@elementor/editor-props';
4
+ import { ChevronDownIcon, VariationsIcon } from '@elementor/icons';
5
+ import { bindPopover, bindTrigger, Box, Popover, UnstableTag, usePopupState } from '@elementor/ui';
6
+ import { __ } from '@wordpress/i18n';
7
+
8
+ import { useBoundProp } from '../../bound-prop-context';
9
+ import { ItemSelector } from '../../components/item-selector';
10
+ import { transitionProperties, transitionsItemsList } from './data';
11
+
12
+ const toTransitionSelectorValue = ( label: string ) => {
13
+ for ( const category of transitionProperties ) {
14
+ const property = category.properties.find( ( prop ) => prop.label === label );
15
+ if ( property ) {
16
+ return {
17
+ key: { value: property.label, $$type: 'string' },
18
+ value: { value: property.value, $$type: 'string' },
19
+ };
20
+ }
21
+ }
22
+
23
+ return null;
24
+ };
25
+
26
+ export const TransitionSelector = () => {
27
+ const { value, setValue } = useBoundProp( keyValuePropTypeUtil );
28
+ const {
29
+ value: { value: transitionValue },
30
+ key: { value: transitionLabel },
31
+ } = value;
32
+ const defaultRef = useRef< HTMLDivElement >( null );
33
+ const popoverState = usePopupState( { variant: 'popover' } );
34
+
35
+ const handleTransitionPropertyChange = ( newLabel: string ) => {
36
+ const newValue = toTransitionSelectorValue( newLabel );
37
+
38
+ if ( ! newValue ) {
39
+ return;
40
+ }
41
+
42
+ setValue( newValue );
43
+ popoverState.close();
44
+ };
45
+
46
+ const getAnchorPosition = () => {
47
+ if ( ! defaultRef.current ) {
48
+ return undefined;
49
+ }
50
+
51
+ const rect = defaultRef.current.getBoundingClientRect();
52
+ return {
53
+ top: rect.top,
54
+ left: rect.right + 36,
55
+ };
56
+ };
57
+
58
+ return (
59
+ <Box ref={ defaultRef }>
60
+ <UnstableTag
61
+ variant="outlined"
62
+ label={ transitionLabel }
63
+ endIcon={ <ChevronDownIcon fontSize="tiny" /> }
64
+ { ...bindTrigger( popoverState ) }
65
+ fullWidth
66
+ />
67
+ <Popover
68
+ disablePortal
69
+ disableScrollLock
70
+ { ...bindPopover( popoverState ) }
71
+ anchorReference="anchorPosition"
72
+ anchorPosition={ getAnchorPosition() }
73
+ anchorOrigin={ { vertical: 'top', horizontal: 'right' } }
74
+ transformOrigin={ { vertical: 'top', horizontal: 'left' } }
75
+ >
76
+ <ItemSelector
77
+ itemsList={ transitionsItemsList }
78
+ selectedItem={ transitionValue }
79
+ onItemChange={ handleTransitionPropertyChange }
80
+ onClose={ popoverState.close }
81
+ sectionWidth={ 268 }
82
+ title={ __( 'Transition Property', 'elementor' ) }
83
+ icon={ VariationsIcon as React.ElementType< { fontSize: string } > }
84
+ />
85
+ </Popover>
86
+ </Box>
87
+ );
88
+ };
@@ -0,0 +1,35 @@
1
+ import * as React from 'react';
2
+ import { transformPropTypeUtil } from '@elementor/editor-props';
3
+ import { __ } from '@wordpress/i18n';
4
+
5
+ import { PropProvider, useBoundProp } from '../../bound-prop-context';
6
+ import { AddItemAction, Header, Item, ItemsContainer, UnstableRepeater } from '../../components/unstable-repeater';
7
+ import { DisableItemAction } from '../../components/unstable-repeater/actions/disable-item-action';
8
+ import { RemoveItemAction } from '../../components/unstable-repeater/actions/remove-item-action';
9
+ import { createControl } from '../../create-control';
10
+ import { TransformContent } from '../transform-control/transform-content';
11
+ import { TransformIcon } from '../transform-control/transform-icon';
12
+ import { TransformLabel } from '../transform-control/transform-label';
13
+ import { initialTransformValue } from '../transform-control/types';
14
+
15
+ export const UnstableTransformRepeaterControl = createControl( () => {
16
+ const { propType, value: transformValues, setValue } = useBoundProp( transformPropTypeUtil );
17
+
18
+ return (
19
+ <PropProvider propType={ propType } value={ transformValues } setValue={ setValue }>
20
+ <UnstableRepeater initial={ initialTransformValue } propTypeUtil={ transformPropTypeUtil }>
21
+ <Header label={ __( 'Transform', 'elementor' ) }>
22
+ <AddItemAction />
23
+ </Header>
24
+ <ItemsContainer
25
+ itemTemplate={
26
+ <Item Icon={ TransformIcon } Label={ TransformLabel } Content={ TransformContent } />
27
+ }
28
+ >
29
+ <DisableItemAction />
30
+ <RemoveItemAction />
31
+ </ItemsContainer>
32
+ </UnstableRepeater>
33
+ </PropProvider>
34
+ );
35
+ } );
@@ -0,0 +1,24 @@
1
+ import { type Category } from '../components/item-selector';
2
+
3
+ export type SelectableItem = {
4
+ type: 'item' | 'category';
5
+ value: string;
6
+ };
7
+
8
+ export const useFilteredItemsList = ( itemsList: Category[], searchValue: string ) => {
9
+ return itemsList.reduce< SelectableItem[] >( ( acc, category ) => {
10
+ const filteredItems = category.items.filter( ( item ) =>
11
+ item.toLowerCase().includes( searchValue.toLowerCase() )
12
+ );
13
+
14
+ if ( filteredItems.length ) {
15
+ acc.push( { type: 'category', value: category.label } );
16
+
17
+ filteredItems.forEach( ( item ) => {
18
+ acc.push( { type: 'item', value: item } );
19
+ } );
20
+ }
21
+
22
+ return acc;
23
+ }, [] );
24
+ };
@@ -1,16 +1,11 @@
1
1
  import { useMemo } from 'react';
2
2
  import { type ExtendedOption } from '@elementor/editor-controls';
3
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
4
-
5
- const EXPERIMENT_ID = 'e_v_3_30';
6
3
 
7
4
  export function useSizeExtendedOptions( options: ExtendedOption[], disableCustom: boolean ) {
8
5
  return useMemo( () => {
9
- const isVersion330Active = isExperimentActive( EXPERIMENT_ID );
10
- const shouldDisableCustom = ! isVersion330Active || disableCustom;
11
6
  const extendedOptions = [ ...options ];
12
7
 
13
- if ( ! shouldDisableCustom && ! extendedOptions.includes( 'custom' ) ) {
8
+ if ( ! disableCustom && ! extendedOptions.includes( 'custom' ) ) {
14
9
  extendedOptions.push( 'custom' );
15
10
  } else if ( options.includes( 'custom' ) ) {
16
11
  extendedOptions.splice( extendedOptions.indexOf( 'custom' ), 1 );
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ export { NumberControl } from './controls/number-control';
13
13
  export { EqualUnequalSizesControl } from './controls/equal-unequal-sizes-control';
14
14
  export { LinkedDimensionsControl } from './controls/linked-dimensions-control';
15
15
  export { FontFamilyControl } from './controls/font-family-control/font-family-control';
16
+ export { ItemSelector } from './components/item-selector';
16
17
  export { UrlControl } from './controls/url-control';
17
18
  export { LinkControl } from './controls/link-control';
18
19
  export { GapControl } from './controls/gap-control';
@@ -24,12 +25,15 @@ export { RepeatableControl } from './controls/repeatable-control';
24
25
  export { KeyValueControl } from './controls/key-value-control';
25
26
  export { PositionControl } from './controls/position-control';
26
27
  export { TransformRepeaterControl } from './controls/transform-control/transform-repeater-control';
28
+ export { TransitionRepeaterControl } from './controls/transition-control/transition-repeater-control';
27
29
  export { PopoverContent } from './components/popover-content';
30
+ export { enqueueFont } from './controls/font-family-control/enqueue-font';
31
+ export { UnstableTransformRepeaterControl } from './controls/unstable-transform-control/unstable-transform-repeater-control';
32
+ export { transitionProperties, transitionsItemsList } from './controls/transition-control/data';
28
33
 
29
34
  // components
30
35
  export { ControlFormLabel } from './components/control-form-label';
31
36
  export { ControlToggleButtonGroup } from './components/control-toggle-button-group';
32
- export { FontFamilySelector } from './components/font-family-selector';
33
37
 
34
38
  // types
35
39
  export type { ControlComponent } from './create-control';
@@ -38,18 +42,24 @@ export type { EqualUnequalItems } from './controls/equal-unequal-sizes-control';
38
42
  export type { ControlActionsItems } from './control-actions/control-actions-context';
39
43
  export type { PropProviderProps } from './bound-prop-context';
40
44
  export type { SetValue } from './bound-prop-context/prop-context';
41
- export type { ExtendedOption, Unit } from './utils/size-control';
45
+ export type { ExtendedOption, Unit, LengthUnit, AngleUnit, TimeUnit } from './utils/size-control';
42
46
  export type { ToggleControlProps } from './controls/toggle-control';
43
47
  export type { FontCategory } from './controls/font-family-control/font-family-control';
44
48
 
45
49
  // providers
46
50
  export { createControlReplacementsRegistry, ControlReplacementsProvider } from './control-replacements';
47
51
  export { ControlActionsProvider, useControlActions } from './control-actions/control-actions-context';
52
+ export { useFloatingActionsBar } from './components/floating-bar';
48
53
  export { useBoundProp, PropProvider, PropKeyProvider } from './bound-prop-context';
49
54
  export { ControlAdornmentsProvider } from './control-adornments/control-adornments-context';
50
55
  export { ControlAdornments } from './control-adornments/control-adornments';
51
56
 
52
- export { injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel } from './locations';
57
+ export {
58
+ injectIntoRepeaterItemIcon,
59
+ injectIntoRepeaterItemLabel,
60
+ injectIntoRepeaterHeaderActions,
61
+ injectIntoRepeaterItemActions,
62
+ } from './components/unstable-repeater/locations';
53
63
 
54
64
  // hooks
55
65
  export { useSyncExternalState } from './hooks/use-sync-external-state';
@@ -1,12 +1,18 @@
1
- export const defaultUnits = [ 'px', '%', 'em', 'rem', 'vw', 'vh' ] as const;
2
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
3
- const degreeUnits = [ 'deg', 'rad', 'grad', 'turn' ] as const;
1
+ export const lengthUnits = [ 'px', '%', 'em', 'rem', 'vw', 'vh' ] as const;
2
+ export const angleUnits = [ 'deg', 'rad', 'grad', 'turn' ] as const;
3
+ export const timeUnits = [ 's', 'ms' ] as const;
4
4
  const defaultExtendedOptions = [ 'auto', 'custom' ] as const;
5
5
 
6
- export type Unit = ( typeof defaultUnits )[ number ];
7
- export type DegreeUnit = ( typeof degreeUnits )[ number ];
6
+ export const DEFAULT_UNIT = 'px';
7
+ export const DEFAULT_SIZE = NaN;
8
+
9
+ export type LengthUnit = ( typeof lengthUnits )[ number ];
10
+ export type AngleUnit = ( typeof angleUnits )[ number ];
11
+ export type TimeUnit = ( typeof timeUnits )[ number ];
8
12
  export type ExtendedOption = ( typeof defaultExtendedOptions )[ number ];
9
13
 
10
- export function isUnitExtendedOption( unit: Unit | DegreeUnit | ExtendedOption ): unit is ExtendedOption {
14
+ export type Unit = LengthUnit | AngleUnit | TimeUnit;
15
+
16
+ export function isUnitExtendedOption( unit: Unit | ExtendedOption ): unit is ExtendedOption {
11
17
  return defaultExtendedOptions.includes( unit as ExtendedOption );
12
18
  }
@@ -1,24 +0,0 @@
1
- import { type FontCategory } from '@elementor/editor-controls';
2
-
3
- export type FontListItem = {
4
- type: 'font' | 'category';
5
- value: string;
6
- };
7
-
8
- export const useFilteredFontFamilies = ( fontFamilies: FontCategory[], searchValue: string ) => {
9
- return fontFamilies.reduce< FontListItem[] >( ( acc, category ) => {
10
- const filteredFonts = category.fonts.filter( ( font ) =>
11
- font.toLowerCase().includes( searchValue.toLowerCase() )
12
- );
13
-
14
- if ( filteredFonts.length ) {
15
- acc.push( { type: 'category', value: category.label } );
16
-
17
- filteredFonts.forEach( ( font ) => {
18
- acc.push( { type: 'font', value: font } );
19
- } );
20
- }
21
-
22
- return acc;
23
- }, [] );
24
- };