@antscorp/antsomi-ui 1.3.7-beta.3 → 1.3.7-beta.5

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.
@@ -49,8 +49,6 @@ export * from './RateV2';
49
49
  export * from './Popover';
50
50
  export * from './Iframe';
51
51
  export * from './Avatar';
52
- export * from './NotificationStatus';
53
- export * from './List';
54
52
  export * from './SelectAssociatedTag';
55
53
  export * from './List';
56
54
  export * from './Upload';
@@ -49,8 +49,6 @@ export * from './RateV2';
49
49
  export * from './Popover';
50
50
  export * from './Iframe';
51
51
  export * from './Avatar';
52
- export * from './NotificationStatus';
53
- export * from './List';
54
52
  export * from './SelectAssociatedTag';
55
53
  export * from './List';
56
54
  export * from './Upload';
@@ -22,10 +22,10 @@ import { acceptablePatternChecking, detectURLRegex, getCachedRegex, getCustomTag
22
22
  // Constants
23
23
  import { DETECT_LINK, EMOJI, PERSONALIZE_PTN, SHORT_LINK, SHORT_LINK_PTN, SHORT_LINK_V2, TAG_TYPE, UNSUBSCRIBE_WHATSAPP, defaultCssVariables, tagifyDefaultProps, TAG_CUSTOM_ATTRIBUTES, } from './constants';
24
24
  const { CUSTOM_TAG } = TAG_TYPE;
25
- const { PREPARING_ST, INVALID_TAG, MESSAGE_TAG, FORCE_SHOW_TOOLTIP, ERROR_TAG, WARNING_TAG } = TAG_CUSTOM_ATTRIBUTES;
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);
@@ -638,7 +638,7 @@ const TagifyInput = forwardRef((props, ref) => {
638
638
  if (!isAccepted)
639
639
  return;
640
640
  const { url, shortener, label } = tagData;
641
- const { label: tagLabel, type: tagType, status, statusMsg, } = getShortLinkTagInfo({
641
+ const { label: tagLabel, status, statusMsg, } = getShortLinkTagInfo({
642
642
  type,
643
643
  label,
644
644
  shortener,
@@ -770,14 +770,24 @@ const TagifyInput = forwardRef((props, ref) => {
770
770
  useEffect(() => {
771
771
  if (!tagifyRef.current)
772
772
  return;
773
+ // Skip if neither readonlyText nor readonlyWhenNotEmpty is defined
774
+ if (typeof readonlyText === 'undefined' && !readonlyWhenNotEmpty)
775
+ return;
773
776
  const inputEl = tagifyRef.current.DOM.input;
774
- if (readonlyText) {
775
- inputEl.setAttribute('contenteditable', 'false');
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');
776
782
  }
777
- else {
778
- inputEl.setAttribute('contenteditable', 'true');
783
+ else if (typeof readonlyText === 'function') {
784
+ const isReadonlyText = readonlyText(tagifyRef.current.getCleanValue());
785
+ inputEl.setAttribute('contenteditable', isReadonlyText ? 'false' : 'true');
786
+ }
787
+ else if (typeof readonlyText !== 'undefined') {
788
+ inputEl.setAttribute('contenteditable', readonlyText ? 'false' : 'true');
779
789
  }
780
- }, [readonlyText]);
790
+ }, [readonlyText, readonlyWhenNotEmpty, tagLength]);
781
791
  const onTagifyWrapperClick = useCallback(event => {
782
792
  event.preventDefault();
783
793
  event.stopPropagation();
@@ -977,6 +987,8 @@ const TagifyInput = forwardRef((props, ref) => {
977
987
  tagifyInstance.on('change', onTagifyChangedDebounce);
978
988
  tagifyInstance.on('remove', onTagifyRemoveTag);
979
989
  tagifyInstance.on('keydown', onKeyDown);
990
+ if (onBlur)
991
+ tagifyInstance.on('blur', onBlur);
980
992
  }
981
993
  // Off listen to Tagify events
982
994
  return () => {
@@ -986,9 +998,12 @@ const TagifyInput = forwardRef((props, ref) => {
986
998
  tagifyInstance.off('change', onTagifyChangedDebounce);
987
999
  tagifyInstance.off('remove', onTagifyRemoveTag);
988
1000
  tagifyInstance.off('keydown', onKeyDown);
1001
+ if (onBlur)
1002
+ tagifyInstance.off('blur', onBlur);
989
1003
  }
990
1004
  };
991
1005
  }, [
1006
+ onBlur,
992
1007
  onTagItemClick,
993
1008
  onInputTagifyDebounce,
994
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).
@@ -154,7 +159,15 @@ export interface TagifyInputProps {
154
159
  /**
155
160
  * Defines whether the input text is read but not the whole tags.
156
161
  */
157
- readonlyText?: boolean;
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;
@@ -34,8 +34,8 @@ export * from './actionsButton';
34
34
  export * from './condition';
35
35
  export * from './api';
36
36
  export * from './date';
37
- export * from './unsubscribe';
38
37
  export * from './auth';
38
+ export * from './unsubscribe';
39
39
  export type PayloadInfo = {
40
40
  url?: string;
41
41
  userId?: string;
package/es/types/index.js CHANGED
@@ -9,5 +9,5 @@ export * from './actionsButton';
9
9
  export * from './condition';
10
10
  export * from './api';
11
11
  export * from './date';
12
- export * from './unsubscribe';
13
12
  export * from './auth';
13
+ export * from './unsubscribe';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antscorp/antsomi-ui",
3
- "version": "1.3.7-beta.3",
3
+ "version": "1.3.7-beta.5",
4
4
  "description": "An enterprise-class UI design language and React UI library.",
5
5
  "sideEffects": [
6
6
  "dist/*",
@@ -153,8 +153,7 @@
153
153
  "react-virtualized-auto-sizer": "^1.0.24",
154
154
  "react-window": "^1.8.10",
155
155
  "rehype-highlight": "^6.0.0",
156
- "remark-gfm": "^3.0.1",
157
- "remark-gfm-alias-story": "npm:remark-gfm@4.0.0",
156
+ "remark-gfm": "^4",
158
157
  "reselect": "^5.1.1",
159
158
  "socket.io-client": "^4.7.5",
160
159
  "string-replace-to-array": "^2.1.0",
@@ -186,17 +185,11 @@
186
185
  "@babel/preset-typescript": "^7.23.3",
187
186
  "@commitlint/cli": "17.5.0",
188
187
  "@commitlint/config-conventional": "17.4.4",
189
- "@storybook/addon-docs": "^8.6.9",
190
- "@storybook/addon-essentials": "^8.6.9",
191
- "@storybook/addon-links": "^8.6.9",
192
- "@storybook/addon-styling-webpack": "^1.0.1",
193
- "@storybook/addon-webpack5-compiler-babel": "^3.0.5",
194
- "@storybook/blocks": "^8.6.9",
195
- "@storybook/manager-api": "^8.6.9",
196
- "@storybook/react": "^8.6.9",
197
- "@storybook/react-webpack5": "^8.6.9",
198
- "@storybook/test": "^8.6.9",
199
- "@storybook/theming": "^8.6.9",
188
+ "@storybook/addon-docs": "^9.1.10",
189
+ "@storybook/addon-links": "^9.1.10",
190
+ "@storybook/addon-styling-webpack": "^2.0.0",
191
+ "@storybook/addon-webpack5-compiler-babel": "^3.0.6",
192
+ "@storybook/react-webpack5": "^9.1.10",
200
193
  "@testing-library/dom": "^10.4.0",
201
194
  "@testing-library/jest-dom": "^6.5.0",
202
195
  "@testing-library/react": "^16.0.0",
@@ -247,7 +240,7 @@
247
240
  "eslint-plugin-prettier": "^5.2.1",
248
241
  "eslint-plugin-react": "^7.32.2",
249
242
  "eslint-plugin-react-hooks": "^4.6.0",
250
- "eslint-plugin-storybook": "^0.12.0",
243
+ "eslint-plugin-storybook": "^9.1.10",
251
244
  "file-loader": "^6.2.0",
252
245
  "googleapis": "^142.0.0",
253
246
  "husky": "^8.0.3",
@@ -264,7 +257,7 @@
264
257
  "react-router-dom": "5.1.0 || 6.14.2",
265
258
  "sass": "^1.77.8",
266
259
  "sass-loader": "^16.0.1",
267
- "storybook": "^8.6.9",
260
+ "storybook": "^9.1.10",
268
261
  "style-loader": "^4.0.0",
269
262
  "styled-components": "^5.3.9",
270
263
  "terser-webpack-plugin": "^5.3.10",