@elementor/editor-app-bar 4.0.7 → 4.0.8

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-app-bar",
3
3
  "description": "App Bar extension for @elementor/editor",
4
- "version": "4.0.7",
4
+ "version": "4.0.8",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -40,18 +40,19 @@
40
40
  "dev": "tsup --config=../../tsup.dev.ts"
41
41
  },
42
42
  "dependencies": {
43
- "@elementor/editor-ui": "4.0.7",
44
- "@elementor/http-client": "4.0.7",
45
- "@elementor/editor": "4.0.7",
46
- "@elementor/editor-documents": "4.0.7",
47
- "@elementor/editor-responsive": "4.0.7",
48
- "@elementor/editor-v1-adapters": "4.0.7",
49
- "@elementor/icons": "^1.68.0",
50
- "@elementor/locations": "4.0.7",
51
- "@elementor/menus": "4.0.7",
52
- "@elementor/events": "4.0.7",
43
+ "@elementor/editor-ui": "4.0.8",
44
+ "@elementor/http-client": "4.0.8",
45
+ "@elementor/editor": "4.0.8",
46
+ "@elementor/editor-documents": "4.0.8",
47
+ "@elementor/editor-responsive": "4.0.8",
48
+ "@elementor/editor-v1-adapters": "4.0.8",
49
+ "@elementor/icons": "~1.75.1",
50
+ "@elementor/locations": "4.0.8",
51
+ "@elementor/menus": "4.0.8",
52
+ "@elementor/events": "4.0.8",
53
53
  "@elementor/ui": "1.36.17",
54
- "@wordpress/i18n": "^5.13.0"
54
+ "@wordpress/i18n": "^5.13.0",
55
+ "@elementor/editor-mcp": "4.0.8"
55
56
  },
