@team-monolith/cds 1.114.1 → 1.114.2
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/dist/patterns/LexicalEditor/components/InsertImageDialog/InsertImageDialog.js +15 -9
- package/dist/patterns/LexicalEditor/components/InsertVideoDialog/InsertVideoDialog.js +1 -6
- package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js +1 -1
- package/package.json +1 -1
|
@@ -7,19 +7,19 @@ import { useForm } from "react-hook-form";
|
|
|
7
7
|
import { FileSelectInput } from "../FileSelectInput";
|
|
8
8
|
import { Button } from "../../../..";
|
|
9
9
|
import { FormInput } from "../../nodes/Form";
|
|
10
|
-
import { useState } from "react";
|
|
10
|
+
import { useEffect, useMemo, useState } from "react";
|
|
11
11
|
import { ImagePreview } from "./ImagePreview";
|
|
12
12
|
import { ImageNotAvailable } from "../../nodes/ImageNode/ImageNotAvailable";
|
|
13
13
|
import styled from "@emotion/styled";
|
|
14
|
+
import { debounce } from "lodash";
|
|
14
15
|
export function InsertImageDialog(props) {
|
|
15
16
|
const { title, open, onClose, imageProps, onChange, onDelete, shouldReset } = props;
|
|
16
17
|
const theme = useTheme();
|
|
17
|
-
const { control, setValue, watch, reset, handleSubmit } = useForm({
|
|
18
|
+
const { control, setValue, watch, reset, handleSubmit, subscribe } = useForm({
|
|
18
19
|
defaultValues: imageProps !== null && imageProps !== void 0 ? imageProps : { src: "", altText: "" },
|
|
19
20
|
});
|
|
20
21
|
const handleOnClose = () => {
|
|
21
22
|
if (shouldReset) {
|
|
22
|
-
setPreviewSrc("");
|
|
23
23
|
reset();
|
|
24
24
|
}
|
|
25
25
|
onClose();
|
|
@@ -32,18 +32,24 @@ export function InsertImageDialog(props) {
|
|
|
32
32
|
// 두 값은 시멘틱이 다르므로 독립적인 state로 관리합니다.
|
|
33
33
|
const [previewSrc, setPreviewSrc] = useState(watch("src"));
|
|
34
34
|
const isDisabled = watch("src") === "";
|
|
35
|
+
const debouncedSetPreviewSrc = useMemo(() => debounce((value) => setPreviewSrc(value), 500), []);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const unsubscribe = subscribe({
|
|
38
|
+
name: "src",
|
|
39
|
+
formState: { values: true },
|
|
40
|
+
callback: ({ values }) => {
|
|
41
|
+
debouncedSetPreviewSrc(values.src);
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
return () => unsubscribe();
|
|
45
|
+
}, [debouncedSetPreviewSrc, subscribe]);
|
|
35
46
|
return (_jsxs(StyledAlertDialog, { component: "form", icon: _jsx(ImageFillIcon, { color: theme.color.background.primary }), open: open, onClose: handleOnClose, onSubmit: (e) => {
|
|
36
47
|
// nested form 구조라서 submit이벤트 전파를 막습니다.
|
|
37
48
|
e.stopPropagation();
|
|
38
49
|
handleSubmit(onSubmit)();
|
|
39
50
|
}, disableIconPadding: true, children: [_jsx(StyledAlertDialogTitle, { onClose: handleOnClose, children: title }), _jsx(AlertDialogContent, { children: _jsxs(Inputs, { children: [_jsx(FileSelectInput, { onChange: (value) => {
|
|
40
51
|
setValue("src", value);
|
|
41
|
-
|
|
42
|
-
}, fileType: "image" }), _jsx(FormInput, { name: "src", control: control, placeholder: "https://www.pexels.com/photo/n-2848492", size: "medium", label: "URL", fullWidth: true, startIcon: _jsx(LinkIcon, {}), inputProps: {
|
|
43
|
-
onBlur: () => {
|
|
44
|
-
setPreviewSrc(watch("src"));
|
|
45
|
-
},
|
|
46
|
-
} }), previewSrc && (_jsx(ImagePreview, { src: previewSrc, alt: watch("altText"), fallback: _jsx(ImageNotAvailable, {}) })), _jsx(FormInput, { name: "altText", control: control, placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", size: "medium", label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", fullWidth: true })] }) }), _jsxs(AlertDialogActions, { children: [_jsx(Button, { type: "submit", fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled }), onDelete && (_jsx(Button, { color: "danger", size: "medium", fullWidth: true, label: "\uC0AD\uC81C\uD558\uAE30", onClick: onDelete }))] })] }));
|
|
52
|
+
}, fileType: "image" }), _jsx(FormInput, { name: "src", control: control, placeholder: "https://www.pexels.com/photo/n-2848492", size: "medium", label: "URL", fullWidth: true, startIcon: _jsx(LinkIcon, {}) }), previewSrc && (_jsx(ImagePreview, { src: previewSrc, alt: watch("altText"), fallback: _jsx(ImageNotAvailable, {}) })), _jsx(FormInput, { name: "altText", control: control, placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", size: "medium", label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", fullWidth: true })] }) }), _jsxs(AlertDialogActions, { children: [_jsx(Button, { type: "submit", fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled }), onDelete && (_jsx(Button, { color: "danger", size: "medium", fullWidth: true, label: "\uC0AD\uC81C\uD558\uAE30", onClick: onDelete }))] })] }));
|
|
47
53
|
}
|
|
48
54
|
const StyledAlertDialog = styled(AlertDialog) `
|
|
49
55
|
gap: 16px;
|
|
@@ -19,7 +19,6 @@ export function InsertVideoDialog(props) {
|
|
|
19
19
|
});
|
|
20
20
|
const handleOnClose = () => {
|
|
21
21
|
if (shouldReset) {
|
|
22
|
-
setPreviewSrc("");
|
|
23
22
|
reset();
|
|
24
23
|
}
|
|
25
24
|
onClose();
|
|
@@ -49,11 +48,7 @@ export function InsertVideoDialog(props) {
|
|
|
49
48
|
handleSubmit(onSubmit)();
|
|
50
49
|
}, disableIconPadding: true, children: [_jsx(StyledAlertDialogTitle, { onClose: handleOnClose, children: title }), _jsx(AlertDialogContent, { children: _jsxs(Inputs, { children: [_jsx(FormInput, { name: "src", control: control, rules: {
|
|
51
50
|
validate: (value) => ReactPlayer.canPlay(value) || "올바른 동영상 URL을 입력하세요.",
|
|
52
|
-
}, placeholder: "https://example.com/video.mp4", size: "medium", label: "URL", fullWidth: true, startIcon: _jsx(LinkIcon, {}),
|
|
53
|
-
onBlur: () => {
|
|
54
|
-
setPreviewSrc(watch("src"));
|
|
55
|
-
},
|
|
56
|
-
} }), videoCanPlay && (_jsx(ReactPlayer, { css: css `
|
|
51
|
+
}, placeholder: "https://example.com/video.mp4", size: "medium", label: "URL", fullWidth: true, startIcon: _jsx(LinkIcon, {}) }), videoCanPlay && (_jsx(ReactPlayer, { css: css `
|
|
57
52
|
background: black;
|
|
58
53
|
`, width: "100%", url: previewSrc, controls: true, config: {
|
|
59
54
|
file: {
|
package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js
CHANGED
|
@@ -336,7 +336,7 @@ export function ComponentPickerMenuPlugin(props) {
|
|
|
336
336
|
option.keywords.some((keyword) => regex.test(keyword)))),
|
|
337
337
|
];
|
|
338
338
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
339
|
-
}, [editor, queryString
|
|
339
|
+
}, [editor, queryString]);
|
|
340
340
|
const onSelectOption = useCallback((selectedOption, nodeToRemove, closeMenu, matchingString) => {
|
|
341
341
|
if (selectedOption instanceof ComponentDrawerOption) {
|
|
342
342
|
return;
|