@quadrats/react 1.1.4 → 1.1.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.
- package/card/toolbar/index.cjs.js +11 -25
- package/card/toolbar/useCardTool.js +11 -25
- package/carousel/toolbar/index.cjs.js +10 -24
- package/carousel/toolbar/useCarouselTool.js +10 -24
- package/core/components/Quadrats.js +4 -4
- package/core/contexts/modal/CardModal/CardModal.js +17 -9
- package/core/contexts/modal/CarouselModal/CarouselItem.js +2 -12
- package/core/contexts/modal/CarouselModal/CarouselModal.js +2 -4
- package/core/contexts/modal/ConfirmModal/ConfirmModal.js +4 -1
- package/core/contexts/modal/EmbedModal/EmbedModal.js +2 -0
- package/embed/toolbar/index.cjs.js +4 -20
- package/embed/toolbar/useEmbedTool.js +4 -20
- package/index.cjs.js +30 -28
- package/package.json +3 -3
- package/table/defaultRenderTableElements.js +1 -1
- package/table/hooks/useTableCellToolbarActions.js +15 -1
- package/table/index.cjs.js +16 -2
- package/table/jsx-serializer/defaultRenderTableElements.js +1 -1
- package/table/jsx-serializer/index.cjs.js +1 -1
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
|
-
var core = require('@quadrats/core');
|
|
5
|
-
var card = require('@quadrats/common/card');
|
|
6
4
|
var react = require('@quadrats/react');
|
|
7
5
|
var tslib = require('tslib');
|
|
8
6
|
var toolbar = require('@quadrats/react/toolbar');
|
|
@@ -11,18 +9,19 @@ function useCardTool(controller) {
|
|
|
11
9
|
const editor = react.useSlateStatic();
|
|
12
10
|
const { setCardModalConfig, isModalClosed, setIsModalClosed } = react.useModal();
|
|
13
11
|
React.useEffect(() => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
if (isModalClosed) {
|
|
13
|
+
setTimeout(() => {
|
|
14
|
+
controller.removeCardPlaceholder(editor);
|
|
15
|
+
setIsModalClosed(false);
|
|
16
|
+
}, 250);
|
|
17
|
+
}
|
|
18
|
+
}, [controller, editor, isModalClosed, setIsModalClosed]);
|
|
19
|
+
return {
|
|
20
|
+
onClick: () => {
|
|
21
|
+
controller.insertCardPlaceholder(editor);
|
|
22
22
|
setCardModalConfig({
|
|
23
23
|
controller,
|
|
24
24
|
onConfirm: ({ values, imageItem, haveLink }) => {
|
|
25
|
-
controller.removeCardPlaceholder(editor);
|
|
26
25
|
controller.insertCard({
|
|
27
26
|
editor,
|
|
28
27
|
cardValues: {
|
|
@@ -36,22 +35,9 @@ function useCardTool(controller) {
|
|
|
36
35
|
linkUrl: values.linkUrl,
|
|
37
36
|
},
|
|
38
37
|
});
|
|
38
|
+
controller.removeCardPlaceholder(editor);
|
|
39
39
|
},
|
|
40
40
|
});
|
|
41
|
-
}
|
|
42
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
|
-
}, [controller, editor]);
|
|
44
|
-
React.useEffect(() => {
|
|
45
|
-
if (isModalClosed) {
|
|
46
|
-
setTimeout(() => {
|
|
47
|
-
controller.removeCardPlaceholder(editor);
|
|
48
|
-
setIsModalClosed(false);
|
|
49
|
-
}, 250);
|
|
50
|
-
}
|
|
51
|
-
}, [controller, editor, isModalClosed, setIsModalClosed]);
|
|
52
|
-
return {
|
|
53
|
-
onClick: () => {
|
|
54
|
-
controller.insertCardPlaceholder(editor);
|
|
55
41
|
},
|
|
56
42
|
};
|
|
57
43
|
}
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
-
import { Editor, Element } from '@quadrats/core';
|
|
3
|
-
import { CARD_PLACEHOLDER_TYPE } from '@quadrats/common/card';
|
|
4
2
|
import { useSlateStatic, useModal } from '@quadrats/react';
|
|
5
3
|
|
|
6
4
|
function useCardTool(controller) {
|
|
7
5
|
const editor = useSlateStatic();
|
|
8
6
|
const { setCardModalConfig, isModalClosed, setIsModalClosed } = useModal();
|
|
9
7
|
useEffect(() => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
if (isModalClosed) {
|
|
9
|
+
setTimeout(() => {
|
|
10
|
+
controller.removeCardPlaceholder(editor);
|
|
11
|
+
setIsModalClosed(false);
|
|
12
|
+
}, 250);
|
|
13
|
+
}
|
|
14
|
+
}, [controller, editor, isModalClosed, setIsModalClosed]);
|
|
15
|
+
return {
|
|
16
|
+
onClick: () => {
|
|
17
|
+
controller.insertCardPlaceholder(editor);
|
|
18
18
|
setCardModalConfig({
|
|
19
19
|
controller,
|
|
20
20
|
onConfirm: ({ values, imageItem, haveLink }) => {
|
|
21
|
-
controller.removeCardPlaceholder(editor);
|
|
22
21
|
controller.insertCard({
|
|
23
22
|
editor,
|
|
24
23
|
cardValues: {
|
|
@@ -32,22 +31,9 @@ function useCardTool(controller) {
|
|
|
32
31
|
linkUrl: values.linkUrl,
|
|
33
32
|
},
|
|
34
33
|
});
|
|
34
|
+
controller.removeCardPlaceholder(editor);
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
|
-
}
|
|
38
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39
|
-
}, [controller, editor]);
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
if (isModalClosed) {
|
|
42
|
-
setTimeout(() => {
|
|
43
|
-
controller.removeCardPlaceholder(editor);
|
|
44
|
-
setIsModalClosed(false);
|
|
45
|
-
}, 250);
|
|
46
|
-
}
|
|
47
|
-
}, [controller, editor, isModalClosed, setIsModalClosed]);
|
|
48
|
-
return {
|
|
49
|
-
onClick: () => {
|
|
50
|
-
controller.insertCardPlaceholder(editor);
|
|
51
37
|
},
|
|
52
38
|
};
|
|
53
39
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
|
-
var core = require('@quadrats/core');
|
|
5
|
-
var carousel = require('@quadrats/common/carousel');
|
|
6
4
|
var react = require('@quadrats/react');
|
|
7
5
|
var tslib = require('tslib');
|
|
8
6
|
var toolbar = require('@quadrats/react/toolbar');
|
|
@@ -10,28 +8,6 @@ var toolbar = require('@quadrats/react/toolbar');
|
|
|
10
8
|
function useCarouselTool(controller) {
|
|
11
9
|
const editor = react.useSlateStatic();
|
|
12
10
|
const { setCarouselModalConfig, isModalClosed, setIsModalClosed } = react.useModal();
|
|
13
|
-
React.useEffect(() => {
|
|
14
|
-
const [match] = core.Editor.nodes(editor, {
|
|
15
|
-
at: [],
|
|
16
|
-
match: (node) => {
|
|
17
|
-
const placeholderElement = node;
|
|
18
|
-
return core.Element.isElement(placeholderElement) && placeholderElement.type === carousel.CAROUSEL_PLACEHOLDER_TYPE;
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
if (match) {
|
|
22
|
-
setCarouselModalConfig({
|
|
23
|
-
controller,
|
|
24
|
-
onConfirm: (items) => {
|
|
25
|
-
controller.removeCarouselPlaceholder(editor);
|
|
26
|
-
controller.insertCarousel({
|
|
27
|
-
editor,
|
|
28
|
-
items,
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
-
}, [controller, editor]);
|
|
35
11
|
React.useEffect(() => {
|
|
36
12
|
if (isModalClosed) {
|
|
37
13
|
setTimeout(() => {
|
|
@@ -43,6 +19,16 @@ function useCarouselTool(controller) {
|
|
|
43
19
|
return {
|
|
44
20
|
onClick: () => {
|
|
45
21
|
controller.insertCarouselPlaceholder(editor);
|
|
22
|
+
setCarouselModalConfig({
|
|
23
|
+
controller,
|
|
24
|
+
onConfirm: (items) => {
|
|
25
|
+
controller.insertCarousel({
|
|
26
|
+
editor,
|
|
27
|
+
items,
|
|
28
|
+
});
|
|
29
|
+
controller.removeCarouselPlaceholder(editor);
|
|
30
|
+
},
|
|
31
|
+
});
|
|
46
32
|
},
|
|
47
33
|
};
|
|
48
34
|
}
|
|
@@ -1,33 +1,9 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
|
-
import { Editor, Element } from '@quadrats/core';
|
|
3
|
-
import { CAROUSEL_PLACEHOLDER_TYPE } from '@quadrats/common/carousel';
|
|
4
2
|
import { useSlateStatic, useModal } from '@quadrats/react';
|
|
5
3
|
|
|
6
4
|
function useCarouselTool(controller) {
|
|
7
5
|
const editor = useSlateStatic();
|
|
8
6
|
const { setCarouselModalConfig, isModalClosed, setIsModalClosed } = useModal();
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
const [match] = Editor.nodes(editor, {
|
|
11
|
-
at: [],
|
|
12
|
-
match: (node) => {
|
|
13
|
-
const placeholderElement = node;
|
|
14
|
-
return Element.isElement(placeholderElement) && placeholderElement.type === CAROUSEL_PLACEHOLDER_TYPE;
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
if (match) {
|
|
18
|
-
setCarouselModalConfig({
|
|
19
|
-
controller,
|
|
20
|
-
onConfirm: (items) => {
|
|
21
|
-
controller.removeCarouselPlaceholder(editor);
|
|
22
|
-
controller.insertCarousel({
|
|
23
|
-
editor,
|
|
24
|
-
items,
|
|
25
|
-
});
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
30
|
-
}, [controller, editor]);
|
|
31
7
|
useEffect(() => {
|
|
32
8
|
if (isModalClosed) {
|
|
33
9
|
setTimeout(() => {
|
|
@@ -39,6 +15,16 @@ function useCarouselTool(controller) {
|
|
|
39
15
|
return {
|
|
40
16
|
onClick: () => {
|
|
41
17
|
controller.insertCarouselPlaceholder(editor);
|
|
18
|
+
setCarouselModalConfig({
|
|
19
|
+
controller,
|
|
20
|
+
onConfirm: (items) => {
|
|
21
|
+
controller.insertCarousel({
|
|
22
|
+
editor,
|
|
23
|
+
items,
|
|
24
|
+
});
|
|
25
|
+
controller.removeCarouselPlaceholder(editor);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
42
28
|
},
|
|
43
29
|
};
|
|
44
30
|
}
|
|
@@ -12,10 +12,10 @@ import { MessageProvider } from '../contexts/message/MessageProvider.js';
|
|
|
12
12
|
function Quadrats(props) {
|
|
13
13
|
const { children, editor, locale, onChange, theme, value, needConfirmModal, setNeedConfirmModal } = props;
|
|
14
14
|
return (React.createElement(ConfigsProvider, { theme: theme, locale: locale },
|
|
15
|
-
React.createElement(
|
|
16
|
-
React.createElement(
|
|
17
|
-
React.createElement(
|
|
18
|
-
React.createElement(
|
|
15
|
+
React.createElement(DndProvider, { backend: HTML5Backend },
|
|
16
|
+
React.createElement(MessageProvider, null,
|
|
17
|
+
React.createElement(ModalProvider, { needConfirmModal: needConfirmModal, setNeedConfirmModal: setNeedConfirmModal },
|
|
18
|
+
React.createElement(Slate, { editor: editor, onChange: onChange, initialValue: value }, children))))));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export { Quadrats as default };
|
|
@@ -17,18 +17,19 @@ const options = [
|
|
|
17
17
|
label: '純文字顯示',
|
|
18
18
|
},
|
|
19
19
|
];
|
|
20
|
+
const emptyValues = {
|
|
21
|
+
alignment: 'leftImageRightText',
|
|
22
|
+
title: '',
|
|
23
|
+
description: '',
|
|
24
|
+
remark: '',
|
|
25
|
+
linkText: '',
|
|
26
|
+
linkUrl: '',
|
|
27
|
+
};
|
|
20
28
|
// TODO: i18n
|
|
21
29
|
const CardModal = ({ isOpen, close, controller, initialValue, onConfirm: onConfirmProps }) => {
|
|
22
30
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
23
31
|
const { message } = useMessage();
|
|
24
|
-
const [values, setValues] = useState(
|
|
25
|
-
alignment: 'leftImageRightText',
|
|
26
|
-
title: '',
|
|
27
|
-
description: '',
|
|
28
|
-
remark: '',
|
|
29
|
-
linkText: '',
|
|
30
|
-
linkUrl: '',
|
|
31
|
-
});
|
|
32
|
+
const [values, setValues] = useState(emptyValues);
|
|
32
33
|
const [imageUploaderItem, setImageUploaderItem] = useState(null);
|
|
33
34
|
const [haveLink, setHaveLink] = useState(true);
|
|
34
35
|
const [errors, setErrors] = useState([]);
|
|
@@ -69,11 +70,18 @@ const CardModal = ({ isOpen, close, controller, initialValue, onConfirm: onConfi
|
|
|
69
70
|
setErrors(errorItems);
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
73
|
+
close();
|
|
74
|
+
setValues(emptyValues);
|
|
75
|
+
setHaveLink(true);
|
|
76
|
+
setImageUploaderItem(null);
|
|
72
77
|
onConfirmProps({ values, imageItem: values.alignment === 'noImage' ? null : imageUploaderItem, haveLink });
|
|
73
78
|
}
|
|
74
|
-
}, [imageUploaderItem, onConfirmProps, haveLink, values]);
|
|
79
|
+
}, [imageUploaderItem, close, onConfirmProps, haveLink, values]);
|
|
75
80
|
return (React.createElement(Modal, { isOpen: isOpen, size: "medium", title: "\u5EFA\u7ACB\u5361\u7247", confirmText: "\u5EFA\u7ACB\u5361\u7247", mainAreaClassName: "qdr-card-modal__main", closable: !uploading, maskClosable: !uploading, onClose: () => {
|
|
76
81
|
close();
|
|
82
|
+
setValues(emptyValues);
|
|
83
|
+
setHaveLink(true);
|
|
84
|
+
setImageUploaderItem(null);
|
|
77
85
|
}, onConfirm: onConfirm },
|
|
78
86
|
React.createElement("div", { className: "qdr-card-modal__block" },
|
|
79
87
|
React.createElement("p", { className: "qdr-card-modal__block-title" }, "\u986F\u793A\u8A2D\u5B9A"),
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { useDrag, useDrop } from 'react-dnd';
|
|
4
4
|
import { Progress, Icon, Input } from '@quadrats/react/components';
|
|
5
5
|
import { Trash, Image } from '@quadrats/icons';
|
|
6
6
|
|
|
7
7
|
const CarouselItem = ({ url, preview, progress, caption, index, onChange, onRemove, swap, ratio, isError, }) => {
|
|
8
|
-
const [inputValue, setInputValue] = useState(caption);
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
const timeoutId = setTimeout(() => {
|
|
11
|
-
onChange(inputValue);
|
|
12
|
-
}, 500);
|
|
13
|
-
return () => {
|
|
14
|
-
clearTimeout(timeoutId);
|
|
15
|
-
};
|
|
16
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
17
|
-
}, [inputValue]);
|
|
18
8
|
const [{ isDragging }, drag, dragPreview] = useDrag(() => ({
|
|
19
9
|
type: 'CarouselItem',
|
|
20
10
|
collect: (monitor) => ({
|
|
@@ -50,7 +40,7 @@ const CarouselItem = ({ url, preview, progress, caption, index, onChange, onRemo
|
|
|
50
40
|
aspectRatio: ratio ? `${ratio[0]} / ${ratio[1]}` : '3 /2',
|
|
51
41
|
} }))),
|
|
52
42
|
React.createElement("div", { className: "qdr-carousel-modal__input-wrapper" },
|
|
53
|
-
React.createElement(Input, { value:
|
|
43
|
+
React.createElement(Input, { value: caption, onChange: onChange, placeholder: "\u5716\u7247\u8AAA\u660E\u6216\u66FF\u4EE3\u6587\u5B57..." }))))));
|
|
54
44
|
};
|
|
55
45
|
|
|
56
46
|
export { CarouselItem as default };
|
|
@@ -3,14 +3,12 @@ import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
|
|
3
3
|
import clsx from 'clsx';
|
|
4
4
|
import { Plus, Upload } from '@quadrats/icons';
|
|
5
5
|
import { usePreviousValue, readFileAsBase64, upload } from '@quadrats/react/utils';
|
|
6
|
-
import { useSlateStatic } from 'slate-react';
|
|
7
6
|
import { Modal, Hints, Button, Icon } from '@quadrats/react/components';
|
|
8
7
|
import { useMessage } from '../../message/message.js';
|
|
9
8
|
import FilesDropZone from './FilesDropZone.js';
|
|
10
9
|
import CarouselItem from './CarouselItem.js';
|
|
11
10
|
|
|
12
11
|
const CarouselModal = ({ isOpen, close, controller, initialValue = [], onConfirm }) => {
|
|
13
|
-
const editor = useSlateStatic();
|
|
14
12
|
const [uploading, setUploading] = useState(false);
|
|
15
13
|
const [isDragging, setIsDragging] = useState(false);
|
|
16
14
|
const [items, setItems] = useState([]);
|
|
@@ -124,7 +122,7 @@ const CarouselModal = ({ isOpen, close, controller, initialValue = [], onConfirm
|
|
|
124
122
|
},
|
|
125
123
|
].filter((h) => !!h) })),
|
|
126
124
|
React.createElement(Button, { className: "qdr-carousel-modal__side__upload", variant: "outlined", size: "large", disabled: isOverMaxLength, prefix: React.createElement(Icon, { icon: Plus, width: 24, height: 24 }), onClick: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
127
|
-
const files = yield (controller === null || controller === void 0 ? void 0 : controller.selectFiles(
|
|
125
|
+
const files = yield (controller === null || controller === void 0 ? void 0 : controller.selectFiles());
|
|
128
126
|
if (files) {
|
|
129
127
|
const correctFiles = files.filter((f) => (controller === null || controller === void 0 ? void 0 : controller.limitSize) && f.size <= controller.limitSize * 1024 * 1024);
|
|
130
128
|
if (correctFiles.length !== files.length) {
|
|
@@ -154,7 +152,7 @@ const CarouselModal = ({ isOpen, close, controller, initialValue = [], onConfirm
|
|
|
154
152
|
} },
|
|
155
153
|
React.createElement(FilesDropZone, { isDragging: isDragging, setIsDragging: setIsDragging, isOverMaxLength: isOverMaxLength, controller: controller, uploadFiles: uploadFiles }, items.length > 0 ? (React.createElement("div", { className: clsx('qdr-carousel-modal__grid', {
|
|
156
154
|
'qdr-carousel-modal__grid--isDragging': isDragging,
|
|
157
|
-
}) }, items.map((item, index) => (React.createElement(CarouselItem, { key: `${item.url}-${item.
|
|
155
|
+
}) }, items.map((item, index) => (React.createElement(CarouselItem, { key: `${item.url}-${item.preview}-${index}`, url: item.url, preview: item.preview, progress: item.progress, caption: item.caption, index: index, ratio: controller === null || controller === void 0 ? void 0 : controller.ratio, isError: item.isError, onChange: (value) => {
|
|
158
156
|
change(index, { url: item.url, caption: value });
|
|
159
157
|
}, onRemove: () => {
|
|
160
158
|
remove(index);
|
|
@@ -15,7 +15,10 @@ const ConfirmModal = ({ isOpen, title, content, confirmText, close, onConfirm, h
|
|
|
15
15
|
React.createElement("div", { className: "qdr-confirm-modal__content" }, content))),
|
|
16
16
|
haveFooter && (React.createElement("div", { className: "qdr-confirm-modal__footer" },
|
|
17
17
|
React.createElement(Button, { variant: "secondary", onClick: close }, locale.editor.cancel),
|
|
18
|
-
React.createElement(Button, { variant: "primary", danger: true, onClick:
|
|
18
|
+
React.createElement(Button, { variant: "primary", danger: true, onClick: () => {
|
|
19
|
+
close();
|
|
20
|
+
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
|
|
21
|
+
} }, confirmText || locale.editor.confirm)))));
|
|
19
22
|
};
|
|
20
23
|
|
|
21
24
|
export { ConfirmModal };
|
|
@@ -18,6 +18,8 @@ const EmbedModal = ({ isOpen, close, placeholder, confirmText, hint, type, onCon
|
|
|
18
18
|
close();
|
|
19
19
|
setValue('');
|
|
20
20
|
}, onConfirm: () => {
|
|
21
|
+
close();
|
|
22
|
+
setValue('');
|
|
21
23
|
onConfirm(value);
|
|
22
24
|
} }, type === 'textarea' ? (React.createElement(Textarea, { textareaRef: textareaRef, value: value, onChange: setValue, placeholder: placeholder, hint: hint, height: 86 })) : (React.createElement(Input, { inputRef: inputRef, value: value, onChange: setValue, placeholder: placeholder, hint: hint }))));
|
|
23
25
|
};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
|
-
var core = require('@quadrats/core');
|
|
5
4
|
var react = require('@quadrats/react');
|
|
6
|
-
var embed = require('@quadrats/common/embed');
|
|
7
5
|
var tslib = require('tslib');
|
|
8
6
|
var toolbar = require('@quadrats/react/toolbar');
|
|
9
7
|
|
|
@@ -71,24 +69,6 @@ function useEmbedTool(controller, provider) {
|
|
|
71
69
|
};
|
|
72
70
|
}
|
|
73
71
|
}, [locale, provider]);
|
|
74
|
-
React.useEffect(() => {
|
|
75
|
-
const [match] = core.Editor.nodes(editor, {
|
|
76
|
-
at: [],
|
|
77
|
-
match: (node) => {
|
|
78
|
-
const placeholderElement = node;
|
|
79
|
-
return (core.Element.isElement(placeholderElement) &&
|
|
80
|
-
placeholderElement.type === embed.EMBED_PLACEHOLDER_TYPE &&
|
|
81
|
-
placeholderElement.provider === provider);
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
if (match) {
|
|
85
|
-
setEmbedModalConfig(Object.assign({ onConfirm: (value) => {
|
|
86
|
-
controller.removeEmbedPlaceholder(editor);
|
|
87
|
-
controller.insertEmbed(editor, provider, value);
|
|
88
|
-
} }, config));
|
|
89
|
-
}
|
|
90
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
91
|
-
}, [config, controller, editor, provider]);
|
|
92
72
|
React.useEffect(() => {
|
|
93
73
|
if (isModalClosed) {
|
|
94
74
|
setTimeout(() => {
|
|
@@ -100,6 +80,10 @@ function useEmbedTool(controller, provider) {
|
|
|
100
80
|
return {
|
|
101
81
|
onClick: () => {
|
|
102
82
|
controller.insertEmbedPlaceholder(editor, provider);
|
|
83
|
+
setEmbedModalConfig(Object.assign({ onConfirm: (value) => {
|
|
84
|
+
controller.insertEmbed(editor, provider, value);
|
|
85
|
+
controller.removeEmbedPlaceholder(editor);
|
|
86
|
+
} }, config));
|
|
103
87
|
},
|
|
104
88
|
};
|
|
105
89
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { useMemo, useEffect } from 'react';
|
|
2
|
-
import { Editor, Element } from '@quadrats/core';
|
|
3
2
|
import { useLocale, useSlateStatic, useModal } from '@quadrats/react';
|
|
4
|
-
import { EMBED_PLACEHOLDER_TYPE } from '@quadrats/common/embed';
|
|
5
3
|
|
|
6
4
|
function useEmbedTool(controller, provider) {
|
|
7
5
|
const locale = useLocale();
|
|
@@ -67,24 +65,6 @@ function useEmbedTool(controller, provider) {
|
|
|
67
65
|
};
|
|
68
66
|
}
|
|
69
67
|
}, [locale, provider]);
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
const [match] = Editor.nodes(editor, {
|
|
72
|
-
at: [],
|
|
73
|
-
match: (node) => {
|
|
74
|
-
const placeholderElement = node;
|
|
75
|
-
return (Element.isElement(placeholderElement) &&
|
|
76
|
-
placeholderElement.type === EMBED_PLACEHOLDER_TYPE &&
|
|
77
|
-
placeholderElement.provider === provider);
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
if (match) {
|
|
81
|
-
setEmbedModalConfig(Object.assign({ onConfirm: (value) => {
|
|
82
|
-
controller.removeEmbedPlaceholder(editor);
|
|
83
|
-
controller.insertEmbed(editor, provider, value);
|
|
84
|
-
} }, config));
|
|
85
|
-
}
|
|
86
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
87
|
-
}, [config, controller, editor, provider]);
|
|
88
68
|
useEffect(() => {
|
|
89
69
|
if (isModalClosed) {
|
|
90
70
|
setTimeout(() => {
|
|
@@ -96,6 +76,10 @@ function useEmbedTool(controller, provider) {
|
|
|
96
76
|
return {
|
|
97
77
|
onClick: () => {
|
|
98
78
|
controller.insertEmbedPlaceholder(editor, provider);
|
|
79
|
+
setEmbedModalConfig(Object.assign({ onConfirm: (value) => {
|
|
80
|
+
controller.insertEmbed(editor, provider, value);
|
|
81
|
+
controller.removeEmbedPlaceholder(editor);
|
|
82
|
+
} }, config));
|
|
99
83
|
},
|
|
100
84
|
};
|
|
101
85
|
}
|
package/index.cjs.js
CHANGED
|
@@ -107,6 +107,8 @@ const EmbedModal = ({ isOpen, close, placeholder, confirmText, hint, type, onCon
|
|
|
107
107
|
close();
|
|
108
108
|
setValue('');
|
|
109
109
|
}, onConfirm: () => {
|
|
110
|
+
close();
|
|
111
|
+
setValue('');
|
|
110
112
|
onConfirm(value);
|
|
111
113
|
} }, type === 'textarea' ? (React.createElement(components.Textarea, { textareaRef: textareaRef, value: value, onChange: setValue, placeholder: placeholder, hint: hint, height: 86 })) : (React.createElement(components.Input, { inputRef: inputRef, value: value, onChange: setValue, placeholder: placeholder, hint: hint }))));
|
|
112
114
|
};
|
|
@@ -175,16 +177,6 @@ const FilesDropZone = ({ isDragging, setIsDragging, children, isOverMaxLength, c
|
|
|
175
177
|
};
|
|
176
178
|
|
|
177
179
|
const CarouselItem = ({ url, preview, progress, caption, index, onChange, onRemove, swap, ratio, isError, }) => {
|
|
178
|
-
const [inputValue, setInputValue] = React.useState(caption);
|
|
179
|
-
React.useEffect(() => {
|
|
180
|
-
const timeoutId = setTimeout(() => {
|
|
181
|
-
onChange(inputValue);
|
|
182
|
-
}, 500);
|
|
183
|
-
return () => {
|
|
184
|
-
clearTimeout(timeoutId);
|
|
185
|
-
};
|
|
186
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
187
|
-
}, [inputValue]);
|
|
188
180
|
const [{ isDragging }, drag, dragPreview] = reactDnd.useDrag(() => ({
|
|
189
181
|
type: 'CarouselItem',
|
|
190
182
|
collect: (monitor) => ({
|
|
@@ -220,11 +212,10 @@ const CarouselItem = ({ url, preview, progress, caption, index, onChange, onRemo
|
|
|
220
212
|
aspectRatio: ratio ? `${ratio[0]} / ${ratio[1]}` : '3 /2',
|
|
221
213
|
} }))),
|
|
222
214
|
React.createElement("div", { className: "qdr-carousel-modal__input-wrapper" },
|
|
223
|
-
React.createElement(components.Input, { value:
|
|
215
|
+
React.createElement(components.Input, { value: caption, onChange: onChange, placeholder: "\u5716\u7247\u8AAA\u660E\u6216\u66FF\u4EE3\u6587\u5B57..." }))))));
|
|
224
216
|
};
|
|
225
217
|
|
|
226
218
|
const CarouselModal = ({ isOpen, close, controller, initialValue = [], onConfirm }) => {
|
|
227
|
-
const editor = slateReact.useSlateStatic();
|
|
228
219
|
const [uploading, setUploading] = React.useState(false);
|
|
229
220
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
230
221
|
const [items, setItems] = React.useState([]);
|
|
@@ -338,7 +329,7 @@ const CarouselModal = ({ isOpen, close, controller, initialValue = [], onConfirm
|
|
|
338
329
|
},
|
|
339
330
|
].filter((h) => !!h) })),
|
|
340
331
|
React.createElement(components.Button, { className: "qdr-carousel-modal__side__upload", variant: "outlined", size: "large", disabled: isOverMaxLength, prefix: React.createElement(components.Icon, { icon: icons.Plus, width: 24, height: 24 }), onClick: () => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
341
|
-
const files = yield (controller === null || controller === void 0 ? void 0 : controller.selectFiles(
|
|
332
|
+
const files = yield (controller === null || controller === void 0 ? void 0 : controller.selectFiles());
|
|
342
333
|
if (files) {
|
|
343
334
|
const correctFiles = files.filter((f) => (controller === null || controller === void 0 ? void 0 : controller.limitSize) && f.size <= controller.limitSize * 1024 * 1024);
|
|
344
335
|
if (correctFiles.length !== files.length) {
|
|
@@ -368,7 +359,7 @@ const CarouselModal = ({ isOpen, close, controller, initialValue = [], onConfirm
|
|
|
368
359
|
} },
|
|
369
360
|
React.createElement(FilesDropZone, { isDragging: isDragging, setIsDragging: setIsDragging, isOverMaxLength: isOverMaxLength, controller: controller, uploadFiles: uploadFiles }, items.length > 0 ? (React.createElement("div", { className: clsx('qdr-carousel-modal__grid', {
|
|
370
361
|
'qdr-carousel-modal__grid--isDragging': isDragging,
|
|
371
|
-
}) }, items.map((item, index) => (React.createElement(CarouselItem, { key: `${item.url}-${item.
|
|
362
|
+
}) }, items.map((item, index) => (React.createElement(CarouselItem, { key: `${item.url}-${item.preview}-${index}`, url: item.url, preview: item.preview, progress: item.progress, caption: item.caption, index: index, ratio: controller === null || controller === void 0 ? void 0 : controller.ratio, isError: item.isError, onChange: (value) => {
|
|
372
363
|
change(index, { url: item.url, caption: value });
|
|
373
364
|
}, onRemove: () => {
|
|
374
365
|
remove(index);
|
|
@@ -396,18 +387,19 @@ const options = [
|
|
|
396
387
|
label: '純文字顯示',
|
|
397
388
|
},
|
|
398
389
|
];
|
|
390
|
+
const emptyValues = {
|
|
391
|
+
alignment: 'leftImageRightText',
|
|
392
|
+
title: '',
|
|
393
|
+
description: '',
|
|
394
|
+
remark: '',
|
|
395
|
+
linkText: '',
|
|
396
|
+
linkUrl: '',
|
|
397
|
+
};
|
|
399
398
|
// TODO: i18n
|
|
400
399
|
const CardModal = ({ isOpen, close, controller, initialValue, onConfirm: onConfirmProps }) => {
|
|
401
400
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
402
401
|
const { message } = useMessage();
|
|
403
|
-
const [values, setValues] = React.useState(
|
|
404
|
-
alignment: 'leftImageRightText',
|
|
405
|
-
title: '',
|
|
406
|
-
description: '',
|
|
407
|
-
remark: '',
|
|
408
|
-
linkText: '',
|
|
409
|
-
linkUrl: '',
|
|
410
|
-
});
|
|
402
|
+
const [values, setValues] = React.useState(emptyValues);
|
|
411
403
|
const [imageUploaderItem, setImageUploaderItem] = React.useState(null);
|
|
412
404
|
const [haveLink, setHaveLink] = React.useState(true);
|
|
413
405
|
const [errors, setErrors] = React.useState([]);
|
|
@@ -448,11 +440,18 @@ const CardModal = ({ isOpen, close, controller, initialValue, onConfirm: onConfi
|
|
|
448
440
|
setErrors(errorItems);
|
|
449
441
|
}
|
|
450
442
|
else {
|
|
443
|
+
close();
|
|
444
|
+
setValues(emptyValues);
|
|
445
|
+
setHaveLink(true);
|
|
446
|
+
setImageUploaderItem(null);
|
|
451
447
|
onConfirmProps({ values, imageItem: values.alignment === 'noImage' ? null : imageUploaderItem, haveLink });
|
|
452
448
|
}
|
|
453
|
-
}, [imageUploaderItem, onConfirmProps, haveLink, values]);
|
|
449
|
+
}, [imageUploaderItem, close, onConfirmProps, haveLink, values]);
|
|
454
450
|
return (React.createElement(components.Modal, { isOpen: isOpen, size: "medium", title: "\u5EFA\u7ACB\u5361\u7247", confirmText: "\u5EFA\u7ACB\u5361\u7247", mainAreaClassName: "qdr-card-modal__main", closable: !uploading, maskClosable: !uploading, onClose: () => {
|
|
455
451
|
close();
|
|
452
|
+
setValues(emptyValues);
|
|
453
|
+
setHaveLink(true);
|
|
454
|
+
setImageUploaderItem(null);
|
|
456
455
|
}, onConfirm: onConfirm },
|
|
457
456
|
React.createElement("div", { className: "qdr-card-modal__block" },
|
|
458
457
|
React.createElement("p", { className: "qdr-card-modal__block-title" }, "\u986F\u793A\u8A2D\u5B9A"),
|
|
@@ -491,7 +490,10 @@ const ConfirmModal = ({ isOpen, title, content, confirmText, close, onConfirm, h
|
|
|
491
490
|
React.createElement("div", { className: "qdr-confirm-modal__content" }, content))),
|
|
492
491
|
haveFooter && (React.createElement("div", { className: "qdr-confirm-modal__footer" },
|
|
493
492
|
React.createElement(components.Button, { variant: "secondary", onClick: close }, locale.editor.cancel),
|
|
494
|
-
React.createElement(components.Button, { variant: "primary", danger: true, onClick:
|
|
493
|
+
React.createElement(components.Button, { variant: "primary", danger: true, onClick: () => {
|
|
494
|
+
close();
|
|
495
|
+
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
|
|
496
|
+
} }, confirmText || locale.editor.confirm)))));
|
|
495
497
|
};
|
|
496
498
|
|
|
497
499
|
const ModalContext = React.createContext({
|
|
@@ -599,10 +601,10 @@ const MessageProvider = ({ children }) => {
|
|
|
599
601
|
function Quadrats(props) {
|
|
600
602
|
const { children, editor, locale, onChange, theme, value, needConfirmModal, setNeedConfirmModal } = props;
|
|
601
603
|
return (React.createElement(configs.ConfigsProvider, { theme: theme, locale: locale },
|
|
602
|
-
React.createElement(
|
|
603
|
-
React.createElement(
|
|
604
|
-
React.createElement(
|
|
605
|
-
React.createElement(
|
|
604
|
+
React.createElement(reactDnd.DndProvider, { backend: reactDndHtml5Backend.HTML5Backend },
|
|
605
|
+
React.createElement(MessageProvider, null,
|
|
606
|
+
React.createElement(ModalProvider, { needConfirmModal: needConfirmModal, setNeedConfirmModal: setNeedConfirmModal },
|
|
607
|
+
React.createElement(slateReact.Slate, { editor: editor, onChange: onChange, initialValue: value }, children))))));
|
|
606
608
|
}
|
|
607
609
|
|
|
608
610
|
function createEventHandler(editor, handlers) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quadrats/react",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Rytass",
|
|
6
6
|
"homepage": "https://github.com/Quadrats/quadrats#readme",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"url": "https://github.com/Quadrats/quadrats/issues"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@quadrats/common": "^1.1.
|
|
24
|
-
"@quadrats/core": "^1.1.
|
|
23
|
+
"@quadrats/common": "^1.1.5",
|
|
24
|
+
"@quadrats/core": "^1.1.5",
|
|
25
25
|
"@quadrats/icons": "^1.1.1",
|
|
26
26
|
"@quadrats/locales": "^1.0.0",
|
|
27
27
|
"@quadrats/theme": "^1.0.0",
|
|
@@ -8,7 +8,7 @@ import TableCell from './components/TableCell.js';
|
|
|
8
8
|
import TableBody from './components/TableBody.js';
|
|
9
9
|
|
|
10
10
|
const defaultRenderTableElements = {
|
|
11
|
-
table: (props) => React.createElement(Table, Object.assign({}, props)),
|
|
11
|
+
table: (props) => React.createElement(Table, Object.assign({ key: Math.random() }, props)),
|
|
12
12
|
table_title: (props) => React.createElement(TableTitle, Object.assign({}, props)),
|
|
13
13
|
table_main: (props) => React.createElement(TableMain, Object.assign({}, props)),
|
|
14
14
|
table_header: (props) => React.createElement(TableHeader, Object.assign({}, props)),
|
|
@@ -471,6 +471,20 @@ function useTableCellToolbarActions({ element, cellPosition, isHeader, transform
|
|
|
471
471
|
}, [tableSelectedOn, setTableSelectedOn, columnCount, element.treatAsTitle, tableElement, moveOrSwapColumn]);
|
|
472
472
|
// Delete actions
|
|
473
473
|
const deleteActions = useMemo(() => {
|
|
474
|
+
// 當選中 row 時,檢查是否為最後一行
|
|
475
|
+
if ((tableSelectedOn === null || tableSelectedOn === void 0 ? void 0 : tableSelectedOn.region) === 'row' && typeof tableSelectedOn.index === 'number') {
|
|
476
|
+
// 如果只剩一行,不顯示刪除按鈕
|
|
477
|
+
if (isReachMinimumBodyRows && !isHeader) {
|
|
478
|
+
return [];
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
// 當選中 column 時,檢查是否為最後一列
|
|
482
|
+
if ((tableSelectedOn === null || tableSelectedOn === void 0 ? void 0 : tableSelectedOn.region) === 'column' && typeof tableSelectedOn.index === 'number') {
|
|
483
|
+
// 如果只剩一列(考慮 title columns),不顯示刪除按鈕
|
|
484
|
+
if (columnCount <= 1) {
|
|
485
|
+
return [];
|
|
486
|
+
}
|
|
487
|
+
}
|
|
474
488
|
return [
|
|
475
489
|
{
|
|
476
490
|
icon: Trash,
|
|
@@ -487,7 +501,7 @@ function useTableCellToolbarActions({ element, cellPosition, isHeader, transform
|
|
|
487
501
|
},
|
|
488
502
|
},
|
|
489
503
|
];
|
|
490
|
-
}, [tableSelectedOn, deleteRow, deleteColumn, setTableSelectedOn]);
|
|
504
|
+
}, [tableSelectedOn, deleteRow, deleteColumn, setTableSelectedOn, isReachMinimumBodyRows, isHeader, columnCount]);
|
|
491
505
|
// Inline toolbar icon groups - 當選中行/列時顯示的完整工具列
|
|
492
506
|
const inlineToolbarIconGroups = useMemo(() => {
|
|
493
507
|
return [
|
package/table/index.cjs.js
CHANGED
|
@@ -1457,6 +1457,20 @@ function useTableCellToolbarActions({ element, cellPosition, isHeader, transform
|
|
|
1457
1457
|
}, [tableSelectedOn, setTableSelectedOn, columnCount, element.treatAsTitle, tableElement, moveOrSwapColumn]);
|
|
1458
1458
|
// Delete actions
|
|
1459
1459
|
const deleteActions = React.useMemo(() => {
|
|
1460
|
+
// 當選中 row 時,檢查是否為最後一行
|
|
1461
|
+
if ((tableSelectedOn === null || tableSelectedOn === void 0 ? void 0 : tableSelectedOn.region) === 'row' && typeof tableSelectedOn.index === 'number') {
|
|
1462
|
+
// 如果只剩一行,不顯示刪除按鈕
|
|
1463
|
+
if (isReachMinimumBodyRows && !isHeader) {
|
|
1464
|
+
return [];
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
// 當選中 column 時,檢查是否為最後一列
|
|
1468
|
+
if ((tableSelectedOn === null || tableSelectedOn === void 0 ? void 0 : tableSelectedOn.region) === 'column' && typeof tableSelectedOn.index === 'number') {
|
|
1469
|
+
// 如果只剩一列(考慮 title columns),不顯示刪除按鈕
|
|
1470
|
+
if (columnCount <= 1) {
|
|
1471
|
+
return [];
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1460
1474
|
return [
|
|
1461
1475
|
{
|
|
1462
1476
|
icon: icons.Trash,
|
|
@@ -1473,7 +1487,7 @@ function useTableCellToolbarActions({ element, cellPosition, isHeader, transform
|
|
|
1473
1487
|
},
|
|
1474
1488
|
},
|
|
1475
1489
|
];
|
|
1476
|
-
}, [tableSelectedOn, deleteRow, deleteColumn, setTableSelectedOn]);
|
|
1490
|
+
}, [tableSelectedOn, deleteRow, deleteColumn, setTableSelectedOn, isReachMinimumBodyRows, isHeader, columnCount]);
|
|
1477
1491
|
// Inline toolbar icon groups - 當選中行/列時顯示的完整工具列
|
|
1478
1492
|
const inlineToolbarIconGroups = React.useMemo(() => {
|
|
1479
1493
|
return [
|
|
@@ -3691,7 +3705,7 @@ function TableBody(props) {
|
|
|
3691
3705
|
}
|
|
3692
3706
|
|
|
3693
3707
|
const defaultRenderTableElements = {
|
|
3694
|
-
table: (props) => React.createElement(Table, Object.assign({}, props)),
|
|
3708
|
+
table: (props) => React.createElement(Table, Object.assign({ key: Math.random() }, props)),
|
|
3695
3709
|
table_title: (props) => React.createElement(TableTitle, Object.assign({}, props)),
|
|
3696
3710
|
table_main: (props) => React.createElement(TableMain, Object.assign({}, props)),
|
|
3697
3711
|
table_header: (props) => React.createElement(TableHeader, Object.assign({}, props)),
|
|
@@ -8,7 +8,7 @@ import { TableRowJsxSerializeElement } from './components/TableRow.js';
|
|
|
8
8
|
import { TableCellJsxSerializeElement } from './components/TableCell.js';
|
|
9
9
|
|
|
10
10
|
const defaultRenderTableElements = {
|
|
11
|
-
table: (props) => React.createElement(TableJsxSerializeElement, Object.assign({}, props)),
|
|
11
|
+
table: (props) => React.createElement(TableJsxSerializeElement, Object.assign({ key: Math.random() }, props)),
|
|
12
12
|
table_title: (props) => React.createElement(TableTitleJsxSerializeElement, Object.assign({}, props)),
|
|
13
13
|
table_main: (props) => React.createElement(TableMainJsxSerializeElement, Object.assign({}, props)),
|
|
14
14
|
table_header: (props) => React.createElement(TableHeaderJsxSerializeElement, Object.assign({}, props)),
|
|
@@ -76,7 +76,7 @@ const TableCellJsxSerializeElement = ({ children, element, isColumnPinned, }) =>
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
const defaultRenderTableElements = {
|
|
79
|
-
table: (props) => React.createElement(TableJsxSerializeElement, Object.assign({}, props)),
|
|
79
|
+
table: (props) => React.createElement(TableJsxSerializeElement, Object.assign({ key: Math.random() }, props)),
|
|
80
80
|
table_title: (props) => React.createElement(TableTitleJsxSerializeElement, Object.assign({}, props)),
|
|
81
81
|
table_main: (props) => React.createElement(TableMainJsxSerializeElement, Object.assign({}, props)),
|
|
82
82
|
table_header: (props) => React.createElement(TableHeaderJsxSerializeElement, Object.assign({}, props)),
|