@antscorp/antsomi-ui 1.3.5-beta.840 → 1.3.5-beta.841
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/es/components/molecules/AddDynamicContent/components/DisplayFormat/DisplayFormat.d.ts +0 -1
- package/es/components/molecules/TagifyInput/TagifyInput.js +172 -172
- package/es/components/molecules/TagifyInput/constants.d.ts +7 -1
- package/es/components/molecules/TagifyInput/constants.js +7 -1
- package/es/components/molecules/TagifyInput/utils.js +5 -1
- package/es/components/template/TemplateListing/Loadable.d.ts +0 -1
- package/es/locales/ja/google-sheet.json +21 -21
- package/package.json +1 -1
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// Libraries
|
|
3
|
-
import { useRef, useEffect, useCallback, useMemo, memo, forwardRef, useImperativeHandle, useLayoutEffect, } from 'react';
|
|
3
|
+
import { useRef, useEffect, useCallback, useMemo, memo, forwardRef, useImperativeHandle, useLayoutEffect, useState, } from 'react';
|
|
4
4
|
import _ from 'lodash';
|
|
5
5
|
import htmlEntities from 'he';
|
|
6
6
|
// Assets
|
|
7
7
|
import iconWarning from '@antscorp/antsomi-ui/es/assets/images/warning-icon.png';
|
|
8
8
|
// Hooks
|
|
9
9
|
import { useDeepCompareMemo } from '@antscorp/antsomi-ui/es/hooks/useDeepCompareMemo';
|
|
10
|
-
import { useDebounce } from '@antscorp/antsomi-ui/es/hooks/useDebounce';
|
|
11
|
-
import { useUpdateEffect } from '@antscorp/antsomi-ui/es/hooks/useUpdateEffect';
|
|
12
10
|
import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks/useDeepCompareEffect';
|
|
13
11
|
// Components
|
|
14
12
|
import Tagify from '@yaireo/tagify';
|
|
@@ -25,8 +23,7 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
25
23
|
// Props
|
|
26
24
|
const { initialValue, escapeHTML, status, readonly, readonlyTag, disabled, maxLength, maxHeight, minWidth, placeholder, isSingleLineText, acceptableTagPattern, mapAttributes, maxPersonalizeTags, name, children, cssTagifyVariables, onTagClick, onChange, } = props;
|
|
27
25
|
// States
|
|
28
|
-
const [
|
|
29
|
-
const [isLineBreakDebounce, , setIsLineBreak] = useDebounce(hasLineBreak(initialValue), 250);
|
|
26
|
+
const [isLineBreak, setIsLineBreak] = useState(hasLineBreak(initialValue));
|
|
30
27
|
// Refs
|
|
31
28
|
const inputRef = useRef(null);
|
|
32
29
|
const tagifyRef = useRef(null);
|
|
@@ -179,6 +176,135 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
179
176
|
console.warn('Error while injecting tag at caret', error);
|
|
180
177
|
}
|
|
181
178
|
}, [onAdjustSelectionIfNeeded, onSelectionAfterInjection]);
|
|
179
|
+
/**
|
|
180
|
+
* Updates the window selection to highlight a specified range of text within a given node.
|
|
181
|
+
* */
|
|
182
|
+
const updateWindowSelection = useCallback((node, start, end) => {
|
|
183
|
+
if (!node || !_.isNumber(start) || !_.isNumber(end))
|
|
184
|
+
return false;
|
|
185
|
+
if (node) {
|
|
186
|
+
try {
|
|
187
|
+
const range = document.createRange();
|
|
188
|
+
const textNodeLength = node.textContent?.length;
|
|
189
|
+
if (textNodeLength && start <= textNodeLength && end <= textNodeLength) {
|
|
190
|
+
range?.setStart(node, start);
|
|
191
|
+
range?.setEnd(node, end);
|
|
192
|
+
const selection = window.getSelection();
|
|
193
|
+
selection?.removeAllRanges();
|
|
194
|
+
selection?.addRange(range);
|
|
195
|
+
return onSyncSelectionStateTagify();
|
|
196
|
+
}
|
|
197
|
+
throw new Error('Invalid start/end position');
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
// eslint-disable-next-line no-console
|
|
201
|
+
console.error(error);
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}, [onSyncSelectionStateTagify]);
|
|
207
|
+
const replaceURLsWithTags = useCallback((nodesURl, lastRange) => {
|
|
208
|
+
try {
|
|
209
|
+
if (!tagifyRef.current) {
|
|
210
|
+
throw new Error('Tagify instance is not initialized');
|
|
211
|
+
}
|
|
212
|
+
// Replace all URLs in the given nodes
|
|
213
|
+
nodesURl.forEach((textNode) => {
|
|
214
|
+
const newTags = [];
|
|
215
|
+
const textContent = textNode.textContent || '';
|
|
216
|
+
if (textContent) {
|
|
217
|
+
let match;
|
|
218
|
+
// Reset the regex's lastIndex before each execution
|
|
219
|
+
detectURLRegex.lastIndex = 0;
|
|
220
|
+
// eslint-disable-next-line no-cond-assign
|
|
221
|
+
while ((match = detectURLRegex.exec(textContent)) !== null) {
|
|
222
|
+
const url = match[0];
|
|
223
|
+
const start = match.index;
|
|
224
|
+
const end = start + url.length;
|
|
225
|
+
const newTag = {
|
|
226
|
+
url,
|
|
227
|
+
range: [start, end],
|
|
228
|
+
};
|
|
229
|
+
// add new valid URL to tags
|
|
230
|
+
newTags.push(newTag);
|
|
231
|
+
}
|
|
232
|
+
if (newTags.length > 0) {
|
|
233
|
+
// Sort tags by their position in reverse order
|
|
234
|
+
// starting from the back avoids messing up earlier parts of the document
|
|
235
|
+
newTags.sort((a, b) => b.range[0] - a.range[0]);
|
|
236
|
+
// Add tags one by one, adjusting the selection for each
|
|
237
|
+
newTags.forEach(tag => {
|
|
238
|
+
const [start, end] = tag.range;
|
|
239
|
+
if (tagifyRef.current) {
|
|
240
|
+
const isUpdated = updateWindowSelection(textNode, start, end);
|
|
241
|
+
if (isUpdated) {
|
|
242
|
+
const newTag = tagifyRef.current.createTagElem({
|
|
243
|
+
value: tag.url,
|
|
244
|
+
label: tag.url,
|
|
245
|
+
type: DETECT_LINK,
|
|
246
|
+
});
|
|
247
|
+
// Inject the new detect link tag
|
|
248
|
+
tagifyRef.current.injectAtCaret(newTag);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
const selection = window.getSelection();
|
|
256
|
+
if (selection) {
|
|
257
|
+
if (lastRange instanceof Range) {
|
|
258
|
+
// Need to restore the selection after execution all process to replace URL to Tag
|
|
259
|
+
// to maintain valid caret
|
|
260
|
+
selection.removeAllRanges();
|
|
261
|
+
selection.addRange(lastRange);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
// In case lost the selection not need to restore
|
|
265
|
+
// Reset the selection to clear and prepare the valid caret to add the next tag at fn: "onAddNewTag"
|
|
266
|
+
selection?.removeAllRanges();
|
|
267
|
+
onSyncSelectionStateTagify();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
// eslint-disable-next-line no-console
|
|
273
|
+
console.error('Error while replacing URL with tag', error);
|
|
274
|
+
}
|
|
275
|
+
}, [onSyncSelectionStateTagify, updateWindowSelection]);
|
|
276
|
+
/**
|
|
277
|
+
* Detects URLs within the text nodes of a specified input element and replaces them with tags.
|
|
278
|
+
*
|
|
279
|
+
* This function scans through all child nodes of the input element, looking for text nodes that contain URLs.
|
|
280
|
+
* When URLs are found, it creates tags for each URL and injects them into the input element, updating the selection
|
|
281
|
+
* as necessary to ensure the DOM structure remains intact.
|
|
282
|
+
* */
|
|
283
|
+
const detectReplaceURLToTag = useCallback(() => {
|
|
284
|
+
const isSupportShortlink = acceptablePatternChecking(SHORT_LINK_PTN, acceptableTagPattern);
|
|
285
|
+
if (!tagifyRef.current || !isSupportShortlink)
|
|
286
|
+
return;
|
|
287
|
+
try {
|
|
288
|
+
const { input: inputElement } = tagifyRef.current.DOM;
|
|
289
|
+
if (inputElement) {
|
|
290
|
+
const selection = window.getSelection();
|
|
291
|
+
const cacheLastRange = selection?.getRangeAt && selection?.rangeCount && selection?.getRangeAt(0);
|
|
292
|
+
const minLengthValidURL = 8; // -> Because of valid URL should be "https://"
|
|
293
|
+
// Get all child nodes that are of type TEXT_NODE and contain an URL
|
|
294
|
+
const nodesURL = findURLInTextNodes(inputElement, minLengthValidURL);
|
|
295
|
+
// Starting from the back to avoid messing up earlier parts of the DOM
|
|
296
|
+
const reversedNodes = nodesURL?.toReversed() || [];
|
|
297
|
+
// Process URL to Tag
|
|
298
|
+
if (reversedNodes && reversedNodes.length > 0) {
|
|
299
|
+
replaceURLsWithTags(reversedNodes, cacheLastRange);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
// eslint-disable-next-line no-console
|
|
305
|
+
console.log(error);
|
|
306
|
+
}
|
|
307
|
+
}, [acceptableTagPattern, replaceURLsWithTags]);
|
|
182
308
|
const placeCaretAfterNode = useCallback((node) => {
|
|
183
309
|
if (!tagifyRef.current) {
|
|
184
310
|
throw new Error('Tagify instance is not initialized');
|
|
@@ -286,35 +412,43 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
286
412
|
onTagClick(event.detail);
|
|
287
413
|
}
|
|
288
414
|
}, [onTagClick]);
|
|
415
|
+
// Used to trigger change data real time
|
|
289
416
|
const onTagifyTyping = useCallback((event) => {
|
|
290
|
-
if (event.detail) {
|
|
291
|
-
const { tagify } = event.detail;
|
|
292
|
-
const inputValue = tagify.getInputValue();
|
|
293
|
-
setInputTyping(inputValue);
|
|
294
|
-
}
|
|
295
|
-
}, [setInputTyping]);
|
|
296
|
-
const onTagifyRemoved = useCallback((event) => {
|
|
297
417
|
if (event.detail) {
|
|
298
418
|
const { tagify } = event.detail;
|
|
299
419
|
const inputValue = tagify.getInputValue();
|
|
300
420
|
const convertedValue = convertInputStringToOriginal(inputValue);
|
|
421
|
+
// Tracking if the tagify input is line break
|
|
422
|
+
setIsLineBreak(hasLineBreak(convertedValue));
|
|
423
|
+
// Update URL to tag to show hint in the tooltip with tag
|
|
424
|
+
if (convertedValue) {
|
|
425
|
+
detectReplaceURLToTag();
|
|
426
|
+
}
|
|
301
427
|
onOutputData(convertedValue);
|
|
302
428
|
}
|
|
303
|
-
}, [onOutputData]);
|
|
429
|
+
}, [onOutputData, detectReplaceURLToTag]);
|
|
304
430
|
/**
|
|
305
431
|
* Used to cover more case
|
|
306
|
-
* e.g: User select all data -> backspace -> remove all data in UI but
|
|
432
|
+
* e.g: User select all data -> backspace -> remove all data in UI but the on input event [onTagifyTyping] not trigger
|
|
307
433
|
*/
|
|
308
|
-
const
|
|
434
|
+
const onTagifyChanged = useCallback((event) => {
|
|
435
|
+
if (event.detail) {
|
|
436
|
+
const { DOM, settings } = event.detail.tagify;
|
|
437
|
+
const { hasNoTags, empty } = settings.classNames;
|
|
438
|
+
const { classList } = DOM.scope;
|
|
439
|
+
if (classList.contains(empty) && classList.contains(hasNoTags)) {
|
|
440
|
+
onOutputData('');
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}, [onOutputData]);
|
|
444
|
+
const onTagifyRemoved = useCallback((event) => {
|
|
309
445
|
if (event.detail) {
|
|
310
446
|
const { tagify } = event.detail;
|
|
311
447
|
const inputValue = tagify.getInputValue();
|
|
312
448
|
const convertedValue = convertInputStringToOriginal(inputValue);
|
|
313
|
-
|
|
314
|
-
onOutputData(convertedValue);
|
|
315
|
-
}
|
|
449
|
+
onOutputData(convertedValue);
|
|
316
450
|
}
|
|
317
|
-
}, [
|
|
451
|
+
}, [onOutputData]);
|
|
318
452
|
const customizeTag = useCallback((tagData, tagify) => {
|
|
319
453
|
const { value, collection, label, type } = tagData;
|
|
320
454
|
const { settings } = tagify;
|
|
@@ -477,134 +611,6 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
477
611
|
}
|
|
478
612
|
}
|
|
479
613
|
}, []);
|
|
480
|
-
/**
|
|
481
|
-
* Updates the window selection to highlight a specified range of text within a given node.
|
|
482
|
-
* */
|
|
483
|
-
const updateWindowSelection = useCallback((node, start, end) => {
|
|
484
|
-
if (!node || !_.isNumber(start) || !_.isNumber(end))
|
|
485
|
-
return false;
|
|
486
|
-
if (node) {
|
|
487
|
-
try {
|
|
488
|
-
const range = document.createRange();
|
|
489
|
-
const textNodeLength = node.textContent?.length;
|
|
490
|
-
if (textNodeLength && start <= textNodeLength && end <= textNodeLength) {
|
|
491
|
-
range?.setStart(node, start);
|
|
492
|
-
range?.setEnd(node, end);
|
|
493
|
-
const selection = window.getSelection();
|
|
494
|
-
selection?.removeAllRanges();
|
|
495
|
-
selection?.addRange(range);
|
|
496
|
-
return onSyncSelectionStateTagify();
|
|
497
|
-
}
|
|
498
|
-
throw new Error('Invalid start/end position');
|
|
499
|
-
}
|
|
500
|
-
catch (error) {
|
|
501
|
-
// eslint-disable-next-line no-console
|
|
502
|
-
console.error(error);
|
|
503
|
-
return false;
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
return false;
|
|
507
|
-
}, [onSyncSelectionStateTagify]);
|
|
508
|
-
const replaceURLsWithTags = useCallback((nodesURl, lastRange) => {
|
|
509
|
-
try {
|
|
510
|
-
if (!tagifyRef.current) {
|
|
511
|
-
throw new Error('Tagify instance is not initialized');
|
|
512
|
-
}
|
|
513
|
-
// Replace all URLs in the given nodes
|
|
514
|
-
nodesURl.forEach((textNode) => {
|
|
515
|
-
const newTags = [];
|
|
516
|
-
const textContent = textNode.textContent || '';
|
|
517
|
-
if (textContent) {
|
|
518
|
-
let match;
|
|
519
|
-
// Reset the regex's lastIndex before each execution
|
|
520
|
-
detectURLRegex.lastIndex = 0;
|
|
521
|
-
// eslint-disable-next-line no-cond-assign
|
|
522
|
-
while ((match = detectURLRegex.exec(textContent)) !== null) {
|
|
523
|
-
const url = match[0];
|
|
524
|
-
const start = match.index;
|
|
525
|
-
const end = start + url.length;
|
|
526
|
-
const newTag = {
|
|
527
|
-
url,
|
|
528
|
-
range: [start, end],
|
|
529
|
-
};
|
|
530
|
-
// add new valid URL to tags
|
|
531
|
-
newTags.push(newTag);
|
|
532
|
-
}
|
|
533
|
-
if (newTags.length > 0) {
|
|
534
|
-
// Sort tags by their position in reverse order
|
|
535
|
-
// starting from the back avoids messing up earlier parts of the document
|
|
536
|
-
newTags.sort((a, b) => b.range[0] - a.range[0]);
|
|
537
|
-
// Add tags one by one, adjusting the selection for each
|
|
538
|
-
newTags.forEach(tag => {
|
|
539
|
-
const [start, end] = tag.range;
|
|
540
|
-
if (tagifyRef.current) {
|
|
541
|
-
const isUpdated = updateWindowSelection(textNode, start, end);
|
|
542
|
-
if (isUpdated) {
|
|
543
|
-
const newTag = tagifyRef.current.createTagElem({
|
|
544
|
-
value: tag.url,
|
|
545
|
-
label: tag.url,
|
|
546
|
-
type: DETECT_LINK,
|
|
547
|
-
});
|
|
548
|
-
// Inject the new detect link tag
|
|
549
|
-
tagifyRef.current.injectAtCaret(newTag);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
});
|
|
556
|
-
const selection = window.getSelection();
|
|
557
|
-
if (selection) {
|
|
558
|
-
if (lastRange instanceof Range) {
|
|
559
|
-
// Need to restore the selection after execution all process to replace URL to Tag
|
|
560
|
-
// to maintain valid caret
|
|
561
|
-
selection.removeAllRanges();
|
|
562
|
-
selection.addRange(lastRange);
|
|
563
|
-
}
|
|
564
|
-
else {
|
|
565
|
-
// In case lost the selection not need to restore
|
|
566
|
-
// Reset the selection to clear and prepare the valid caret to add the next tag at fn: "onAddNewTag"
|
|
567
|
-
selection?.removeAllRanges();
|
|
568
|
-
onSyncSelectionStateTagify();
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
catch (error) {
|
|
573
|
-
// eslint-disable-next-line no-console
|
|
574
|
-
console.error('Error while replacing URL with tag', error);
|
|
575
|
-
}
|
|
576
|
-
}, [onSyncSelectionStateTagify, updateWindowSelection]);
|
|
577
|
-
/**
|
|
578
|
-
* Detects URLs within the text nodes of a specified input element and replaces them with tags.
|
|
579
|
-
*
|
|
580
|
-
* This function scans through all child nodes of the input element, looking for text nodes that contain URLs.
|
|
581
|
-
* When URLs are found, it creates tags for each URL and injects them into the input element, updating the selection
|
|
582
|
-
* as necessary to ensure the DOM structure remains intact.
|
|
583
|
-
* */
|
|
584
|
-
const detectReplaceURLToTag = useCallback(() => {
|
|
585
|
-
if (!tagifyRef.current)
|
|
586
|
-
return;
|
|
587
|
-
try {
|
|
588
|
-
const { input: inputElement } = tagifyRef.current.DOM;
|
|
589
|
-
if (inputElement) {
|
|
590
|
-
const selection = window.getSelection();
|
|
591
|
-
const cacheLastRange = selection?.getRangeAt && selection?.rangeCount && selection?.getRangeAt(0);
|
|
592
|
-
const minLengthValidURL = 8; // -> Because of valid URL should be "https://"
|
|
593
|
-
// Get all child nodes that are of type TEXT_NODE and contain an URL
|
|
594
|
-
const nodesURL = findURLInTextNodes(inputElement, minLengthValidURL);
|
|
595
|
-
// Starting from the back to avoid messing up earlier parts of the DOM
|
|
596
|
-
const reversedNodes = nodesURL?.toReversed() || [];
|
|
597
|
-
// Process URL to Tag
|
|
598
|
-
if (reversedNodes && reversedNodes.length > 0) {
|
|
599
|
-
replaceURLsWithTags(reversedNodes, cacheLastRange);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
catch (error) {
|
|
604
|
-
// eslint-disable-next-line no-console
|
|
605
|
-
console.log(error);
|
|
606
|
-
}
|
|
607
|
-
}, [replaceURLsWithTags]);
|
|
608
614
|
// Initialization tagify
|
|
609
615
|
useLayoutEffect(() => {
|
|
610
616
|
initializeTagify();
|
|
@@ -669,41 +675,31 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
669
675
|
// Listen to Tagify events
|
|
670
676
|
useEffect(() => {
|
|
671
677
|
const { current: tagifyInstance } = tagifyRef || {};
|
|
678
|
+
let onInputTagifyDebounce;
|
|
672
679
|
if (tagifyInstance) {
|
|
680
|
+
onInputTagifyDebounce = _.debounce(onTagifyTyping, 350);
|
|
673
681
|
tagifyInstance.on('click', onTagItemClick);
|
|
674
|
-
tagifyInstance.on('input',
|
|
682
|
+
tagifyInstance.on('input', onInputTagifyDebounce);
|
|
675
683
|
tagifyInstance.on('remove', onTagifyRemoved);
|
|
676
|
-
tagifyInstance.on('
|
|
684
|
+
tagifyInstance.on('change', onTagifyChanged);
|
|
677
685
|
}
|
|
678
686
|
// Off listen to Tagify events
|
|
679
687
|
return () => {
|
|
680
688
|
if (tagifyInstance) {
|
|
681
689
|
tagifyInstance.off('click', onTagItemClick);
|
|
682
|
-
tagifyInstance.off('input', onTagifyTyping);
|
|
683
690
|
tagifyInstance.off('remove', onTagifyRemoved);
|
|
684
|
-
tagifyInstance.off('
|
|
691
|
+
tagifyInstance.off('change', onTagifyChanged);
|
|
692
|
+
if (onInputTagifyDebounce) {
|
|
693
|
+
tagifyInstance.off('input', onInputTagifyDebounce);
|
|
694
|
+
}
|
|
685
695
|
}
|
|
686
696
|
};
|
|
687
|
-
}, [onTagItemClick, onTagifyTyping, onTagifyRemoved,
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}, [inputTypeDebounce]);
|
|
694
|
-
// Update URL to tag to show hint in the tooltip with tag
|
|
695
|
-
useDeepCompareEffect(() => {
|
|
696
|
-
const isSupportShortlink = acceptablePatternChecking(SHORT_LINK_PTN, acceptableTagPattern);
|
|
697
|
-
if (inputTypeDebounce && isSupportShortlink) {
|
|
698
|
-
detectReplaceURLToTag();
|
|
699
|
-
}
|
|
700
|
-
}, [inputTypeDebounce, acceptableTagPattern, detectReplaceURLToTag]);
|
|
701
|
-
// Removes all tags and resets the original input tag's value property if the initial value back to is empty string
|
|
702
|
-
useUpdateEffect(() => {
|
|
703
|
-
if (initialValue === '' && tagifyRef.current) {
|
|
704
|
-
tagifyRef.current.removeAllTags();
|
|
705
|
-
}
|
|
706
|
-
}, [initialValue]);
|
|
697
|
+
}, [onTagItemClick, onTagifyTyping, onTagifyRemoved, onTagifyChanged]);
|
|
698
|
+
// At the first render, need to update URL to tag to show hint in the tooltip with tag
|
|
699
|
+
useEffect(() => {
|
|
700
|
+
detectReplaceURLToTag();
|
|
701
|
+
}, [detectReplaceURLToTag]);
|
|
702
|
+
// CAVEAT: Some case need to "FORCE" sync the original values to Tagify instance
|
|
707
703
|
useEffect(() => {
|
|
708
704
|
if (tagifyRef.current) {
|
|
709
705
|
const { DOM, settings } = tagifyRef.current;
|
|
@@ -725,9 +721,13 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
725
721
|
makeValidLabelTags(mapAttributes);
|
|
726
722
|
}
|
|
727
723
|
}
|
|
724
|
+
else if (!classList.contains(empty) && initialValue === '') {
|
|
725
|
+
// Removes all tags and resets the original input tag's value property if the initial value back to is empty string
|
|
726
|
+
tagifyRef.current.removeAllTags();
|
|
727
|
+
}
|
|
728
728
|
}
|
|
729
729
|
}, [initialValue, mapAttributes, escapeHTML, acceptableTagPattern, makeValidLabelTags]);
|
|
730
|
-
return (_jsxs(TagifyWrapper, { ref: tagifyWrapperRef, "$cssTagifyVariables": cssVariablesMemoized, className: "tagify-container", id: "tagify-container", "data-test": "tagify-wrapper", "$status": status, "$maxHeight": maxHeight, "$minWidth": minWidth, "$tagifyFullWidth":
|
|
730
|
+
return (_jsxs(TagifyWrapper, { ref: tagifyWrapperRef, "$cssTagifyVariables": cssVariablesMemoized, className: "tagify-container", id: "tagify-container", "data-test": "tagify-wrapper", "$status": status, "$maxHeight": maxHeight, "$minWidth": minWidth, "$tagifyFullWidth": isLineBreak, "$placeholder": placeholder, "$isSingleLineText": isSingleLineText, "$tagInvalidIcon": iconWarning, onClick: onTagifyWrapperClick, children: [_jsx(TagTextArea, { id: "tagify-textarea", ref: inputRef, name: name, defaultValue: parsedDefaultValue, "data-test": "tagify-input" }), _jsx(WrapperPlaceHolder, { "data-test": "wrapper-placeholder", ref: placeholderRef, "$isShow": !!children, children: children })] }));
|
|
731
731
|
});
|
|
732
732
|
TagifyInput.defaultProps = tagifyDefaultProps;
|
|
733
733
|
export default memo(TagifyInput);
|
|
@@ -40,6 +40,9 @@ export declare const TAG_TYPE: {
|
|
|
40
40
|
readonly CUSTOMER: "customer";
|
|
41
41
|
readonly VISITOR: "visitor";
|
|
42
42
|
readonly EVENT: "event";
|
|
43
|
+
readonly JOURNEY: "journey_attr";
|
|
44
|
+
readonly CAMPAIGN: "campaign_attr";
|
|
45
|
+
readonly VARIANT: "variant_attr";
|
|
43
46
|
readonly OBJECT_WIDGET: "objectWidget";
|
|
44
47
|
readonly PROMOTION_CODE: "promotion_code";
|
|
45
48
|
readonly CUSTOM_FN: "custom";
|
|
@@ -48,7 +51,7 @@ export declare const TAG_TYPE: {
|
|
|
48
51
|
readonly DETECT_LINK: "detect_link";
|
|
49
52
|
readonly CONTENT_SOURCE_GROUP: "groups";
|
|
50
53
|
};
|
|
51
|
-
export declare const CUSTOMER: "customer", VISITOR: "visitor", EVENT: "event", PROMOTION_CODE: "promotion_code", CUSTOM_FN: "custom", EMOJI: "emoji", DETECT_LINK: "detect_link", SHORT_LINK: "shortlink", OBJECT_WIDGET: "objectWidget", CONTENT_SOURCE_GROUP: "groups";
|
|
54
|
+
export declare const CUSTOMER: "customer", VISITOR: "visitor", EVENT: "event", JOURNEY: "journey_attr", CAMPAIGN: "campaign_attr", VARIANT: "variant_attr", PROMOTION_CODE: "promotion_code", CUSTOM_FN: "custom", EMOJI: "emoji", DETECT_LINK: "detect_link", SHORT_LINK: "shortlink", OBJECT_WIDGET: "objectWidget", CONTENT_SOURCE_GROUP: "groups";
|
|
52
55
|
export declare const SHORT_LINK_TYPE: {
|
|
53
56
|
readonly INDIVIDUAL: "shortlink";
|
|
54
57
|
readonly GENERAL: "shortlink_static";
|
|
@@ -62,6 +65,9 @@ export declare const TAG_COLOR: {
|
|
|
62
65
|
};
|
|
63
66
|
readonly visitor: "#e8feca";
|
|
64
67
|
readonly event: "#fecaca";
|
|
68
|
+
readonly journey_attr: "#FAFAAF";
|
|
69
|
+
readonly campaign_attr: "#FBCBE8";
|
|
70
|
+
readonly variant_attr: "#FFD8DB";
|
|
65
71
|
readonly promotion_code: "#d8cafe";
|
|
66
72
|
readonly objectWidget: "#cafedd";
|
|
67
73
|
readonly custom: "#bbefbe";
|
|
@@ -53,6 +53,9 @@ export const TAG_TYPE = {
|
|
|
53
53
|
CUSTOMER: 'customer',
|
|
54
54
|
VISITOR: 'visitor',
|
|
55
55
|
EVENT: 'event',
|
|
56
|
+
JOURNEY: 'journey_attr',
|
|
57
|
+
CAMPAIGN: 'campaign_attr',
|
|
58
|
+
VARIANT: 'variant_attr',
|
|
56
59
|
OBJECT_WIDGET: 'objectWidget',
|
|
57
60
|
PROMOTION_CODE: 'promotion_code',
|
|
58
61
|
CUSTOM_FN: 'custom',
|
|
@@ -61,7 +64,7 @@ export const TAG_TYPE = {
|
|
|
61
64
|
DETECT_LINK: 'detect_link',
|
|
62
65
|
CONTENT_SOURCE_GROUP: 'groups',
|
|
63
66
|
};
|
|
64
|
-
export const { CUSTOMER, VISITOR, EVENT, PROMOTION_CODE, CUSTOM_FN, EMOJI, DETECT_LINK, SHORT_LINK, OBJECT_WIDGET, CONTENT_SOURCE_GROUP, } = TAG_TYPE;
|
|
67
|
+
export const { CUSTOMER, VISITOR, EVENT, JOURNEY, CAMPAIGN, VARIANT, PROMOTION_CODE, CUSTOM_FN, EMOJI, DETECT_LINK, SHORT_LINK, OBJECT_WIDGET, CONTENT_SOURCE_GROUP, } = TAG_TYPE;
|
|
65
68
|
export const SHORT_LINK_TYPE = {
|
|
66
69
|
INDIVIDUAL: 'shortlink', // Individual link
|
|
67
70
|
GENERAL: 'shortlink_static', // General link
|
|
@@ -75,6 +78,9 @@ export const TAG_COLOR = {
|
|
|
75
78
|
},
|
|
76
79
|
[VISITOR]: '#e8feca',
|
|
77
80
|
[EVENT]: '#fecaca',
|
|
81
|
+
[JOURNEY]: '#FAFAAF',
|
|
82
|
+
[CAMPAIGN]: '#FBCBE8',
|
|
83
|
+
[VARIANT]: '#FFD8DB',
|
|
78
84
|
[PROMOTION_CODE]: '#d8cafe',
|
|
79
85
|
[OBJECT_WIDGET]: '#cafedd',
|
|
80
86
|
[CUSTOM_FN]: '#bbefbe',
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// Libraries
|
|
2
2
|
import stringReplaceToArray from 'string-replace-to-array';
|
|
3
3
|
// Constants
|
|
4
|
-
import {
|
|
4
|
+
import { EMOJI_COLLECTIONS, PREFIX_PATTERN_LINE_MESSAGE, READONLY_TAG, TAG_TYPE, } from './constants';
|
|
5
5
|
import { iconsViber } from './iconsViber';
|
|
6
6
|
// Utils
|
|
7
7
|
import { acceptablePatternChecking, detectURLRegex, getCachedRegex, patternHandlers, tagRegexStringPattern, } from './patternHandlers';
|
|
8
|
+
const { CUSTOMER, VISITOR, EVENT, JOURNEY, CAMPAIGN, VARIANT, PROMOTION_CODE, CUSTOM_FN, OBJECT_WIDGET, CONTENT_SOURCE_GROUP, } = TAG_TYPE;
|
|
8
9
|
/*
|
|
9
10
|
* Custom error type for JSON parse errors
|
|
10
11
|
*/
|
|
@@ -392,6 +393,9 @@ export const isPersonalizeTagType = (type) => [
|
|
|
392
393
|
CUSTOMER,
|
|
393
394
|
VISITOR,
|
|
394
395
|
EVENT,
|
|
396
|
+
JOURNEY,
|
|
397
|
+
CAMPAIGN,
|
|
398
|
+
VARIANT,
|
|
395
399
|
PROMOTION_CODE,
|
|
396
400
|
OBJECT_WIDGET,
|
|
397
401
|
CUSTOM_FN,
|
|
@@ -925,7 +925,7 @@
|
|
|
925
925
|
"_TAB_INFORMATION_FIELD": "情報フィールド",
|
|
926
926
|
"_TAB_JOURNEY": "旅",
|
|
927
927
|
"_TAB_METRIC": "メトリック",
|
|
928
|
-
"_TAB_MODEL_DIAGRAM": "
|
|
928
|
+
"_TAB_MODEL_DIAGRAM": "ダイアグラム",
|
|
929
929
|
"_TAB_MODEL_FIELD": "フィールド",
|
|
930
930
|
"_TAB_OBECT_REFERENCE": "オブジェクトリファレンス",
|
|
931
931
|
"_TAB_OBJECT_ATTRIBUTE": "属性",
|
|
@@ -1717,7 +1717,7 @@
|
|
|
1717
1717
|
"_TITL_VERSION": "バージョン",
|
|
1718
1718
|
"_TAB_DELIVERY_LOG": "配信ログ",
|
|
1719
1719
|
"_TAB_DETAIL": "詳細",
|
|
1720
|
-
"_TAB_DIAGRAM": "
|
|
1720
|
+
"_TAB_DIAGRAM": "ダイアグラム",
|
|
1721
1721
|
"_CODE_BUILD_CONTENT_ERROR": "ビルドコンテンツエラー",
|
|
1722
1722
|
"_CODE_MISSING_RECEIVER": "受信機がありません",
|
|
1723
1723
|
"_CODE_DESTINATION_FREQUENCY_CAPPING": "宛先フリークエンシー キャップに違反する",
|
|
@@ -2288,7 +2288,7 @@
|
|
|
2288
2288
|
"_CHANNEL_DES_WEB_NOTI": "リアルタイムのメッセージを送信して Web サイト訪問者を引きつけ、タイムリーなインタラクションとコンバージョンを促進します",
|
|
2289
2289
|
"_CHANNEL_DES_APP_NOTI": "即時通知をモバイル アプリのみに送信し、即時のエンゲージメントとインタラクションを促進します",
|
|
2290
2290
|
"_CHANNEL_DES_EMAIL": "パーソナライズされたメッセージをユーザーの受信箱に直接配信し、ターゲットを絞ったコンテンツでのエンゲージメントとコンバージョンを促進します。",
|
|
2291
|
-
"_CHANNEL_DES_SMS": "
|
|
2291
|
+
"_CHANNEL_DES_SMS": "直接的かつ即時的なコミュニケーションを提供し、ユーザーのモバイルデバイスに到達して即時のエンゲージメントとインタラクションを実現します。",
|
|
2292
2292
|
"_CHANNEL_DES_SMART_INB": "プッシュ通知のコンテンツを一元管理して管理とエンゲージメントを合理化",
|
|
2293
2293
|
"_CHANNEL_DES_FB_MESS": "直接的な会話型のコミュニケーションを提供し、使い慣れたソーシャル メディア プラットフォームでユーザーを惹きつけます",
|
|
2294
2294
|
"_CHANNEL_DES_VIBER": "ダイレクト メッセージング機能を提供し、安全で使い慣れたソーシャル メディア プラットフォームでユーザーを魅了します。",
|
|
@@ -2432,7 +2432,7 @@
|
|
|
2432
2432
|
"_OBJ_DES_WEB_1": "没入型のブラウジング体験に合わせてコンテンツを調整することで、セッションが長くなり、エンゲージメント指標が向上します",
|
|
2433
2433
|
"_OBJ_DES_WEB_2": "より多くのコンバージョンと売上を促進するために、ユーザーの興味やニーズに合った製品やコンテンツをユーザーに提示します。",
|
|
2434
2434
|
"_OBJ_DES_WEB_3": "視聴者とのより深いつながりを育み、ロイヤルティと維持率を高めます",
|
|
2435
|
-
"_OBJ_DES_WEB_4": "
|
|
2435
|
+
"_OBJ_DES_WEB_4": "それぞれの訪問者のインタラクションの価値を最大化するために、独自のパーソナライズされたオファーを提供します",
|
|
2436
2436
|
"_OBJ_DES_WEB_5": "ユーザーインタラクションを分析してコンテンツを洗練し、戦略をセグメント化し、Web サイトのレイアウトを最適化します。",
|
|
2437
2437
|
"_OBJ_DES_WEB_NOTI_1": "タイムリーな更新、プロモーション、アラートでユーザーに即座に連絡します",
|
|
2438
2438
|
"_OBJ_DES_WEB_NOTI_2": "新しいコンテンツ、製品リリース、または期間限定オファーをユーザーに通知することで、Web サイトへのトラフィックを促進します。",
|
|
@@ -2440,12 +2440,12 @@
|
|
|
2440
2440
|
"_OBJ_DES_WEB_NOTI_4": "ユーザーの興味や好みに合わせた関連性の高い有益な通知を送信することで、ユーザーの関心とリピートを維持します。",
|
|
2441
2441
|
"_OBJ_DES_WEB_NOTI_5": "アカウント、トランザクション更新などの関連情報をユーザーのブラウザに直接配信します。",
|
|
2442
2442
|
"_OBJ_DES_APP_NOTI_1": "タイムリーな更新、プロモーション、アラートでユーザーに即座に連絡します",
|
|
2443
|
-
"_OBJ_DES_APP_NOTI_2": "
|
|
2443
|
+
"_OBJ_DES_APP_NOTI_2": "貴重な通知でユーザーを誘導することで、ユーザーがアプリを積極的に操作するよう促します。",
|
|
2444
2444
|
"_OBJ_DES_APP_NOTI_3": "パーソナライズされたオファーやリマインダーを配信してユーザーの行動を促す",
|
|
2445
2445
|
"_OBJ_DES_APP_NOTI_4": "ユーザーの興味や好みに合わせた関連性の高い有益な通知を送信することで、ユーザーの関心を維持し、さらに戻ってくるようにします。",
|
|
2446
2446
|
"_OBJ_DES_APP_NOTI_5": "アカウント、トランザクション更新などの関連情報をユーザーのブラウザに直接配信します。",
|
|
2447
2447
|
"_OBJ_DES_EMAIL_1": "魅力的なコンテンツと電子メールの行動喚起 (CTA) でユーザーを Web サイトに誘導します",
|
|
2448
|
-
"_OBJ_DES_EMAIL_2": "
|
|
2448
|
+
"_OBJ_DES_EMAIL_2": "貴重なコンテンツやインセンティブを提供してサインアップや問い合わせを促進することで見込み顧客を獲得します。",
|
|
2449
2449
|
"_OBJ_DES_EMAIL_3": "ターゲットを絞ったコンテンツと自動化された電子メール シーケンスを使用して、セールス ファネルを通じてリードを誘導します。",
|
|
2450
2450
|
"_OBJ_DES_EMAIL_4": "関連するアップデート、オファー、限定コンテンツで顧客の関心とロイヤルティを維持します",
|
|
2451
2451
|
"_OBJ_DES_EMAIL_5": "製品やサービスを紹介して売上とコンバージョンを促進する",
|
|
@@ -2457,7 +2457,7 @@
|
|
|
2457
2457
|
"_OBJ_DES_SMS_5": "注文確認、出荷通知、アカウント更新をリアルタイムで提供します",
|
|
2458
2458
|
"_OBJ_DES_SMART_INB_1": "通知を集約し、ユーザーがメッセージを 1 か所で簡単に表示および管理できるようにします。",
|
|
2459
2459
|
"_OBJ_DES_SMART_INB_2": "プラットフォーム間で通知にアクセスし、通知を操作するためのシームレスで直感的なインターフェイスを提供します。",
|
|
2460
|
-
"_OBJ_DES_SMART_INB_3": "通知によるタイムリーな応答と対話を促進し、ユーザー
|
|
2460
|
+
"_OBJ_DES_SMART_INB_3": "通知によるタイムリーな応答と対話を促進し、ユーザー エンゲージメントと満足度を最大化します。",
|
|
2461
2461
|
"_OBJ_DES_SMART_INB_4": "Web プッシュやアプリ プッシュなどのさまざまなチャネルからの通知を統合し、ユーザーとの一貫性のある一貫したコミュニケーションを確保します。",
|
|
2462
2462
|
"_OBJ_DES_FB_MESS_1": "ターゲットを絞ったプロモーションやオファーをブロードキャストして、エンゲージメントと販売を促進します",
|
|
2463
2463
|
"_OBJ_DES_FB_MESS_2": "鮮やかなメッセージ テンプレートを使用してタイムリーで関連性のある更新を提供します",
|
|
@@ -2472,23 +2472,23 @@
|
|
|
2472
2472
|
"_OBJ_DES_ZALO_1": "ターゲットを絞ったプロモーションやオファーをブロードキャストして、エンゲージメントと販売を促進します",
|
|
2473
2473
|
"_OBJ_DES_ZALO_2": "インタラクティブな要素を使用して販売目標到達プロセスをガイドし、リードと見込み顧客を育成します。",
|
|
2474
2474
|
"_OBJ_DES_ZALO_3": "タイムリーなコミュニケーションを確保するために、注文確認、配送の最新情報、または予約のリマインダーを送信します。",
|
|
2475
|
-
"_OBJ_DES_ZALO_4": "
|
|
2475
|
+
"_OBJ_DES_ZALO_4": "重要なお知らせ、アップデート、ニュースをユーザーと共有して常に最新情報を入手します。",
|
|
2476
2476
|
"_OBJ_DES_ZALO_5": "一貫性があり、有益で魅力的なコンテンツを通じてブランド アイデンティティと価値を強化する",
|
|
2477
2477
|
"_OBJ_DES_WHATSAPP_1": "ターゲットを絞ったプロモーションやオファーをブロードキャストして、エンゲージメントと販売を促進します",
|
|
2478
2478
|
"_OBJ_DES_WHATSAPP_2": "鮮やかなメッセージ テンプレートを使用してタイムリーで関連性のある更新を提供します",
|
|
2479
2479
|
"_OBJ_DES_WHATSAPP_3": "インタラクティブな要素を使用して販売目標到達プロセスをガイドし、リードと見込み顧客を育成します。",
|
|
2480
2480
|
"_OBJ_DES_WHATSAPP_4": "予定や予約のリマインダーと確認を送信してノーショーを減らします",
|
|
2481
|
-
"_OBJ_DES_WHATSAPP_5": "
|
|
2481
|
+
"_OBJ_DES_WHATSAPP_5": "重要なお知らせ、アップデート、ニュースをユーザーと共有して常に最新情報を入手します。",
|
|
2482
2482
|
"_OBJ_DES_TELEGRAM_1": "ターゲットを絞ったプロモーションやオファーをブロードキャストして、エンゲージメントと販売を促進します",
|
|
2483
2483
|
"_OBJ_DES_TELEGRAM_2": "鮮やかなメッセージ テンプレートを使用してタイムリーで関連性のある更新を提供します",
|
|
2484
2484
|
"_OBJ_DES_TELEGRAM_3": "インタラクティブなテンプレート要素を使用してセールスファネルを誘導し、リードと見込み顧客を育成します。",
|
|
2485
2485
|
"_OBJ_DES_TELEGRAM_4": "予定や予約のリマインダーと確認を送信してノーショーを減らします",
|
|
2486
|
-
"_OBJ_DES_TELEGRAM_5": "
|
|
2486
|
+
"_OBJ_DES_TELEGRAM_5": "重要なお知らせ、アップデート、ニュースをユーザーと共有して常に最新情報を入手します。",
|
|
2487
2487
|
"_OBJ_DES_LINE_1": "ターゲットを絞ったプロモーションやオファーをブロードキャストして、エンゲージメントと販売を促進します",
|
|
2488
2488
|
"_OBJ_DES_LINE_2": "Line のリッチ メニューを利用して、メッセージ内のインタラクティブなオプションとナビゲーションをユーザーに提供します",
|
|
2489
2489
|
"_OBJ_DES_LINE_3": "インタラクティブなテンプレート要素を使用してセールスファネルを誘導し、リードと見込み顧客を育成します。",
|
|
2490
2490
|
"_OBJ_DES_LINE_4": "予定や予約のリマインダーと確認を送信してノーショーを減らします",
|
|
2491
|
-
"_OBJ_DES_LINE_5": "
|
|
2491
|
+
"_OBJ_DES_LINE_5": "重要なお知らせ、アップデート、ニュースをユーザーと共有して常に最新情報を入手します。",
|
|
2492
2492
|
"_OBJ_DES_FILE_TRANSFER_1": "さまざまなシステム間での大規模なデータセットの共有を自動化し、より迅速かつ正確なデータ処理を実現します。",
|
|
2493
2493
|
"_OBJ_DES_FILE_TRANSFER_2": "マーケティング資料やキャンペーン資産をチームメンバーや外部関係者に簡単に配布し、より良いコラボレーションとコミュニケーションを促進します。",
|
|
2494
2494
|
"_OBJ_DES_FILE_TRANSFER_3": "ファイル転送をマーケティングオートメーションに統合して時間と人的リソースを節約する",
|
|
@@ -2497,22 +2497,22 @@
|
|
|
2497
2497
|
"_OBJ_DES_ORCHES_3": "チャネル全体でターゲットを絞ったメッセージを送信することで、購入者のジャーニーを見込み顧客に導き、コンバージョンを促進し、販売機会を最大化します。",
|
|
2498
2498
|
"_OBJ_DES_ORCHES_4": "チャネルの好みや行動に基づいて特定の視聴者セグメントに合わせてキャンペーンを調整し、共感を呼び、コンバージョンにつながるパーソナライズされたエクスペリエンスを提供します。",
|
|
2499
2499
|
"_OBJ_DES_ORCHES_5": "すべてのチャネルにわたって包括的な分析を取得し、データ主導の意思決定と継続的なキャンペーンの改善を強化して、最適な結果と ROI を実現します。",
|
|
2500
|
-
"_WEBPER_TEMP_OBJ_DES_POP_1": "
|
|
2500
|
+
"_WEBPER_TEMP_OBJ_DES_POP_1": "潜在的な顧客からの情報、または既存の顧客からのレビューやフィードバックを収集してデータを充実させます",
|
|
2501
2501
|
"_WEBPER_TEMP_OBJ_DES_POP_2": "限定セール、期間限定プロモーション、見逃せないおすすめ商品を紹介することで、収益を飛躍的に高めます。",
|
|
2502
2502
|
"_WEBPER_TEMP_OBJ_DES_POP_3": "追加購入を促すために補完的な製品やアップグレードを提案する",
|
|
2503
|
-
"_WEBPER_TEMP_OBJ_DES_POP_4": "
|
|
2503
|
+
"_WEBPER_TEMP_OBJ_DES_POP_4": "躊躇する訪問者をさらに滞在させ、さらに探索したくなる魅力的なオファーで出口をチャンスに変えます。",
|
|
2504
2504
|
"_WEBPER_TEMP_OBJ_DES_POP_5": "重要なニュースやイベントを視聴者に直接ブロードキャストして最新情報を提供します",
|
|
2505
2505
|
"_WEBPER_TEMP_OBJ_DES_POP_6": "Cookie の使用についてユーザーの同意を得ることで、視聴者の安心とプライバシー規制の遵守を確保します。",
|
|
2506
|
-
"_WEBPER_TEMP_OBJ_DES_POP_7": "CDP 365
|
|
2507
|
-
"_WEBPER_TEMP_OBJ_DES_POP_8": "
|
|
2506
|
+
"_WEBPER_TEMP_OBJ_DES_POP_7": "CDP 365 からのデータを利用して、パーソナライズされた製品の推奨事項を表示し、各訪問者の興味や過去のやり取りに合わせて調整できます。",
|
|
2507
|
+
"_WEBPER_TEMP_OBJ_DES_POP_8": "ターゲットを絞ったオファー、インセンティブ、またはリマインダーを使用して、躊躇している買い物客に購入を完了させるよう促します。",
|
|
2508
2508
|
"_WEBPER_TEMP_OBJ_DES_POP_9": "ソーシャル メディア プラットフォームでコミュニティを拡大し、ブランドの存在感を高めます",
|
|
2509
2509
|
"_WEBPER_TEMP_OBJ_DES_POP_10": "参加者と興奮を促進する注目を集めるイベント プロモーションで成功への舞台を整えます。",
|
|
2510
2510
|
"_WEBPER_TEMP_OBJ_DES_POP_11": "魅力的な運ゲーやインタラクティブなコンテンツで興奮を呼び起こし、エンゲージメントを高め、ユーザーを何度もリピートさせ続ける",
|
|
2511
|
-
"_WEBPER_TEMP_OBJ_DES_POP_12": "
|
|
2511
|
+
"_WEBPER_TEMP_OBJ_DES_POP_12": "新規ユーザーを支援し、提供された回答に基づいてパーソナライズされた推奨事項を提供します",
|
|
2512
2512
|
"_WEBPER_TEMP_OBJ_DES_POP_13": "直接リンクまたは QR コードを介してモバイル アプリをダウンロードしてスキャンするようユーザーに奨励します。",
|
|
2513
2513
|
"_WEBPER_TEMP_OBJ_DES_FLOAT_1": "リード獲得フォームを含めて、訪問者にニュースレター、プロモーション、その他のマーケティング資料への登録を促します。",
|
|
2514
2514
|
"_WEBPER_TEMP_OBJ_DES_FLOAT_2": "カウントダウンタイマー付きの特別セールや限定プロモーションで視聴者の目を引き、さらに探索するよう促します。",
|
|
2515
|
-
"_WEBPER_TEMP_OBJ_DES_FLOAT_3": "
|
|
2515
|
+
"_WEBPER_TEMP_OBJ_DES_FLOAT_3": "訪問者がスクロールしても表示され続けるバナーを使用して、重要なニュースを確実に目に留まり、更新情報を前面と中央に保ちます。",
|
|
2516
2516
|
"_WEBPER_TEMP_OBJ_DES_FLOAT_4": "あなたのブランドに対するフレンドリーな意見を確立するために、初めて Web サイトを閲覧する訪問者を歓迎します。",
|
|
2517
2517
|
"_WEBPER_TEMP_OBJ_DES_FLOAT_5": "ソーシャル メディア プラットフォームでコミュニティを拡大することで、ブランドの存在感を高めます。",
|
|
2518
2518
|
"_WEBPER_TEMP_OBJ_DES_FLOAT_6": "ブランドロゴを目立つように表示することでアイデンティティを強化し、ブランド認知度を向上させます",
|
|
@@ -2524,7 +2524,7 @@
|
|
|
2524
2524
|
"_WEBPER_TEMP_OBJ_DES_FULLSCR_6": "直接リンクまたは QR コードを介してモバイル アプリをダウンロードしてスキャンするようユーザーに奨励します。",
|
|
2525
2525
|
"_WEBPER_TEMP_OBJ_DES_FULLSCR_7": "顧客の生活に価値を付加し、単なる購入を超えてブランドと関わるよう促すために、詳細な情報と関連チュートリアルを提供します。",
|
|
2526
2526
|
"_WEBPER_TEMP_OBJ_DES_INLINE_1": "購読フォームや登録プロンプトを通じてユーザー情報を取得する",
|
|
2527
|
-
"_WEBPER_TEMP_OBJ_DES_INLINE_2": "CDP 365
|
|
2527
|
+
"_WEBPER_TEMP_OBJ_DES_INLINE_2": "CDP 365 からのデータを利用して、パーソナライズされた製品の推奨事項を表示し、各訪問者の興味や過去のやり取りに合わせて調整できます。",
|
|
2528
2528
|
"_WEBPER_TEMP_OBJ_DES_INLINE_3": "魅力的な運ゲーやインタラクティブなコンテンツで興奮を呼び起こし、エンゲージメントを高め、ユーザーを何度もリピートさせます。",
|
|
2529
2529
|
"_WEBPER_TEMP_OBJ_DES_INLINE_4": "アンケート、投票、フィードバック フォームを組み込んで、貴重な洞察を収集し、交流を促進します。",
|
|
2530
2530
|
"_WEBPER_TEMP_OBJ_DES_INLINE_5": "顧客のレビュー、評価、お客様の声などの社会的証明要素を紹介して、購入の意思決定に影響を与える信頼と信用を構築します。",
|
|
@@ -2532,11 +2532,11 @@
|
|
|
2532
2532
|
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_1": "購読フォーム、登録プロンプト、またはゲート付きコンテンツのオファーを通じて、電子メール アドレスや連絡先の詳細などのユーザー情報を取得します。",
|
|
2533
2533
|
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_2": "直前の取引やコンテンツの推奨を提供して、ユーザーに滞在してさらに探索するよう促します。",
|
|
2534
2534
|
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_3": "今後のコンテンツ、製品の発売、イベントを予告して、視聴者の期待と興奮を高め、Web サイトへのトラフィックを促進します。",
|
|
2535
|
-
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_4": "
|
|
2535
|
+
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_4": "アンケート、投票、フィードバック フォームを組み込んで貴重な洞察を収集し、交流を促進します。",
|
|
2536
2536
|
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_5": "顧客のレビュー、評価、お客様の声などの社会的証明要素を紹介して、購入の意思決定に影響を与える信頼と信用を構築します。",
|
|
2537
2537
|
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_6": "期間限定のオファー、カウントダウンタイマー、フラッシュセール通知を提示することで、緊迫感を醸成し、即時行動を促します。",
|
|
2538
|
-
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_7": "
|
|
2539
|
-
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_8": "
|
|
2538
|
+
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_7": "ターゲットを絞ったオファー、インセンティブ、またはリマインダーを使用して、躊躇している買い物客に購入を完了させるよう促します。",
|
|
2539
|
+
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_8": "顧客からの問い合わせの必要性を減らし、ショッピング体験の全体的な満足度を向上させるために、顧客が遭遇する可能性のある一般的な懸念事項や問題のトラブルシューティングに対処します。",
|
|
2540
2540
|
"_WEBPER_TEMP_OBJ_DES_SLIDEIN_9": "登録や出欠確認のオプションを提供して、ウェビナー、ワークショップ、イベントに参加するようユーザーを招待し、参加とエンゲージメントを促進します。",
|
|
2541
2541
|
"_LINE_MESS_OBJ_DES_1": "各ユーザーの好み、行動、過去のやり取りに基づいてメッセージをカスタマイズする",
|
|
2542
2542
|
"_LINE_MESS_OBJ_DES_2": "画像、ビデオ、ステッカーなどのマルチメディア コンテンツでメッセージを充実させます",
|