@elementor/editor-controls 4.2.0-868 → 4.2.0-870
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/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +283 -187
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +231 -135
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -15
- package/src/controls/chips-control.tsx +16 -9
- package/src/controls/email-form-action-control/email-chips-field.tsx +104 -0
- package/src/controls/email-form-action-control/email-field.tsx +25 -0
- package/src/controls/email-form-action-control/fields.tsx +138 -0
- package/src/controls/email-form-action-control/index.tsx +60 -0
- package/src/controls/email-form-action-control/utils.ts +24 -0
- package/src/controls/email-form-action-control.tsx +0 -194
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.2.0-
|
|
4
|
+
"version": "4.2.0-870",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -40,22 +40,23 @@
|
|
|
40
40
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elementor/editor-current-user": "4.2.0-
|
|
44
|
-
"@elementor/editor-elements": "4.2.0-
|
|
45
|
-
"@elementor/editor-props": "4.2.0-
|
|
46
|
-
"@elementor/editor-responsive": "4.2.0-
|
|
47
|
-
"@elementor/editor-ui": "4.2.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "4.2.0-
|
|
49
|
-
"@elementor/env": "4.2.0-
|
|
50
|
-
"@elementor/events": "4.2.0-
|
|
51
|
-
"@elementor/http-client": "4.2.0-
|
|
43
|
+
"@elementor/editor-current-user": "4.2.0-870",
|
|
44
|
+
"@elementor/editor-elements": "4.2.0-870",
|
|
45
|
+
"@elementor/editor-props": "4.2.0-870",
|
|
46
|
+
"@elementor/editor-responsive": "4.2.0-870",
|
|
47
|
+
"@elementor/editor-ui": "4.2.0-870",
|
|
48
|
+
"@elementor/editor-v1-adapters": "4.2.0-870",
|
|
49
|
+
"@elementor/env": "4.2.0-870",
|
|
50
|
+
"@elementor/events": "4.2.0-870",
|
|
51
|
+
"@elementor/http-client": "4.2.0-870",
|
|
52
52
|
"@elementor/icons": "~1.75.1",
|
|
53
|
-
"@elementor/locations": "4.2.0-
|
|
54
|
-
"@elementor/query": "4.2.0-
|
|
55
|
-
"@elementor/
|
|
53
|
+
"@elementor/locations": "4.2.0-870",
|
|
54
|
+
"@elementor/query": "4.2.0-870",
|
|
55
|
+
"@elementor/schema": "4.2.0-870",
|
|
56
|
+
"@elementor/session": "4.2.0-870",
|
|
56
57
|
"@elementor/ui": "1.37.5",
|
|
57
|
-
"@elementor/utils": "4.2.0-
|
|
58
|
-
"@elementor/wp-media": "4.2.0-
|
|
58
|
+
"@elementor/utils": "4.2.0-870",
|
|
59
|
+
"@elementor/wp-media": "4.2.0-870",
|
|
59
60
|
"@monaco-editor/react": "^4.7.0",
|
|
60
61
|
"@tiptap/extension-bold": "^3.11.1",
|
|
61
62
|
"@tiptap/extension-document": "^3.11.1",
|
|
@@ -15,24 +15,29 @@ export type ChipsOption = {
|
|
|
15
15
|
|
|
16
16
|
type ChipsControlProps = {
|
|
17
17
|
options: ChipsOption[];
|
|
18
|
+
freeChips?: boolean;
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
const SIZE = 'tiny';
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
const toChipsOption = ( val: string, options: ChipsOption[] ): ChipsOption =>
|
|
24
|
+
options.find( ( opt ) => opt.value === val ) ?? { label: val, value: val };
|
|
25
|
+
|
|
26
|
+
export const ChipsControl = createControl( ( { options, freeChips }: ChipsControlProps ) => {
|
|
23
27
|
const { value, setValue, disabled } = useBoundProp( stringArrayPropTypeUtil );
|
|
24
28
|
|
|
25
29
|
const selectedValues: string[] = ( value || [] )
|
|
26
30
|
.map( ( item ) => stringPropTypeUtil.extract( item ) )
|
|
27
31
|
.filter( ( val ): val is string => val !== null );
|
|
28
32
|
|
|
29
|
-
const selectedOptions = selectedValues
|
|
30
|
-
.map( ( val ) => options.find( ( opt ) => opt.value === val ) )
|
|
31
|
-
.filter( ( opt ): opt is ChipsOption => opt !== undefined );
|
|
33
|
+
const selectedOptions = selectedValues.map( ( val ) => toChipsOption( val, options ) );
|
|
32
34
|
|
|
33
|
-
const handleChange = ( _: SyntheticEvent, newValue: ChipsOption[] ) => {
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
const handleChange = ( _: SyntheticEvent, newValue: ( ChipsOption | string )[] ) => {
|
|
36
|
+
setValue(
|
|
37
|
+
newValue.map( ( option ) =>
|
|
38
|
+
stringPropTypeUtil.create( typeof option === 'string' ? option : option.value )
|
|
39
|
+
)
|
|
40
|
+
);
|
|
36
41
|
};
|
|
37
42
|
|
|
38
43
|
return (
|
|
@@ -40,17 +45,19 @@ export const ChipsControl = createControl( ( { options }: ChipsControlProps ) =>
|
|
|
40
45
|
<Autocomplete
|
|
41
46
|
fullWidth
|
|
42
47
|
multiple
|
|
48
|
+
freeSolo={ freeChips }
|
|
43
49
|
size={ SIZE }
|
|
44
50
|
disabled={ disabled }
|
|
45
51
|
value={ selectedOptions }
|
|
52
|
+
filterSelectedOptions
|
|
46
53
|
onChange={ handleChange }
|
|
47
54
|
options={ options }
|
|
48
|
-
getOptionLabel={ ( option ) => option.label }
|
|
55
|
+
getOptionLabel={ ( option ) => ( typeof option === 'string' ? option : option.label ) }
|
|
49
56
|
isOptionEqualToValue={ ( option, val ) => option.value === val.value }
|
|
50
57
|
renderInput={ ( params ) => <TextField { ...params } /> }
|
|
51
58
|
renderTags={ ( tagValues, getTagProps ) => (
|
|
52
59
|
<ChipsList
|
|
53
|
-
getLabel={ ( option ) => option.label }
|
|
60
|
+
getLabel={ ( option ) => ( typeof option === 'string' ? option : option.label ) }
|
|
54
61
|
getTagProps={ getTagProps }
|
|
55
62
|
values={ tagValues }
|
|
56
63
|
/>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type KeyboardEvent, type SyntheticEvent, useState } from 'react';
|
|
3
|
+
import { stringArrayPropTypeUtil, stringPropTypeUtil } from '@elementor/editor-props';
|
|
4
|
+
import { Autocomplete, Grid, TextField } from '@elementor/ui';
|
|
5
|
+
|
|
6
|
+
import { useBoundProp } from '../../bound-prop-context';
|
|
7
|
+
import { ChipsList } from '../../components/chips-list';
|
|
8
|
+
import { ControlFormLabel } from '../../components/control-form-label';
|
|
9
|
+
import { CHIP_TRIGGER_KEYS, isValidEmail } from './utils';
|
|
10
|
+
|
|
11
|
+
// type EmailChip = { label: string; value: string };
|
|
12
|
+
|
|
13
|
+
type EmailChipsFieldProps = {
|
|
14
|
+
fieldLabel: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const EmailChipsField = ( { fieldLabel, placeholder }: EmailChipsFieldProps ) => {
|
|
19
|
+
const { value, setValue, disabled } = useBoundProp( stringArrayPropTypeUtil );
|
|
20
|
+
const [ inputValue, setInputValue ] = useState( '' );
|
|
21
|
+
|
|
22
|
+
const items = value || [];
|
|
23
|
+
|
|
24
|
+
const selectedValues: string[] = items
|
|
25
|
+
.map( ( item ) => stringPropTypeUtil.extract( item ) )
|
|
26
|
+
.filter( ( val ): val is string => val !== null );
|
|
27
|
+
|
|
28
|
+
const tryAddChip = ( raw: string ) => {
|
|
29
|
+
const address = raw.trim();
|
|
30
|
+
|
|
31
|
+
if ( ! address || selectedValues.includes( address ) || ! isValidEmail( address ) ) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setValue( [ ...items, stringPropTypeUtil.create( address ) ] );
|
|
36
|
+
setInputValue( '' );
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const handleChange = ( _: SyntheticEvent, newValue: string[] ) => {
|
|
40
|
+
const updated = [];
|
|
41
|
+
|
|
42
|
+
for ( const entry of newValue ) {
|
|
43
|
+
const address = entry.trim();
|
|
44
|
+
|
|
45
|
+
if ( ! address || ! isValidEmail( address ) ) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
updated.push( stringPropTypeUtil.create( address ) );
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
setValue( updated );
|
|
53
|
+
setInputValue( '' );
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const handleBlur = ( event: SyntheticEvent ) => {
|
|
57
|
+
const target = event.target as HTMLInputElement;
|
|
58
|
+
|
|
59
|
+
tryAddChip( target.value );
|
|
60
|
+
setInputValue( '' );
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const handleKeyDown = ( event: KeyboardEvent< HTMLDivElement > ) => {
|
|
64
|
+
if ( CHIP_TRIGGER_KEYS.has( event.key ) && inputValue.trim() ) {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
tryAddChip( inputValue );
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<Grid container direction="column" gap={ 0.5 }>
|
|
72
|
+
<Grid item>
|
|
73
|
+
<ControlFormLabel>{ fieldLabel }</ControlFormLabel>
|
|
74
|
+
</Grid>
|
|
75
|
+
<Grid item>
|
|
76
|
+
<Autocomplete
|
|
77
|
+
fullWidth
|
|
78
|
+
multiple
|
|
79
|
+
freeSolo
|
|
80
|
+
size="tiny"
|
|
81
|
+
disabled={ disabled }
|
|
82
|
+
inputValue={ inputValue }
|
|
83
|
+
onInputChange={ ( _, val, reason ) => {
|
|
84
|
+
if ( reason !== 'reset' ) {
|
|
85
|
+
setInputValue( val );
|
|
86
|
+
}
|
|
87
|
+
} }
|
|
88
|
+
value={ selectedValues }
|
|
89
|
+
onChange={ handleChange }
|
|
90
|
+
options={ [] }
|
|
91
|
+
onBlur={ handleBlur }
|
|
92
|
+
getOptionLabel={ ( option ) => option }
|
|
93
|
+
isOptionEqualToValue={ ( option, val ) => option === val }
|
|
94
|
+
renderInput={ ( params ) => (
|
|
95
|
+
<TextField { ...params } placeholder={ placeholder } onKeyDown={ handleKeyDown } />
|
|
96
|
+
) }
|
|
97
|
+
renderTags={ ( tagValues, getTagProps ) => (
|
|
98
|
+
<ChipsList getLabel={ ( option ) => option } getTagProps={ getTagProps } values={ tagValues } />
|
|
99
|
+
) }
|
|
100
|
+
/>
|
|
101
|
+
</Grid>
|
|
102
|
+
</Grid>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Grid } from '@elementor/ui';
|
|
3
|
+
|
|
4
|
+
import { PropKeyProvider } from '../../bound-prop-context';
|
|
5
|
+
import { ControlFormLabel } from '../../components/control-form-label';
|
|
6
|
+
import { TextControl } from '../text-control';
|
|
7
|
+
|
|
8
|
+
type EmailFieldProps = {
|
|
9
|
+
bind: string;
|
|
10
|
+
label: string;
|
|
11
|
+
placeholder?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const EmailField = ( { bind, label, placeholder }: EmailFieldProps ) => (
|
|
15
|
+
<PropKeyProvider bind={ bind }>
|
|
16
|
+
<Grid container direction="column" gap={ 0.5 }>
|
|
17
|
+
<Grid item>
|
|
18
|
+
<ControlFormLabel>{ label }</ControlFormLabel>
|
|
19
|
+
</Grid>
|
|
20
|
+
<Grid item>
|
|
21
|
+
<TextControl placeholder={ placeholder } />
|
|
22
|
+
</Grid>
|
|
23
|
+
</Grid>
|
|
24
|
+
</PropKeyProvider>
|
|
25
|
+
);
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { InfoAlert } from '@elementor/editor-ui';
|
|
3
|
+
import { Grid, Stack } from '@elementor/ui';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
|
|
6
|
+
import { PropKeyProvider } from '../../bound-prop-context';
|
|
7
|
+
import { ControlFormLabel } from '../../components/control-form-label';
|
|
8
|
+
import { useFormFieldSuggestions } from '../../hooks/use-form-field-suggestions';
|
|
9
|
+
import { ChipsControl } from '../chips-control';
|
|
10
|
+
import { MentionTextAreaControl } from '../mention-text-area-control';
|
|
11
|
+
import { SelectControl } from '../select-control';
|
|
12
|
+
import { EmailChipsField } from './email-chips-field';
|
|
13
|
+
import { EmailField } from './email-field';
|
|
14
|
+
import { shouldShowMentionsInfo } from './utils';
|
|
15
|
+
|
|
16
|
+
export const SendToField = ( { placeholder }: { placeholder?: string } ) => (
|
|
17
|
+
<EmailChipsField fieldLabel={ __( 'Send to', 'elementor' ) } placeholder={ placeholder } />
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const SubjectField = () => (
|
|
21
|
+
<EmailField
|
|
22
|
+
bind="subject"
|
|
23
|
+
label={ __( 'Email subject', 'elementor' ) }
|
|
24
|
+
placeholder={ __( 'New form submission', 'elementor' ) }
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export const MessageField = () => {
|
|
29
|
+
const suggestions = useFormFieldSuggestions();
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<PropKeyProvider bind="message">
|
|
33
|
+
<Grid container direction="column" gap={ 0.5 }>
|
|
34
|
+
<Grid item>
|
|
35
|
+
<ControlFormLabel>{ __( 'Message', 'elementor' ) }</ControlFormLabel>
|
|
36
|
+
</Grid>
|
|
37
|
+
<Grid item>
|
|
38
|
+
<MentionTextAreaControl suggestions={ suggestions } />
|
|
39
|
+
</Grid>
|
|
40
|
+
<Grid item>
|
|
41
|
+
<InfoAlert>
|
|
42
|
+
{ shouldShowMentionsInfo()
|
|
43
|
+
? __(
|
|
44
|
+
'[all-fields] shortcode sends all fields. Type @ to insert specific fields and customize your message.',
|
|
45
|
+
'elementor'
|
|
46
|
+
)
|
|
47
|
+
: __( '[all-fields] shortcode sends all fields.', 'elementor' ) }
|
|
48
|
+
</InfoAlert>
|
|
49
|
+
</Grid>
|
|
50
|
+
</Grid>
|
|
51
|
+
</PropKeyProvider>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const FromEmailField = () => (
|
|
56
|
+
<EmailField
|
|
57
|
+
bind="from"
|
|
58
|
+
label={ __( 'From email', 'elementor' ) }
|
|
59
|
+
placeholder={ __( 'What email should appear as the sender?', 'elementor' ) }
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export const FromNameField = () => (
|
|
64
|
+
<EmailField
|
|
65
|
+
bind="from-name"
|
|
66
|
+
label={ __( 'From name', 'elementor' ) }
|
|
67
|
+
placeholder={ __( 'What name should appear as the sender?', 'elementor' ) }
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
export const ReplyToField = () => {
|
|
72
|
+
const emailSuggestions = useFormFieldSuggestions( { inputType: 'email' } );
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<PropKeyProvider bind="reply-to">
|
|
76
|
+
<Grid container direction="column" gap={ 0.5 }>
|
|
77
|
+
<Grid item>
|
|
78
|
+
<ControlFormLabel>{ __( 'Reply-to', 'elementor' ) }</ControlFormLabel>
|
|
79
|
+
</Grid>
|
|
80
|
+
<Grid item>
|
|
81
|
+
<MentionTextAreaControl
|
|
82
|
+
suggestions={ emailSuggestions }
|
|
83
|
+
rows={ 1 }
|
|
84
|
+
triggerPosition="start"
|
|
85
|
+
placeholder={ __( 'You can type @ to insert an email field', 'elementor' ) }
|
|
86
|
+
/>
|
|
87
|
+
</Grid>
|
|
88
|
+
</Grid>
|
|
89
|
+
</PropKeyProvider>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const CcField = () => (
|
|
94
|
+
<PropKeyProvider bind="cc">
|
|
95
|
+
<EmailChipsField fieldLabel={ __( 'Cc', 'elementor' ) } />
|
|
96
|
+
</PropKeyProvider>
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
export const BccField = () => (
|
|
100
|
+
<PropKeyProvider bind="bcc">
|
|
101
|
+
<EmailChipsField fieldLabel={ __( 'Bcc', 'elementor' ) } />
|
|
102
|
+
</PropKeyProvider>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
export const MetaDataField = () => (
|
|
106
|
+
<PropKeyProvider bind="meta-data">
|
|
107
|
+
<Stack gap={ 0.5 }>
|
|
108
|
+
<ControlFormLabel>{ __( 'Metadata', 'elementor' ) }</ControlFormLabel>
|
|
109
|
+
<ChipsControl
|
|
110
|
+
options={ [
|
|
111
|
+
{ label: __( 'Date', 'elementor' ), value: 'date' },
|
|
112
|
+
{ label: __( 'Time', 'elementor' ), value: 'time' },
|
|
113
|
+
{ label: __( 'Page URL', 'elementor' ), value: 'page-url' },
|
|
114
|
+
{ label: __( 'User agent', 'elementor' ), value: 'user-agent' },
|
|
115
|
+
{ label: __( 'Credit', 'elementor' ), value: 'credit' },
|
|
116
|
+
] }
|
|
117
|
+
/>
|
|
118
|
+
</Stack>
|
|
119
|
+
</PropKeyProvider>
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
export const SendAsField = () => (
|
|
123
|
+
<PropKeyProvider bind="send-as">
|
|
124
|
+
<Grid container direction="column" gap={ 0.5 }>
|
|
125
|
+
<Grid item>
|
|
126
|
+
<ControlFormLabel>{ __( 'Send as', 'elementor' ) }</ControlFormLabel>
|
|
127
|
+
</Grid>
|
|
128
|
+
<Grid item>
|
|
129
|
+
<SelectControl
|
|
130
|
+
options={ [
|
|
131
|
+
{ label: __( 'HTML', 'elementor' ), value: 'html' },
|
|
132
|
+
{ label: __( 'Plain Text', 'elementor' ), value: 'plain' },
|
|
133
|
+
] }
|
|
134
|
+
/>
|
|
135
|
+
</Grid>
|
|
136
|
+
</Grid>
|
|
137
|
+
</PropKeyProvider>
|
|
138
|
+
);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { emailsPropTypeUtil } from '@elementor/editor-props';
|
|
3
|
+
import { CollapsibleContent } from '@elementor/editor-ui';
|
|
4
|
+
import { Box, Divider, Stack } from '@elementor/ui';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
|
|
7
|
+
import { PropKeyProvider, PropProvider, useBoundProp } from '../../bound-prop-context';
|
|
8
|
+
import { ControlLabel } from '../../components/control-label';
|
|
9
|
+
import { createControl } from '../../create-control';
|
|
10
|
+
import {
|
|
11
|
+
BccField,
|
|
12
|
+
CcField,
|
|
13
|
+
FromEmailField,
|
|
14
|
+
FromNameField,
|
|
15
|
+
MessageField,
|
|
16
|
+
MetaDataField,
|
|
17
|
+
ReplyToField,
|
|
18
|
+
SendAsField,
|
|
19
|
+
SendToField,
|
|
20
|
+
SubjectField,
|
|
21
|
+
} from './fields';
|
|
22
|
+
|
|
23
|
+
export const EmailFormActionControl = createControl(
|
|
24
|
+
( { toPlaceholder, label }: { toPlaceholder?: string; label?: string } ) => {
|
|
25
|
+
const { value, setValue, ...propContext } = useBoundProp( emailsPropTypeUtil );
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<PropProvider { ...propContext } value={ value } setValue={ setValue }>
|
|
29
|
+
<Stack gap={ 2 }>
|
|
30
|
+
<ControlLabel>
|
|
31
|
+
{ label ? label + ' ' + __( 'settings', 'elementor' ) : __( 'Email settings', 'elementor' ) }
|
|
32
|
+
</ControlLabel>
|
|
33
|
+
<PropKeyProvider bind="to">
|
|
34
|
+
<SendToField placeholder={ toPlaceholder } />
|
|
35
|
+
</PropKeyProvider>
|
|
36
|
+
<SubjectField />
|
|
37
|
+
<MessageField />
|
|
38
|
+
<FromEmailField />
|
|
39
|
+
<AdvancedSettings />
|
|
40
|
+
</Stack>
|
|
41
|
+
</PropProvider>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const AdvancedSettings = () => (
|
|
47
|
+
<CollapsibleContent defaultOpen={ false }>
|
|
48
|
+
<Box sx={ { pt: 2 } }>
|
|
49
|
+
<Stack gap={ 2 }>
|
|
50
|
+
<FromNameField />
|
|
51
|
+
<ReplyToField />
|
|
52
|
+
<CcField />
|
|
53
|
+
<BccField />
|
|
54
|
+
<Divider />
|
|
55
|
+
<MetaDataField />
|
|
56
|
+
<SendAsField />
|
|
57
|
+
</Stack>
|
|
58
|
+
</Box>
|
|
59
|
+
</CollapsibleContent>
|
|
60
|
+
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from '@elementor/schema';
|
|
2
|
+
import { hasProInstalled, isVersionGreaterOrEqual } from '@elementor/utils';
|
|
3
|
+
|
|
4
|
+
const MIN_PRO_VERSION_FOR_MENTIONS = '4.1.0';
|
|
5
|
+
|
|
6
|
+
export const CHIP_TRIGGER_KEYS = new Set( [ ' ', ',' ] );
|
|
7
|
+
|
|
8
|
+
export function isValidEmail( email: string ): boolean {
|
|
9
|
+
return z.string().email().safeParse( email ).success;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const shouldShowMentionsInfo = (): boolean => {
|
|
13
|
+
if ( ! hasProInstalled() ) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const proVersion = window.elementorPro?.config?.version;
|
|
18
|
+
|
|
19
|
+
if ( ! proVersion ) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return isVersionGreaterOrEqual( proVersion, MIN_PRO_VERSION_FOR_MENTIONS );
|
|
24
|
+
};
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { emailPropTypeUtil } from '@elementor/editor-props';
|
|
3
|
-
import { CollapsibleContent, InfoAlert } from '@elementor/editor-ui';
|
|
4
|
-
import { Box, Divider, Grid, Stack } from '@elementor/ui';
|
|
5
|
-
import { hasProInstalled, isVersionGreaterOrEqual } from '@elementor/utils';
|
|
6
|
-
import { __ } from '@wordpress/i18n';
|
|
7
|
-
|
|
8
|
-
import { PropKeyProvider, PropProvider, useBoundProp } from '../bound-prop-context';
|
|
9
|
-
import { ControlFormLabel } from '../components/control-form-label';
|
|
10
|
-
import { ControlLabel } from '../components/control-label';
|
|
11
|
-
import { createControl } from '../create-control';
|
|
12
|
-
import { useFormFieldSuggestions } from '../hooks/use-form-field-suggestions';
|
|
13
|
-
import { ChipsControl } from './chips-control';
|
|
14
|
-
import { MentionTextAreaControl } from './mention-text-area-control';
|
|
15
|
-
import { SelectControl } from './select-control';
|
|
16
|
-
import { TextControl } from './text-control';
|
|
17
|
-
|
|
18
|
-
const EmailField = ( { bind, label, placeholder }: { bind: string; label: string; placeholder?: string } ) => (
|
|
19
|
-
<PropKeyProvider bind={ bind }>
|
|
20
|
-
<Grid container direction="column" gap={ 0.5 }>
|
|
21
|
-
<Grid item>
|
|
22
|
-
<ControlFormLabel>{ label }</ControlFormLabel>
|
|
23
|
-
</Grid>
|
|
24
|
-
<Grid item>
|
|
25
|
-
<TextControl placeholder={ placeholder } />
|
|
26
|
-
</Grid>
|
|
27
|
-
</Grid>
|
|
28
|
-
</PropKeyProvider>
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
const SendToField = ( { placeholder }: { placeholder?: string } ) => (
|
|
32
|
-
<EmailField bind="to" label={ __( 'Send to', 'elementor' ) } placeholder={ placeholder } />
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
const SubjectField = () => (
|
|
36
|
-
<EmailField
|
|
37
|
-
bind="subject"
|
|
38
|
-
label={ __( 'Email subject', 'elementor' ) }
|
|
39
|
-
placeholder={ __( 'New form submission', 'elementor' ) }
|
|
40
|
-
/>
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
const MIN_PRO_VERSION_FOR_MENTIONS = '4.1.0';
|
|
44
|
-
|
|
45
|
-
const shouldShowMentionsInfo = (): boolean => {
|
|
46
|
-
if ( ! hasProInstalled() ) {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const proVersion = window.elementorPro?.config?.version;
|
|
51
|
-
|
|
52
|
-
if ( ! proVersion ) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return isVersionGreaterOrEqual( proVersion, MIN_PRO_VERSION_FOR_MENTIONS );
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const MessageField = () => {
|
|
60
|
-
const suggestions = useFormFieldSuggestions();
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<PropKeyProvider bind="message">
|
|
64
|
-
<Grid container direction="column" gap={ 0.5 }>
|
|
65
|
-
<Grid item>
|
|
66
|
-
<ControlFormLabel>{ __( 'Message', 'elementor' ) }</ControlFormLabel>
|
|
67
|
-
</Grid>
|
|
68
|
-
<Grid item>
|
|
69
|
-
<MentionTextAreaControl suggestions={ suggestions } />
|
|
70
|
-
</Grid>
|
|
71
|
-
<Grid item>
|
|
72
|
-
<InfoAlert>
|
|
73
|
-
{ shouldShowMentionsInfo()
|
|
74
|
-
? __(
|
|
75
|
-
'[all-fields] shortcode sends all fields. Type @ to insert specific fields and customize your message.',
|
|
76
|
-
'elementor'
|
|
77
|
-
)
|
|
78
|
-
: __( '[all-fields] shortcode sends all fields.', 'elementor' ) }
|
|
79
|
-
</InfoAlert>
|
|
80
|
-
</Grid>
|
|
81
|
-
</Grid>
|
|
82
|
-
</PropKeyProvider>
|
|
83
|
-
);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const FromEmailField = () => (
|
|
87
|
-
<EmailField
|
|
88
|
-
bind="from"
|
|
89
|
-
label={ __( 'From email', 'elementor' ) }
|
|
90
|
-
placeholder={ __( 'What email should appear as the sender?', 'elementor' ) }
|
|
91
|
-
/>
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const FromNameField = () => (
|
|
95
|
-
<EmailField
|
|
96
|
-
bind="from-name"
|
|
97
|
-
label={ __( 'From name', 'elementor' ) }
|
|
98
|
-
placeholder={ __( 'What name should appear as the sender?', 'elementor' ) }
|
|
99
|
-
/>
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
const ReplyToField = () => {
|
|
103
|
-
const emailSuggestions = useFormFieldSuggestions( { inputType: 'email' } );
|
|
104
|
-
|
|
105
|
-
return (
|
|
106
|
-
<PropKeyProvider bind="reply-to">
|
|
107
|
-
<Grid container direction="column" gap={ 0.5 }>
|
|
108
|
-
<Grid item>
|
|
109
|
-
<ControlFormLabel>{ __( 'Reply-to', 'elementor' ) }</ControlFormLabel>
|
|
110
|
-
</Grid>
|
|
111
|
-
<Grid item>
|
|
112
|
-
<MentionTextAreaControl
|
|
113
|
-
suggestions={ emailSuggestions }
|
|
114
|
-
rows={ 1 }
|
|
115
|
-
triggerPosition="start"
|
|
116
|
-
placeholder={ __( 'You can type @ to insert an email field', 'elementor' ) }
|
|
117
|
-
/>
|
|
118
|
-
</Grid>
|
|
119
|
-
</Grid>
|
|
120
|
-
</PropKeyProvider>
|
|
121
|
-
);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
const CcField = () => <EmailField bind="cc" label={ __( 'Cc', 'elementor' ) } />;
|
|
125
|
-
|
|
126
|
-
const BccField = () => <EmailField bind="bcc" label={ __( 'Bcc', 'elementor' ) } />;
|
|
127
|
-
|
|
128
|
-
const MetaDataField = () => (
|
|
129
|
-
<PropKeyProvider bind="meta-data">
|
|
130
|
-
<Stack gap={ 0.5 }>
|
|
131
|
-
<ControlFormLabel>{ __( 'Metadata', 'elementor' ) }</ControlFormLabel>
|
|
132
|
-
<ChipsControl
|
|
133
|
-
options={ [
|
|
134
|
-
{ label: __( 'Date', 'elementor' ), value: 'date' },
|
|
135
|
-
{ label: __( 'Time', 'elementor' ), value: 'time' },
|
|
136
|
-
{ label: __( 'Page URL', 'elementor' ), value: 'page-url' },
|
|
137
|
-
{ label: __( 'User agent', 'elementor' ), value: 'user-agent' },
|
|
138
|
-
{ label: __( 'Credit', 'elementor' ), value: 'credit' },
|
|
139
|
-
] }
|
|
140
|
-
/>
|
|
141
|
-
</Stack>
|
|
142
|
-
</PropKeyProvider>
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
const SendAsField = () => (
|
|
146
|
-
<PropKeyProvider bind="send-as">
|
|
147
|
-
<Grid container direction="column" gap={ 0.5 }>
|
|
148
|
-
<Grid item>
|
|
149
|
-
<ControlFormLabel>{ __( 'Send as', 'elementor' ) }</ControlFormLabel>
|
|
150
|
-
</Grid>
|
|
151
|
-
<Grid item>
|
|
152
|
-
<SelectControl
|
|
153
|
-
options={ [
|
|
154
|
-
{ label: __( 'HTML', 'elementor' ), value: 'html' },
|
|
155
|
-
{ label: __( 'Plain Text', 'elementor' ), value: 'plain' },
|
|
156
|
-
] }
|
|
157
|
-
/>
|
|
158
|
-
</Grid>
|
|
159
|
-
</Grid>
|
|
160
|
-
</PropKeyProvider>
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
const AdvancedSettings = () => (
|
|
164
|
-
<CollapsibleContent defaultOpen={ false }>
|
|
165
|
-
<Box sx={ { pt: 2 } }>
|
|
166
|
-
<Stack gap={ 2 }>
|
|
167
|
-
<FromNameField />
|
|
168
|
-
<ReplyToField />
|
|
169
|
-
<CcField />
|
|
170
|
-
<BccField />
|
|
171
|
-
<Divider />
|
|
172
|
-
<MetaDataField />
|
|
173
|
-
<SendAsField />
|
|
174
|
-
</Stack>
|
|
175
|
-
</Box>
|
|
176
|
-
</CollapsibleContent>
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
export const EmailFormActionControl = createControl( ( { toPlaceholder }: { toPlaceholder?: string } ) => {
|
|
180
|
-
const { value, setValue, ...propContext } = useBoundProp( emailPropTypeUtil );
|
|
181
|
-
|
|
182
|
-
return (
|
|
183
|
-
<PropProvider { ...propContext } value={ value } setValue={ setValue }>
|
|
184
|
-
<Stack gap={ 2 }>
|
|
185
|
-
<ControlLabel>{ __( 'Email settings', 'elementor' ) }</ControlLabel>
|
|
186
|
-
<SendToField placeholder={ toPlaceholder } />
|
|
187
|
-
<SubjectField />
|
|
188
|
-
<MessageField />
|
|
189
|
-
<FromEmailField />
|
|
190
|
-
<AdvancedSettings />
|
|
191
|
-
</Stack>
|
|
192
|
-
</PropProvider>
|
|
193
|
-
);
|
|
194
|
-
} );
|