@antscorp/antsomi-ui 1.3.5-beta.926 → 1.3.5-beta.928

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.
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import type { PayloadInfo } from '@antscorp/antsomi-ui/es/types';
3
2
  export type TDisplayFormat = 'number' | 'percentage' | 'currency' | 'datetime';
4
3
  type DisplayFormatProps = {
@@ -26,6 +26,7 @@ const TagifyInput = forwardRef((props, ref) => {
26
26
  // States
27
27
  const [isLineBreak, setIsLineBreak] = useState(hasLineBreak(initialValue));
28
28
  const [tooltipRefresher, setTooltipRefresher] = useState(1);
29
+ const [labelTagRefreshness, setLabelTagRefreshness] = useState(1);
29
30
  // Refs
30
31
  const inputRef = useRef(null);
31
32
  const tagifyRef = useRef(null);
@@ -84,7 +85,8 @@ const TagifyInput = forwardRef((props, ref) => {
84
85
  throw new Error('Tagify instance is not initialized');
85
86
  }
86
87
  const { scope } = tagifyRef.current?.DOM;
87
- const isValidSelection = isAnchorNodeChildOfElement(scope);
88
+ const anchorNodeInstance = _.get(tagifyRef.current, 'state.selection.anchorNode', null);
89
+ const isValidSelection = isAnchorNodeChildOfElement(scope, anchorNodeInstance);
88
90
  if (isValidSelection) {
89
91
  const selection = window.getSelection();
90
92
  if (!selection?.rangeCount)
@@ -113,17 +115,20 @@ const TagifyInput = forwardRef((props, ref) => {
113
115
  }
114
116
  const { settings, DOM } = tagifyRef.current;
115
117
  const rangeInstance = _.get(tagifyRef.current, 'state.selection.range', null);
118
+ const anchorNodeInstance = _.get(tagifyRef.current, 'state.selection.anchorNode', null);
116
119
  const { empty } = settings.classNames;
117
- const isValidSelection = isAnchorNodeChildOfElement(DOM.scope);
120
+ const isValidAnchor = isAnchorNodeChildOfElement(DOM.scope, anchorNodeInstance);
118
121
  const selection = window.getSelection();
122
+ const isValidRange = selection?.rangeCount && rangeInstance;
123
+ const hasValidSelection = isValidRange && isValidAnchor;
119
124
  // In case not have the selection yet or lost the selection,
120
- if (!selection?.rangeCount || !isValidSelection || !rangeInstance) {
125
+ if (!hasValidSelection) {
121
126
  // need to restore the last range before inject a new tag if the last range exists
122
127
  if (lastRange.current) {
123
128
  selection?.removeAllRanges();
124
129
  selection?.addRange(lastRange.current);
125
130
  }
126
- else {
131
+ else if (!isValidRange) {
127
132
  // If the last range is lost, need to select the last text node of the input
128
133
  const { input: inputElement } = tagifyRef.current.DOM;
129
134
  if (inputElement) {
@@ -426,6 +431,12 @@ const TagifyInput = forwardRef((props, ref) => {
426
431
  tagifyRef.current.loadOriginalValues(newContent);
427
432
  }
428
433
  },
434
+ onLabelTagRefreshness() {
435
+ if (!tagifyRef.current) {
436
+ throw new Error('Tagify instance is not initialized');
437
+ }
438
+ setLabelTagRefreshness(prev => prev + 1);
439
+ },
429
440
  }), [acceptableTagPattern, escapeHTML, onInjectTagAtCaret, placeCaretAfterNode]);
430
441
  const onTagItemClick = useCallback((event) => {
431
442
  event.stopPropagation();
@@ -518,7 +529,7 @@ const TagifyInput = forwardRef((props, ref) => {
518
529
  * Any map attribute change will sync label of the tags
519
530
  */
520
531
  const makeValidLabelTags = useCallback((attributes, errorAttributes) => {
521
- if (tagifyRef.current) {
532
+ if (tagifyRef.current && labelTagRefreshness) {
522
533
  const tagElements = tagifyRef.current.getTagElms();
523
534
  const { pattern, name: cachePatternName, acceptablePattern: acceptableType, } = patternHandlers[PERSONALIZE_PTN];
524
535
  tagElements.forEach(tagElement => {
@@ -633,7 +644,7 @@ const TagifyInput = forwardRef((props, ref) => {
633
644
  });
634
645
  setTooltipRefresher(prev => prev + 1);
635
646
  }
636
- }, [acceptableTagPattern]);
647
+ }, [acceptableTagPattern, labelTagRefreshness]);
637
648
  const initializeTagify = useCallback(() => {
638
649
  if (inputRef.current && !tagifyRef.current) {
639
650
  tagifyRef.current = new Tagify(inputRef.current, {
@@ -130,6 +130,7 @@ export interface TagifyInputRef {
130
130
  onAddNewTag: (newTag: TagDataCustomize | string) => void;
131
131
  onReplaceTag: (currentTagEle: HTMLElement, newTag: TagDataCustomize) => void;
132
132
  onReload: (newValue: string) => void;
133
+ onLabelTagRefreshness: () => void;
133
134
  }
134
135
  export type EmojiCollection = (typeof EMOJI_COLLECTIONS)[keyof typeof EMOJI_COLLECTIONS];
135
136
  export type TagType = (typeof TAG_TYPE)[keyof typeof TAG_TYPE];
@@ -180,6 +180,7 @@ export declare const getAttributesString: (map: Map<string, string | boolean | n
180
180
  * is a child of a specific DOM element.
181
181
  *
182
182
  * @param {HTMLElement} element - The parent element to check against
183
+ * @param {HTMLElement} anchorNodeInstance - The anchor node of the Tagify instance
183
184
  * @returns {boolean} True if the anchor node is a child of the element, false otherwise
184
185
  */
185
- export declare const isAnchorNodeChildOfElement: (element: Node) => boolean;
186
+ export declare const isAnchorNodeChildOfElement: (element: Node, anchorNodeInstance: Node | null) => boolean;
@@ -628,9 +628,10 @@ export const getAttributesString = (map) => Array.from(map.entries())
628
628
  * is a child of a specific DOM element.
629
629
  *
630
630
  * @param {HTMLElement} element - The parent element to check against
631
+ * @param {HTMLElement} anchorNodeInstance - The anchor node of the Tagify instance
631
632
  * @returns {boolean} True if the anchor node is a child of the element, false otherwise
632
633
  */
633
- export const isAnchorNodeChildOfElement = (element) => {
634
+ export const isAnchorNodeChildOfElement = (element, anchorNodeInstance) => {
634
635
  // Get the current selection
635
636
  const selection = window.getSelection();
636
637
  // Check if there's an active selection
@@ -644,5 +645,5 @@ export const isAnchorNodeChildOfElement = (element) => {
644
645
  return false;
645
646
  }
646
647
  // Use Node.contains() to check if the element contains the anchor node
647
- return element.contains(anchorNode);
648
+ return element.contains(anchorNode) && element.contains(anchorNodeInstance);
648
649
  };
@@ -3,5 +3,4 @@
3
3
  * Asynchronously loads the component for TemplateListing
4
4
  *
5
5
  */
6
- /// <reference types="react" />
7
6
  export declare const TemplateListing: (props: import("./types").TemplateListingProps<{}>) => JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.5-beta.926",
3
+ "version": "1.3.5-beta.928",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",