@elementor/editor-controls 4.1.0-797 → 4.1.0-798
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 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +43 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +43 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/controls/email-form-action-control.tsx +21 -1
- package/src/controls/mention-text-area-control.tsx +32 -11
- package/src/hooks/use-form-field-suggestions.ts +14 -1
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.1.0-
|
|
4
|
+
"version": "4.1.0-798",
|
|
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.1.0-
|
|
44
|
-
"@elementor/editor-elements": "4.1.0-
|
|
45
|
-
"@elementor/editor-props": "4.1.0-
|
|
46
|
-
"@elementor/editor-responsive": "4.1.0-
|
|
47
|
-
"@elementor/editor-ui": "4.1.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "4.1.0-
|
|
49
|
-
"@elementor/env": "4.1.0-
|
|
50
|
-
"@elementor/events": "4.1.0-
|
|
51
|
-
"@elementor/http-client": "4.1.0-
|
|
43
|
+
"@elementor/editor-current-user": "4.1.0-798",
|
|
44
|
+
"@elementor/editor-elements": "4.1.0-798",
|
|
45
|
+
"@elementor/editor-props": "4.1.0-798",
|
|
46
|
+
"@elementor/editor-responsive": "4.1.0-798",
|
|
47
|
+
"@elementor/editor-ui": "4.1.0-798",
|
|
48
|
+
"@elementor/editor-v1-adapters": "4.1.0-798",
|
|
49
|
+
"@elementor/env": "4.1.0-798",
|
|
50
|
+
"@elementor/events": "4.1.0-798",
|
|
51
|
+
"@elementor/http-client": "4.1.0-798",
|
|
52
52
|
"@elementor/icons": "^1.68.0",
|
|
53
|
-
"@elementor/locations": "4.1.0-
|
|
54
|
-
"@elementor/query": "4.1.0-
|
|
55
|
-
"@elementor/session": "4.1.0-
|
|
53
|
+
"@elementor/locations": "4.1.0-798",
|
|
54
|
+
"@elementor/query": "4.1.0-798",
|
|
55
|
+
"@elementor/session": "4.1.0-798",
|
|
56
56
|
"@elementor/ui": "1.37.5",
|
|
57
|
-
"@elementor/utils": "4.1.0-
|
|
58
|
-
"@elementor/wp-media": "4.1.0-
|
|
57
|
+
"@elementor/utils": "4.1.0-798",
|
|
58
|
+
"@elementor/wp-media": "4.1.0-798",
|
|
59
59
|
"@monaco-editor/react": "^4.7.0",
|
|
60
60
|
"@tiptap/extension-bold": "^3.11.1",
|
|
61
61
|
"@tiptap/extension-document": "^3.11.1",
|
|
@@ -99,7 +99,27 @@ const FromNameField = () => (
|
|
|
99
99
|
/>
|
|
100
100
|
);
|
|
101
101
|
|
|
102
|
-
const ReplyToField = () =>
|
|
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
|
+
};
|
|
103
123
|
|
|
104
124
|
const CcField = () => <EmailField bind="cc" label={ __( 'Cc', 'elementor' ) } />;
|
|
105
125
|
|
|
@@ -76,16 +76,30 @@ const MentionWrapper = styled( 'div' )( ( { theme } ) => ( {
|
|
|
76
76
|
backgroundColor: theme.palette.action.selected,
|
|
77
77
|
},
|
|
78
78
|
},
|
|
79
|
+
'&[data-single-line="true"] textarea': {
|
|
80
|
+
resize: 'none',
|
|
81
|
+
},
|
|
79
82
|
} ) );
|
|
80
83
|
|
|
84
|
+
type TriggerPosition = 'start' | 'auto';
|
|
85
|
+
|
|
86
|
+
function createMentionPattern( value: string, triggerPosition: TriggerPosition ): RegExp {
|
|
87
|
+
const escaped = value.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' );
|
|
88
|
+
const prefix = 'start' === triggerPosition ? '^' : '';
|
|
89
|
+
|
|
90
|
+
return new RegExp( `${ prefix }@${ escaped }(?=\\s|$|[^a-zA-Z0-9_-])`, 'g' );
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
type Props = {
|
|
82
94
|
placeholder?: string;
|
|
83
95
|
ariaLabel?: string;
|
|
84
96
|
suggestions: Suggestion[];
|
|
97
|
+
rows?: number;
|
|
98
|
+
triggerPosition?: TriggerPosition;
|
|
85
99
|
};
|
|
86
100
|
|
|
87
101
|
export const MentionTextAreaControl = createControl(
|
|
88
|
-
( { placeholder, ariaLabel, suggestions: allSuggestions }: Props ) => {
|
|
102
|
+
( { placeholder, ariaLabel, suggestions: allSuggestions, rows = 5, triggerPosition = 'auto' }: Props ) => {
|
|
89
103
|
const { value, setValue, disabled } = useBoundProp( stringPropTypeUtil );
|
|
90
104
|
const [ filteredSuggestions, setFilteredSuggestions ] = useState< Suggestion[] >( [] );
|
|
91
105
|
|
|
@@ -94,16 +108,13 @@ export const MentionTextAreaControl = createControl(
|
|
|
94
108
|
let result = text;
|
|
95
109
|
|
|
96
110
|
for ( const suggestion of allSuggestions ) {
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
'g'
|
|
100
|
-
);
|
|
101
|
-
result = result.replace( mentionPattern, `[${ suggestion.value }]` );
|
|
111
|
+
const pattern = createMentionPattern( suggestion.value, triggerPosition );
|
|
112
|
+
result = result.replace( pattern, `[${ suggestion.value }]` );
|
|
102
113
|
}
|
|
103
114
|
|
|
104
115
|
return result;
|
|
105
116
|
},
|
|
106
|
-
[ allSuggestions ]
|
|
117
|
+
[ allSuggestions, triggerPosition ]
|
|
107
118
|
);
|
|
108
119
|
|
|
109
120
|
const handleChange = useCallback(
|
|
@@ -116,19 +127,29 @@ export const MentionTextAreaControl = createControl(
|
|
|
116
127
|
);
|
|
117
128
|
|
|
118
129
|
const handleSearch = useCallback(
|
|
119
|
-
( event: { query: string } ) => {
|
|
130
|
+
( event: { originalEvent: React.SyntheticEvent; trigger: string; query: string } ) => {
|
|
131
|
+
if ( 'start' === triggerPosition ) {
|
|
132
|
+
const target = event.originalEvent.target as HTMLTextAreaElement;
|
|
133
|
+
const triggerIndex = target.selectionStart - event.query.length - event.trigger.length;
|
|
134
|
+
|
|
135
|
+
if ( triggerIndex !== 0 ) {
|
|
136
|
+
setFilteredSuggestions( [] );
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
120
141
|
const query = event.query.toLowerCase();
|
|
121
142
|
const filtered = allSuggestions.filter(
|
|
122
143
|
( item ) => item.label.toLowerCase().includes( query ) || item.value.toLowerCase().includes( query )
|
|
123
144
|
);
|
|
124
145
|
setFilteredSuggestions( filtered );
|
|
125
146
|
},
|
|
126
|
-
[ allSuggestions ]
|
|
147
|
+
[ allSuggestions, triggerPosition ]
|
|
127
148
|
);
|
|
128
149
|
|
|
129
150
|
return (
|
|
130
151
|
<ControlActions>
|
|
131
|
-
<MentionWrapper>
|
|
152
|
+
<MentionWrapper data-single-line={ rows === 1 ? 'true' : undefined }>
|
|
132
153
|
<Mention
|
|
133
154
|
value={ value ?? '' }
|
|
134
155
|
onChange={ handleChange }
|
|
@@ -136,7 +157,7 @@ export const MentionTextAreaControl = createControl(
|
|
|
136
157
|
onSearch={ handleSearch }
|
|
137
158
|
field="value"
|
|
138
159
|
trigger="@"
|
|
139
|
-
rows={
|
|
160
|
+
rows={ rows }
|
|
140
161
|
disabled={ disabled }
|
|
141
162
|
placeholder={ placeholder }
|
|
142
163
|
itemTemplate={ SuggestionItem }
|
|
@@ -9,7 +9,11 @@ export type Suggestion = {
|
|
|
9
9
|
|
|
10
10
|
const FORM_FIELD_WIDGET_TYPES = [ 'e-form-input', 'e-form-textarea', 'e-form-checkbox' ];
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
type Options = {
|
|
13
|
+
inputType?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function useFormFieldSuggestions( options?: Options ): Suggestion[] {
|
|
13
17
|
return useListenTo(
|
|
14
18
|
[
|
|
15
19
|
v1ReadyEvent(),
|
|
@@ -40,6 +44,15 @@ export function useFormFieldSuggestions(): Suggestion[] {
|
|
|
40
44
|
return;
|
|
41
45
|
}
|
|
42
46
|
|
|
47
|
+
if ( options?.inputType ) {
|
|
48
|
+
const typeProp = child.settings.get( 'type' );
|
|
49
|
+
const typeValue = isTransformable( typeProp ) ? typeProp.value : typeProp;
|
|
50
|
+
|
|
51
|
+
if ( typeValue !== options.inputType ) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
const cssIdProp = child.settings.get( '_cssid' );
|
|
44
57
|
const fieldId = isTransformable( cssIdProp ) ? cssIdProp.value : cssIdProp;
|
|
45
58
|
|