@team-monolith/cds 1.99.7 → 1.99.9
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/components/Button.js +1 -1
- package/dist/components/OverflowTooltip.d.ts +1 -1
- package/dist/components/OverflowTooltip.js +4 -2
- package/dist/components/SquareButton.js +3 -1
- package/dist/components/Tooltip.d.ts +6 -0
- package/dist/components/Tooltip.js +2 -2
- package/dist/patterns/Dropdown/Dropdown.js +2 -2
- package/dist/patterns/Dropdown/DropdownItem/DropdownItem.js +3 -3
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/FormSolution.js +5 -2
- package/dist/patterns/LexicalEditor/nodes/ProblemInputNode/SettingForm/SettingForm.js +8 -4
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SettingForm/SettingForm.js +3 -2
- package/dist/patterns/LexicalEditor/nodes/SheetInputNode/SettingForm.js +5 -2
- package/dist/patterns/ToggleButtonGroup/ToggleButton.js +4 -1
- package/package.json +1 -1
|
@@ -212,7 +212,7 @@ const SIZE_TO_LABEL_STYLE = {
|
|
|
212
212
|
export const Button = React.forwardRef(function Button(props, ref) {
|
|
213
213
|
const { className, component: Component = "button", disabled, color, size, startIcon, endIcon, label, fullWidth, bold = false, loading = false } = props, other = __rest(props, ["className", "component", "disabled", "color", "size", "startIcon", "endIcon", "label", "fullWidth", "bold", "loading"]);
|
|
214
214
|
const theme = useTheme();
|
|
215
|
-
return (_jsxs(Component, Object.assign({ type: Component === "
|
|
215
|
+
return (_jsxs(Component, Object.assign({ type: Component === "button" || Component === "input" ? "button" : undefined }, other, { className: className, ref: ref, css: [
|
|
216
216
|
css `
|
|
217
217
|
display: inline-flex;
|
|
218
218
|
align-items: center;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/** @jsxImportSource @emotion/react */
|
|
3
3
|
import { SerializedStyles } from "@emotion/react";
|
|
4
4
|
import { TooltipProps } from "./Tooltip";
|
|
5
|
-
interface OverflowTooltipProps extends Omit<TooltipProps, "open" | "onOpen" | "onClose" | "children"> {
|
|
5
|
+
interface OverflowTooltipProps extends Omit<TooltipProps, "open" | "onOpen" | "onClose" | "children" | "tooltipId"> {
|
|
6
6
|
className?: string;
|
|
7
7
|
childrenCss?: SerializedStyles;
|
|
8
8
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "@emotion/react/jsx-runtime";
|
|
2
2
|
import styled from "@emotion/styled";
|
|
3
|
-
import { useRef, useState } from "react";
|
|
3
|
+
import { useRef, useState, useMemo } from "react";
|
|
4
4
|
import { Tooltip } from "./Tooltip";
|
|
5
|
+
import { uid } from "uid";
|
|
5
6
|
/**
|
|
6
7
|
* 인자로 주어진 텍스트를 그립니다.
|
|
7
8
|
* 공간이 부족하면 ...으로 표시하고 툴팁으로 전체 내용을 노출합니다.
|
|
@@ -9,6 +10,7 @@ import { Tooltip } from "./Tooltip";
|
|
|
9
10
|
export function OverflowTooltip(props) {
|
|
10
11
|
const tooltipRef = useRef(null);
|
|
11
12
|
const [isTooltipOpen, setIsTooltipOpen] = useState(false);
|
|
13
|
+
const tooltipId = useMemo(() => `tooltip-${uid()}`, []);
|
|
12
14
|
const getIsOverflow = () => {
|
|
13
15
|
if (tooltipRef.current) {
|
|
14
16
|
return tooltipRef.current.scrollWidth > tooltipRef.current.offsetWidth;
|
|
@@ -23,7 +25,7 @@ export function OverflowTooltip(props) {
|
|
|
23
25
|
const handleClose = () => {
|
|
24
26
|
setIsTooltipOpen(false);
|
|
25
27
|
};
|
|
26
|
-
return (_jsx(Tooltip, Object.assign({ open: isTooltipOpen, onOpen: handleOpen, onClose: handleClose }, props, { children: _jsx(OverflowDiv, Object.assign({ css: props.childrenCss, ref: tooltipRef, onMouseOver: handleOpen }, { children: props.text })) })));
|
|
28
|
+
return (_jsx(Tooltip, Object.assign({ tooltipId: tooltipId, open: isTooltipOpen, onOpen: handleOpen, onClose: handleClose }, props, { children: _jsx(OverflowDiv, Object.assign({ css: props.childrenCss, ref: tooltipRef, onMouseOver: handleOpen, "aria-labelledby": tooltipId }, { children: props.text })) })));
|
|
27
29
|
}
|
|
28
30
|
const OverflowDiv = styled.div `
|
|
29
31
|
overflow: hidden;
|
|
@@ -184,7 +184,9 @@ export const SquareButton = React.forwardRef(function SquareButton(props, ref) {
|
|
|
184
184
|
align-items: center;
|
|
185
185
|
gap: 8px;
|
|
186
186
|
width: ${fullWidth ? "100%" : "fit-content"};
|
|
187
|
-
` }, { children: [_jsx(Component, Object.assign({ type: Component === "
|
|
187
|
+
` }, { children: [_jsx(Component, Object.assign({ type: Component === "button" || Component === "input"
|
|
188
|
+
? "button"
|
|
189
|
+
: undefined }, other, buttonProps, { ref: ref, css: [
|
|
188
190
|
COLOR_TO_BUTTON_STYLE(theme, color, Boolean(disabled || loading)),
|
|
189
191
|
SIZE_TO_BUTTON_STYLE[size],
|
|
190
192
|
css `
|
|
@@ -21,6 +21,12 @@ export interface TooltipProps {
|
|
|
21
21
|
placement?: "bottom-end" | "bottom-start" | "bottom" | "left-end" | "left-start" | "left" | "right-end" | "right-start" | "right" | "top-end" | "top-start" | "top";
|
|
22
22
|
/** 툴팁을 표시할 객체입니다. ref를 props로 받을 수 있어야합니다. */
|
|
23
23
|
children: React.ReactElement;
|
|
24
|
+
/**
|
|
25
|
+
* 툴팁의 고유 id입니다.
|
|
26
|
+
* 이 id는 툴팁을 띄우는 요소에 aria-labelledby 속성을 통해 연결되어,
|
|
27
|
+
* 스크린 리더 등의 보조 기술이 툴팁 내용을 올바르게 인식하도록 돕습니다.
|
|
28
|
+
*/
|
|
29
|
+
tooltipId: string;
|
|
24
30
|
}
|
|
25
31
|
/**
|
|
26
32
|
* [피그마](https://www.figma.com/file/yhrRFizzmhPoHdw9FbYow2/Codle-PD-Kit---Components?type=design&node-id=172-626&t=aFkKTFgWq2xFFGC5-0)
|
|
@@ -45,9 +45,9 @@ function addTabIndexIfNeeded(element) {
|
|
|
45
45
|
* [피그마](https://www.figma.com/file/yhrRFizzmhPoHdw9FbYow2/Codle-PD-Kit---Components?type=design&node-id=172-626&t=aFkKTFgWq2xFFGC5-0)
|
|
46
46
|
*/
|
|
47
47
|
export const Tooltip = React.forwardRef(function Tooltip(props, ref) {
|
|
48
|
-
const { title, text, children } = props, restProps = __rest(props, ["title", "text", "children"]);
|
|
48
|
+
const { tooltipId, title, text, children } = props, restProps = __rest(props, ["tooltipId", "title", "text", "children"]);
|
|
49
49
|
const focusableChildren = addTabIndexIfNeeded(children);
|
|
50
|
-
return (_jsx(StyledTooltip, Object.assign({ ref: ref, title:
|
|
50
|
+
return (_jsx(StyledTooltip, Object.assign({ id: tooltipId, ref: ref, title:
|
|
51
51
|
// title이 없고 text가 null인 경우 툴팁을 표시하지 않음
|
|
52
52
|
!title && text === null ? null : (_jsxs(_Fragment, { children: [title && _jsx(TitleDiv, { children: title }), text] })), describeChild: true }, restProps, { children: focusableChildren })));
|
|
53
53
|
});
|
|
@@ -32,7 +32,7 @@ const Dropdown = forwardRef(function Dropdown(props, ref) {
|
|
|
32
32
|
const isControlled = menuProps.open !== undefined;
|
|
33
33
|
const [open, setOpen] = useState(false);
|
|
34
34
|
const [itemState, setItemState] = useState(new Map());
|
|
35
|
-
const
|
|
35
|
+
const dropdownMenuId = useMemo(() => `dropdown-menu-${uid()}`, []);
|
|
36
36
|
const handleClick = (e) => {
|
|
37
37
|
onClick === null || onClick === void 0 ? void 0 : onClick(e);
|
|
38
38
|
if (!isControlled)
|
|
@@ -55,6 +55,6 @@ const Dropdown = forwardRef(function Dropdown(props, ref) {
|
|
|
55
55
|
});
|
|
56
56
|
(_a = menuProps.onClose) === null || _a === void 0 ? void 0 : _a.call(menuProps, e);
|
|
57
57
|
};
|
|
58
|
-
return (_jsxs(Component, Object.assign({ className: className }, other, { ref: ref }, { children: [_jsx(Button, Object.assign({ css: buttonCss, ref: menuRef }, buttonProps, { onClick: handleClick, fullWidth: true, "aria-expanded": (_a = menuProps.open) !== null && _a !== void 0 ? _a : open, "aria-controls":
|
|
58
|
+
return (_jsxs(Component, Object.assign({ className: className }, other, { ref: ref }, { children: [_jsx(Button, Object.assign({ css: buttonCss, ref: menuRef }, buttonProps, { onClick: handleClick, fullWidth: true, "aria-expanded": (_a = menuProps.open) !== null && _a !== void 0 ? _a : open, "aria-controls": dropdownMenuId })), _jsx(DropdownMenu, Object.assign({ dropdownMenuId: dropdownMenuId }, menuProps, { open: isControlled ? menuProps.open : open, onClose: handleClose, anchorEl: menuRef.current, closeOnItemClick: closeOnItemClick, itemState: itemState, setItemState: setItemState }, { children: children }))] })));
|
|
59
59
|
});
|
|
60
60
|
export { Dropdown };
|
|
@@ -31,7 +31,7 @@ const DropdownItem = React.forwardRef(function DropdownItem(props, ref) {
|
|
|
31
31
|
const { className, index, labelCss, component: Component = "div", type = "default", checkbox, checkboxProps = { checked: false }, startIcon, label, endIcon, preserveIconColor = false, disabled, active, onMouseEnter, onMouseLeave, onClick, subMenuProps, children } = props, other = __rest(props, ["className", "index", "labelCss", "component", "type", "checkbox", "checkboxProps", "startIcon", "label", "endIcon", "preserveIconColor", "disabled", "active", "onMouseEnter", "onMouseLeave", "onClick", "subMenuProps", "children"]);
|
|
32
32
|
const itemRef = useRef(null);
|
|
33
33
|
const { open, onCloseOnItemClick, nestedIndex, itemState, setItemState } = useContext(DropdownContext);
|
|
34
|
-
const
|
|
34
|
+
const dropdownMenuId = useMemo(() => `dropdown-menu-${uid()}`, []);
|
|
35
35
|
const absItemIndex = nestedIndex ? `${nestedIndex}-${index}` : `${index}`;
|
|
36
36
|
// 서브메뉴가 존재하는지 여부
|
|
37
37
|
const isSubMenuExist = Boolean(children);
|
|
@@ -51,7 +51,7 @@ const DropdownItem = React.forwardRef(function DropdownItem(props, ref) {
|
|
|
51
51
|
setSelected(setItemState, absItemIndex);
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
|
-
return (_jsxs(_Fragment, { children: [_jsx(Component, Object.assign({ className: className, ref: ref, tabIndex: disabled ? -1 : 0, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: handleClick, "aria-disabled": disabled }, other, { "aria-expanded": isSubMenuExist ? isSubMenuShowed : undefined, "aria-controls": isSubMenuExist ?
|
|
54
|
+
return (_jsxs(_Fragment, { children: [_jsx(Component, Object.assign({ className: className, ref: ref, tabIndex: disabled ? -1 : 0, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: handleClick, "aria-disabled": disabled }, other, { "aria-expanded": isSubMenuExist ? isSubMenuShowed : undefined, "aria-controls": isSubMenuExist ? dropdownMenuId : undefined }, { children: _jsxs(Item, Object.assign({ ref: itemRef, disabled: disabled, selected: isSubMenuShowed || Boolean(active) }, { children: [_jsxs(LeftWrapper, { children: [checkbox && (_jsx(StyledCheckboxInput, Object.assign({}, checkboxProps, { disabled: disabled, onClick: (e) => {
|
|
55
55
|
e.stopPropagation();
|
|
56
56
|
} }))), startIcon && (_jsx(IconDiv, Object.assign({ type: type, preserveIconColor: preserveIconColor }, { children: startIcon }))), _jsx(LabelDiv, Object.assign({ css: labelCss, type: type }, { children: label }))] }), endIcon && (_jsx(IconDiv, Object.assign({ type: type, preserveIconColor: preserveIconColor }, { children: endIcon }))), !endIcon && isSubMenuExist && (_jsx(IconDiv, Object.assign({ type: type, preserveIconColor: preserveIconColor }, { children: _jsx(ArrowRightSLineIcon, {}) })))] })) })), isSubMenuExist && (_jsx(DropdownContext.Provider, Object.assign({ value: {
|
|
57
57
|
open,
|
|
@@ -59,7 +59,7 @@ const DropdownItem = React.forwardRef(function DropdownItem(props, ref) {
|
|
|
59
59
|
nestedIndex: absItemIndex,
|
|
60
60
|
itemState,
|
|
61
61
|
setItemState,
|
|
62
|
-
} }, { children: _jsx(DropdownMenu, Object.assign({ dropdownMenuId:
|
|
62
|
+
} }, { children: _jsx(DropdownMenu, Object.assign({ dropdownMenuId: dropdownMenuId }, subMenuProps, { open: isSubMenuShowed, anchorEl: itemRef.current, isNestedMenu: true, anchorOrigin: {
|
|
63
63
|
vertical: "top",
|
|
64
64
|
horizontal: "right",
|
|
65
65
|
}, itemState: itemState, setItemState: setItemState }, { children: children })) })))] }));
|
|
@@ -7,9 +7,12 @@ import { AlertFillIcon, DeleteBinLineIcon, ErrorWarningFillIcon, } from "../../.
|
|
|
7
7
|
import { SquareButton } from "../../../../../components/SquareButton";
|
|
8
8
|
import { Tooltip } from "../../../../../components/Tooltip";
|
|
9
9
|
import { TextTypeDropdown } from "./TextTypeDropdown";
|
|
10
|
+
import { uid } from "uid";
|
|
11
|
+
import { useMemo } from "react";
|
|
10
12
|
export function FormSolution(props) {
|
|
11
13
|
const { index, control, rules, onDelete } = props;
|
|
12
14
|
const theme = useTheme();
|
|
15
|
+
const tooltipId = useMemo(() => `tooltip-${uid()}`, []);
|
|
13
16
|
return (_jsx(Controller, { name: `solutions.${index}.value`, control: control, rules: rules, render: ({ field: { value, onChange }, fieldState: { invalid, error }, }) => {
|
|
14
17
|
const disabled = (error === null || error === void 0 ? void 0 : error.type) === "enabled";
|
|
15
18
|
return (_jsx(Input, { size: "small", color: invalid ? "activeDanger" : "default", onChange: onChange, disabled: disabled, value: value, hintIcon: !disabled && invalid ? _jsx(ErrorWarningFillIcon, {}) : undefined, hintText: !disabled ? error === null || error === void 0 ? void 0 : error.message : undefined, placeholder: "\uC548\uB155\uD558\uC138\uC694", fullWidth: true, css: css `
|
|
@@ -21,8 +24,8 @@ export function FormSolution(props) {
|
|
|
21
24
|
gap: 4px;
|
|
22
25
|
` }, { children: [onDelete && (_jsx(SquareButton, { color: "white", size: "xsmall", icon: _jsx(DeleteBinLineIcon, {}), onClick: onDelete, buttonProps: {
|
|
23
26
|
"aria-label": "삭제",
|
|
24
|
-
} })), disabled && (_jsx(Tooltip, Object.assign({ text: _jsxs("span", { children: ["\uC785\uB825 \uCE78 \uC124\uC815\uC774 '\uAE00\uC790 \uC218\uB300\uB85C'\uC778 \uACBD\uC6B0", _jsx("br", {}), "\uC815\uB2F5\uC744 \uD558\uB098\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."] }) }, { children: _jsx(SquareButton, { color: "danger", size: "xsmall", icon: _jsx(AlertFillIcon, { color: theme.color.foreground.neutralAlt }), disabled: true, buttonProps: {
|
|
27
|
+
} })), disabled && (_jsx(Tooltip, Object.assign({ tooltipId: tooltipId, text: _jsxs("span", { children: ["\uC785\uB825 \uCE78 \uC124\uC815\uC774 '\uAE00\uC790 \uC218\uB300\uB85C'\uC778 \uACBD\uC6B0", _jsx("br", {}), "\uC815\uB2F5\uC744 \uD558\uB098\uB9CC \uB4F1\uB85D\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."] }) }, { children: _jsx(SquareButton, { color: "danger", size: "xsmall", icon: _jsx(AlertFillIcon, { color: theme.color.foreground.neutralAlt }), disabled: true, buttonProps: {
|
|
25
28
|
"aria-label": "정답 등록 불가",
|
|
26
|
-
} }) })))] })) }));
|
|
29
|
+
}, "aria-labelledby": tooltipId }) })))] })) }));
|
|
27
30
|
} }));
|
|
28
31
|
}
|
|
@@ -13,9 +13,13 @@ import { FormSegmentedControl } from "./FormSegmentedControl";
|
|
|
13
13
|
import { FormPlaceholder } from "./FormPlaceholder";
|
|
14
14
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
15
15
|
import { $getNodeByKey } from "lexical";
|
|
16
|
+
import { uid } from "uid";
|
|
17
|
+
import { useMemo } from "react";
|
|
16
18
|
export function SettingForm(props) {
|
|
17
19
|
const { solutions, showCharacterNumber, placeholder, nodeKey, onClose, caseSensitive, ignoreWhitespace, } = props;
|
|
18
20
|
const [editor] = useLexicalComposerContext();
|
|
21
|
+
const inputTooltipId = useMemo(() => `tooltip-${uid()}`, []);
|
|
22
|
+
const placeholderTooltipId = useMemo(() => `tooltip-${uid()}`, []);
|
|
19
23
|
const { control, handleSubmit, watch, trigger } = useForm({
|
|
20
24
|
mode: "all",
|
|
21
25
|
defaultValues: {
|
|
@@ -73,16 +77,16 @@ export function SettingForm(props) {
|
|
|
73
77
|
` }, { children: [_jsx(AlarmWarningFillIcon, { color: theme.color.foreground.neutralBaseDisabled, css: css `
|
|
74
78
|
width: 14px;
|
|
75
79
|
height: 14px;
|
|
76
|
-
` }), _jsx(Label, { children: "\uAC00\uB2A5\uD55C \uC815\uB2F5\uC744 \uBAA8\uB450 \uCD94\uAC00\uD574\uC57C \uC6D0\uD65C\uD558\uAC8C \uC790\uB3D9 \uCC44\uC810\uD560 \uC218 \uC788\uC5B4\uC694." })] }))] }), _jsxs(Right, { children: [_jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC785\uB825 \uCE78", _jsx(Tooltip, Object.assign({ text: _jsxs("span", { children: [`예를 들어 정답이 '글자 수'이고`, _jsx("br", {}), _jsx("b", { children: "\uAE00\uC790 \uC218\uB300\uB85C" }), " \uC635\uC158\uC744 \uC120\uD0DD\uD588\uB2E4\uBA74", _jsx("br", {}), `입력 칸이 '☐☐ ☐' 처럼 표시됩니다.`] }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
|
|
80
|
+
` }), _jsx(Label, { children: "\uAC00\uB2A5\uD55C \uC815\uB2F5\uC744 \uBAA8\uB450 \uCD94\uAC00\uD574\uC57C \uC6D0\uD65C\uD558\uAC8C \uC790\uB3D9 \uCC44\uC810\uD560 \uC218 \uC788\uC5B4\uC694." })] }))] }), _jsxs(Right, { children: [_jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC785\uB825 \uCE78", _jsx(Tooltip, Object.assign({ tooltipId: inputTooltipId, text: _jsxs("span", { children: [`예를 들어 정답이 '글자 수'이고`, _jsx("br", {}), _jsx("b", { children: "\uAE00\uC790 \uC218\uB300\uB85C" }), " \uC635\uC158\uC744 \uC120\uD0DD\uD588\uB2E4\uBA74", _jsx("br", {}), `입력 칸이 '☐☐ ☐' 처럼 표시됩니다.`] }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
|
|
77
81
|
width: 12px;
|
|
78
82
|
height: 12px;
|
|
79
|
-
|
|
83
|
+
`, "aria-labelledby": inputTooltipId }) }))] }), _jsx(FormSegmentedControl, { control: control, trigger: trigger, name: "showCharacterNumber", items: [
|
|
80
84
|
{ value: false, label: "한 칸으로" },
|
|
81
85
|
{ value: true, label: "글자 수대로" },
|
|
82
|
-
] })] }), _jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC790\uB9AC \uD45C\uC2DC\uC790", _jsx(Tooltip, Object.assign({ text: _jsx("span", { children: "\uC785\uB825 \uCE78\uC5D0 \uAE30\uBCF8\uC73C\uB85C \uB178\uCD9C\uB418\uB294 \uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4." }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
|
|
86
|
+
] })] }), _jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC790\uB9AC \uD45C\uC2DC\uC790", _jsx(Tooltip, Object.assign({ tooltipId: placeholderTooltipId, text: _jsx("span", { children: "\uC785\uB825 \uCE78\uC5D0 \uAE30\uBCF8\uC73C\uB85C \uB178\uCD9C\uB418\uB294 \uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4." }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
|
|
83
87
|
width: 12px;
|
|
84
88
|
height: 12px;
|
|
85
|
-
|
|
89
|
+
`, "aria-labelledby": placeholderTooltipId }) }))] }), _jsx(FormPlaceholder, { control: control })] }), _jsxs(FormArea, { children: [_jsx(Label, { children: "\uB744\uC5B4\uC4F0\uAE30" }), _jsx(FormSegmentedControl, { control: control, trigger: trigger, name: "ignoreWhitespace", items: [
|
|
86
90
|
{ value: true, label: "무시하기" },
|
|
87
91
|
{ value: false, label: "포함하기" },
|
|
88
92
|
] })] }), _jsxs(FormArea, { children: [_jsx(Label, { children: "\uB300\uC18C\uBB38\uC790" }), _jsx(FormSegmentedControl, { control: control, trigger: trigger, name: "caseSensitive", items: [
|
|
@@ -11,12 +11,13 @@ import { AddFillIcon, AlarmWarningFillIcon, ListRadioIcon, } from "../../../../.
|
|
|
11
11
|
import { Button } from "../../../../../components/Button";
|
|
12
12
|
import { FormSelection } from "./FormSelection";
|
|
13
13
|
import { Tooltip } from "../../../../../components/Tooltip";
|
|
14
|
-
import { useState } from "react";
|
|
14
|
+
import { useState, useMemo } from "react";
|
|
15
15
|
import { uid } from "uid";
|
|
16
16
|
export function SettingForm(props) {
|
|
17
17
|
const { selections, nodeKey, onClose } = props;
|
|
18
18
|
const [editor] = useLexicalComposerContext();
|
|
19
19
|
const [tooltipOpen, setTooltipOpen] = useState(false);
|
|
20
|
+
const tooltipId = useMemo(() => `tooltip-${uid()}`, []);
|
|
20
21
|
const { control, handleSubmit, watch } = useForm({
|
|
21
22
|
mode: "all",
|
|
22
23
|
defaultValues: {
|
|
@@ -89,7 +90,7 @@ export function SettingForm(props) {
|
|
|
89
90
|
}, disabled: fields.length >= 9 }), hasMultipleAnswers && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
|
|
90
91
|
width: 14px;
|
|
91
92
|
height: 14px;
|
|
92
|
-
` }), "\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 }) }) }))] })] })));
|
|
93
|
+
` }), "\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({ tooltipId: tooltipId, 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", Object.assign({ "aria-labelledby": tooltipId }, { children: _jsx(Button, { color: "primary", size: "xsmall", label: "\uC774\uB300\uB85C \uB123\uAE30", type: "submit", disabled: !hasAnswer }) })) }))] })] })));
|
|
93
94
|
}
|
|
94
95
|
const Form = styled.form(({ theme }) => css `
|
|
95
96
|
display: flex;
|
|
@@ -8,10 +8,13 @@ import { css } from "@emotion/react";
|
|
|
8
8
|
import { InputMethodLineIcon, QuestionFillIcon } from "../../../../icons";
|
|
9
9
|
import { Button, Input, shadows, Tooltip } from "../../../..";
|
|
10
10
|
import { $isSheetInputNode } from "./SheetInputNode";
|
|
11
|
+
import { uid } from "uid";
|
|
12
|
+
import { useMemo } from "react";
|
|
11
13
|
/** 활동지 활동의 입력칸 설정 컴포넌트입니다. */
|
|
12
14
|
export function SettingForm(props) {
|
|
13
15
|
const { multiline, placeholder, nodeKey, onClose } = props;
|
|
14
16
|
const [editor] = useLexicalComposerContext();
|
|
17
|
+
const tooltipId = useMemo(() => `tooltip-${uid()}`, []);
|
|
15
18
|
const { control, handleSubmit } = useForm({
|
|
16
19
|
mode: "all",
|
|
17
20
|
defaultValues: {
|
|
@@ -31,10 +34,10 @@ export function SettingForm(props) {
|
|
|
31
34
|
return (_jsxs(Form, Object.assign({ onSubmit: handleSubmit(onSettingSubmit) }, { children: [_jsxs(Title, { children: [_jsx(InputMethodLineIcon, { css: css `
|
|
32
35
|
width: 12px;
|
|
33
36
|
height: 12px;
|
|
34
|
-
` }), multiline ? "서술형 입력 칸" : "단답형 입력 칸"] }), _jsx(Content, { children: _jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC790\uB9AC \uD45C\uC2DC\uC790", _jsx(Tooltip, Object.assign({ text: _jsx("span", { children: "\uC785\uB825 \uCE78\uC5D0 \uAE30\uBCF8\uC73C\uB85C \uB178\uCD9C\uB418\uB294 \uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4." }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
|
|
37
|
+
` }), multiline ? "서술형 입력 칸" : "단답형 입력 칸"] }), _jsx(Content, { children: _jsxs(FormArea, { children: [_jsxs(Label, { children: ["\uC790\uB9AC \uD45C\uC2DC\uC790", _jsx(Tooltip, Object.assign({ tooltipId: tooltipId, text: _jsx("span", { children: "\uC785\uB825 \uCE78\uC5D0 \uAE30\uBCF8\uC73C\uB85C \uB178\uCD9C\uB418\uB294 \uD14D\uC2A4\uD2B8\uC785\uB2C8\uB2E4." }), placement: "top" }, { children: _jsx(QuestionFillIcon, { css: css `
|
|
35
38
|
width: 12px;
|
|
36
39
|
height: 12px;
|
|
37
|
-
|
|
40
|
+
`, "aria-labelledby": tooltipId }) }))] }), _jsx(Controller, { name: "placeholder", control: control, render: ({ field: { value, onChange } }) => (_jsx(Input, { size: "small", color: "default", value: value, onChange: onChange, placeholder: "\uC608) \uC5EC\uAE30\uC5D0 \uC785\uB825\uD558\uC138\uC694." })) })] }) }), _jsxs(Buttons, { children: [_jsx(Button, { color: "grey", size: "xsmall", label: "\uB2EB\uAE30", onClick: onClose }), _jsx(Button, { color: "primary", size: "xsmall", label: "\uC774\uB300\uB85C \uB123\uAE30", bold: true, type: "submit" })] })] })));
|
|
38
41
|
}
|
|
39
42
|
const Form = styled.form(({ theme }) => css `
|
|
40
43
|
display: flex;
|
|
@@ -3,14 +3,17 @@ import styled from "@emotion/styled";
|
|
|
3
3
|
import { HOVER, RESET_BUTTON, Tooltip } from "../..";
|
|
4
4
|
import { css } from "@emotion/react";
|
|
5
5
|
import { toggleButtonGroupClasses, } from "./ToggleButtonGroup";
|
|
6
|
+
import { uid } from "uid";
|
|
7
|
+
import { useMemo } from "react";
|
|
6
8
|
/** 하나의 ToggleButton을 그립니다. */
|
|
7
9
|
export function ToggleButton(props) {
|
|
8
10
|
const { datum, placement, isActive, onClick } = props;
|
|
9
11
|
const { label, onIcon, offIcon } = datum;
|
|
12
|
+
const tooltipId = useMemo(() => `tooltip-${uid()}`, []);
|
|
10
13
|
if (isActive) {
|
|
11
14
|
return (_jsxs(Active, Object.assign({ "aria-label": `${label} 선택 해제하기`, className: toggleButtonGroupClasses.toggleButton.active, onClick: onClick }, { children: [onIcon, label] })));
|
|
12
15
|
}
|
|
13
|
-
return (_jsx(Tooltip, Object.assign({ placement: placement, text: label }, { children: _jsx(Inactive, Object.assign({ "aria-label": `${label} 선택하기`, className: toggleButtonGroupClasses.toggleButton.inactive, onClick: onClick }, { children: offIcon })) })));
|
|
16
|
+
return (_jsx(Tooltip, Object.assign({ tooltipId: tooltipId, placement: placement, text: label }, { children: _jsx(Inactive, Object.assign({ "aria-label": `${label} 선택하기`, className: toggleButtonGroupClasses.toggleButton.inactive, onClick: onClick, "aria-labelledby": tooltipId }, { children: offIcon })) })));
|
|
14
17
|
}
|
|
15
18
|
const Active = styled.button(({ theme }) => css `
|
|
16
19
|
${RESET_BUTTON};
|