56
57
  "devDependencies": {
57
58
  "tsup": "^8.3.5"
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
 
3
+ import AngieGuideLocation from '../../extensions/angie/components/angie-guide-location';
3
4
  import { toolsMenu } from '../../locations';
4
5
  import ToolbarMenu from '../ui/toolbar-menu';
5
6
  import ToolbarMenuMore from '../ui/toolbar-menu-more';
@@ -21,6 +22,7 @@ export default function ToolsMenuLocation() {
21
22
  { toolbarMenuItems.map( ( { MenuItem, id } ) => (
22
23
  <MenuItem key={ id } />
23
24
  ) ) }
25
+ <AngieGuideLocation />
24
26
  <SendFeedbackPopupLocation />
25
27
  <IntegrationsMenuLocation />
26
28
  { popoverMenuItems.length > 0 && (
@@ -0,0 +1,20 @@
1
+ import { __ } from '@wordpress/i18n';
2
+
3
+ export const ANGIE_GUIDE_TOGGLE_EVENT = 'elementor/editor/toggle-angie-guide';
4
+ export const CREATE_WIDGET_EVENT = 'elementor/editor/create-widget';
5
+
6
+ export const ANGIE_BUTTON_ARIA_LABEL = __( 'Angie', 'elementor' );
7
+
8
+ export const ANGIE_PROMOTION_IMAGE_URL = 'https://assets.elementor.com/packages/v1/images/angie-promotion.svg';
9
+
10
+ export const ANGIE_LEARN_MORE_URL = 'https://go.elementor.com/angie-learn-more';
11
+
12
+ export const ANGIE_DESCRIPTION = __(
13
+ 'Angie lets you generate custom widgets, sections, and code using simple instructions.',
14
+ 'elementor'
15
+ );
16
+
17
+ export const AI_WIDGET_CTA_VIEWED_EVENT = 'ai_widget_cta_viewed' as const;
18
+ export const ANGIE_TOP_BAR_PROMOTION_IMAGE_URL =
19
+ 'https://assets.elementor.com/packages/v1/images/angie-top-bar-promotion.svg';
20
+ export const ANGIE_TOP_BAR_DESCRIPTION = __( 'Build custom widgets using simple instructions.', 'elementor' );
@@ -0,0 +1,52 @@
1
+ import * as React from 'react';
2
+ import { Button, Chip, ClickAwayListener, CloseButton, Image, Stack, Typography } from '@elementor/ui';
3
+ import { __ } from '@wordpress/i18n';
4
+
5
+ type Props = {
6
+ imageUrl: string;
7
+ description: string;
8
+ learnMoreUrl: string;
9
+ onInstall: () => void;
10
+ onClose: () => void;
11
+ };
12
+
13
+ export default function AngieGuideCard( { imageUrl, description, learnMoreUrl, onInstall, onClose }: Props ) {
14
+ return (
15
+ <ClickAwayListener onClickAway={ onClose }>
16
+ <Stack sx={ { width: 296 } } data-testid="e-angie-guide-card">
17
+ <Stack direction="row" alignItems="center" gap={ 1 } py={ 1 } px={ 2 }>
18
+ <Typography variant="subtitle2">{ __( 'Meet Angie', 'elementor' ) }</Typography>
19
+ <Chip label={ __( 'New', 'elementor' ) } size="small" color="info" variant="standard" />
20
+ <CloseButton
21
+ edge="end"
22
+ sx={ { ml: 'auto' } }
23
+ slotProps={ { icon: { fontSize: 'small' } } }
24
+ onClick={ onClose }
25
+ />
26
+ </Stack>
27
+ <Image src={ imageUrl } alt={ __( 'Angie', 'elementor' ) } sx={ { height: 150, width: '100%' } } />
28
+ <Stack px={ 2 } pt={ 1.5 } pb={ 1 }>
29
+ <Typography variant="body2" color="secondary">
30
+ { description }
31
+ </Typography>
32
+ </Stack>
33
+ <Stack direction="row" justifyContent="flex-end" gap={ 1 } pt={ 1 } pb={ 1.5 } px={ 2 }>
34
+ <Button
35
+ variant="text"
36
+ size="small"
37
+ color="secondary"
38
+ onClick={ () => {
39
+ window.open( learnMoreUrl, '_blank', 'noopener,noreferrer' );
40
+ onClose();
41
+ } }
42
+ >
43
+ { __( 'Learn More', 'elementor' ) }
44
+ </Button>
45
+ <Button variant="contained" size="small" color="accent" onClick={ onInstall }>
46
+ { __( 'Try for free', 'elementor' ) }
47
+ </Button>
48
+ </Stack>
49
+ </Stack>
50
+ </ClickAwayListener>
51
+ );
52
+ }
@@ -0,0 +1,87 @@
1
+ import * as React from 'react';
2
+ import { useEffect, useState } from 'react';
3
+ import { ThemeProvider } from '@elementor/editor-ui';
4
+ import { useMixpanel } from '@elementor/events';
5
+ import { Infotip } from '@elementor/ui';
6
+
7
+ import {
8
+ AI_WIDGET_CTA_VIEWED_EVENT,
9
+ ANGIE_BUTTON_ARIA_LABEL,
10
+ ANGIE_GUIDE_TOGGLE_EVENT,
11
+ ANGIE_LEARN_MORE_URL,
12
+ ANGIE_TOP_BAR_DESCRIPTION,
13
+ ANGIE_TOP_BAR_PROMOTION_IMAGE_URL,
14
+ CREATE_WIDGET_EVENT,
15
+ } from '../angie-consts';
16
+ import AngieGuideCard from '../components/angie-guide-card';
17
+
18
+ export default function AngieGuideLocation() {
19
+ const [ anchorEl, setAnchorEl ] = useState< Element | null >( null );
20
+ const { dispatchEvent } = useMixpanel();
21
+
22
+ const isOpen = Boolean( anchorEl );
23
+
24
+ useEffect( () => {
25
+ const handleToggle = () => {
26
+ setAnchorEl( ( prev ) => {
27
+ if ( prev ) {
28
+ return null;
29
+ }
30
+
31
+ return document.querySelector( `[aria-label="${ ANGIE_BUTTON_ARIA_LABEL }"]` );
32
+ } );
33
+ };
34
+
35
+ window.addEventListener( ANGIE_GUIDE_TOGGLE_EVENT, handleToggle );
36
+
37
+ return () => {
38
+ window.removeEventListener( ANGIE_GUIDE_TOGGLE_EVENT, handleToggle );
39
+ };
40
+ }, [] );
41
+
42
+ const handleClose = () => setAnchorEl( null );
43
+
44
+ const handleInstall = async () => {
45
+ dispatchEvent?.( AI_WIDGET_CTA_VIEWED_EVENT, {
46
+ entry_point: 'top_bar_icon',
47
+ } );
48
+ window.dispatchEvent(
49
+ new CustomEvent( CREATE_WIDGET_EVENT, {
50
+ detail: {
51
+ entry_point: 'top_bar_icon',
52
+ },
53
+ } )
54
+ );
55
+ handleClose();
56
+ };
57
+
58
+ return (
59
+ <ThemeProvider>
60
+ <Infotip
61
+ content={
62
+ <AngieGuideCard
63
+ imageUrl={ ANGIE_TOP_BAR_PROMOTION_IMAGE_URL }
64
+ description={ ANGIE_TOP_BAR_DESCRIPTION }
65
+ learnMoreUrl={ ANGIE_LEARN_MORE_URL }
66
+ onInstall={ handleInstall }
67
+ onClose={ handleClose }
68
+ />
69
+ }
70
+ placement="bottom-start"
71
+ open={ isOpen }
72
+ disableHoverListener={ true }
73
+ PopperProps={ {
74
+ anchorEl,
75
+ modifiers: [
76
+ {
77
+ name: 'offset',
78
+ options: { offset: [ -4, -4 ] },
79
+ },
80
+ ],
81
+ } }
82
+ >
83
+ <span />
84
+ </Infotip>
85
+ </ThemeProvider>
86
+ );
87
+ }
@@ -0,0 +1,34 @@
1
+ import { useEffect } from 'react';
2
+ import { isAngieAvailable } from '@elementor/editor-mcp';
3
+ import { trackEvent } from '@elementor/events';
4
+ import { AngieIcon } from '@elementor/icons';
5
+ import { __ } from '@wordpress/i18n';
6
+
7
+ import { AI_WIDGET_CTA_VIEWED_EVENT, ANGIE_GUIDE_TOGGLE_EVENT } from '../angie-consts';
8
+
9
+ export default function useActionProps() {
10
+ const hasAngieInstalled = isAngieAvailable();
11
+ const visible = ! hasAngieInstalled;
12
+
13
+ useEffect( () => {
14
+ if ( ! visible ) {
15
+ return;
16
+ }
17
+
18
+ trackEvent( {
19
+ eventName: AI_WIDGET_CTA_VIEWED_EVENT,
20
+ entry_point: 'top_bar_icon',
21
+ has_angie_installed: false,
22
+ } );
23
+ }, [ visible ] );
24
+
25
+ return {
26
+ title: __( 'Angie', 'elementor' ),
27
+ icon: AngieIcon,
28
+ onClick: () => {
29
+ window.dispatchEvent( new CustomEvent( ANGIE_GUIDE_TOGGLE_EVENT ) );
30
+ },
31
+ selected: false,
32
+ visible,
33
+ };
34
+ }
@@ -0,0 +1,10 @@
1
+ import { toolsMenu } from '../../locations';
2
+ import useActionProps from './hooks/use-action-props';
3
+
4
+ export function init() {
5
+ toolsMenu.registerToggleAction( {
6
+ id: 'toggle-angie',
7
+ priority: 2,
8
+ useProps: useActionProps,
9
+ } );
10
+ }
@@ -4,7 +4,7 @@ import useActionProps from './hooks/use-action-props';
4
4
  export function init() {
5
5
  toolsMenu.registerToggleAction( {
6
6
  id: 'document-settings-button',
7
- priority: 2,
7
+ priority: 3,
8
8
  useProps: useActionProps,
9
9
  } );
10
10
  }
@@ -3,6 +3,7 @@
3
3
  * The code should be moved to the appropriate packages.
4
4
  */
5
5
 
6
+ import { init as initAngie } from './angie';
6
7
  import { init as initConnect } from './connect';
7
8
  import { init as initDocumentsPreview } from './documents-preview';
8
9
  import { init as initDocumentsSave } from './documents-save';
@@ -21,6 +22,7 @@ import { init as initUserPreferences } from './user-preferences';
21
22
  import { init as initWordpress } from './wordpress';
22
23
 
23
24
  export function init() {
25
+ initAngie();
24
26
  initDocumentsPreview();
25
27
  initDocumentsSave();
26
28
  initDocumentsSettings();