@antscorp/antsomi-ui 2.0.72 → 2.0.73
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/atoms/index.d.ts +0 -1
- package/es/components/atoms/index.js +0 -1
- package/es/components/molecules/SearchPopover/utils.js +1 -1
- package/es/components/molecules/SelectV2/styled.d.ts +1 -3
- package/es/components/molecules/SelectV2/styled.js +2 -2
- package/es/components/molecules/TagifyInput/TagifyInput.js +77 -169
- package/es/components/molecules/TagifyInput/constants.d.ts +2 -24
- package/es/components/molecules/TagifyInput/constants.js +2 -25
- package/es/components/molecules/TagifyInput/patternHandlers.d.ts +6 -12
- package/es/components/molecules/TagifyInput/patternHandlers.js +43 -88
- package/es/components/molecules/TagifyInput/types.d.ts +3 -24
- package/es/components/molecules/TagifyInput/utils.d.ts +1 -7
- package/es/components/molecules/TagifyInput/utils.js +4 -72
- package/es/components/molecules/TagifyInput/utils.style.js +96 -82
- package/es/components/molecules/index.d.ts +0 -1
- package/es/components/molecules/index.js +0 -1
- package/package.json +1 -1
- package/es/components/atoms/SelectAssociatedTag/SelectAssociatedTag.d.ts +0 -5
- package/es/components/atoms/SelectAssociatedTag/SelectAssociatedTag.js +0 -15
- package/es/components/atoms/SelectAssociatedTag/SelectTag.d.ts +0 -4
- package/es/components/atoms/SelectAssociatedTag/SelectTag.js +0 -26
- package/es/components/atoms/SelectAssociatedTag/constants.d.ts +0 -11
- package/es/components/atoms/SelectAssociatedTag/constants.js +0 -42
- package/es/components/atoms/SelectAssociatedTag/index.d.ts +0 -3
- package/es/components/atoms/SelectAssociatedTag/index.js +0 -2
- package/es/components/atoms/SelectAssociatedTag/styled.d.ts +0 -7
- package/es/components/atoms/SelectAssociatedTag/styled.js +0 -60
- package/es/components/atoms/SelectAssociatedTag/types.d.ts +0 -76
- package/es/components/atoms/SelectAssociatedTag/types.js +0 -1
- package/es/components/molecules/InputSelectAttribute/index.d.ts +0 -25
- package/es/components/molecules/InputSelectAttribute/index.js +0 -124
- package/es/components/molecules/InputSelectAttribute/styled.d.ts +0 -14
- package/es/components/molecules/InputSelectAttribute/styled.js +0 -33
|
@@ -48,7 +48,6 @@ export * from './RateV2';
|
|
|
48
48
|
export * from './Popover';
|
|
49
49
|
export * from './Iframe';
|
|
50
50
|
export * from './Avatar';
|
|
51
|
-
export * from './SelectAssociatedTag';
|
|
52
51
|
export type { SliderProps } from './Slider';
|
|
53
52
|
export type { PaginationProps } from './Pagination';
|
|
54
53
|
export type { InputDynamicProps } from './InputDynamic';
|
|
@@ -14,7 +14,7 @@ export const defaultSearch = (opt, search, config) => {
|
|
|
14
14
|
};
|
|
15
15
|
export const calDefaultListHeightInPopover = (params) => {
|
|
16
16
|
const { listLength, itemSpacing, itemSize } = params;
|
|
17
|
-
const DEFAULT_NUM_ITEM_SHOWED =
|
|
17
|
+
const DEFAULT_NUM_ITEM_SHOWED = 6;
|
|
18
18
|
const itemLength = min([DEFAULT_NUM_ITEM_SHOWED, listLength]);
|
|
19
19
|
return calInlineListSize(itemLength || 0, itemSize, itemSpacing);
|
|
20
20
|
};
|
|
@@ -9,9 +9,7 @@ export declare const StyledSelect: import("styled-components").StyledComponent<(
|
|
|
9
9
|
OptGroup: import("rc-select/lib/OptGroup").OptionGroupFC;
|
|
10
10
|
_InternalPanelDoNotUseOrYouWillBeFired: (props: import("antd/es/_util/type").AnyObject) => import("react").JSX.Element;
|
|
11
11
|
}, any, {}, never>;
|
|
12
|
-
export declare const StyledTag: import("styled-components").StyledComponent<import("antd").TagType, any, {
|
|
13
|
-
isError?: boolean | undefined;
|
|
14
|
-
}, never>;
|
|
12
|
+
export declare const StyledTag: import("styled-components").StyledComponent<import("antd").TagType, any, {}, never>;
|
|
15
13
|
export declare const CloseButton: import("styled-components").StyledComponent<"div", any, {
|
|
16
14
|
borderColor?: any;
|
|
17
15
|
}, never>;
|
|
@@ -105,8 +105,8 @@ export const StyledTag = styled(Tag) `
|
|
|
105
105
|
margin-right: 5px !important;
|
|
106
106
|
padding: 5px 10px !important;
|
|
107
107
|
border-radius: 15px !important;
|
|
108
|
-
border:
|
|
109
|
-
background-color: ${
|
|
108
|
+
border: none !important;
|
|
109
|
+
background-color: ${THEME.token?.blue2} !important;
|
|
110
110
|
cursor: pointer !important;
|
|
111
111
|
|
|
112
112
|
.antsomi-tag-close-icon {
|
|
@@ -16,15 +16,13 @@ import '@yaireo/tagify/dist/tagify.css';
|
|
|
16
16
|
// Styled
|
|
17
17
|
import { TagTextArea, TagifyWrapper, WrapperPlaceHolder } from './styled';
|
|
18
18
|
// Utils
|
|
19
|
-
import { parseTagStringToTagify, convertInputStringToOriginal, emojiManufacturer, getEmojiTag, isPersonalizeTagType, generateTagContent, unescapeString, hasLineBreak, selectRange, isTagClickable, findURLInTextNodes, getAttributesString, isAnchorNodeChildOfElement, isShortLinkTagType,
|
|
20
|
-
import { acceptablePatternChecking, detectURLRegex, getCachedRegex,
|
|
19
|
+
import { parseTagStringToTagify, convertInputStringToOriginal, emojiManufacturer, getEmojiTag, isPersonalizeTagType, generateTagContent, unescapeString, hasLineBreak, selectRange, isTagClickable, findURLInTextNodes, getAttributesString, isAnchorNodeChildOfElement, isShortLinkTagType, } from './utils';
|
|
20
|
+
import { acceptablePatternChecking, detectURLRegex, getCachedRegex, getPersonalizeTagInfo, getShortLinkTagInfo, patternHandlers, } from './patternHandlers';
|
|
21
21
|
// Constants
|
|
22
|
-
import { DETECT_LINK, EMOJI, PERSONALIZE_PTN, SHORT_LINK, SHORT_LINK_PTN, SHORT_LINK_V2,
|
|
23
|
-
const { CUSTOM_TAG } = TAG_TYPE;
|
|
24
|
-
const { PREPARING_ST, INVALID_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP, ERROR_TAG, WARNING_TAG } = TAG_CUSTOM_ATTRIBUTES;
|
|
22
|
+
import { DETECT_LINK, EMOJI, FORCE_SHOW_TOOLTIP, INVALID_TAG, MESSAGE_TAG, NO_VIEW_TAG, PERSONALIZE_PTN, PROMOTION_CODE, READONLY_TAG, REMOVED_TAG, SHORT_LINK, SHORT_LINK_PTN, SHORT_LINK_V2, defaultCssVariables, tagifyDefaultProps, } from './constants';
|
|
25
23
|
const TagifyInput = forwardRef((props, ref) => {
|
|
26
24
|
// Props
|
|
27
|
-
const { initialValue, escapeHTML, status, readonly, readonlyTag, realtime, disabled, maxLength, maxHeight, minWidth, placeholder, minWidthPlaceholder, isSingleLineText, acceptableTagPattern,
|
|
25
|
+
const { initialValue, escapeHTML, status, readonly, readonlyTag, realtime, disabled, maxLength, maxHeight, minWidth, placeholder, minWidthPlaceholder, isSingleLineText, acceptableTagPattern, mapAttributes, mapErrorAttributes, maxPersonalizeTags, name, children, cssTagifyVariables, onTagClick, onChange, } = props;
|
|
28
26
|
// States
|
|
29
27
|
const [isLineBreak, setIsLineBreak] = useState(hasLineBreak(initialValue));
|
|
30
28
|
const [tooltipRefresher, setTooltipRefresher] = useState(1);
|
|
@@ -34,7 +32,6 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
34
32
|
const tagifyWrapperRef = useRef(null);
|
|
35
33
|
const placeholderRef = useRef(null);
|
|
36
34
|
const lastRange = useRef(null);
|
|
37
|
-
const tagLength = tagifyRef?.current?.getTagElms().length;
|
|
38
35
|
// Memoizations
|
|
39
36
|
const cssVariablesMemoized = useMemo(() => _.assign({}, defaultCssVariables, cssTagifyVariables || {}), [cssTagifyVariables]);
|
|
40
37
|
// Only run in the first render
|
|
@@ -441,11 +438,6 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
441
438
|
onTagClick(event.detail);
|
|
442
439
|
}
|
|
443
440
|
}, [onTagClick]);
|
|
444
|
-
const onTagifyRemoveTag = useCallback((event) => {
|
|
445
|
-
if (event.detail && onTagRemove) {
|
|
446
|
-
onTagRemove(event.detail);
|
|
447
|
-
}
|
|
448
|
-
}, [onTagRemove]);
|
|
449
441
|
// Used to trigger replace URL detection and line break
|
|
450
442
|
const onTagifyTyping = useCallback((event) => {
|
|
451
443
|
if (event.detail) {
|
|
@@ -489,11 +481,7 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
489
481
|
case EMOJI: {
|
|
490
482
|
closeIcon = '';
|
|
491
483
|
const emojiPath = emojiManufacturer(value, collection);
|
|
492
|
-
visibleTagContent = getEmojiTag({
|
|
493
|
-
src: emojiPath,
|
|
494
|
-
emoji: label,
|
|
495
|
-
code: value,
|
|
496
|
-
});
|
|
484
|
+
visibleTagContent = getEmojiTag({ src: emojiPath, emoji: label, code: value });
|
|
497
485
|
break;
|
|
498
486
|
}
|
|
499
487
|
case DETECT_LINK: {
|
|
@@ -552,29 +540,52 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
552
540
|
while ((match = regex.exec(value)) !== null) {
|
|
553
541
|
const [, personalizeContent] = match;
|
|
554
542
|
const [tagCode] = personalizeContent.split('||');
|
|
555
|
-
const { label: tagLabel, type,
|
|
543
|
+
const { label: tagLabel, isValid, message, type, isRemoved, hasViewPermission, } = getPersonalizeTagInfo(tagCode, attributes, errorAttributes);
|
|
544
|
+
const isPromotionCode = type === PROMOTION_CODE;
|
|
556
545
|
const tagTextNode = tagifyRef.current?.getTagTextNode(tagElement);
|
|
557
546
|
/*
|
|
558
547
|
* Just only update to the correct text of the tag
|
|
559
548
|
* NOTE: Do not actually affect raw data
|
|
560
549
|
*/
|
|
561
550
|
if (tagTextNode) {
|
|
562
|
-
|
|
563
|
-
//
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
551
|
+
tagTextNode.textContent = tagLabel;
|
|
552
|
+
// Clear all previous attributes
|
|
553
|
+
tagElement.removeAttribute(REMOVED_TAG);
|
|
554
|
+
tagElement.removeAttribute(NO_VIEW_TAG);
|
|
555
|
+
tagElement.removeAttribute(INVALID_TAG);
|
|
556
|
+
tagElement.removeAttribute(READONLY_TAG);
|
|
557
|
+
tagElement.removeAttribute(MESSAGE_TAG);
|
|
558
|
+
// In case promotion pool has something wrong
|
|
559
|
+
if (isPromotionCode && message) {
|
|
560
|
+
if (isRemoved) {
|
|
561
|
+
tagElement.setAttribute(REMOVED_TAG, 'true');
|
|
562
|
+
tagElement.setAttribute(MESSAGE_TAG, message);
|
|
563
|
+
tagifyRef.current?.getSetTagData(tagElement, {
|
|
564
|
+
...tagData,
|
|
565
|
+
status: 'error',
|
|
566
|
+
statusMsg: message,
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
else if (!hasViewPermission) {
|
|
570
|
+
tagElement.setAttribute(NO_VIEW_TAG, 'true');
|
|
571
|
+
tagElement.setAttribute(MESSAGE_TAG, message);
|
|
572
|
+
tagifyRef.current?.getSetTagData(tagElement, {
|
|
573
|
+
...tagData,
|
|
574
|
+
status: 'warning',
|
|
575
|
+
statusMsg: message,
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
else if (!isValid) {
|
|
579
|
+
tagElement.setAttribute(READONLY_TAG, 'true');
|
|
580
|
+
tagElement.setAttribute(INVALID_TAG, 'true');
|
|
581
|
+
tagElement.setAttribute(MESSAGE_TAG, message);
|
|
582
|
+
tagifyRef.current?.getSetTagData(tagElement, {
|
|
583
|
+
...tagData,
|
|
584
|
+
status: 'warning',
|
|
585
|
+
statusMsg: message,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
567
588
|
}
|
|
568
|
-
// Remove all existing attributes
|
|
569
|
-
sanitizeTagAttributes(tagElement);
|
|
570
|
-
// Update new tag attributes
|
|
571
|
-
const tagAttributes = getTagAttributes({
|
|
572
|
-
type: type,
|
|
573
|
-
status,
|
|
574
|
-
statusMsg,
|
|
575
|
-
displayName: tagLabel,
|
|
576
|
-
});
|
|
577
|
-
applyTagAttributes(tagElement, tagAttributes);
|
|
578
589
|
}
|
|
579
590
|
}
|
|
580
591
|
}
|
|
@@ -584,7 +595,7 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
584
595
|
if (!isAccepted)
|
|
585
596
|
return;
|
|
586
597
|
const { url, shortener, label } = tagData;
|
|
587
|
-
const { label: tagLabel, type: tagType,
|
|
598
|
+
const { label: tagLabel, isValid, message, type: tagType, } = getShortLinkTagInfo({
|
|
588
599
|
type,
|
|
589
600
|
label,
|
|
590
601
|
shortener,
|
|
@@ -599,16 +610,22 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
599
610
|
*/
|
|
600
611
|
if (tagTextNode) {
|
|
601
612
|
tagTextNode.textContent = tagLabel;
|
|
602
|
-
//
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
613
|
+
// Clear all previous attributes
|
|
614
|
+
tagElement.removeAttribute(REMOVED_TAG);
|
|
615
|
+
tagElement.removeAttribute(NO_VIEW_TAG);
|
|
616
|
+
tagElement.removeAttribute(INVALID_TAG);
|
|
617
|
+
tagElement.removeAttribute(READONLY_TAG);
|
|
618
|
+
tagElement.removeAttribute(MESSAGE_TAG);
|
|
619
|
+
// In case promotion pool has something wrong
|
|
620
|
+
if (!isValid && message) {
|
|
621
|
+
tagElement.setAttribute(REMOVED_TAG, 'true');
|
|
622
|
+
tagElement.setAttribute(MESSAGE_TAG, message);
|
|
623
|
+
tagifyRef.current?.getSetTagData(tagElement, {
|
|
624
|
+
...tagData,
|
|
625
|
+
status: 'error',
|
|
626
|
+
statusMsg: message,
|
|
627
|
+
});
|
|
628
|
+
}
|
|
612
629
|
}
|
|
613
630
|
}
|
|
614
631
|
}
|
|
@@ -616,52 +633,6 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
616
633
|
setTooltipRefresher(prev => prev + 1);
|
|
617
634
|
}
|
|
618
635
|
}, [acceptableTagPattern]);
|
|
619
|
-
/*
|
|
620
|
-
* Execute tag properties for each tag
|
|
621
|
-
*/
|
|
622
|
-
const executeTagProperties = useCallback((properties) => {
|
|
623
|
-
if (tagifyRef.current) {
|
|
624
|
-
let isChangeOccurred = false;
|
|
625
|
-
const tagElements = tagifyRef.current.getTagElms();
|
|
626
|
-
const { pattern, name: cachePatternName } = patternHandlers[PERSONALIZE_PTN];
|
|
627
|
-
tagElements.forEach(tagElement => {
|
|
628
|
-
const { __tagifyTagData: tagData } = tagElement;
|
|
629
|
-
if (!tagData || tagData?.type !== CUSTOM_TAG || !tagData?.value)
|
|
630
|
-
return;
|
|
631
|
-
const { type, value } = tagData;
|
|
632
|
-
// Use the cached regex instead of creating a new one each time
|
|
633
|
-
const regex = getCachedRegex(pattern, 'g', cachePatternName);
|
|
634
|
-
let match;
|
|
635
|
-
// Iterate over matches of the current pattern
|
|
636
|
-
// eslint-disable-next-line no-cond-assign
|
|
637
|
-
while ((match = regex.exec(value)) !== null) {
|
|
638
|
-
const [, contentCode] = match;
|
|
639
|
-
const customTagId = getCustomTagId(type, contentCode);
|
|
640
|
-
const property = _.get(properties, customTagId);
|
|
641
|
-
if (!customTagId || !property)
|
|
642
|
-
continue;
|
|
643
|
-
const { displayName } = property;
|
|
644
|
-
// Update tag text (but not raw data)
|
|
645
|
-
tagifyRef.current?.setTagTextNode(tagElement, displayName);
|
|
646
|
-
isChangeOccurred = true;
|
|
647
|
-
// Remove all existing attributes
|
|
648
|
-
sanitizeTagAttributes(tagElement);
|
|
649
|
-
// Update new tag attributes
|
|
650
|
-
const tagAttributes = getTagAttributes(property);
|
|
651
|
-
applyTagAttributes(tagElement, tagAttributes);
|
|
652
|
-
// Update tag content element attributes
|
|
653
|
-
const tagContentEl = tagElement.querySelector('.tagify__tag-content');
|
|
654
|
-
if (tagContentEl) {
|
|
655
|
-
const tagContentAttributes = getTagContentAttributes(property.type);
|
|
656
|
-
applyTagAttributes(tagContentEl, tagContentAttributes);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
});
|
|
660
|
-
if (isChangeOccurred) {
|
|
661
|
-
setTooltipRefresher(prev => prev + 1);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
}, []);
|
|
665
636
|
const initializeTagify = useCallback(() => {
|
|
666
637
|
if (inputRef.current && !tagifyRef.current) {
|
|
667
638
|
tagifyRef.current = new Tagify(inputRef.current, {
|
|
@@ -765,50 +736,6 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
765
736
|
}
|
|
766
737
|
};
|
|
767
738
|
}, [initializeTagify]);
|
|
768
|
-
useEffect(() => {
|
|
769
|
-
if (tagifyRef.current && tagLength && _.isFunction(onTagRemove)) {
|
|
770
|
-
// Because the remove tag event is not triggered when the tag is removed with Backspace or drag selection tags
|
|
771
|
-
// we need to listen to the input element to detect when a tag is removed
|
|
772
|
-
let mutationQueue = [];
|
|
773
|
-
let processing = false;
|
|
774
|
-
const processMutations = () => {
|
|
775
|
-
processing = true;
|
|
776
|
-
const relevantNodes = mutationQueue.flatMap(mutation => [...mutation.removedNodes].filter(node => {
|
|
777
|
-
const isUpdatedTag = mutation.addedNodes.length > 0;
|
|
778
|
-
return !isUpdatedTag && node.nodeType === Node.ELEMENT_NODE && node.nodeName === 'TAG';
|
|
779
|
-
}));
|
|
780
|
-
relevantNodes.forEach(node => {
|
|
781
|
-
try {
|
|
782
|
-
const tagData = tagifyRef.current?.getSetTagData(node);
|
|
783
|
-
if (tagData && tagData.type === CUSTOM_TAG && !tagData?.__removed) {
|
|
784
|
-
onTagRemove({ data: tagData });
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
catch (error) {
|
|
788
|
-
// biome-ignore lint/suspicious/noConsole: <explanation>
|
|
789
|
-
console.error('Error while removing tag with Backspace', error);
|
|
790
|
-
}
|
|
791
|
-
});
|
|
792
|
-
mutationQueue = [];
|
|
793
|
-
processing = false;
|
|
794
|
-
};
|
|
795
|
-
const observer = new MutationObserver(mutations => {
|
|
796
|
-
mutationQueue.push(...mutations);
|
|
797
|
-
if (!processing) {
|
|
798
|
-
requestAnimationFrame(processMutations); // Ensures all mutations are processed efficiently
|
|
799
|
-
}
|
|
800
|
-
});
|
|
801
|
-
observer.observe(tagifyRef.current.DOM.input, {
|
|
802
|
-
childList: true, // Only observe direct child additions/removals
|
|
803
|
-
subtree: false, // Prevent deep observation
|
|
804
|
-
attributes: false, // Ignore attribute changes
|
|
805
|
-
characterData: false, // Ignore text content changes
|
|
806
|
-
});
|
|
807
|
-
return () => {
|
|
808
|
-
observer.disconnect();
|
|
809
|
-
};
|
|
810
|
-
}
|
|
811
|
-
}, [tagLength, onTagRemove]);
|
|
812
739
|
// Settings some tagify attributes
|
|
813
740
|
// Set [readonly, disabled, placeholder]
|
|
814
741
|
useEffect(() => {
|
|
@@ -826,28 +753,27 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
826
753
|
}, [disabled, placeholder, readonly]);
|
|
827
754
|
// Set readonly for each tag
|
|
828
755
|
useEffect(() => {
|
|
829
|
-
if (tagifyRef.current &&
|
|
756
|
+
if (tagifyRef.current && typeof readonlyTag !== 'undefined') {
|
|
830
757
|
const tagElementList = tagifyRef.current.getTagElms();
|
|
831
758
|
tagElementList.forEach((tagElement) => {
|
|
832
759
|
const tagType = _.get(tagElement, '__tagifyTagData.type', '');
|
|
833
760
|
const isPersonalizeTag = isPersonalizeTagType(tagType);
|
|
834
|
-
const isCustomTag = isCustomTagType(tagType);
|
|
835
761
|
// Only support readonly for personalize tag
|
|
836
|
-
if (!isPersonalizeTag
|
|
762
|
+
if (!isPersonalizeTag)
|
|
837
763
|
return;
|
|
838
764
|
// Caution: Don't use readonly attribute -> readonly attribute Tagify library managed
|
|
839
765
|
if (readonlyTag) {
|
|
840
|
-
tagElement.setAttribute(
|
|
766
|
+
tagElement.setAttribute(READONLY_TAG, readonlyTag.toString());
|
|
841
767
|
}
|
|
842
768
|
else {
|
|
843
769
|
// Only remove readonly-tag attribute if the invalid attribute is not existing
|
|
844
770
|
if (!tagElement.hasAttribute(INVALID_TAG)) {
|
|
845
|
-
tagElement.removeAttribute(
|
|
771
|
+
tagElement.removeAttribute(READONLY_TAG);
|
|
846
772
|
}
|
|
847
773
|
}
|
|
848
774
|
});
|
|
849
775
|
}
|
|
850
|
-
}, [readonlyTag
|
|
776
|
+
}, [readonlyTag]);
|
|
851
777
|
// Set max personalize tags
|
|
852
778
|
useLayoutEffect(() => {
|
|
853
779
|
if (tagifyRef.current && typeof maxPersonalizeTags !== 'undefined') {
|
|
@@ -858,13 +784,10 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
858
784
|
* Need to sync label of the tags if any map attribute is changed to make correct label
|
|
859
785
|
* */
|
|
860
786
|
useDeepCompareEffect(() => {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
useLayoutEffect(() => {
|
|
864
|
-
if (tagProperties && tagLength) {
|
|
865
|
-
executeTagProperties(tagProperties);
|
|
787
|
+
if (!_.isEmpty(mapAttributes)) {
|
|
788
|
+
makeValidLabelTags(mapAttributes, mapErrorAttributes);
|
|
866
789
|
}
|
|
867
|
-
}, [
|
|
790
|
+
}, [mapAttributes, mapErrorAttributes, makeValidLabelTags]);
|
|
868
791
|
// Listen to Tagify events
|
|
869
792
|
useEffect(() => {
|
|
870
793
|
const { current: tagifyInstance } = tagifyRef || {};
|
|
@@ -876,13 +799,11 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
876
799
|
tagifyInstance.on('click', onTagItemClick);
|
|
877
800
|
tagifyInstance.on('input', onInputTagifyDebounce);
|
|
878
801
|
tagifyInstance.on('change', onTagifyChangedDebounce);
|
|
879
|
-
tagifyInstance.on('remove', onTagifyRemoveTag);
|
|
880
802
|
}
|
|
881
803
|
// Off listen to Tagify events
|
|
882
804
|
return () => {
|
|
883
805
|
if (tagifyInstance) {
|
|
884
806
|
tagifyInstance.off('click', onTagItemClick);
|
|
885
|
-
tagifyInstance.off('remove', onTagifyRemoveTag);
|
|
886
807
|
if (onInputTagifyDebounce) {
|
|
887
808
|
tagifyInstance.off('input', onInputTagifyDebounce);
|
|
888
809
|
}
|
|
@@ -891,7 +812,7 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
891
812
|
}
|
|
892
813
|
}
|
|
893
814
|
};
|
|
894
|
-
}, [onTagItemClick, onTagifyTyping, onTagifyChanged
|
|
815
|
+
}, [onTagItemClick, onTagifyTyping, onTagifyChanged]);
|
|
895
816
|
// At the first render, need to update URL to tag to show hint in the tooltip with tag
|
|
896
817
|
useEffect(() => {
|
|
897
818
|
detectReplaceURLToTag();
|
|
@@ -912,24 +833,20 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
912
833
|
}
|
|
913
834
|
// Convert the string to tagify pattern
|
|
914
835
|
const content = parseTagStringToTagify(textValue, acceptableTagPattern);
|
|
915
|
-
setIsLineBreak(hasLineBreak(textValue));
|
|
916
836
|
tagifyRef.current.loadOriginalValues(content);
|
|
917
837
|
// Need to sync label of the tags if any map attribute is changed to make correct label
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
executeTagProperties(tagProperties);
|
|
838
|
+
if (!_.isEmpty(mapAttributes)) {
|
|
839
|
+
makeValidLabelTags(mapAttributes, mapErrorAttributes);
|
|
921
840
|
}
|
|
922
841
|
}
|
|
923
842
|
}
|
|
924
843
|
}, [
|
|
925
844
|
initialValue,
|
|
926
845
|
mapAttributes,
|
|
927
|
-
tagProperties,
|
|
928
846
|
mapErrorAttributes,
|
|
929
847
|
escapeHTML,
|
|
930
848
|
acceptableTagPattern,
|
|
931
849
|
makeValidLabelTags,
|
|
932
|
-
executeTagProperties,
|
|
933
850
|
]);
|
|
934
851
|
useEffect(() => {
|
|
935
852
|
if (tagifyRef.current && initialValue === '') {
|
|
@@ -989,14 +906,9 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
989
906
|
}, []);
|
|
990
907
|
useDeepCompareEffect(() => {
|
|
991
908
|
const showTooltip = (tagElement) => {
|
|
992
|
-
const isTagReadonly = tagifyRef.current?.settings.readonly;
|
|
993
|
-
const tagType = tagElement.getAttribute('type');
|
|
994
|
-
// If tag is readonly and tag type is hint for link, do not show the tooltip
|
|
995
|
-
if (isTagReadonly && tagType === DETECT_LINK)
|
|
996
|
-
return;
|
|
997
909
|
const tagRect = tagElement.getBoundingClientRect();
|
|
998
|
-
const
|
|
999
|
-
const
|
|
910
|
+
const removeTag = tagElement.getAttribute(REMOVED_TAG);
|
|
911
|
+
const noViewTag = tagElement.getAttribute(NO_VIEW_TAG);
|
|
1000
912
|
const invalidTag = tagElement.getAttribute(INVALID_TAG);
|
|
1001
913
|
const messageTag = tagElement.getAttribute(MESSAGE_TAG);
|
|
1002
914
|
const forceShowTooltipAttr = tagElement.getAttribute(FORCE_SHOW_TOOLTIP);
|
|
@@ -1009,19 +921,15 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
1009
921
|
const tooltip = document.querySelector('.tagify__tooltip');
|
|
1010
922
|
tooltip?.setAttribute('style', 'display: block !important;visibility: hidden !important;');
|
|
1011
923
|
const tooltipRect = tooltip?.getBoundingClientRect();
|
|
1012
|
-
const hasWrongAttribute =
|
|
924
|
+
const hasWrongAttribute = removeTag === 'true' || noViewTag === 'true' || invalidTag === 'true';
|
|
1013
925
|
const isTooltipVisible = tooltipRect && hasWrongAttribute;
|
|
1014
926
|
const isForceVisible = tooltipRect && forceShowTooltipAttr === 'true';
|
|
1015
927
|
if (isTooltipVisible || isForceVisible) {
|
|
1016
|
-
const offsetTop = 30;
|
|
1017
|
-
const top = tagRect.y - offsetTop;
|
|
1018
928
|
if (tooltipRect?.width > tagRect.width) {
|
|
1019
|
-
|
|
1020
|
-
tooltip?.setAttribute('style', `visibility: visible !important;display: block !important;top:${top}px;left:${left}px;`);
|
|
929
|
+
tooltip?.setAttribute('style', `visibility: visible !important;display: block !important;top:${tagRect.y - tagRect.height - 10}px;left:${tagRect.x - (tooltipRect?.width - tagRect.width) / 2}px;`);
|
|
1021
930
|
}
|
|
1022
931
|
else {
|
|
1023
|
-
|
|
1024
|
-
tooltip?.setAttribute('style', `visibility: visible !important;display: block !important;top:${top}px;left:${left}px;`);
|
|
932
|
+
tooltip?.setAttribute('style', `visibility: visible !important;display: block !important;top:${tagRect.y - tagRect.height - 10}px;left:${tagRect.x + (tagRect?.width - tooltipRect.width) / 2}px;`);
|
|
1025
933
|
}
|
|
1026
934
|
}
|
|
1027
935
|
};
|
|
@@ -4,32 +4,15 @@ export declare const DIMENSIONS: {
|
|
|
4
4
|
readonly TAG_H: 24;
|
|
5
5
|
};
|
|
6
6
|
export declare const MIN_H_WRAPPER: 34, TAG_H: 24;
|
|
7
|
-
export declare const TAG_STATUS: {
|
|
8
|
-
readonly REMOVED: "removed";
|
|
9
|
-
readonly ARCHIVED: "archived";
|
|
10
|
-
readonly ACTIVE: "active";
|
|
11
|
-
readonly INACTIVE: "inactive";
|
|
12
|
-
readonly EXPIRED: "expired";
|
|
13
|
-
readonly WARNING: "warning";
|
|
14
|
-
readonly ERROR: "error";
|
|
15
|
-
readonly INVALID: "invalid";
|
|
16
|
-
readonly DO_NOT_VIEW: "do-not-view";
|
|
17
|
-
};
|
|
18
7
|
export declare const TAG_CUSTOM_ATTRIBUTES: {
|
|
19
|
-
readonly PREPARING_ST: "preparing-setting";
|
|
20
8
|
readonly READONLY_TAG: "readonly-tag";
|
|
21
9
|
readonly INVALID_TAG: "invalid-tag";
|
|
22
10
|
readonly REMOVED_TAG: "removed-tag";
|
|
23
11
|
readonly NO_VIEW_TAG: "no-view-tag";
|
|
24
12
|
readonly MESSAGE_TAG: "message-tag";
|
|
25
13
|
readonly FORCE_SHOW_TOOLTIP: "force-show-tooltip";
|
|
26
|
-
readonly ERROR_TAG: "error-tag";
|
|
27
|
-
readonly WARNING_TAG: "warning-tag";
|
|
28
|
-
readonly PRIORITY_COLOR_TYPE: "priority-color-type";
|
|
29
|
-
readonly BG_COLOR_PERSONALIZE_TYPE: "bg-color-personalize-type";
|
|
30
|
-
readonly BG_COLOR_PERSONALIZE_TYPE_V2: "bgColorPersonalizeType";
|
|
31
14
|
};
|
|
32
|
-
export declare const
|
|
15
|
+
export declare const READONLY_TAG: "readonly-tag", INVALID_TAG: "invalid-tag", REMOVED_TAG: "removed-tag", NO_VIEW_TAG: "no-view-tag", MESSAGE_TAG: "message-tag", FORCE_SHOW_TOOLTIP: "force-show-tooltip";
|
|
33
16
|
export declare const defaultCssVariables: {
|
|
34
17
|
'--input-color': string | undefined;
|
|
35
18
|
'--input-font-size': string;
|
|
@@ -74,11 +57,8 @@ export declare const TAG_TYPE: {
|
|
|
74
57
|
readonly SHORT_LINK_V2: "shortlink_v2";
|
|
75
58
|
readonly DETECT_LINK: "detect_link";
|
|
76
59
|
readonly CONTENT_SOURCE_GROUP: "groups";
|
|
77
|
-
readonly ALLOCATED_CODE: "allocated_code";
|
|
78
|
-
readonly CUSTOM_TAG: "custom_tag";
|
|
79
60
|
};
|
|
80
|
-
export declare const CUSTOMER: "customer", VISITOR: "visitor", EVENT: "event", JOURNEY: "story", CAMPAIGN: "campaign", VARIANT: "variant", PROMOTION_CODE: "promotion_code", CUSTOM_FN: "custom", EMOJI: "emoji", DETECT_LINK: "detect_link", SHORT_LINK: "shortlink", SHORT_LINK_V2: "shortlink_v2", OBJECT_WIDGET: "objectWidget", CONTENT_SOURCE_GROUP: "groups"
|
|
81
|
-
export declare const TAG_TYPE_LIST: readonly ("campaign" | "event" | "custom" | "emoji" | "visitor" | "customer" | "groups" | "shortlink" | "story" | "variant" | "objectWidget" | "promotion_code" | "shortlink_v2" | "detect_link" | "allocated_code" | "custom_tag")[];
|
|
61
|
+
export declare const CUSTOMER: "customer", VISITOR: "visitor", EVENT: "event", JOURNEY: "story", CAMPAIGN: "campaign", VARIANT: "variant", PROMOTION_CODE: "promotion_code", CUSTOM_FN: "custom", EMOJI: "emoji", DETECT_LINK: "detect_link", SHORT_LINK: "shortlink", SHORT_LINK_V2: "shortlink_v2", OBJECT_WIDGET: "objectWidget", CONTENT_SOURCE_GROUP: "groups";
|
|
82
62
|
export declare const SHORT_LINK_TYPE: {
|
|
83
63
|
readonly INDIVIDUAL: "shortlink";
|
|
84
64
|
readonly GENERAL: "shortlink_static";
|
|
@@ -108,8 +88,6 @@ export declare const TAG_COLOR: {
|
|
|
108
88
|
readonly custom: "#bbefbe";
|
|
109
89
|
readonly groups: "#ffdd9f";
|
|
110
90
|
readonly emoji: "transparent";
|
|
111
|
-
readonly allocated_code: "#DAA7F8";
|
|
112
|
-
readonly custom_tag: "transparent";
|
|
113
91
|
};
|
|
114
92
|
export declare const EMOJI_COLLECTIONS: {
|
|
115
93
|
readonly COMMON: "common";
|
|
@@ -5,32 +5,15 @@ export const DIMENSIONS = {
|
|
|
5
5
|
TAG_H: 24,
|
|
6
6
|
};
|
|
7
7
|
export const { MIN_H_WRAPPER, TAG_H } = DIMENSIONS;
|
|
8
|
-
export const TAG_STATUS = {
|
|
9
|
-
REMOVED: 'removed',
|
|
10
|
-
ARCHIVED: 'archived',
|
|
11
|
-
ACTIVE: 'active',
|
|
12
|
-
INACTIVE: 'inactive',
|
|
13
|
-
EXPIRED: 'expired',
|
|
14
|
-
WARNING: 'warning',
|
|
15
|
-
ERROR: 'error',
|
|
16
|
-
INVALID: 'invalid',
|
|
17
|
-
DO_NOT_VIEW: 'do-not-view',
|
|
18
|
-
};
|
|
19
8
|
export const TAG_CUSTOM_ATTRIBUTES = {
|
|
20
|
-
PREPARING_ST: 'preparing-setting',
|
|
21
9
|
READONLY_TAG: 'readonly-tag',
|
|
22
10
|
INVALID_TAG: 'invalid-tag',
|
|
23
11
|
REMOVED_TAG: 'removed-tag',
|
|
24
12
|
NO_VIEW_TAG: 'no-view-tag',
|
|
25
13
|
MESSAGE_TAG: 'message-tag',
|
|
26
14
|
FORCE_SHOW_TOOLTIP: 'force-show-tooltip',
|
|
27
|
-
ERROR_TAG: 'error-tag',
|
|
28
|
-
WARNING_TAG: 'warning-tag',
|
|
29
|
-
PRIORITY_COLOR_TYPE: 'priority-color-type',
|
|
30
|
-
BG_COLOR_PERSONALIZE_TYPE: 'bg-color-personalize-type',
|
|
31
|
-
BG_COLOR_PERSONALIZE_TYPE_V2: 'bgColorPersonalizeType',
|
|
32
15
|
};
|
|
33
|
-
export const {
|
|
16
|
+
export const { READONLY_TAG, INVALID_TAG, REMOVED_TAG, NO_VIEW_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP, } = TAG_CUSTOM_ATTRIBUTES;
|
|
34
17
|
export const defaultCssVariables = {
|
|
35
18
|
'--input-color': globalToken?.colorText,
|
|
36
19
|
'--input-font-size': `${globalToken?.fontSize}px`,
|
|
@@ -72,7 +55,6 @@ export const tagifyDefaultProps = {
|
|
|
72
55
|
placeholder: undefined,
|
|
73
56
|
minWidthPlaceholder: 130,
|
|
74
57
|
acceptableTagPattern: DEFAULT_ACCEPT_TAGS,
|
|
75
|
-
mapErrorAttributes: {},
|
|
76
58
|
onChange: () => { },
|
|
77
59
|
};
|
|
78
60
|
export const TAG_TYPE = {
|
|
@@ -90,11 +72,8 @@ export const TAG_TYPE = {
|
|
|
90
72
|
SHORT_LINK_V2: 'shortlink_v2',
|
|
91
73
|
DETECT_LINK: 'detect_link',
|
|
92
74
|
CONTENT_SOURCE_GROUP: 'groups',
|
|
93
|
-
ALLOCATED_CODE: 'allocated_code',
|
|
94
|
-
CUSTOM_TAG: 'custom_tag', // Refer to all tag type
|
|
95
75
|
};
|
|
96
|
-
export const { CUSTOMER, VISITOR, EVENT, JOURNEY, CAMPAIGN, VARIANT, PROMOTION_CODE, CUSTOM_FN, EMOJI, DETECT_LINK, SHORT_LINK, SHORT_LINK_V2, OBJECT_WIDGET, CONTENT_SOURCE_GROUP,
|
|
97
|
-
export const TAG_TYPE_LIST = Object.freeze(Object.values(TAG_TYPE));
|
|
76
|
+
export const { CUSTOMER, VISITOR, EVENT, JOURNEY, CAMPAIGN, VARIANT, PROMOTION_CODE, CUSTOM_FN, EMOJI, DETECT_LINK, SHORT_LINK, SHORT_LINK_V2, OBJECT_WIDGET, CONTENT_SOURCE_GROUP, } = TAG_TYPE;
|
|
98
77
|
export const SHORT_LINK_TYPE = {
|
|
99
78
|
INDIVIDUAL: 'shortlink', // Individual link
|
|
100
79
|
GENERAL: 'shortlink_static', // General link
|
|
@@ -124,8 +103,6 @@ export const TAG_COLOR = {
|
|
|
124
103
|
[CUSTOM_FN]: '#bbefbe',
|
|
125
104
|
[CONTENT_SOURCE_GROUP]: '#ffdd9f',
|
|
126
105
|
[EMOJI]: 'transparent',
|
|
127
|
-
[ALLOCATED_CODE]: '#DAA7F8',
|
|
128
|
-
[CUSTOM_TAG]: 'transparent',
|
|
129
106
|
};
|
|
130
107
|
export const EMOJI_COLLECTIONS = {
|
|
131
108
|
COMMON: 'common',
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { AcceptablePattern, MapAttributesProps, PatterTagName, PatternHandlerWrapper
|
|
1
|
+
import type { AcceptablePattern, MapAttributesProps, PatterTagName, PatternHandlerWrapper } from './types';
|
|
2
2
|
interface TagInfo {
|
|
3
3
|
label: string;
|
|
4
4
|
type: string;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
isValid: boolean;
|
|
6
|
+
message?: string;
|
|
7
|
+
isRemoved?: boolean;
|
|
8
|
+
hasViewPermission?: boolean;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* Retrieves a cached regular expression or compiles and caches it if not found.
|
|
@@ -16,15 +18,7 @@ export declare function getCachedRegex(pattern: string, flags?: string, cacheKey
|
|
|
16
18
|
export declare const detectURLRegex: RegExp;
|
|
17
19
|
export declare const tagRegexStringPattern = "\\[\\[({.*?})\\]\\]";
|
|
18
20
|
export declare function acceptablePatternChecking(pattern: AcceptablePattern, acceptablePattern: Array<AcceptablePattern>): boolean;
|
|
19
|
-
|
|
20
|
-
* Extracts the custom tag ID from a merge code if the tag type is a custom tag.
|
|
21
|
-
*
|
|
22
|
-
* @param {TagTypeProperty} tagType - The type of the tag to check.
|
|
23
|
-
* @param {string} mergeCode - The merge code containing the tag information, typically in the format "type.customTagId||additionalInfo".
|
|
24
|
-
* @returns {string} The extracted custom tag ID if the tag type is a custom tag; otherwise, empty string.
|
|
25
|
-
*/
|
|
26
|
-
export declare const getCustomTagId: (tagType: TagTypeProperty, mergeCode: string) => string;
|
|
27
|
-
export declare const getPersonalizeTagInfo: (originalTag: string, mapAttributes: MapAttributesProps, mapErrorAttributes: MapAttributesProps) => TagInfo;
|
|
21
|
+
export declare const getPersonalizeTagInfo: (originalTag: string, mapAttributes?: MapAttributesProps, mapErrorAttributes?: MapAttributesProps) => TagInfo;
|
|
28
22
|
export declare const getShortLinkTagInfo: (params: {
|
|
29
23
|
type: string;
|
|
30
24
|
label: string;
|