@team-monolith/cds 1.10.0 → 1.10.1
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/LexicalCustomConfigContext.d.ts +6 -0
- package/dist/patterns/LexicalEditor/LexicalCustomConfigContext.js +5 -0
- package/dist/patterns/LexicalEditor/LexicalEditor.d.ts +4 -0
- package/dist/patterns/LexicalEditor/LexicalEditor.js +5 -2
- package/dist/patterns/LexicalEditor/Plugins.d.ts +1 -0
- package/dist/patterns/LexicalEditor/Plugins.js +4 -3
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/InputComponent.js +16 -9
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/ProblemSelectNode.d.ts +45 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/ProblemSelectNode.js +74 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox.d.ts +11 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectBox.js +73 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.d.ts +9 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.js +85 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.d.ts +14 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/FormSelection.js +91 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageDialog.d.ts +10 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageDialog.js +109 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageUploadedDialogBody.d.ts +9 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageUploadedDialogBody.js +50 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageUriDialogBody.d.ts +8 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageUriDialogBody.js +17 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.d.ts +8 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.js +146 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/index.d.ts +1 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/index.js +1 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/index.d.ts +2 -0
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/index.js +2 -0
- package/dist/patterns/LexicalEditor/plugins/ActionsPlugin/index.d.ts +9 -0
- package/dist/patterns/LexicalEditor/plugins/ActionsPlugin/index.js +24 -0
- package/dist/patterns/LexicalEditor/plugins/ComponentAdderPlugin/useContextMenuOptions.js +15 -0
- package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js +13 -1
- package/dist/patterns/LexicalEditor/plugins/ImagesPlugin/InsertImageDialog.js +7 -6
- package/dist/patterns/LexicalEditor/plugins/ImagesPlugin/InsertImageUploadedDialogBody.d.ts +13 -4
- package/dist/patterns/LexicalEditor/plugins/ImagesPlugin/InsertImageUploadedDialogBody.js +5 -6
- package/dist/patterns/LexicalEditor/plugins/ImagesPlugin/InsertImageUriDialogBody.d.ts +9 -4
- package/dist/patterns/LexicalEditor/plugins/ImagesPlugin/InsertImageUriDialogBody.js +4 -7
- package/dist/patterns/LexicalEditor/plugins/ProblemSelectPlugin/index.d.ts +5 -0
- package/dist/patterns/LexicalEditor/plugins/ProblemSelectPlugin/index.js +20 -0
- package/dist/patterns/LexicalEditor/theme.d.ts +1 -0
- package/dist/patterns/LexicalEditor/theme.js +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
|
|
11
|
+
/** @jsxImportSource @emotion/react */
|
|
12
|
+
import { useContext, useRef, useState } from "react";
|
|
13
|
+
import styled from "@emotion/styled";
|
|
14
|
+
import { css, useTheme } from "@emotion/react";
|
|
15
|
+
import { ImageFillIcon, LinkIcon, UploadLineIcon } from "../../../../../icons";
|
|
16
|
+
import { AlertDialog, AlertDialogContent, AlertDialogTitle, } from "../../../../../components/AlertDialog";
|
|
17
|
+
import Button from "../../../../../components/Button";
|
|
18
|
+
import { CodleDesignSystemContext } from "../../../../../CodleDesignSystemProvider";
|
|
19
|
+
import { InsertImageUriDialogBody } from "./InsertImageUriDialogBody";
|
|
20
|
+
import { InsertImageUploadedDialogBody } from "./InsertImageUploadedDialogBody";
|
|
21
|
+
import { useForm } from "react-hook-form";
|
|
22
|
+
export function InsertImageDialog(props) {
|
|
23
|
+
const { title, open, onClose, updateImg, deleteButton } = props;
|
|
24
|
+
const theme = useTheme();
|
|
25
|
+
const [mode, setMode] = useState(null);
|
|
26
|
+
const inputRef = useRef(null);
|
|
27
|
+
const cdsContext = useContext(CodleDesignSystemContext);
|
|
28
|
+
const { control, setValue, watch, reset } = useForm({
|
|
29
|
+
defaultValues: { src: "", altText: "" },
|
|
30
|
+
});
|
|
31
|
+
const onClick = (props) => {
|
|
32
|
+
updateImg(props);
|
|
33
|
+
handleOnClose();
|
|
34
|
+
};
|
|
35
|
+
const handleOnClose = () => {
|
|
36
|
+
setMode(null);
|
|
37
|
+
reset();
|
|
38
|
+
onClose();
|
|
39
|
+
};
|
|
40
|
+
return (_jsxs(StyledAlertDialog, Object.assign({ icon: _jsx(ImageFillIcon, { color: theme.color.background.primary }), open: open, onClose: handleOnClose, disableIconPadding: true }, { children: [_jsx(StyledAlertDialogTitle, Object.assign({ onClose: handleOnClose }, { children: title })), !mode && (_jsx(AlertDialogContent, { children: _jsxs("div", Object.assign({ css: css `
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
gap: 16px;
|
|
44
|
+
// Actions가 없는 경우 하단이 디자인과 맞지 않는다
|
|
45
|
+
margin-bottom: -16px;
|
|
46
|
+
` }, { children: [_jsxs(Buttons, { children: [_jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uC774\uBBF8\uC9C0 URL\uC744 \uC54C\uACE0 \uC788\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "URL\uB85C \uC0BD\uC785\uD558\uAE30", startIcon: _jsx(LinkIcon, {}), onClick: () => setMode("url") })] }), _jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uAC16\uACE0 \uC788\uB294 \uC774\uBBF8\uC9C0\uB97C \uC0BD\uC785\uD558\uACE0 \uC2F6\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "\uD30C\uC77C \uC120\uD0DD\uD558\uAE30", startIcon: _jsx(UploadLineIcon, {}), onClick: () => {
|
|
47
|
+
var _a;
|
|
48
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
49
|
+
} }), _jsx(HiddenInput, { ref: inputRef, type: "file", accept: "image/*", onChange: (event) => __awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
var _a, _b;
|
|
51
|
+
const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
52
|
+
if (!file)
|
|
53
|
+
return;
|
|
54
|
+
const uploadByFile = (_b = cdsContext.lexical) === null || _b === void 0 ? void 0 : _b.uploadByFile;
|
|
55
|
+
if (uploadByFile) {
|
|
56
|
+
setValue("src", yield uploadByFile(file));
|
|
57
|
+
setMode("file");
|
|
58
|
+
}
|
|
59
|
+
}) })] })] }), deleteButton && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(Button, { color: "textDanger", size: "medium", fullWidth: true, label: "\uC774\uBBF8\uC9C0 \uC0AD\uC81C\uD558\uAE30", onClick: () => {
|
|
60
|
+
onClick(null);
|
|
61
|
+
} })] }))] })) })), mode === "url" && (_jsx(InsertImageUriDialogBody, { control: control, watch: watch, onClick: onClick })), mode === "file" && (_jsx(InsertImageUploadedDialogBody, { control: control, watch: watch, setValue: setValue, onClick: onClick }))] })));
|
|
62
|
+
}
|
|
63
|
+
const StyledAlertDialog = styled(AlertDialog) `
|
|
64
|
+
gap: 16px;
|
|
65
|
+
`;
|
|
66
|
+
const StyledAlertDialogTitle = styled(AlertDialogTitle) `
|
|
67
|
+
color: ${({ theme }) => theme.color.foreground.neutralBase};
|
|
68
|
+
text-align: center;
|
|
69
|
+
|
|
70
|
+
/* Default/Heading/20px-Bd */
|
|
71
|
+
font-family: ${({ theme }) => theme.fontFamily.ui};
|
|
72
|
+
font-size: 20px;
|
|
73
|
+
font-style: normal;
|
|
74
|
+
font-weight: 700;
|
|
75
|
+
line-height: 28px; /* 140% */
|
|
76
|
+
letter-spacing: 0.25px;
|
|
77
|
+
`;
|
|
78
|
+
const Buttons = styled.div `
|
|
79
|
+
display: flex;
|
|
80
|
+
flex: 1;
|
|
81
|
+
align-items: flex-start;
|
|
82
|
+
gap: 8px;
|
|
83
|
+
`;
|
|
84
|
+
const Divider = styled.div(({ theme }) => css `
|
|
85
|
+
width: 100%;
|
|
86
|
+
height: 1px;
|
|
87
|
+
background: ${theme.color.background.neutralAltActive};
|
|
88
|
+
`);
|
|
89
|
+
const ButtonAndDescription = styled.div `
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
align-items: center;
|
|
93
|
+
gap: 8px;
|
|
94
|
+
flex: 1 0 0;
|
|
95
|
+
`;
|
|
96
|
+
const Description = styled.div `
|
|
97
|
+
color: ${({ theme }) => theme.color.foreground.neutralBaseDisabled};
|
|
98
|
+
text-align: center;
|
|
99
|
+
|
|
100
|
+
/* Default/Label/12px-Md */
|
|
101
|
+
font-family: ${({ theme }) => theme.fontFamily.ui};
|
|
102
|
+
font-size: 12px;
|
|
103
|
+
font-style: normal;
|
|
104
|
+
font-weight: 500;
|
|
105
|
+
line-height: 16px; /* 133.333% */
|
|
106
|
+
`;
|
|
107
|
+
const HiddenInput = styled.input `
|
|
108
|
+
display: none;
|
|
109
|
+
`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ImageProps } from "../ProblemSelectNode";
|
|
2
|
+
import { Control, UseFormSetValue, UseFormWatch } from "react-hook-form";
|
|
3
|
+
export interface InsertImageUploadedDialogBodyProps {
|
|
4
|
+
control: Control<ImageProps, any>;
|
|
5
|
+
watch: UseFormWatch<ImageProps>;
|
|
6
|
+
setValue: UseFormSetValue<ImageProps>;
|
|
7
|
+
onClick: (props: ImageProps) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function InsertImageUploadedDialogBody(props: InsertImageUploadedDialogBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
|
+
import { useContext, useRef } from "react";
|
|
12
|
+
import styled from "@emotion/styled";
|
|
13
|
+
import { CodleDesignSystemContext } from "../../../../../CodleDesignSystemProvider";
|
|
14
|
+
import { AlertDialogActions, AlertDialogContent, } from "../../../../../components/AlertDialog";
|
|
15
|
+
import Button from "../../../../../components/Button";
|
|
16
|
+
import { RefreshLineIcon } from "../../../../../icons";
|
|
17
|
+
import Input from "../../../../../components/Input";
|
|
18
|
+
import { Controller, } from "react-hook-form";
|
|
19
|
+
export function InsertImageUploadedDialogBody(props) {
|
|
20
|
+
const { control, watch, setValue, onClick } = props;
|
|
21
|
+
const inputRef = useRef(null);
|
|
22
|
+
const cdsContext = useContext(CodleDesignSystemContext);
|
|
23
|
+
const isDisabled = watch("src") === "";
|
|
24
|
+
return (_jsxs(_Fragment, { children: [_jsx(AlertDialogContent, { children: _jsxs(Inputs, { children: [_jsx(Button, { fullWidth: true, color: "grey", size: "medium", label: "\uD30C\uC77C \uBC14\uAFB8\uAE30", onClick: () => {
|
|
25
|
+
var _a;
|
|
26
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
27
|
+
}, startIcon: _jsx(RefreshLineIcon, {}) }), _jsx(HiddenInput, { ref: inputRef, type: "file", accept: "image/*", onChange: (event) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
30
|
+
if (!file)
|
|
31
|
+
return;
|
|
32
|
+
const uploadByFile = (_b = cdsContext.lexical) === null || _b === void 0 ? void 0 : _b.uploadByFile;
|
|
33
|
+
if (uploadByFile) {
|
|
34
|
+
setValue("src", yield uploadByFile(file));
|
|
35
|
+
}
|
|
36
|
+
}) }), _jsxs(ImagePreview, { children: ["\uC774\uBBF8\uC9C0 \uBBF8\uB9AC\uBCF4\uAE30", _jsx("img", { src: watch("src"), alt: watch("altText") })] }), _jsx(Controller, { name: "altText", control: control, render: ({ field: { value, onChange } }) => (_jsx(Input, { fullWidth: true, label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", color: "default", size: "medium", onChange: onChange, value: value })) })] }) }), _jsx(AlertDialogActions, { children: _jsx(Button, { fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled, onClick: () => onClick({ altText: watch("altText"), src: watch("src") }) }) })] }));
|
|
37
|
+
}
|
|
38
|
+
const Inputs = styled.div `
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
gap: 16px;
|
|
42
|
+
`;
|
|
43
|
+
const HiddenInput = styled.input `
|
|
44
|
+
display: none;
|
|
45
|
+
`;
|
|
46
|
+
const ImagePreview = styled.div `
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
gap: 8px;
|
|
50
|
+
`;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ImageProps } from "../ProblemSelectNode";
|
|
2
|
+
import { Control, UseFormWatch } from "react-hook-form";
|
|
3
|
+
export interface InsertImageUriDialogBodyProps {
|
|
4
|
+
control: Control<ImageProps, any>;
|
|
5
|
+
watch: UseFormWatch<ImageProps>;
|
|
6
|
+
onClick: (props: ImageProps) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function InsertImageUriDialogBody(props: InsertImageUriDialogBodyProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/InsertImageUriDialogBody.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import styled from "@emotion/styled";
|
|
3
|
+
import { AlertDialogActions, AlertDialogContent, } from "../../../../../components/AlertDialog";
|
|
4
|
+
import Input from "../../../../../components/Input";
|
|
5
|
+
import { LinkIcon } from "../../../../../icons";
|
|
6
|
+
import Button from "../../../../../components/Button";
|
|
7
|
+
import { Controller } from "react-hook-form";
|
|
8
|
+
export function InsertImageUriDialogBody(props) {
|
|
9
|
+
const { control, watch, onClick } = props;
|
|
10
|
+
const isDisabled = watch("src") === "";
|
|
11
|
+
return (_jsxs(_Fragment, { children: [" ", _jsx(AlertDialogContent, { children: _jsxs(Inputs, { children: [_jsx(Controller, { name: "src", control: control, render: ({ field: { value, onChange } }) => (_jsx(Input, { fullWidth: true, label: "URL", placeholder: "https://www.pexels.com/photo/n-2848492/", color: "default", size: "medium", onChange: onChange, value: value, startIcon: _jsx(LinkIcon, {}) })) }), _jsx(Controller, { name: "altText", control: control, render: ({ field: { value, onChange } }) => (_jsx(Input, { fullWidth: true, label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", color: "default", size: "medium", onChange: onChange, value: value })) })] }) }), _jsx(AlertDialogActions, { children: _jsx(Button, { fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled, onClick: () => onClick({ altText: watch("altText"), src: watch("src") }) }) })] }));
|
|
12
|
+
}
|
|
13
|
+
const Inputs = styled.div `
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: 16px;
|
|
17
|
+
`;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Selection } from "../ProblemSelectNode";
|
|
2
|
+
import { NodeKey } from "lexical";
|
|
3
|
+
export interface SettingFormProps {
|
|
4
|
+
selections: Selection[];
|
|
5
|
+
nodeKey: NodeKey;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
}
|
|
8
|
+
export default function SettingForm(props: SettingFormProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
/** @jsxImportSource @emotion/react */
|
|
3
|
+
import { useFieldArray, useForm, } from "react-hook-form";
|
|
4
|
+
import { $isProblemSelectNode } from "../ProblemSelectNode";
|
|
5
|
+
import { $getNodeByKey } from "lexical";
|
|
6
|
+
import { css } from "@emotion/react";
|
|
7
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
8
|
+
import styled from "@emotion/styled";
|
|
9
|
+
import shadows from "../../../../../foundation/shadows";
|
|
10
|
+
import { AddFillIcon, AlarmWarningFillIcon, ListRadioIcon, } from "../../../../../icons";
|
|
11
|
+
import Button from "../../../../../components/Button";
|
|
12
|
+
import { FormSelection } from "./FormSelection";
|
|
13
|
+
import Tooltip from "../../../../../components/Tooltip";
|
|
14
|
+
import { useState } from "react";
|
|
15
|
+
export default function SettingForm(props) {
|
|
16
|
+
const { selections, nodeKey, onClose } = props;
|
|
17
|
+
const [editor] = useLexicalComposerContext();
|
|
18
|
+
const [tooltipOpen, setTooltipOpen] = useState(false);
|
|
19
|
+
const { control, handleSubmit, watch } = useForm({
|
|
20
|
+
mode: "all",
|
|
21
|
+
defaultValues: {
|
|
22
|
+
selections: selections.map((selection) => {
|
|
23
|
+
var _a;
|
|
24
|
+
return ({
|
|
25
|
+
isAnswer: selection.isAnswer,
|
|
26
|
+
show: {
|
|
27
|
+
image: (_a = selection.show.image) !== null && _a !== void 0 ? _a : null,
|
|
28
|
+
text: selection.show.text,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}),
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
const { fields, append, remove } = useFieldArray({
|
|
35
|
+
control,
|
|
36
|
+
name: "selections",
|
|
37
|
+
keyName: "uid",
|
|
38
|
+
});
|
|
39
|
+
const onSettingSubmit = (data) => {
|
|
40
|
+
editor.update(() => {
|
|
41
|
+
const node = $getNodeByKey(nodeKey);
|
|
42
|
+
if (!$isProblemSelectNode(node)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
node.setSelections(data.selections);
|
|
46
|
+
});
|
|
47
|
+
onClose();
|
|
48
|
+
};
|
|
49
|
+
function validateDuplicatedSelection(fields, index) {
|
|
50
|
+
if (index === 0)
|
|
51
|
+
return true;
|
|
52
|
+
const duplicatedIndex = fields
|
|
53
|
+
.slice(0, index)
|
|
54
|
+
.findIndex((prevField) => prevField.show.text === fields[index].show.text);
|
|
55
|
+
if (duplicatedIndex < 0)
|
|
56
|
+
return true;
|
|
57
|
+
return `${duplicatedIndex + 1}번 선택지와 같은 내용입니다.`;
|
|
58
|
+
}
|
|
59
|
+
const answersCount = watch("selections").filter((selection) => selection.isAnswer).length;
|
|
60
|
+
const hasMultipleAnswers = answersCount > 1;
|
|
61
|
+
const hasAnswer = answersCount > 0;
|
|
62
|
+
return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(ListRadioIcon, { css: css `
|
|
63
|
+
width: 12px;
|
|
64
|
+
height: 12px;
|
|
65
|
+
` }), "\uAC1D\uAD00\uC2DD \uC785\uB825 \uCE78"] }), _jsxs(Content, { children: [_jsxs(FormArea, { children: [_jsx(Label, { children: "\uB2F5\uC548" }), fields.map((field, index) => (_jsx(FormSelection, { index: index, control: control, watch: watch, rules: {
|
|
66
|
+
required: "필수 입력 항목입니다.",
|
|
67
|
+
validate: () => validateDuplicatedSelection(fields, index),
|
|
68
|
+
}, onDelete: index !== 0
|
|
69
|
+
? () => {
|
|
70
|
+
remove(index);
|
|
71
|
+
}
|
|
72
|
+
: undefined }, field.uid)))] }), _jsx(Button, { color: "grey", size: "small", startIcon: _jsx(AddFillIcon, {}), label: "\uC120\uD0DD\uC9C0 \uCD94\uAC00", onClick: () => {
|
|
73
|
+
append({
|
|
74
|
+
isAnswer: false,
|
|
75
|
+
show: {
|
|
76
|
+
text: "",
|
|
77
|
+
},
|
|
78
|
+
value: (fields.length + 1).toString(),
|
|
79
|
+
});
|
|
80
|
+
} }), hasMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
|
|
81
|
+
width: 14px;
|
|
82
|
+
height: 14px;
|
|
83
|
+
` }), "\uC815\uB2F5\uC774 \uC5EC\uB7EC \uAC1C\uC778 \uBB38\uC81C\uC5D0\uB294 \uC815\uB2F5\uC744 \uBAA8\uB450 \uC120\uD0DD\uD574\uC57C \uD55C\uB2E4\uB294 \uC548\uB0B4\uAC00 \uC81C\uACF5\uB429\uB2C8\uB2E4."] }))] }), _jsxs(Buttons, { children: [_jsx(Button, { color: "grey", size: "xsmall", label: "\uB2EB\uAE30", onClick: onClose }), _jsx(Tooltip, Object.assign({ open: !hasAnswer && tooltipOpen, text: "\uC120\uD0DD\uC9C0 \uC911 \uC815\uB2F5\uC744 \uD45C\uC2DC\uD574\uC8FC\uC138\uC694.", onOpen: () => setTooltipOpen(true), onClose: () => setTooltipOpen(false), placement: "top-end" }, { children: _jsx("span", { children: _jsx(Button, { color: "primary", size: "xsmall", label: "\uC774\uB300\uB85C \uB123\uAE30", type: "submit", disabled: !hasAnswer }) }) }))] })] })));
|
|
84
|
+
}
|
|
85
|
+
const Form = styled.form(({ theme }) => css `
|
|
86
|
+
display: flex;
|
|
87
|
+
width: 620px;
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
border-radius: 6px;
|
|
90
|
+
border: 1px solid ${theme.color.background.neutralAltActive};
|
|
91
|
+
background: ${theme.color.background.neutralBase};
|
|
92
|
+
box-shadow: ${shadows.shadow08};
|
|
93
|
+
`);
|
|
94
|
+
const Title = styled.div(({ theme }) => css `
|
|
95
|
+
display: flex;
|
|
96
|
+
padding: 8px 12px;
|
|
97
|
+
gap: 4px;
|
|
98
|
+
align-items: center;
|
|
99
|
+
color: ${theme.color.foreground.neutralBase};
|
|
100
|
+
/* Default/Label/12px-Md */
|
|
101
|
+
font-family: ${theme.fontFamily.ui};
|
|
102
|
+
font-size: 12px;
|
|
103
|
+
font-style: normal;
|
|
104
|
+
font-weight: 500;
|
|
105
|
+
line-height: 16px; /* 133.333% */
|
|
106
|
+
`);
|
|
107
|
+
const Content = styled.div(({ theme }) => css `
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
gap: 12px;
|
|
111
|
+
padding: 12px;
|
|
112
|
+
border-top: 1px solid ${theme.color.background.neutralAltActive};
|
|
113
|
+
border-bottom: 1px solid ${theme.color.background.neutralAltActive};
|
|
114
|
+
`);
|
|
115
|
+
const FormArea = styled.div `
|
|
116
|
+
display: flex;
|
|
117
|
+
flex-direction: column;
|
|
118
|
+
gap: 8px;
|
|
119
|
+
`;
|
|
120
|
+
const Label = styled.div(({ theme }) => css `
|
|
121
|
+
color: ${theme.color.foreground.neutralBaseDisabled};
|
|
122
|
+
/* Default/Label/12px-Md */
|
|
123
|
+
font-family: ${theme.fontFamily.ui};
|
|
124
|
+
font-size: 12px;
|
|
125
|
+
font-style: normal;
|
|
126
|
+
font-weight: 500;
|
|
127
|
+
line-height: 16px; /* 133.333% */
|
|
128
|
+
`);
|
|
129
|
+
const Buttons = styled.div `
|
|
130
|
+
display: flex;
|
|
131
|
+
padding: 12px;
|
|
132
|
+
justify-content: flex-end;
|
|
133
|
+
align-items: center;
|
|
134
|
+
gap: 8px;
|
|
135
|
+
`;
|
|
136
|
+
const Alert = styled.div(({ theme }) => css `
|
|
137
|
+
display: flex;
|
|
138
|
+
gap: 4px;
|
|
139
|
+
color: ${theme.color.foreground.neutralBaseDisabled};
|
|
140
|
+
/* Default/Label/12px-Md */
|
|
141
|
+
font-family: ${theme.fontFamily.ui};
|
|
142
|
+
font-size: 12px;
|
|
143
|
+
font-style: normal;
|
|
144
|
+
font-weight: 500;
|
|
145
|
+
line-height: 16px; /* 133.333% */
|
|
146
|
+
`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./SettingForm";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./SettingForm";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { ReactElement } from "react";
|
|
9
|
+
export default function ActionsPlugin(): ReactElement;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
10
|
+
import { mergeRegister } from "@lexical/utils";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { Button, LockFillIcon, LockUnlockFillIcon } from "../../../..";
|
|
13
|
+
export default function ActionsPlugin() {
|
|
14
|
+
const [editor] = useLexicalComposerContext();
|
|
15
|
+
const [isEditable, setIsEditable] = useState(() => editor.isEditable());
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
return mergeRegister(editor.registerEditableListener((editable) => {
|
|
18
|
+
setIsEditable(editable);
|
|
19
|
+
}));
|
|
20
|
+
}, [editor]);
|
|
21
|
+
return (_jsx(Button, { color: "primary", size: "small", startIcon: isEditable ? _jsx(LockFillIcon, {}) : _jsx(LockUnlockFillIcon, {}), onClick: () => {
|
|
22
|
+
editor.setEditable(!editor.isEditable());
|
|
23
|
+
}, title: "Read-Only Mode", label: `${!isEditable ? "수정 모드" : "읽기 모드"}로 변경`, "aria-label": `${!isEditable ? "Unlock" : "Lock"} read-only mode` }));
|
|
24
|
+
}
|
|
@@ -14,6 +14,7 @@ import { $isColoredQuoteNode, } from "../../nodes/ColoredQuoteNode";
|
|
|
14
14
|
import { useTheme } from "@emotion/react";
|
|
15
15
|
import { css } from "@emotion/css";
|
|
16
16
|
import { $isProblemInputNode } from "../../nodes";
|
|
17
|
+
import { $isProblemSelectNode, } from "../../nodes/ProblemSelectNode";
|
|
17
18
|
function getParagraphContextMenuOptions(editor, node, setOpen) {
|
|
18
19
|
return [
|
|
19
20
|
new ComponentPickerOption("본문", {
|
|
@@ -185,6 +186,17 @@ function getProblemInputContextMenuOptions(node) {
|
|
|
185
186
|
}),
|
|
186
187
|
];
|
|
187
188
|
}
|
|
189
|
+
function getProblemSelectContextMenuOptions(node) {
|
|
190
|
+
return [
|
|
191
|
+
new ComponentPickerOption("블록 삭제", {
|
|
192
|
+
icon: _jsx(CloseFillIcon, {}),
|
|
193
|
+
keywords: [],
|
|
194
|
+
onSelect: () => {
|
|
195
|
+
node.remove();
|
|
196
|
+
},
|
|
197
|
+
}),
|
|
198
|
+
];
|
|
199
|
+
}
|
|
188
200
|
function getColoredQuoteContextMenuOptions(editor, theme, node) {
|
|
189
201
|
return [
|
|
190
202
|
new ComponentPickerOption("회색", {
|
|
@@ -264,6 +276,9 @@ export function useContextMenuOptions() {
|
|
|
264
276
|
if ($isProblemInputNode(node)) {
|
|
265
277
|
return getProblemInputContextMenuOptions(node);
|
|
266
278
|
}
|
|
279
|
+
else if ($isProblemSelectNode(node)) {
|
|
280
|
+
return getProblemSelectContextMenuOptions(node);
|
|
281
|
+
}
|
|
267
282
|
else if (node instanceof ParagraphNode) {
|
|
268
283
|
return getParagraphContextMenuOptions(editor, node, setImageOpen);
|
|
269
284
|
}
|
package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js
CHANGED
|
@@ -25,6 +25,7 @@ import { TextIcon, H1Icon, H2Icon, H3Icon, ListUnorderedIcon, ListOrderedIcon, D
|
|
|
25
25
|
import { ZINDEX } from "../../../../utils/zIndex";
|
|
26
26
|
import { css, useTheme } from "@emotion/react";
|
|
27
27
|
import { INSERT_PROBLEM_INPUT_COMMAND } from "../ProblemInputPlugin";
|
|
28
|
+
import { INSERT_PROBLEM_SELECT_COMMAND } from "../ProblemSelectPlugin";
|
|
28
29
|
// import useModal from "../../hooks/useModal";
|
|
29
30
|
// import catTypingGif from "../../images/cat-typing.gif";
|
|
30
31
|
// import { INSERT_IMAGE_COMMAND, InsertImageDialog } from "../ImagesPlugin";
|
|
@@ -86,7 +87,18 @@ function getQuizContextOptions(editor, theme) {
|
|
|
86
87
|
icon: _jsx(ListRadioIcon, { color: theme.color.foreground.primary }),
|
|
87
88
|
keywords: ["problem select", "객관식 입력"],
|
|
88
89
|
onSelect: () => {
|
|
89
|
-
|
|
90
|
+
editor.dispatchCommand(INSERT_PROBLEM_SELECT_COMMAND, {
|
|
91
|
+
selections: [
|
|
92
|
+
{
|
|
93
|
+
isAnswer: false,
|
|
94
|
+
show: {
|
|
95
|
+
text: "",
|
|
96
|
+
},
|
|
97
|
+
value: "1",
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
selected: [],
|
|
101
|
+
});
|
|
90
102
|
},
|
|
91
103
|
}),
|
|
92
104
|
new ComponentDrawerOption("메뉴구분선", (_jsx("div", { css: css `
|
|
@@ -18,6 +18,7 @@ import { ImageFillIcon, LinkIcon, UploadLineIcon } from "../../../../icons";
|
|
|
18
18
|
import Button from "../../../../components/Button";
|
|
19
19
|
import { useTheme } from "@emotion/react";
|
|
20
20
|
import { CodleDesignSystemContext } from "../../../../CodleDesignSystemProvider";
|
|
21
|
+
import { useForm } from "react-hook-form";
|
|
21
22
|
export function InsertImageDialog(props) {
|
|
22
23
|
const { open, activeEditor, onClose } = props;
|
|
23
24
|
const theme = useTheme();
|
|
@@ -25,8 +26,9 @@ export function InsertImageDialog(props) {
|
|
|
25
26
|
const hasModifier = useRef(false);
|
|
26
27
|
const inputRef = useRef(null);
|
|
27
28
|
const cdsContext = useContext(CodleDesignSystemContext);
|
|
28
|
-
const
|
|
29
|
-
|
|
29
|
+
const { control, setValue, watch, reset } = useForm({
|
|
30
|
+
defaultValues: { src: "", altText: "" },
|
|
31
|
+
});
|
|
30
32
|
useEffect(() => {
|
|
31
33
|
hasModifier.current = false;
|
|
32
34
|
const handler = (e) => {
|
|
@@ -43,8 +45,7 @@ export function InsertImageDialog(props) {
|
|
|
43
45
|
};
|
|
44
46
|
const handleOnClose = () => {
|
|
45
47
|
setMode(null);
|
|
46
|
-
|
|
47
|
-
setAltText("");
|
|
48
|
+
reset();
|
|
48
49
|
onClose();
|
|
49
50
|
};
|
|
50
51
|
return (_jsxs(StyledAlertDialog, Object.assign({ icon: _jsx(ImageFillIcon, { color: theme.color.background.primary }), open: open, onClose: handleOnClose, disableIconPadding: true }, { children: [_jsx(StyledAlertDialogTitle, Object.assign({ onClose: handleOnClose }, { children: "\uC774\uBBF8\uC9C0 \uC0BD\uC785\uD558\uAE30" })), !mode && (_jsx(AlertDialogContent, { children: _jsxs(Buttons, { children: [_jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uC774\uBBF8\uC9C0 URL\uC744 \uC54C\uACE0 \uC788\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "URL\uB85C \uC0BD\uC785\uD558\uAE30", startIcon: _jsx(LinkIcon, {}), onClick: () => setMode("url") })] }), _jsxs(ButtonAndDescription, { children: [_jsx(Description, { children: "\uAC16\uACE0 \uC788\uB294 \uC774\uBBF8\uC9C0\uB97C \uC0BD\uC785\uD558\uACE0 \uC2F6\uB2E4\uBA74" }), _jsx(Button, { color: "grey", size: "medium", fullWidth: true, label: "\uD30C\uC77C \uC120\uD0DD\uD558\uAE30", startIcon: _jsx(UploadLineIcon, {}), onClick: () => {
|
|
@@ -57,10 +58,10 @@ export function InsertImageDialog(props) {
|
|
|
57
58
|
return;
|
|
58
59
|
const uploadByFile = (_b = cdsContext.lexical) === null || _b === void 0 ? void 0 : _b.uploadByFile;
|
|
59
60
|
if (uploadByFile) {
|
|
60
|
-
|
|
61
|
+
setValue("src", yield uploadByFile(file));
|
|
61
62
|
setMode("file");
|
|
62
63
|
}
|
|
63
|
-
}) })] })] }) })), mode === "url" && (_jsx(InsertImageUriDialogBody, {
|
|
64
|
+
}) })] })] }) })), mode === "url" && (_jsx(InsertImageUriDialogBody, { control: control, watch: watch, onClick: onClick })), mode === "file" && (_jsx(InsertImageUploadedDialogBody, { control: control, watch: watch, setValue: setValue, onClick: onClick }))] })));
|
|
64
65
|
}
|
|
65
66
|
const StyledAlertDialog = styled(AlertDialog) `
|
|
66
67
|
gap: 16px;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { InsertImagePayload } from ".";
|
|
2
|
+
import { Control, UseFormSetValue, UseFormWatch } from "react-hook-form";
|
|
2
3
|
export interface InsertImageUploadedDialogBodyProps {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
control: Control<{
|
|
5
|
+
src: string;
|
|
6
|
+
altText: string;
|
|
7
|
+
}, any>;
|
|
8
|
+
watch: UseFormWatch<{
|
|
9
|
+
src: string;
|
|
10
|
+
altText: string;
|
|
11
|
+
}>;
|
|
12
|
+
setValue: UseFormSetValue<{
|
|
13
|
+
src: string;
|
|
14
|
+
altText: string;
|
|
15
|
+
}>;
|
|
7
16
|
onClick: (payload: InsertImagePayload) => void;
|
|
8
17
|
}
|
|
9
18
|
export declare function InsertImageUploadedDialogBody(props: InsertImageUploadedDialogBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -15,11 +15,12 @@ import { AlertDialogContent, AlertDialogActions, } from "../../../../components/
|
|
|
15
15
|
import Button from "../../../../components/Button";
|
|
16
16
|
import Input from "../../../../components/Input";
|
|
17
17
|
import { RefreshLineIcon } from "../../../../icons";
|
|
18
|
+
import { Controller, } from "react-hook-form";
|
|
18
19
|
export function InsertImageUploadedDialogBody(props) {
|
|
19
|
-
const {
|
|
20
|
+
const { control, watch, setValue, onClick } = props;
|
|
20
21
|
const inputRef = useRef(null);
|
|
21
22
|
const cdsContext = useContext(CodleDesignSystemContext);
|
|
22
|
-
const isDisabled = src === "";
|
|
23
|
+
const isDisabled = watch("src") === "";
|
|
23
24
|
return (_jsxs(_Fragment, { children: [_jsx(AlertDialogContent, { children: _jsxs(Inputs, { children: [_jsx(Button, { fullWidth: true, color: "grey", size: "medium", label: "\uD30C\uC77C \uBC14\uAFB8\uAE30", onClick: () => {
|
|
24
25
|
var _a;
|
|
25
26
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
@@ -30,11 +31,9 @@ export function InsertImageUploadedDialogBody(props) {
|
|
|
30
31
|
return;
|
|
31
32
|
const uploadByFile = (_b = cdsContext.lexical) === null || _b === void 0 ? void 0 : _b.uploadByFile;
|
|
32
33
|
if (uploadByFile) {
|
|
33
|
-
|
|
34
|
+
setValue("src", yield uploadByFile(file));
|
|
34
35
|
}
|
|
35
|
-
}) }), _jsxs(ImagePreview, { children: ["\uC774\uBBF8\uC9C0 \uBBF8\uB9AC\uBCF4\uAE30", _jsx("img", { src: src, alt: altText })] }), _jsx(Input, { fullWidth: true, label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", color: "default", size: "medium", onChange: (
|
|
36
|
-
setAltText(e.target.value);
|
|
37
|
-
}, value: altText })] }) }), _jsx(AlertDialogActions, { children: _jsx(Button, { fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled, onClick: () => onClick({ altText, src }) }) })] }));
|
|
36
|
+
}) }), _jsxs(ImagePreview, { children: ["\uC774\uBBF8\uC9C0 \uBBF8\uB9AC\uBCF4\uAE30", _jsx("img", { src: watch("src"), alt: watch("altText") })] }), _jsx(Controller, { name: "altText", control: control, render: ({ field: { value, onChange } }) => (_jsx(Input, { fullWidth: true, label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", color: "default", size: "medium", onChange: onChange, value: value })) })] }) }), _jsx(AlertDialogActions, { children: _jsx(Button, { fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled, onClick: () => onClick({ altText: watch("altText"), src: watch("src") }) }) })] }));
|
|
38
37
|
}
|
|
39
38
|
const Inputs = styled.div `
|
|
40
39
|
display: flex;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { InsertImagePayload } from ".";
|
|
2
|
+
import { Control, UseFormWatch } from "react-hook-form";
|
|
2
3
|
export interface InsertImageUriDialogBodyProps {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
control: Control<{
|
|
5
|
+
src: string;
|
|
6
|
+
altText: string;
|
|
7
|
+
}, any>;
|
|
8
|
+
watch: UseFormWatch<{
|
|
9
|
+
src: string;
|
|
10
|
+
altText: string;
|
|
11
|
+
}>;
|
|
7
12
|
onClick: (payload: InsertImagePayload) => void;
|
|
8
13
|
}
|
|
9
14
|
export declare function InsertImageUriDialogBody(props: InsertImageUriDialogBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,14 +4,11 @@ import { AlertDialogActions, AlertDialogContent, } from "../../../../components/
|
|
|
4
4
|
import Input from "../../../../components/Input";
|
|
5
5
|
import { LinkIcon } from "../../../../icons";
|
|
6
6
|
import Button from "../../../../components/Button";
|
|
7
|
+
import { Controller } from "react-hook-form";
|
|
7
8
|
export function InsertImageUriDialogBody(props) {
|
|
8
|
-
const {
|
|
9
|
-
const isDisabled = src === "";
|
|
10
|
-
return (_jsxs(_Fragment, { children: [" ", _jsx(AlertDialogContent, { children: _jsxs(Inputs, { children: [_jsx(Input, { fullWidth: true, label: "URL", placeholder: "https://www.pexels.com/photo/n-2848492/", color: "default", size: "medium", onChange: (
|
|
11
|
-
setSrc(e.target.value);
|
|
12
|
-
}, value: src, startIcon: _jsx(LinkIcon, {}) }), _jsx(Input, { fullWidth: true, label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", color: "default", size: "medium", onChange: (e) => {
|
|
13
|
-
setAltText(e.target.value);
|
|
14
|
-
}, value: altText })] }) }), _jsx(AlertDialogActions, { children: _jsx(Button, { fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled, onClick: () => onClick({ altText, src }) }) })] }));
|
|
9
|
+
const { control, watch, onClick } = props;
|
|
10
|
+
const isDisabled = watch("src") === "";
|
|
11
|
+
return (_jsxs(_Fragment, { children: [" ", _jsx(AlertDialogContent, { children: _jsxs(Inputs, { children: [_jsx(Controller, { name: "src", control: control, render: ({ field: { value, onChange } }) => (_jsx(Input, { fullWidth: true, label: "URL", placeholder: "https://www.pexels.com/photo/n-2848492/", color: "default", size: "medium", onChange: onChange, value: value, startIcon: _jsx(LinkIcon, {}) })) }), _jsx(Controller, { name: "altText", control: control, render: ({ field: { value, onChange } }) => (_jsx(Input, { fullWidth: true, label: "\uB300\uCCB4 \uD14D\uC2A4\uD2B8", placeholder: "\uC0BD\uC785\uD558\uB294 \uC774\uBBF8\uC9C0\uC5D0 \uAD00\uD55C \uC124\uBA85", color: "default", size: "medium", onChange: onChange, value: value })) })] }) }), _jsx(AlertDialogActions, { children: _jsx(Button, { fullWidth: true, label: "\uC0BD\uC785\uD558\uAE30", size: "medium", color: "primary", disabled: isDisabled, onClick: () => onClick({ altText: watch("altText"), src: watch("src") }) }) })] }));
|
|
15
12
|
}
|
|
16
13
|
const Inputs = styled.div `
|
|
17
14
|
display: flex;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { LexicalCommand } from "lexical";
|
|
3
|
+
import { ProblemSelectPayload } from "../../nodes/ProblemSelectNode";
|
|
4
|
+
export declare const INSERT_PROBLEM_SELECT_COMMAND: LexicalCommand<ProblemSelectPayload>;
|
|
5
|
+
export default function ProblemInputPlugin(): JSX.Element | null;
|