@antscorp/antsomi-ui 1.3.7-beta.4 → 1.3.7-beta.41
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/InputDynamic/InputDynamic.js +3 -3
- package/es/components/icons/QRCodeManagementIcon.d.ts +3 -0
- package/es/components/icons/QRCodeManagementIcon.js +7 -0
- package/es/components/icons/QRSetDashboardIcon.d.ts +3 -0
- package/es/components/icons/QRSetDashboardIcon.js +7 -0
- package/es/components/icons/index.d.ts +2 -0
- package/es/components/icons/index.js +2 -0
- package/es/components/molecules/AddDynamicContent/AddDynamicContent.js +28 -2
- package/es/components/molecules/AddDynamicContent/constants.d.ts +2 -0
- package/es/components/molecules/AddDynamicContent/constants.js +2 -0
- package/es/components/molecules/ColorPicker/index.d.ts +2 -0
- package/es/components/molecules/ColorPicker/index.js +8 -3
- package/es/components/molecules/EmojiPopover/EmojiPopover.d.ts +1 -0
- package/es/components/molecules/EmojiPopover/EmojiPopover.js +2 -2
- package/es/components/molecules/EmojiPopover/styled.d.ts +2 -2
- package/es/components/molecules/EmojiPopover/styled.js +1 -1
- package/es/components/molecules/SearchPopover/SearchPopover.js +2 -2
- package/es/components/molecules/SearchPopover/styled.d.ts +12 -1
- package/es/components/molecules/SearchPopover/styled.js +1 -2
- package/es/components/molecules/SearchPopover/types.d.ts +4 -3
- package/es/components/molecules/TagifyInput/TagifyInput.js +53 -18
- package/es/components/molecules/TagifyInput/types.d.ts +21 -2
- package/es/components/molecules/TagifyInput/utils.d.ts +6 -1
- package/es/components/molecules/TagifyInput/utils.js +19 -0
- package/es/components/molecules/VirtualizedMenu/VirtualizedMenu.d.ts +1 -0
- package/es/components/molecules/VirtualizedMenu/components/Item/Item.js +3 -7
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.d.ts +10 -10
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.js +46 -327
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.d.ts +9 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.js +5 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.d.ts +23 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.js +81 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.d.ts +24 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.js +32 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.d.ts +26 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.js +93 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.d.ts +24 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.js +94 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.d.ts +7 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.js +132 -0
- package/es/components/molecules/VirtualizedMenu/styled.js +14 -3
- package/es/components/molecules/VirtualizedMenu/types.d.ts +1 -0
- package/es/components/molecules/VirtualizedMenu/utils.d.ts +1 -0
- package/es/components/molecules/VirtualizedMenu/utils.js +1 -0
- package/es/components/organism/ActivityTimeline/ActivityTimeline.js +3 -3
- package/es/components/organism/ActivityTimeline/constants.d.ts +9 -9
- package/es/components/organism/ActivityTimeline/constants.js +3 -3
- package/es/components/organism/ActivityTimeline/index.d.ts +530 -1
- package/es/components/organism/ActivityTimeline/index.js +9 -1
- package/es/components/organism/ActivityTimeline/utils.js +7 -6
- package/es/components/organism/TextEditor/TextEditor.d.ts +9 -2
- package/es/components/organism/TextEditor/TextEditor.js +187 -42
- package/es/components/organism/TextEditor/constants.d.ts +9 -0
- package/es/components/organism/TextEditor/constants.js +66 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.d.ts +6 -128
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.js +7 -292
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.d.ts +1 -1
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.js +4 -0
- package/es/components/organism/TextEditor/extensions/Link.js +33 -14
- package/es/components/organism/TextEditor/extensions/ListItem.d.ts +10 -0
- package/es/components/organism/TextEditor/extensions/ListItem.js +93 -0
- package/es/components/organism/TextEditor/extensions/SmartTag.d.ts +5 -6
- package/es/components/organism/TextEditor/extensions/SmartTag.js +96 -4
- package/es/components/organism/TextEditor/hooks/useColorSet.js +7 -0
- package/es/components/organism/TextEditor/hooks/useMarkTracking.js +2 -1
- package/es/components/organism/TextEditor/index.d.ts +7 -5
- package/es/components/organism/TextEditor/index.scss +4 -7
- package/es/components/organism/TextEditor/provider.d.ts +1 -0
- package/es/components/organism/TextEditor/provider.js +6 -3
- package/es/components/organism/TextEditor/store.d.ts +11 -4
- package/es/components/organism/TextEditor/store.js +22 -2
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/froala-legacy-format.settings.json +95 -0
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.d.ts +111 -0
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.js +82 -0
- package/es/components/organism/TextEditor/stories/shared.d.ts +64 -0
- package/es/components/organism/TextEditor/stories/shared.js +57 -0
- package/es/components/organism/TextEditor/styled.d.ts +1 -1
- package/es/components/organism/TextEditor/styled.js +1 -0
- package/es/components/organism/TextEditor/types.d.ts +157 -11
- package/es/components/organism/TextEditor/types.js +1 -0
- package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.d.ts +2 -1
- package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.js +80 -51
- package/es/components/organism/TextEditor/ui/Emoji/EmojiList.js +1 -1
- package/es/components/organism/TextEditor/ui/Emoji/suggestion.d.ts +1 -1
- package/es/components/organism/TextEditor/ui/Emoji/suggestion.js +2 -2
- package/es/components/organism/TextEditor/ui/FontPopover/FontPopover.js +12 -2
- package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.d.ts +16 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.js +61 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/index.js +1 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.d.ts +9 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.js +126 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Popover/Popover.js +1 -1
- package/es/components/organism/TextEditor/ui/TextAlignSelect/TextAlignSelect.js +1 -3
- package/es/components/organism/TextEditor/ui/Toolbar/{Toolbar.d.ts → FormattingToolbar.d.ts} +3 -4
- package/es/components/organism/TextEditor/ui/Toolbar/FormattingToolbar.js +85 -0
- package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.d.ts +10 -0
- package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.js +39 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/EmojiAction.js +4 -3
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.js +2 -2
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontSizeAction.js +6 -1
- package/es/components/organism/TextEditor/ui/Toolbar/index.d.ts +2 -1
- package/es/components/organism/TextEditor/ui/Toolbar/index.js +2 -1
- package/es/components/organism/TextEditor/utils/documentState.d.ts +14 -0
- package/es/components/organism/TextEditor/utils/documentState.js +25 -0
- package/es/components/organism/TextEditor/utils/htmlProcessing.js +60 -0
- package/es/components/organism/TextEditor/utils/link.d.ts +10 -1
- package/es/components/organism/TextEditor/utils/link.js +161 -7
- package/es/components/organism/TextEditor/utils/menu.js +2 -1
- package/es/components/organism/TextEditor/utils/selection.js +3 -2
- package/es/components/organism/TextEditor/utils/smartTag.js +2 -1
- package/es/components/organism/index.d.ts +1 -1
- package/es/hooks/index.d.ts +1 -1
- package/es/hooks/index.js +1 -1
- package/es/services/MediaTemplateDesign/UploadFile/index.js +4 -4
- package/es/utils/common.d.ts +1 -1
- package/es/utils/common.js +3 -3
- package/package.json +15 -20
- package/es/components/organism/TextEditor/ui/BubbleToolbar/BubbleToolbar.d.ts +0 -1
- package/es/components/organism/TextEditor/ui/BubbleToolbar/BubbleToolbar.js +0 -1
- package/es/components/organism/TextEditor/ui/BubbleToolbar/index.d.ts +0 -0
- package/es/components/organism/TextEditor/ui/BubbleToolbar/index.js +0 -1
- package/es/components/organism/TextEditor/ui/Toolbar/Toolbar.js +0 -39
|
@@ -30,9 +30,9 @@ const defaultProps = {
|
|
|
30
30
|
apiConfig: {
|
|
31
31
|
domain: 'https://sandbox-media-template.antsomi.com/cdp',
|
|
32
32
|
slug: '/api/v1',
|
|
33
|
-
token: '
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
token: '5474r2x214z284d4w2b4y4o5l4u5n4x5s2x2h4g45416',
|
|
34
|
+
userId: '1600083836',
|
|
35
|
+
accountId: '1600083836',
|
|
36
36
|
},
|
|
37
37
|
disabled: false,
|
|
38
38
|
showIndex: true,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { useIcon } from './hooks/useIcon';
|
|
4
|
+
export const QRCodeManagementIcon = forwardRef((props, ref) => {
|
|
5
|
+
const { width, height } = useIcon(props);
|
|
6
|
+
return (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, ref: ref, width: width, height: height, children: _jsx("g", { children: _jsx("path", { d: "M2.604 7.3118V2.60425H7.31156V4.16675H4.1665V7.3118H2.604ZM2.604 22.3959V17.6884H4.1665V20.8334H7.31156V22.3959H2.604ZM17.6881 22.3959V20.8334H20.8332V17.6884H22.3957V22.3959H17.6881ZM20.8332 7.3118V4.16675H17.6881V2.60425H22.3957V7.3118H20.8332ZM17.9386 17.9389H19.3509V19.3511H17.9386V17.9389ZM17.9386 15.1141H19.3509V16.5264H17.9386V15.1141ZM16.5261 16.5264H17.9386V17.9389H16.5261V16.5264ZM15.1139 17.9389H16.5261V19.3511H15.1139V17.9389ZM13.7017 16.5264H15.1139V17.9389H13.7017V16.5264ZM16.5261 13.7019H17.9386V15.1141H16.5261V13.7019ZM15.1139 15.1141H16.5261V16.5264H15.1139V15.1141ZM13.7017 13.7019H15.1139V15.1141H13.7017V13.7019ZM19.3509 5.64904V11.2983H13.7017V5.64904H19.3509ZM11.298 13.7019V19.3511H5.6488V13.7019H11.298ZM11.298 5.64904V11.2983H5.6488V5.64904H11.298ZM10.0558 18.1089V14.9441H6.89098V18.1089H10.0558ZM10.0558 10.0561V6.89123H6.89098V10.0561H10.0558ZM18.1087 10.0561V6.89123H14.9438V10.0561H18.1087Z", fill: "currentColor" }) }) }));
|
|
7
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { useIcon } from './hooks/useIcon';
|
|
4
|
+
export const QRSetDashboardIcon = forwardRef((props, ref) => {
|
|
5
|
+
const { width, height } = useIcon(props);
|
|
6
|
+
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "currentColor", viewBox: "0 0 18 18", width: width, height: height, ref: ref, ...props, children: _jsx("path", { fill: "currentColor", d: "M10 18v-2h2v2zm-2-2v-5h2v5zm8-3V9h2v4zm-2-4V7h2v2zM2 11V9h2v2zM0 9V7h2v2zm9-7V0h2v2zM1.5 4.5h3v-3h-3zM0 6V0h6v6zm1.5 10.5h3v-3h-3zM0 18v-6h6v6zM13.5 4.5h3v-3h-3zM12 6V0h6v6zm2 12v-3h-2v-2h4v3h2v2zm-4-7V9h4v2zm-4 0V9H4V7h6v2H8v2zm1-5V2h2v2h2v2zM2.25 3.75v-1.5h1.5v1.5zm0 12v-1.5h1.5v1.5zm12-12v-1.5h1.5v1.5z" }) }));
|
|
7
|
+
});
|
|
@@ -401,3 +401,5 @@ export { WebIcon } from './WebIcon';
|
|
|
401
401
|
export { WebPersonalizationIcon } from './WebPersonalizationIcon';
|
|
402
402
|
export { WidgetIcon } from './WidgetIcon';
|
|
403
403
|
export { WritingAIAssitantIcon } from './WritingAIAssitantIcon';
|
|
404
|
+
export { QRSetDashboardIcon } from './QRSetDashboardIcon';
|
|
405
|
+
export { QRCodeManagementIcon } from './QRCodeManagementIcon';
|
|
@@ -401,3 +401,5 @@ export { WebIcon } from './WebIcon';
|
|
|
401
401
|
export { WebPersonalizationIcon } from './WebPersonalizationIcon';
|
|
402
402
|
export { WidgetIcon } from './WidgetIcon';
|
|
403
403
|
export { WritingAIAssitantIcon } from './WritingAIAssitantIcon';
|
|
404
|
+
export { QRSetDashboardIcon } from './QRSetDashboardIcon';
|
|
405
|
+
export { QRCodeManagementIcon } from './QRCodeManagementIcon';
|
|
@@ -15,6 +15,7 @@ import { Text } from '@antscorp/antsomi-ui/es/components/atoms/Text';
|
|
|
15
15
|
import { Form, Select, TreeSelect } from 'antd';
|
|
16
16
|
import { TreeNode } from 'rc-tree-select';
|
|
17
17
|
// Locales
|
|
18
|
+
import { translate, translations as translationLib } from '@antscorp/antsomi-locales';
|
|
18
19
|
import i18nInstance from '@antscorp/antsomi-ui/es/locales/i18n';
|
|
19
20
|
import { translations } from '@antscorp/antsomi-ui/es/locales/translations';
|
|
20
21
|
// Query
|
|
@@ -33,6 +34,7 @@ import { buildMappingFields, buildOptionAttrArchive, checkStatusAttr, CUSTOM_TYP
|
|
|
33
34
|
// Style
|
|
34
35
|
import { EditorScript } from '../EditorScript';
|
|
35
36
|
import { InputSuggestion, ModalCustom } from './styled';
|
|
37
|
+
import { Input, Radio } from '../../atoms';
|
|
36
38
|
const getMembers = (member) => {
|
|
37
39
|
if (!member.children || !member.children.length) {
|
|
38
40
|
return member;
|
|
@@ -303,6 +305,12 @@ export const AddDynamicContent = props => {
|
|
|
303
305
|
}
|
|
304
306
|
return false;
|
|
305
307
|
}, [selectedAttr, selectedDynamicContentType, eventTrackingAttributes?.mainObjects]);
|
|
308
|
+
const eventBOAttributeLabel = useMemo(() => {
|
|
309
|
+
if (!selectedAttr?.itemTypeId || !listEventAttributes)
|
|
310
|
+
return '';
|
|
311
|
+
const boAttr = listEventAttributes.find(row => row.itemTypeId === selectedAttr?.itemTypeId);
|
|
312
|
+
return boAttr?.label;
|
|
313
|
+
}, [listEventAttributes, selectedAttr]);
|
|
306
314
|
const itemTypeName = useMemo(() => {
|
|
307
315
|
let draftItemTypeName = '';
|
|
308
316
|
if (itemTypeId) {
|
|
@@ -416,6 +424,8 @@ export const AddDynamicContent = props => {
|
|
|
416
424
|
[DYNAMIC_CONTENT_SETTING_KEY.DISPLAY_FORMAT_TYPE]: undefined,
|
|
417
425
|
[DYNAMIC_CONTENT_SETTING_KEY.FUNCTION]: undefined,
|
|
418
426
|
[DYNAMIC_CONTENT_SETTING_KEY.DATA_TYPE]: optionDataType[0].value,
|
|
427
|
+
[DYNAMIC_CONTENT_SETTING_KEY.DEFAULT_VALUE]: '',
|
|
428
|
+
[DYNAMIC_CONTENT_SETTING_KEY.DATA_SOURCE]: 'event',
|
|
419
429
|
});
|
|
420
430
|
}, [form]);
|
|
421
431
|
useEffect(() => {
|
|
@@ -1119,7 +1129,7 @@ export const AddDynamicContent = props => {
|
|
|
1119
1129
|
__html: `${t(translations.dynamicContent.modal.label.displayFormat)}: <bdo dir='ltr'>${formatedAttr}</bdo>`,
|
|
1120
1130
|
} })) : null, !showDetailEditDF && (_jsx(Button, { disabled: isActionArchive &&
|
|
1121
1131
|
selectedDynamicContentType !== DYNAMIC_CONTENT_TYPE.EVENT_ATTRIBUTE.value, type: "text", style: { display: 'inline-block' }, onClick: () => setShowDetailEditDF(prevShow => !prevShow), children: t(translations.edit.title) }))] }), children: _jsx(Select, { disabled: isActionArchive &&
|
|
1122
|
-
selectedDynamicContentType !== DYNAMIC_CONTENT_TYPE.EVENT_ATTRIBUTE.value, style: { height: 28 }, options: attrDFOptions }) })] }));
|
|
1132
|
+
selectedDynamicContentType !== DYNAMIC_CONTENT_TYPE.EVENT_ATTRIBUTE.value, style: { height: 28 }, options: attrDFOptions }) }), renderDefaultValue()] }));
|
|
1123
1133
|
};
|
|
1124
1134
|
const renderCustomerAttrFields = () => {
|
|
1125
1135
|
if (hasError[DYNAMIC_CONTENT_SETTING_KEY.ATTRIBUTE]) {
|
|
@@ -1205,6 +1215,22 @@ export const AddDynamicContent = props => {
|
|
|
1205
1215
|
gap: '8px',
|
|
1206
1216
|
}, children: _jsx(DisplayFormat, { infos: infos, url: url, displayFormatType: selectedDFType, formatSettings: attrDFSettings, onSettingsChange: (values) => setAttrDFSettings(values), dynamicContentType: form.getFieldValue(DYNAMIC_CONTENT_SETTING_KEY.DYNAMIC_CONTENT_TYPE) }) }));
|
|
1207
1217
|
};
|
|
1218
|
+
const renderGetFromData = () => (_jsx(Form.Item, { className: "ants-items-center", label: translate(translationLib._TITL_PERSONALIZATION_LOOKUP_YES, 'Get data from'), name: DYNAMIC_CONTENT_SETTING_KEY.DATA_SOURCE, required: true, children: _jsx(Radio.Group, { defaultValue: "event", options: [
|
|
1219
|
+
{
|
|
1220
|
+
value: 'event',
|
|
1221
|
+
label: 'Event data',
|
|
1222
|
+
},
|
|
1223
|
+
{
|
|
1224
|
+
value: 'object',
|
|
1225
|
+
label: (_jsxs(Text, { children: [translate(translationLib._TITL_PERSONALIZATION_LOOKUP_YES, 'Data object'), ' ', _jsx("b", { children: eventBOAttributeLabel })] })),
|
|
1226
|
+
disabled: !selectedAttr?.itemTypeId,
|
|
1227
|
+
},
|
|
1228
|
+
], style: {
|
|
1229
|
+
display: 'flex',
|
|
1230
|
+
flexDirection: 'column',
|
|
1231
|
+
gap: 8,
|
|
1232
|
+
} }) }));
|
|
1233
|
+
const renderDefaultValue = () => (_jsx(Form.Item, { className: "ants-items-center", label: translate(translations._TITL_DEFAULT_VALUE, 'Default value'), name: DYNAMIC_CONTENT_SETTING_KEY.DEFAULT_VALUE, children: _jsx(Input, { placeholder: "Enter fallback text when data is unavailable" }) }));
|
|
1208
1234
|
return (_jsx(ModalCustom, { closable: false, destroyOnClose: true, forceRender: true, mask: true, okButtonProps: { disabled: formSubmitDisabled }, title: modalTitle || t(translations.dynamicContent.modal.title.addDynamicContent), visible: visible, onCancel: handleOnCancelModal, onOk: handleOnOkModal, children: _jsxs(Spin, { spinning: isFetchingSourceBO ||
|
|
1209
1235
|
isFetchingListBoAttr ||
|
|
1210
1236
|
isFetchingEventAttr ||
|
|
@@ -1212,7 +1238,7 @@ export const AddDynamicContent = props => {
|
|
|
1212
1238
|
isFetchingPromotionCodeAttr ||
|
|
1213
1239
|
isFetchingDynamicContentAttr, children: [_jsxs(Form, { style: { width: '100%' }, form: form, labelAlign: "left", labelCol: { span: 9 }, wrapperCol: { span: 15 }, onValuesChange: handleFormValuesChanges, initialValues: {
|
|
1214
1240
|
[DYNAMIC_CONTENT_SETTING_KEY.DYNAMIC_CONTENT_TYPE]: listDynamicContentTypes[0].value,
|
|
1215
|
-
}, children: [_jsx(Form.Item, { style: { alignItems: 'center' }, label: t(translations.dynamicContent.modal.label.contentSource), name: DYNAMIC_CONTENT_SETTING_KEY.DYNAMIC_CONTENT_TYPE, required: true, children: _jsx(Select, { style: { height: 28 }, options: listDynamicContentTypes }) }), selectedDynamicContentType === DYNAMIC_CONTENT_TYPE.VISITOR_ATTRIBUTE.value && (
|
|
1241
|
+
}, children: [_jsx(Form.Item, { style: { alignItems: 'center' }, label: t(translations.dynamicContent.modal.label.contentSource), name: DYNAMIC_CONTENT_SETTING_KEY.DYNAMIC_CONTENT_TYPE, required: true, children: _jsx(Select, { style: { height: 28 }, options: listDynamicContentTypes }) }), selectedDynamicContentType === DYNAMIC_CONTENT_TYPE.VISITOR_ATTRIBUTE.value && (_jsxs(_Fragment, { children: [renderVisitorAttrFields(), renderDefaultValue()] })), selectedDynamicContentType === DYNAMIC_CONTENT_TYPE.CUSTOMER_ATTRIBUTE.value && (_jsxs(_Fragment, { children: [renderCustomerAttrFields(), renderDefaultValue()] })), selectedDynamicContentType === CUSTOM_TYPE.value && _jsx(_Fragment, { children: renderCustomFunctionFields() }), selectedDynamicContentType === DYNAMIC_CONTENT_TYPE.EVENT_ATTRIBUTE.value && (_jsxs(_Fragment, { children: [renderEventFields(), renderSourceFields(), renderEventAttrFields(), renderGetFromData(), renderDefaultValue(), isShowEventIndexField
|
|
1216
1242
|
? renderIndexFields({ disabled: false, loading: false })
|
|
1217
1243
|
: null] })), selectedDynamicContentType === DYNAMIC_CONTENT_TYPE.PROMOTION_CODE.value && (_jsxs(_Fragment, { children: [renderPromotionPoolFields(), renderPromotionCodeAttr()] })), selectedDynamicContentType && regexCSType.test(selectedDynamicContentType) && (_jsxs(_Fragment, { children: [renderBoAttrFields(), renderIndexFields({ disabled: isActionArchive, loading: isFetchingListBoAttr })] })), showDisplayFormat && renderDisplayFormat()] }), showDisplayFormat && renderDisplayFormat() !== null && renderDetailDFSettings(), isShowCustomFunction && selectedDynamicContentType === CUSTOM_TYPE.value && (_jsx("div", { style: {
|
|
1218
1244
|
display: 'flex',
|
|
@@ -12,6 +12,8 @@ export declare const DYNAMIC_CONTENT_SETTING_KEY: {
|
|
|
12
12
|
PERNAME: string;
|
|
13
13
|
SAVE_AS_TEMPLATE: string;
|
|
14
14
|
DATA_TYPE: string;
|
|
15
|
+
DATA_SOURCE: string;
|
|
16
|
+
DEFAULT_VALUE: string;
|
|
15
17
|
};
|
|
16
18
|
export declare const DYNAMIC_CONTENT_TYPE_KEY: {
|
|
17
19
|
readonly BO_SETTINGS: "bo-settings";
|
|
@@ -12,6 +12,8 @@ export const DYNAMIC_CONTENT_SETTING_KEY = {
|
|
|
12
12
|
PERNAME: 'templateName',
|
|
13
13
|
SAVE_AS_TEMPLATE: 'saveAsTemplate',
|
|
14
14
|
DATA_TYPE: 'dataType',
|
|
15
|
+
DATA_SOURCE: 'dataSource',
|
|
16
|
+
DEFAULT_VALUE: 'defaultValue',
|
|
15
17
|
};
|
|
16
18
|
export const DYNAMIC_CONTENT_TYPE_KEY = {
|
|
17
19
|
BO_SETTINGS: 'bo-settings',
|
|
@@ -7,8 +7,10 @@ export interface ColorPickerProps {
|
|
|
7
7
|
defaultColor?: string;
|
|
8
8
|
icon?: React.ReactNode | string;
|
|
9
9
|
onChange?: (color: string) => void;
|
|
10
|
+
onAfterClosePicker?: (color: string) => void;
|
|
10
11
|
showInput?: boolean;
|
|
11
12
|
positionInput?: 'right' | 'left';
|
|
12
13
|
style?: React.CSSProperties;
|
|
14
|
+
inputProps?: any;
|
|
13
15
|
}
|
|
14
16
|
export declare const ColorPicker: React.FC<ColorPickerProps>;
|
|
@@ -22,8 +22,8 @@ const styleBtnColor = {
|
|
|
22
22
|
};
|
|
23
23
|
export const ColorPicker = props => {
|
|
24
24
|
// Props
|
|
25
|
-
const { className = '', defaultColor = '#000000', presetColors, positionInput = 'left', icon, showInput = true, style = {}, isHideAlpha, } = props;
|
|
26
|
-
const { onChange = () => { } } = props;
|
|
25
|
+
const { className = '', defaultColor = '#000000', presetColors, positionInput = 'left', icon, showInput = true, style = {}, isHideAlpha, inputProps = {}, } = props;
|
|
26
|
+
const { onChange = () => { }, onAfterClosePicker = () => { } } = props;
|
|
27
27
|
// States
|
|
28
28
|
const [color, setColor] = useState(defaultColor);
|
|
29
29
|
const [popoverVisible, setPopoverVisible] = useState(false);
|
|
@@ -71,7 +71,12 @@ export const ColorPicker = props => {
|
|
|
71
71
|
const onPopoverVisibleChange = visible => {
|
|
72
72
|
setPopoverVisible(visible);
|
|
73
73
|
};
|
|
74
|
-
|
|
74
|
+
const handleAfterOpenChange = (visible) => {
|
|
75
|
+
if (!visible && typeof onAfterClosePicker === 'function') {
|
|
76
|
+
onAfterClosePicker(color);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
return (_jsxs(ColorPickerWrapper, { className: `antsomi-color-picker ${className || ''}`, style: style, children: [showInput && positionInput === 'left' && (_jsx(Input, { style: { textTransform: 'uppercase' }, value: color, onChange: onChangeColorInput, ...inputProps })), _jsx(Popover, { arrow: true, content: _jsx(CustomPicker, { color: color, presetColors: presetColors, isHideAlpha: isHideAlpha, onChange: onChangeColorPicker, onChangeComplete: onChangeComplete }), trigger: "click", open: popoverVisible, getPopupContainer: triggerNode => triggerNode, onOpenChange: onPopoverVisibleChange, afterOpenChange: handleAfterOpenChange, children: _jsx("div", { className: "antsomi-popover-button", style: styleBtnColor, children: iconNode || (_jsx("span", { style: {
|
|
75
80
|
backgroundColor: color,
|
|
76
81
|
display: 'block',
|
|
77
82
|
width: 20,
|
|
@@ -9,6 +9,7 @@ interface EmojiPopoverProps {
|
|
|
9
9
|
collections?: CollectionItemProps[];
|
|
10
10
|
isForceHide?: boolean;
|
|
11
11
|
children?: React.ReactNode;
|
|
12
|
+
destroyTooltipOnHide?: boolean;
|
|
12
13
|
onEmojiClick?: (emoji: string | TagDataCustomize) => void;
|
|
13
14
|
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
|
14
15
|
}
|
|
@@ -11,7 +11,7 @@ import { EMOJI_COLLECTIONS, } from '@antscorp/antsomi-ui/es/components/molecules
|
|
|
11
11
|
import { EmojiTabs, EmojiPopoverStyled } from './styled';
|
|
12
12
|
// Utils
|
|
13
13
|
import { handleGetTextToReplace } from './utils';
|
|
14
|
-
const EmojiPopover = ({ disabled, collections, isForceHide, children, onEmojiClick, getPopupContainer, }) => {
|
|
14
|
+
const EmojiPopover = ({ disabled, collections, isForceHide, children, destroyTooltipOnHide, onEmojiClick, getPopupContainer, }) => {
|
|
15
15
|
const [state, setState] = useImmer({
|
|
16
16
|
isOpen: false,
|
|
17
17
|
collectionActive: collections ? collections[0]?.key : EMOJI_COLLECTIONS.COMMON,
|
|
@@ -70,7 +70,7 @@ const EmojiPopover = ({ disabled, collections, isForceHide, children, onEmojiCli
|
|
|
70
70
|
if (emojiCollections.length <= 1) {
|
|
71
71
|
content = emojiCollections.at(0)?.children;
|
|
72
72
|
}
|
|
73
|
-
return (_jsx(EmojiPopoverStyled, { content: content, placement: "topLeft", trigger: "click", fresh: false, style: { padding: 15 }, arrow: false, rootClassName: "antsomi-emoji-popover", open: state.isOpen, onOpenChange: handleOpenChange, getPopupContainer: getPopupContainer, children: children || (_jsx(Button, { type: "link", icon: _jsx(EmojiSmileIcon, {}), disabled: disabled, onClick: () => handleOpenChange(true) })) }));
|
|
73
|
+
return (_jsx(EmojiPopoverStyled, { content: content, placement: "topLeft", destroyTooltipOnHide: destroyTooltipOnHide, trigger: "click", fresh: false, style: { padding: 15 }, arrow: false, rootClassName: "antsomi-emoji-popover", open: state.isOpen, onOpenChange: handleOpenChange, getPopupContainer: getPopupContainer, children: children || (_jsx(Button, { type: "link", icon: _jsx(EmojiSmileIcon, {}), disabled: disabled, onClick: () => handleOpenChange(true) })) }));
|
|
74
74
|
};
|
|
75
75
|
EmojiPopover.defaultProps = {
|
|
76
76
|
disabled: false,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export declare const EmojiTabs: import("styled-components").StyledComponent<import("react").FC<import("antd").TabsProps> & {
|
|
2
|
+
export declare const EmojiTabs: import("styled-components").StyledComponent<import("react").FC<import("antd/es/tabs").TabsProps> & {
|
|
3
3
|
TabPane: import("react").FC<import("antd").TabPaneProps>;
|
|
4
4
|
}, any, {
|
|
5
5
|
shadow?: boolean | undefined;
|
|
6
6
|
}, never>;
|
|
7
|
-
export declare const EmojiPopoverStyled: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd").PopoverProps & import("react").RefAttributes<unknown>> & {
|
|
7
|
+
export declare const EmojiPopoverStyled: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd/es/popover").PopoverProps & import("react").RefAttributes<unknown>> & {
|
|
8
8
|
_InternalPanelDoNotUseOrYouWillBeFired: import("react").FC<import("antd/es/popover/PurePanel").PurePanelProps>;
|
|
9
9
|
}, any, {}, never>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Libraries
|
|
2
|
-
import { Popover } from 'antd';
|
|
3
2
|
import styled from 'styled-components';
|
|
4
3
|
// Components
|
|
5
4
|
import { Tabs as TabsUI } from '@antscorp/antsomi-ui/es/components/molecules';
|
|
5
|
+
import { Popover } from '../../atoms/Popover';
|
|
6
6
|
export const EmojiTabs = styled(TabsUI) `
|
|
7
7
|
.antsomi-tabs-tab {
|
|
8
8
|
padding: 5.5px 20px !important;
|
|
@@ -5,7 +5,7 @@ import { StyledInput } from './styled';
|
|
|
5
5
|
import { translate, translations } from '@antscorp/antsomi-ui/es/locales';
|
|
6
6
|
import { SearchIcon } from '../../icons';
|
|
7
7
|
export const SearchPopover = props => {
|
|
8
|
-
const { inputSearchProps = {}, ...popoverProps } = props;
|
|
8
|
+
const { inputSearchProps = {}, inputSearchRef, ...popoverProps } = props;
|
|
9
9
|
const { overlayClassName, arrow = false, children, content, trigger = ['click'], ...restPopoverProps } = popoverProps;
|
|
10
|
-
return (_jsx(Popover, { trigger: trigger, arrow: arrow, destroyTooltipOnHide: true, ...restPopoverProps, overlayClassName: clsx('no-padding-content', overlayClassName), overlay: true, content: _jsxs(_Fragment, { children: [_jsx(StyledInput, { placeholder: inputSearchProps?.placeholder || `${translate(translations.global.search)}`, bordered: false, ...inputSearchProps, addonAfter: _jsx(SearchIcon, {}), withWrapper: false }), content] }), children: children }));
|
|
10
|
+
return (_jsx(Popover, { trigger: trigger, arrow: arrow, destroyTooltipOnHide: true, ...restPopoverProps, overlayClassName: clsx('no-padding-content', overlayClassName), overlay: true, content: _jsxs(_Fragment, { children: [_jsx(StyledInput, { ref: inputSearchRef, placeholder: inputSearchProps?.placeholder || `${translate(translations.global.search)}`, bordered: false, ...inputSearchProps, addonAfter: _jsx(SearchIcon, {}), withWrapper: false }), content] }), children: children }));
|
|
11
11
|
};
|
|
@@ -1 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const StyledInput: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../../atoms/Input").InputProps & import("react").RefAttributes<import("rc-input").InputRef>> & {
|
|
3
|
+
readonly DefaultInput: import("react").ForwardRefExoticComponent<import("antd").InputProps & import("react").RefAttributes<import("rc-input").InputRef>> & {
|
|
4
|
+
Group: import("react").FC<import("antd/es/input").GroupProps>;
|
|
5
|
+
Search: import("react").ForwardRefExoticComponent<import("antd/es/input").SearchProps & import("react").RefAttributes<import("rc-input").InputRef>>;
|
|
6
|
+
TextArea: import("react").ForwardRefExoticComponent<import("antd/es/input").TextAreaProps & import("react").RefAttributes<import("antd/es/input/TextArea").TextAreaRef>>;
|
|
7
|
+
Password: import("react").ForwardRefExoticComponent<import("antd/es/input").PasswordProps & import("react").RefAttributes<import("rc-input").InputRef>>;
|
|
8
|
+
};
|
|
9
|
+
readonly CustomSearch: import("react").ForwardRefExoticComponent<import("../../atoms/Input").InputProps & import("react").RefAttributes<import("rc-input").InputRef>>;
|
|
10
|
+
readonly TextArea: import("react").ForwardRefExoticComponent<import("antd/es/input").TextAreaProps & import("react").RefAttributes<import("antd/es/input/TextArea").TextAreaRef>>;
|
|
11
|
+
readonly Password: import("react").ForwardRefExoticComponent<import("../../atoms/Input").InputProps & import("react").RefAttributes<import("rc-input").InputRef>>;
|
|
12
|
+
}, any, {}, never>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
1
|
import styled from 'styled-components';
|
|
3
2
|
import { Input } from '../../atoms/Input';
|
|
4
3
|
import { THEME } from '@antscorp/antsomi-ui/es/constants';
|
|
5
|
-
export const StyledInput = styled(
|
|
4
|
+
export const StyledInput = styled(Input) `
|
|
6
5
|
&.antsomi-input-group-wrapper {
|
|
7
6
|
padding: 8px 10px;
|
|
8
7
|
border-bottom: 1px solid var(--divider-1);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { PopoverProps } from 'antd';
|
|
2
|
-
import { InputProps } from '../../atoms/Input';
|
|
1
|
+
import type { InputRef, PopoverProps } from 'antd';
|
|
2
|
+
import type { InputProps } from '../../atoms/Input';
|
|
3
3
|
import React, { PropsWithChildren } from 'react';
|
|
4
|
-
import { MenuInlineProps } from '../VirtualizedMenu/types';
|
|
4
|
+
import type { MenuInlineProps } from '../VirtualizedMenu/types';
|
|
5
5
|
export type SearchConfig = {
|
|
6
6
|
searchWithKey?: boolean;
|
|
7
7
|
};
|
|
@@ -9,6 +9,7 @@ export type SearchPopoverProps = PropsWithChildren<{
|
|
|
9
9
|
inputSearchProps?: InputProps & {
|
|
10
10
|
searchConfig?: SearchConfig;
|
|
11
11
|
};
|
|
12
|
+
inputSearchRef?: React.RefObject<InputRef>;
|
|
12
13
|
isAllowEmpty?: boolean;
|
|
13
14
|
noItemContent?: React.ReactNode;
|
|
14
15
|
} & PopoverProps>;
|
|
@@ -17,7 +17,7 @@ import '@yaireo/tagify/dist/tagify.css';
|
|
|
17
17
|
// Styled
|
|
18
18
|
import { TagTextArea, TagifyWrapper, WrapperPlaceHolder } from './styled';
|
|
19
19
|
// Utils
|
|
20
|
-
import { parseTagStringToTagify, convertInputStringToOriginal, emojiManufacturer, getEmojiTag, isPersonalizeTagType, generateTagContent, unescapeString, hasLineBreak, selectRange, isTagClickable, findURLInTextNodes, getAttributesString, isAnchorNodeChildOfElement, isShortLinkTagType, isCustomTagType, sanitizeTagAttributes, getTagAttributes, applyTagAttributes, getTagContentAttributes, isCaretAtEndOfTextNodeWithNextTag, getCurrentSelectionAndCloneRange, handleEnterWithNextTag, handleTextNodeBackspace, } from './utils';
|
|
20
|
+
import { parseTagStringToTagify, convertInputStringToOriginal, emojiManufacturer, getEmojiTag, isPersonalizeTagType, generateTagContent, unescapeString, hasLineBreak, selectRange, isTagClickable, findURLInTextNodes, getAttributesString, isAnchorNodeChildOfElement, isShortLinkTagType, isCustomTagType, sanitizeTagAttributes, getTagAttributes, applyTagAttributes, getTagContentAttributes, isCaretAtEndOfTextNodeWithNextTag, getCurrentSelectionAndCloneRange, handleEnterWithNextTag, handleTextNodeBackspace, extractTagValues, preventUndoRedo, } from './utils';
|
|
21
21
|
import { acceptablePatternChecking, detectURLRegex, getCachedRegex, getCustomTagId, getPersonalizeTagInfo, getShortLinkTagInfo, patternHandlers, } from './patternHandlers';
|
|
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';
|
|
@@ -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, realtime, disabled, maxLength, maxHeight, minWidth, placeholder, minWidthPlaceholder, isSingleLineText, acceptableTagPattern, tagProperties, mapAttributes = {}, mapErrorAttributes = {}, maxPersonalizeTags, name, children, cssTagifyVariables, disableEditableIfContainsTags, onTagClick, onAddTag, onTagRemove, onChange, onRestoreTagProperty, onBlur, } = props;
|
|
29
29
|
// States
|
|
30
30
|
const [isLineBreak, setIsLineBreak] = useState(hasLineBreak(initialValue));
|
|
31
31
|
const [tooltipRefresher, setTooltipRefresher] = useState(1);
|
|
@@ -456,6 +456,7 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
456
456
|
}
|
|
457
457
|
setLabelTagRefreshness(prev => prev + 1);
|
|
458
458
|
},
|
|
459
|
+
getInputValues: () => extractTagValues(tagifyRef.current),
|
|
459
460
|
}), [acceptableTagPattern, escapeHTML, onInjectTagAtCaret, placeCaretAfterNode]);
|
|
460
461
|
const onTagItemClick = useCallback((event) => {
|
|
461
462
|
event.stopPropagation();
|
|
@@ -471,7 +472,7 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
471
472
|
}, [onTagClick]);
|
|
472
473
|
const onTagifyRemoveTag = useCallback((event) => {
|
|
473
474
|
if (event.detail && onTagRemove) {
|
|
474
|
-
onTagRemove(event.detail);
|
|
475
|
+
onTagRemove(event.detail, extractTagValues(event.detail.tagify));
|
|
475
476
|
}
|
|
476
477
|
}, [onTagRemove]);
|
|
477
478
|
// Used to trigger replace URL detection and line break
|
|
@@ -767,18 +768,6 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
767
768
|
});
|
|
768
769
|
}
|
|
769
770
|
}, [maxLength, customizeTag]);
|
|
770
|
-
useEffect(() => {
|
|
771
|
-
if (!tagifyRef.current || typeof readonlyText === 'undefined')
|
|
772
|
-
return;
|
|
773
|
-
const inputEl = tagifyRef.current.DOM.input;
|
|
774
|
-
if (typeof readonlyText === 'function') {
|
|
775
|
-
const isReadonlyText = readonlyText(tagifyRef.current.getCleanValue());
|
|
776
|
-
inputEl.setAttribute('contenteditable', isReadonlyText ? 'false' : 'true');
|
|
777
|
-
}
|
|
778
|
-
else {
|
|
779
|
-
inputEl.setAttribute('contenteditable', readonlyText ? 'false' : 'true');
|
|
780
|
-
}
|
|
781
|
-
}, [readonlyText, tagLength]);
|
|
782
771
|
const onTagifyWrapperClick = useCallback(event => {
|
|
783
772
|
event.preventDefault();
|
|
784
773
|
event.stopPropagation();
|
|
@@ -790,6 +779,22 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
790
779
|
return;
|
|
791
780
|
const { classList } = DOM?.scope;
|
|
792
781
|
const { classNames } = settings;
|
|
782
|
+
if (disableEditableIfContainsTags) {
|
|
783
|
+
// Empty input is always editable
|
|
784
|
+
const isEmpty = classList.contains(classNames.empty);
|
|
785
|
+
let shouldBeEditable = isEmpty;
|
|
786
|
+
// If not empty, check if input contains restricted tags
|
|
787
|
+
if (!isEmpty) {
|
|
788
|
+
const { listTags } = extractTagValues(tagifyRef.current);
|
|
789
|
+
const hasRestrictedTag = listTags.some(tag => disableEditableIfContainsTags.includes(tag.type));
|
|
790
|
+
shouldBeEditable = !hasRestrictedTag;
|
|
791
|
+
}
|
|
792
|
+
// Apply contenteditable attribute
|
|
793
|
+
DOM.input.setAttribute('contenteditable', shouldBeEditable ? 'true' : 'false');
|
|
794
|
+
// Exit early if input should not be editable
|
|
795
|
+
if (!shouldBeEditable)
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
793
798
|
if (!classList.contains(classNames.focus) && DOM?.input) {
|
|
794
799
|
try {
|
|
795
800
|
const { lastChild } = DOM?.input;
|
|
@@ -825,6 +830,12 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
825
830
|
}
|
|
826
831
|
}
|
|
827
832
|
}
|
|
833
|
+
}, [disableEditableIfContainsTags]);
|
|
834
|
+
const onContentEditable = useCallback((editable) => {
|
|
835
|
+
if (!tagifyRef.current)
|
|
836
|
+
return;
|
|
837
|
+
const inputEl = tagifyRef.current.DOM.input;
|
|
838
|
+
inputEl.setAttribute('contenteditable', editable ? 'true' : 'false');
|
|
828
839
|
}, []);
|
|
829
840
|
// Initialization tagify
|
|
830
841
|
useLayoutEffect(() => {
|
|
@@ -836,7 +847,12 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
836
847
|
};
|
|
837
848
|
}, [initializeTagify]);
|
|
838
849
|
useEffect(() => {
|
|
839
|
-
if (
|
|
850
|
+
if (typeof readonlyText !== 'boolean')
|
|
851
|
+
return;
|
|
852
|
+
onContentEditable(!readonlyText);
|
|
853
|
+
}, [readonlyText, onContentEditable]);
|
|
854
|
+
useEffect(() => {
|
|
855
|
+
if (tagifyRef.current && typeof tagLength === 'number' && _.isFunction(onTagRemove)) {
|
|
840
856
|
// Because the remove tag event is not triggered when the tag is removed with Backspace or drag selection tags
|
|
841
857
|
// we need to listen to the input element to detect when a tag is removed
|
|
842
858
|
let mutationQueue = [];
|
|
@@ -865,8 +881,11 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
865
881
|
try {
|
|
866
882
|
node.dataset.__removed_by_mutation = 'true';
|
|
867
883
|
const tagData = tagifyRef.current?.getSetTagData(node);
|
|
868
|
-
if (
|
|
869
|
-
|
|
884
|
+
if (tagifyRef.current &&
|
|
885
|
+
tagData &&
|
|
886
|
+
tagData.type === CUSTOM_TAG &&
|
|
887
|
+
!tagData?.__removed) {
|
|
888
|
+
onTagRemove({ data: tagData }, extractTagValues(tagifyRef.current));
|
|
870
889
|
}
|
|
871
890
|
}
|
|
872
891
|
catch (error) {
|
|
@@ -978,6 +997,13 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
978
997
|
tagifyInstance.on('change', onTagifyChangedDebounce);
|
|
979
998
|
tagifyInstance.on('remove', onTagifyRemoveTag);
|
|
980
999
|
tagifyInstance.on('keydown', onKeyDown);
|
|
1000
|
+
if (onAddTag)
|
|
1001
|
+
tagifyInstance.on('add', onAddTag);
|
|
1002
|
+
if (onBlur)
|
|
1003
|
+
tagifyInstance.on('blur', onBlur);
|
|
1004
|
+
if (tagifyInstance.DOM.input) {
|
|
1005
|
+
tagifyInstance.DOM.input.addEventListener('keydown', preventUndoRedo);
|
|
1006
|
+
}
|
|
981
1007
|
}
|
|
982
1008
|
// Off listen to Tagify events
|
|
983
1009
|
return () => {
|
|
@@ -987,9 +1013,18 @@ const TagifyInput = forwardRef((props, ref) => {
|
|
|
987
1013
|
tagifyInstance.off('change', onTagifyChangedDebounce);
|
|
988
1014
|
tagifyInstance.off('remove', onTagifyRemoveTag);
|
|
989
1015
|
tagifyInstance.off('keydown', onKeyDown);
|
|
1016
|
+
if (onAddTag)
|
|
1017
|
+
tagifyInstance.off('add', onAddTag);
|
|
1018
|
+
if (onBlur)
|
|
1019
|
+
tagifyInstance.off('blur', onBlur);
|
|
1020
|
+
if (tagifyInstance.DOM.input) {
|
|
1021
|
+
tagifyInstance.DOM.input.removeEventListener('keydown', preventUndoRedo);
|
|
1022
|
+
}
|
|
990
1023
|
}
|
|
991
1024
|
};
|
|
992
1025
|
}, [
|
|
1026
|
+
onAddTag,
|
|
1027
|
+
onBlur,
|
|
993
1028
|
onTagItemClick,
|
|
994
1029
|
onInputTagifyDebounce,
|
|
995
1030
|
onTagifyChangedDebounce,
|
|
@@ -15,6 +15,10 @@ export type TagStatus = (typeof TAG_STATUS)[keyof typeof TAG_STATUS];
|
|
|
15
15
|
export type MapAttributesProps = Record<string, Record<string, any>>;
|
|
16
16
|
export type StatusType = 'error' | 'success' | 'warning';
|
|
17
17
|
export type BackgroundColorPersonalizeType = Exclude<keyof typeof TAG_COLOR, 'detect_link' | 'emoji' | 'shortlink'>;
|
|
18
|
+
export interface TagValues {
|
|
19
|
+
listTags: TagDataCustomize[];
|
|
20
|
+
value: string;
|
|
21
|
+
}
|
|
18
22
|
/**
|
|
19
23
|
* Interface defining the properties for the Tagify input component.
|
|
20
24
|
* Provides configuration options and event handlers to manage Tagify's behavior and appearance.
|
|
@@ -134,11 +138,16 @@ export interface TagifyInputProps {
|
|
|
134
138
|
* Receives the tag detail as parameter, allowing custom actions on tag click.
|
|
135
139
|
*/
|
|
136
140
|
onTagClick?: (tagDetail: Tagify.ClickEventData<TagDataCustomize>) => void;
|
|
141
|
+
/**
|
|
142
|
+
* Event handler triggered when a tag is added.
|
|
143
|
+
* Receives the tag detail as parameter, allowing custom actions on tag addition.
|
|
144
|
+
*/
|
|
145
|
+
onAddTag?: (event: CustomEvent<Tagify.AddEventData<TagDataCustomize>>) => void;
|
|
137
146
|
/**
|
|
138
147
|
* Event handler triggered when a tag is removed.
|
|
139
148
|
* Receives the tag detail as parameter, allowing custom actions on tag removal.
|
|
140
149
|
*/
|
|
141
|
-
onTagRemove?: (tagDetail: Tagify.RemoveEventData<TagDataCustomize
|
|
150
|
+
onTagRemove?: (tagDetail: Tagify.RemoveEventData<TagDataCustomize>, values: TagValues) => void;
|
|
142
151
|
/**
|
|
143
152
|
* Event handler triggered when the input value changes.
|
|
144
153
|
* Receives the updated input value as a string, allowing for controlled component updates.
|
|
@@ -146,6 +155,11 @@ export interface TagifyInputProps {
|
|
|
146
155
|
* @default () => {}
|
|
147
156
|
*/
|
|
148
157
|
onChange: (inputValue: string) => void;
|
|
158
|
+
/**
|
|
159
|
+
* Event handler triggered when the input value is blurred.
|
|
160
|
+
* Receives the updated input value as a string, allowing for controlled component updates.
|
|
161
|
+
*/
|
|
162
|
+
onBlur?: (event: CustomEvent<Tagify.BlurEventData<TagDataCustomize>>) => void;
|
|
149
163
|
/**
|
|
150
164
|
* Event handler triggered when found mismatch tag properties.
|
|
151
165
|
* Receives an array of tag properties that were restored (e.g., via undo operation).
|
|
@@ -154,13 +168,18 @@ export interface TagifyInputProps {
|
|
|
154
168
|
/**
|
|
155
169
|
* Defines whether the input text is read but not the whole tags.
|
|
156
170
|
*/
|
|
157
|
-
readonlyText?: boolean
|
|
171
|
+
readonlyText?: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Tags that, when present in input, make the entire input non-editable
|
|
174
|
+
*/
|
|
175
|
+
disableEditableIfContainsTags?: TagType[];
|
|
158
176
|
}
|
|
159
177
|
export interface TagifyInputRef {
|
|
160
178
|
onAddNewTag: (newTag: TagDataCustomize | string) => void;
|
|
161
179
|
onReplaceTag: (currentTagEle: HTMLElement, newTag: TagDataCustomize) => void;
|
|
162
180
|
onReload: (newValue: string) => void;
|
|
163
181
|
onLabelTagRefreshness: () => void;
|
|
182
|
+
getInputValues: () => TagValues;
|
|
164
183
|
}
|
|
165
184
|
export type EmojiCollection = (typeof EMOJI_COLLECTIONS)[keyof typeof EMOJI_COLLECTIONS];
|
|
166
185
|
export type ShortLinkType = (typeof SHORT_LINK_TYPE)[keyof typeof SHORT_LINK_TYPE];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="yaireo__tagify" />
|
|
2
2
|
import Tagify from '@yaireo/tagify';
|
|
3
|
-
import { AcceptablePattern, TagAttribute, EmojiCollection, EmojiTag, TagDataCustomize, TagProperty, TagType } from './types';
|
|
3
|
+
import { AcceptablePattern, TagAttribute, EmojiCollection, EmojiTag, TagDataCustomize, TagProperty, TagType, TagValues } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Parses the input string and replaces matching patterns with processed tags.
|
|
6
6
|
* This function iterates over predefined regex patterns and replaces each match
|
|
@@ -202,3 +202,8 @@ export declare const getCurrentSelectionAndCloneRange: () => {
|
|
|
202
202
|
};
|
|
203
203
|
export declare const handleTextNodeBackspace: (range: Range) => void;
|
|
204
204
|
export declare const handleEnterWithNextTag: (range: Range) => void;
|
|
205
|
+
export declare const removeInvisibleChars: (str: string) => string;
|
|
206
|
+
export declare const extractTagValues: (tagify: Tagify<TagDataCustomize>) => TagValues;
|
|
207
|
+
export declare function preventUndoRedo(e: CustomEvent<Tagify.KeydownEventData<TagDataCustomize>>['detail']['event'], { disableRedo }?: {
|
|
208
|
+
disableRedo?: boolean | undefined;
|
|
209
|
+
}): void;
|
|
@@ -796,3 +796,22 @@ export const handleEnterWithNextTag = (range) => {
|
|
|
796
796
|
return;
|
|
797
797
|
insertZeroWidthSpaceBeforeTag(currentNode);
|
|
798
798
|
};
|
|
799
|
+
export const removeInvisibleChars = (str) => str.replace(/[\r\n\u200B-\u200D\uFEFF]/g, '');
|
|
800
|
+
export const extractTagValues = (tagify) => {
|
|
801
|
+
if (!tagify)
|
|
802
|
+
return { listTags: [], value: '' };
|
|
803
|
+
return {
|
|
804
|
+
listTags: tagify.getCleanValue(),
|
|
805
|
+
value: tagify.getInputValue(),
|
|
806
|
+
};
|
|
807
|
+
};
|
|
808
|
+
export function preventUndoRedo(e, { disableRedo = false } = {}) {
|
|
809
|
+
const key = e.key.toLowerCase();
|
|
810
|
+
const isUndo = (e.ctrlKey || e.metaKey) && key === 'z';
|
|
811
|
+
const isRedo = (disableRedo && (e.ctrlKey || e.metaKey) && key === 'y') ||
|
|
812
|
+
((e.ctrlKey || e.metaKey) && e.shiftKey && key === 'z');
|
|
813
|
+
if (isUndo || isRedo) {
|
|
814
|
+
e.preventDefault();
|
|
815
|
+
e.stopPropagation();
|
|
816
|
+
}
|
|
817
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { memo, useMemo, useRef,
|
|
2
|
+
import { memo, useMemo, useRef, useCallback } from 'react';
|
|
3
3
|
import { Typography } from '../../../../atoms/Typography';
|
|
4
4
|
import { MenuItemRoot } from '../../styled';
|
|
5
5
|
import clsx from 'clsx';
|
|
@@ -69,11 +69,7 @@ export const Item = memo((props) => {
|
|
|
69
69
|
}, [item.id, normalizeTreeItems, selectedKeys]);
|
|
70
70
|
const className = clsx(itemClassName, {
|
|
71
71
|
[CLS.Item.selectedDescendant]: isSelectedDescendant,
|
|
72
|
+
[CLS.Item.focused]: isFocused,
|
|
72
73
|
});
|
|
73
|
-
|
|
74
|
-
if (isFocused) {
|
|
75
|
-
itemRef.current?.focus({ preventScroll: true });
|
|
76
|
-
}
|
|
77
|
-
}, [isFocused]);
|
|
78
|
-
return (_jsxs(MenuItemRoot, { ref: handleItemRef, role: displayOnly ? 'none' : 'treeitem', tabIndex: displayOnly ? -1 : isFocused ? 0 : -1, "aria-selected": displayOnly ? undefined : selected, "aria-disabled": displayOnly ? undefined : disabled, "aria-expanded": displayOnly ? undefined : expanded, "aria-level": displayOnly ? undefined : item.level, "aria-posinset": displayOnly ? undefined : index + 1, "aria-setsize": displayOnly ? undefined : items.length, className: className, style: itemStyle, onClick: e => handleOnClick(e, 'item'), children: [_jsx("div", { className: CLS.ItemLabel.default, children: labelContent }), actionContent] }));
|
|
74
|
+
return (_jsxs(MenuItemRoot, { "data-selected": !!selected, "data-focused": isFocused, ref: handleItemRef, role: displayOnly ? 'none' : 'treeitem', "aria-selected": displayOnly ? undefined : selected, "aria-disabled": displayOnly ? undefined : disabled, "aria-expanded": displayOnly ? undefined : expanded, "aria-level": displayOnly ? undefined : item.level, "aria-posinset": displayOnly ? undefined : index + 1, "aria-setsize": displayOnly ? undefined : items.length, className: className, style: itemStyle, onClick: e => handleOnClick(e, 'item'), children: [_jsx("div", { className: CLS.ItemLabel.default, children: labelContent }), actionContent] }));
|
|
79
75
|
}, areEqual);
|