@antscorp/antsomi-ui 1.3.7-beta.4 → 1.3.7-beta.6

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.
@@ -25,7 +25,7 @@ const { CUSTOM_TAG } = TAG_TYPE;
25
25
  const { PREPARING_ST, INVALID_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP } = TAG_CUSTOM_ATTRIBUTES;
26
26
  const TagifyInput = forwardRef((props, ref) => {
27
27
  // Props
28
- const { initialValue, escapeHTML, status, readonly, readonlyTag, readonlyText, realtime, disabled, maxLength, maxHeight, minWidth, placeholder, minWidthPlaceholder, isSingleLineText, acceptableTagPattern, tagProperties, mapAttributes = {}, mapErrorAttributes = {}, maxPersonalizeTags, name, children, cssTagifyVariables, onTagClick, onTagRemove, onChange, onRestoreTagProperty, } = props;
28
+ const { initialValue, escapeHTML, status, readonly, readonlyTag, readonlyText, readonlyWhenNotEmpty, realtime, disabled, maxLength, maxHeight, minWidth, placeholder, minWidthPlaceholder, isSingleLineText, acceptableTagPattern, tagProperties, mapAttributes = {}, mapErrorAttributes = {}, maxPersonalizeTags, name, children, cssTagifyVariables, onTagClick, onTagRemove, onChange, onRestoreTagProperty, onBlur, } = props;
29
29
  // States
30
30
  const [isLineBreak, setIsLineBreak] = useState(hasLineBreak(initialValue));
31
31
  const [tooltipRefresher, setTooltipRefresher] = useState(1);
@@ -768,17 +768,26 @@ const TagifyInput = forwardRef((props, ref) => {
768
768
  }
769
769
  }, [maxLength, customizeTag]);
770
770
  useEffect(() => {
771
- if (!tagifyRef.current || typeof readonlyText === 'undefined')
771
+ if (!tagifyRef.current)
772
+ return;
773
+ // Skip if neither readonlyText nor readonlyWhenNotEmpty is defined
774
+ if (typeof readonlyText === 'undefined' && !readonlyWhenNotEmpty)
772
775
  return;
773
776
  const inputEl = tagifyRef.current.DOM.input;
774
- if (typeof readonlyText === 'function') {
777
+ // readonlyWhenNotEmpty takes priority if both are set
778
+ if (readonlyWhenNotEmpty) {
779
+ const cleanValue = tagifyRef.current.getInputValue();
780
+ const hasContent = cleanValue.length > 0;
781
+ inputEl.setAttribute('contenteditable', hasContent ? 'false' : 'true');
782
+ }
783
+ else if (typeof readonlyText === 'function') {
775
784
  const isReadonlyText = readonlyText(tagifyRef.current.getCleanValue());
776
785
  inputEl.setAttribute('contenteditable', isReadonlyText ? 'false' : 'true');
777
786
  }
778
- else {
787
+ else if (typeof readonlyText !== 'undefined') {
779
788
  inputEl.setAttribute('contenteditable', readonlyText ? 'false' : 'true');
780
789
  }
781
- }, [readonlyText, tagLength]);
790
+ }, [readonlyText, readonlyWhenNotEmpty, tagLength]);
782
791
  const onTagifyWrapperClick = useCallback(event => {
783
792
  event.preventDefault();
784
793
  event.stopPropagation();
@@ -978,6 +987,8 @@ const TagifyInput = forwardRef((props, ref) => {
978
987
  tagifyInstance.on('change', onTagifyChangedDebounce);
979
988
  tagifyInstance.on('remove', onTagifyRemoveTag);
980
989
  tagifyInstance.on('keydown', onKeyDown);
990
+ if (onBlur)
991
+ tagifyInstance.on('blur', onBlur);
981
992
  }
982
993
  // Off listen to Tagify events
983
994
  return () => {
@@ -987,9 +998,12 @@ const TagifyInput = forwardRef((props, ref) => {
987
998
  tagifyInstance.off('change', onTagifyChangedDebounce);
988
999
  tagifyInstance.off('remove', onTagifyRemoveTag);
989
1000
  tagifyInstance.off('keydown', onKeyDown);
1001
+ if (onBlur)
1002
+ tagifyInstance.off('blur', onBlur);
990
1003
  }
991
1004
  };
992
1005
  }, [
1006
+ onBlur,
993
1007
  onTagItemClick,
994
1008
  onInputTagifyDebounce,
995
1009
  onTagifyChangedDebounce,
@@ -146,6 +146,11 @@ export interface TagifyInputProps {
146
146
  * @default () => {}
147
147
  */
148
148
  onChange: (inputValue: string) => void;
149
+ /**
150
+ * Event handler triggered when the input value is blurred.
151
+ * Receives the updated input value as a string, allowing for controlled component updates.
152
+ */
153
+ onBlur?: (event: CustomEvent<Tagify.BlurEventData<TagDataCustomize>>) => void;
149
154
  /**
150
155
  * Event handler triggered when found mismatch tag properties.
151
156
  * Receives an array of tag properties that were restored (e.g., via undo operation).
@@ -155,6 +160,14 @@ export interface TagifyInputProps {
155
160
  * Defines whether the input text is read but not the whole tags.
156
161
  */
157
162
  readonlyText?: boolean | ((listTags: TagDataCustomize[]) => boolean);
163
+ /**
164
+ * When true, automatically sets the input text to readonly (contenteditable='false')
165
+ * when the input is not empty (has tags or content).
166
+ * This is a convenience prop that internally uses readonlyText callback.
167
+ *
168
+ * @default false
169
+ */
170
+ readonlyWhenNotEmpty?: boolean;
158
171
  }
159
172
  export interface TagifyInputRef {
160
173
  onAddNewTag: (newTag: TagDataCustomize | string) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.7-beta.4",
3
+ "version": "1.3.7-beta.6",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",