@antscorp/antsomi-ui 1.3.5-beta.907 → 1.3.5-beta.908

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 = {
@@ -16,7 +16,7 @@ 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, } from './utils';
19
+ import { parseTagStringToTagify, convertInputStringToOriginal, emojiManufacturer, getEmojiTag, isPersonalizeTagType, generateTagContent, unescapeString, hasLineBreak, selectRange, isTagClickable, findURLInTextNodes, getAttributesString, isAnchorNodeChildOfElement, } from './utils';
20
20
  import { acceptablePatternChecking, detectURLRegex, getCachedRegex, getPersonalizeTagInfo, patternHandlers, } from './patternHandlers';
21
21
  // Constants
22
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, defaultCssVariables, tagifyDefaultProps, } from './constants';
@@ -80,8 +80,15 @@ const TagifyInput = forwardRef((props, ref) => {
80
80
  }, []);
81
81
  const onSelectionAfterInjection = useCallback((addRangeAfterInjected) => {
82
82
  try {
83
- const selection = window.getSelection();
84
- if (selection?.rangeCount) {
83
+ if (!tagifyRef.current) {
84
+ throw new Error('Tagify instance is not initialized');
85
+ }
86
+ const { scope } = tagifyRef.current?.DOM;
87
+ const isValidSelection = isAnchorNodeChildOfElement(scope);
88
+ if (isValidSelection) {
89
+ const selection = window.getSelection();
90
+ if (!selection?.rangeCount)
91
+ return;
85
92
  const range = selection.getRangeAt(0);
86
93
  if (addRangeAfterInjected) {
87
94
  // Need to re-select to keep the caret position
@@ -107,9 +114,10 @@ const TagifyInput = forwardRef((props, ref) => {
107
114
  const { settings, DOM } = tagifyRef.current;
108
115
  const rangeInstance = _.get(tagifyRef.current, 'state.selection.range', null);
109
116
  const { empty } = settings.classNames;
117
+ const isValidSelection = isAnchorNodeChildOfElement(DOM.scope);
110
118
  const selection = window.getSelection();
111
119
  // In case not have the selection yet or lost the selection,
112
- if (!selection?.rangeCount || !rangeInstance) {
120
+ if (!selection?.rangeCount || !isValidSelection || !rangeInstance) {
113
121
  // need to restore the last range before inject a new tag if the last range exists
114
122
  if (lastRange.current) {
115
123
  selection?.removeAllRanges();
@@ -173,3 +173,11 @@ export declare function findURLInTextNodes(element: HTMLSpanElement, minLengthVa
173
173
  * // Returns: 'class="btn-primary" disabled data-testid="submit-button" aria-label="Submit form" tabindex="0"'
174
174
  */
175
175
  export declare const getAttributesString: (map: Map<string, string | boolean | number>) => string;
176
+ /**
177
+ * Checks if the anchor node of the current text selection
178
+ * is a child of a specific DOM element.
179
+ *
180
+ * @param {HTMLElement} element - The parent element to check against
181
+ * @returns {boolean} True if the anchor node is a child of the element, false otherwise
182
+ */
183
+ export declare const isAnchorNodeChildOfElement: (element: Node) => boolean;
@@ -602,3 +602,26 @@ export const getAttributesString = (map) => Array.from(map.entries())
602
602
  })
603
603
  .filter(Boolean)
604
604
  .join(' ');
605
+ /**
606
+ * Checks if the anchor node of the current text selection
607
+ * is a child of a specific DOM element.
608
+ *
609
+ * @param {HTMLElement} element - The parent element to check against
610
+ * @returns {boolean} True if the anchor node is a child of the element, false otherwise
611
+ */
612
+ export const isAnchorNodeChildOfElement = (element) => {
613
+ // Get the current selection
614
+ const selection = window.getSelection();
615
+ // Check if there's an active selection
616
+ if (!selection || selection.rangeCount === 0) {
617
+ return false;
618
+ }
619
+ // Get the anchor node (where the selection starts)
620
+ const { anchorNode } = selection;
621
+ // Check if the anchor node exists and the element exists
622
+ if (!anchorNode || !element) {
623
+ return false;
624
+ }
625
+ // Use Node.contains() to check if the element contains the anchor node
626
+ return element.contains(anchorNode);
627
+ };
@@ -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.907",
3
+ "version": "1.3.5-beta.908",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",