@elementor/editor-controls 4.0.0-676 → 4.0.0-677

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-controls",
3
3
  "description": "This package contains the controls model and utils for the Elementor editor",
4
- "version": "4.0.0-676",
4
+ "version": "4.0.0-677",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -40,22 +40,22 @@
40
40
  "dev": "tsup --config=../../tsup.dev.ts"
41
41
  },
42
42
  "dependencies": {
43
- "@elementor/editor-current-user": "4.0.0-676",
44
- "@elementor/editor-elements": "4.0.0-676",
45
- "@elementor/editor-props": "4.0.0-676",
46
- "@elementor/editor-responsive": "4.0.0-676",
47
- "@elementor/editor-ui": "4.0.0-676",
48
- "@elementor/editor-v1-adapters": "4.0.0-676",
49
- "@elementor/env": "4.0.0-676",
50
- "@elementor/http-client": "4.0.0-676",
43
+ "@elementor/editor-current-user": "4.0.0-677",
44
+ "@elementor/editor-elements": "4.0.0-677",
45
+ "@elementor/editor-props": "4.0.0-677",
46
+ "@elementor/editor-responsive": "4.0.0-677",
47
+ "@elementor/editor-ui": "4.0.0-677",
48
+ "@elementor/editor-v1-adapters": "4.0.0-677",
49
+ "@elementor/env": "4.0.0-677",
50
+ "@elementor/http-client": "4.0.0-677",
51
51
  "@elementor/icons": "^1.68.0",
52
- "@elementor/locations": "4.0.0-676",
53
- "@elementor/events": "4.0.0-676",
54
- "@elementor/query": "4.0.0-676",
55
- "@elementor/session": "4.0.0-676",
52
+ "@elementor/locations": "4.0.0-677",
53
+ "@elementor/events": "4.0.0-677",
54
+ "@elementor/query": "4.0.0-677",
55
+ "@elementor/session": "4.0.0-677",
56
56
  "@elementor/ui": "1.36.17",
57
- "@elementor/utils": "4.0.0-676",
58
- "@elementor/wp-media": "4.0.0-676",
57
+ "@elementor/utils": "4.0.0-677",
58
+ "@elementor/wp-media": "4.0.0-677",
59
59
  "@wordpress/i18n": "^5.13.0",
60
60
  "@monaco-editor/react": "^4.7.0",
61
61
  "dayjs": "^1.11.18",
@@ -8,6 +8,7 @@ import { createControl } from '../../create-control';
8
8
  import { PromotionTrigger, type PromotionTriggerRef } from './promotion-trigger';
9
9
 
10
10
  const ARIA_LABEL = __( 'Attributes', 'elementor' );
11
+ const TRACKING_DATA = { target_name: 'attributes', location_l2: 'general' } as const;
11
12
 
12
13
  export const AttributesControl = createControl( () => {
13
14
  const triggerRef = useRef< PromotionTriggerRef >( null );
@@ -21,7 +22,7 @@ export const AttributesControl = createControl( () => {
21
22
  alignItems: 'center',
22
23
  } }
23
24
  >
24
- <PromotionTrigger ref={ triggerRef } promotionKey="attributes" />
25
+ <PromotionTrigger ref={ triggerRef } promotionKey="attributes" trackingData={ TRACKING_DATA } />
25
26
  <Tooltip title={ ARIA_LABEL } placement="top">
26
27
  <PlusIcon
27
28
  aria-label={ ARIA_LABEL }
@@ -8,6 +8,7 @@ import { createControl } from '../../create-control';
8
8
  import { PromotionTrigger, type PromotionTriggerRef } from './promotion-trigger';
9
9
 
10
10
  const ARIA_LABEL = __( 'Display Conditions', 'elementor' );
11
+ const TRACKING_DATA = { target_name: 'display_conditions', location_l2: 'general' } as const;
11
12
 
12
13
  export const DisplayConditionsControl = createControl( () => {
13
14
  const triggerRef = useRef< PromotionTriggerRef >( null );
@@ -21,7 +22,7 @@ export const DisplayConditionsControl = createControl( () => {
21
22
  alignItems: 'center',
22
23
  } }
23
24
  >
24
- <PromotionTrigger ref={ triggerRef } promotionKey="displayConditions" />
25
+ <PromotionTrigger ref={ triggerRef } promotionKey="displayConditions" trackingData={ TRACKING_DATA } />
25
26
  <Tooltip title={ ARIA_LABEL } placement="top">
26
27
  <IconButton
27
28
  size="tiny"
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
- import { forwardRef, type ReactNode, useImperativeHandle, useState } from 'react';
2
+ import { forwardRef, type ReactNode, useCallback, useImperativeHandle, useState } from 'react';
3
3
  import { PromotionChip, PromotionInfotip } from '@elementor/editor-ui';
4
4
  import { Box } from '@elementor/ui';
5
5
 
6
+ import { type PromotionTrackingData, trackUpgradePromotionClick, trackViewPromotion } from '../../utils/tracking';
6
7
  import type { V4PromotionData, V4PromotionKey } from './types';
7
8
 
8
9
  function getV4Promotion( key: V4PromotionKey ): V4PromotionData | undefined {
@@ -12,6 +13,7 @@ function getV4Promotion( key: V4PromotionKey ): V4PromotionData | undefined {
12
13
  type PromotionTriggerProps = {
13
14
  promotionKey: V4PromotionKey;
14
15
  children?: ReactNode;
16
+ trackingData: PromotionTrackingData;
15
17
  };
16
18
 
17
19
  export type PromotionTriggerRef = {
@@ -19,13 +21,20 @@ export type PromotionTriggerRef = {
19
21
  };
20
22
 
21
23
  export const PromotionTrigger = forwardRef< PromotionTriggerRef, PromotionTriggerProps >(
22
- ( { promotionKey, children }, ref ) => {
24
+ ( { promotionKey, children, trackingData }, ref ) => {
23
25
  const [ isOpen, setIsOpen ] = useState( false );
24
26
  const promotion = getV4Promotion( promotionKey );
25
27
 
26
- const toggle = () => setIsOpen( ( prev ) => ! prev );
28
+ const toggle = useCallback( () => {
29
+ setIsOpen( ( prev ) => {
30
+ if ( ! prev ) {
31
+ trackViewPromotion( trackingData );
32
+ }
33
+ return ! prev;
34
+ } );
35
+ }, [ trackingData ] );
27
36
 
28
- useImperativeHandle( ref, () => ( { toggle } ), [] );
37
+ useImperativeHandle( ref, () => ( { toggle } ), [ toggle ] );
29
38
 
30
39
  return (
31
40
  <>
@@ -40,6 +49,7 @@ export const PromotionTrigger = forwardRef< PromotionTriggerRef, PromotionTrigge
40
49
  e.stopPropagation();
41
50
  setIsOpen( false );
42
51
  } }
52
+ onCtaClick={ () => trackUpgradePromotionClick( trackingData ) }
43
53
  >
44
54
  <Box
45
55
  onClick={ ( e: MouseEvent ) => {
package/src/index.ts CHANGED
@@ -80,6 +80,8 @@ export type { FontCategory } from './controls/font-family-control/font-family-co
80
80
  export type { InlineEditorToolbarProps } from './components/inline-editor-toolbar';
81
81
  export type { V4PromotionData, V4PromotionKey } from './components/promotions/types';
82
82
  export type { PromotionTriggerRef } from './components/promotions/promotion-trigger';
83
+ export { trackViewPromotion, trackUpgradePromotionClick } from './utils/tracking';
84
+ export type { PromotionTrackingData } from './utils/tracking';
83
85
 
84
86
  // providers
85
87
  export {
@@ -0,0 +1,61 @@
1
+ import { getSelectedElements } from '@elementor/editor-elements';
2
+ import { getMixpanel } from '@elementor/events';
3
+
4
+ export type PromotionTrackingData = {
5
+ target_name: string;
6
+ target_location?: 'widget_panel' | 'variables_manager';
7
+ location_l1?: string;
8
+ location_l2?: 'style' | 'general' | 'interactions';
9
+ };
10
+
11
+ type PromotionEventOptions = {
12
+ eventName: string | undefined;
13
+ interactionResult: string;
14
+ interactionDescription: string;
15
+ };
16
+
17
+ type MixpanelConfig = ReturnType< typeof getMixpanel >[ 'config' ];
18
+
19
+ const getBaseEventProperties = ( data: PromotionTrackingData, config: MixpanelConfig ) => ( {
20
+ app_type: config?.appTypes?.editor ?? 'editor',
21
+ window_name: config?.appTypes?.editor ?? 'editor',
22
+ interaction_type: config?.triggers?.click ?? 'Click',
23
+ target_name: data.target_name,
24
+ target_location: data.target_location ?? 'widget_panel',
25
+ location_l1: data.location_l1 ?? getSelectedElements()[ 0 ]?.type ?? '',
26
+ ...( data.location_l2 && { location_l2: data.location_l2 } ),
27
+ } );
28
+
29
+ const dispatchPromotionEvent = (
30
+ data: PromotionTrackingData,
31
+ resolveOptions: ( config: MixpanelConfig ) => PromotionEventOptions
32
+ ) => {
33
+ const { dispatchEvent, config } = getMixpanel();
34
+ const { eventName, interactionResult, interactionDescription } = resolveOptions( config );
35
+
36
+ if ( ! eventName ) {
37
+ return;
38
+ }
39
+
40
+ dispatchEvent?.( eventName, {
41
+ ...getBaseEventProperties( data, config ),
42
+ interaction_result: interactionResult,
43
+ interaction_description: interactionDescription,
44
+ } );
45
+ };
46
+
47
+ export const trackViewPromotion = ( data: PromotionTrackingData ) => {
48
+ dispatchPromotionEvent( data, ( config ) => ( {
49
+ eventName: config?.names?.promotions?.viewPromotion,
50
+ interactionResult: config?.interactionResults?.promotionViewed ?? 'promotion_viewed',
51
+ interactionDescription: 'user_viewed_promotion',
52
+ } ) );
53
+ };
54
+
55
+ export const trackUpgradePromotionClick = ( data: PromotionTrackingData ) => {
56
+ dispatchPromotionEvent( data, ( config ) => ( {
57
+ eventName: config?.names?.promotions?.upgradePromotionClick,
58
+ interactionResult: config?.interactionResults?.upgradeNow ?? 'upgrade_now',
59
+ interactionDescription: 'user_clicked_upgrade_now',
60
+ } ) );
61
+ };