@pop-ui/core 0.0.11 → 0.0.12
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/README.md +1 -1
- package/dist/assets/PretendardVariable.woff2 +0 -0
- package/dist/assets/core-O7aPPk54.css +1 -0
- package/dist/core.js +490 -463
- package/dist/core.umd.cjs +1 -1
- package/package.json +70 -79
- package/dist/components/Alert/Alert.stories.js +0 -18
- package/dist/components/Alert/index.js +0 -31
- package/dist/components/Button/Button.stories.js +0 -42
- package/dist/components/Button/index.js +0 -28
- package/dist/components/Checkbox/Checkbox.stories.js +0 -14
- package/dist/components/Checkbox/index.js +0 -23
- package/dist/components/DatePicker/DatePicker.stories.js +0 -27
- package/dist/components/DatePicker/index.js +0 -23
- package/dist/components/Dropdown/Dropdown.stories.js +0 -16
- package/dist/components/Dropdown/index.js +0 -40
- package/dist/components/ImageUploader/ImageUploader.stories.js +0 -9
- package/dist/components/ImageUploader/index.js +0 -28
- package/dist/components/Modal/Modal.stories.js +0 -13
- package/dist/components/Modal/index.js +0 -20
- package/dist/components/Pagination/Pagination.stories.js +0 -14
- package/dist/components/Pagination/index.js +0 -49
- package/dist/components/Radio/Radio.stories.js +0 -14
- package/dist/components/Radio/index.js +0 -15
- package/dist/components/SearchBar/SearchBar.stories.js +0 -16
- package/dist/components/SearchBar/index.js +0 -34
- package/dist/components/SegmentButton/SegmentButton.stories.js +0 -14
- package/dist/components/SegmentButton/index.js +0 -19
- package/dist/components/Tab/Tab.stories.js +0 -28
- package/dist/components/Tab/index.js +0 -8
- package/dist/components/Table/Table.stories.js +0 -127
- package/dist/components/Table/index.js +0 -112
- package/dist/components/TextField/TextField.stories.js +0 -36
- package/dist/components/TextField/index.js +0 -44
- package/dist/components/TimePicker/TimePicker.stories.js +0 -13
- package/dist/components/TimePicker/index.js +0 -26
- package/dist/components/Toggle/Toggle.stories.js +0 -15
- package/dist/components/Toggle/index.js +0 -34
- package/dist/components/Tooltip/Tooltip.stories.js +0 -24
- package/dist/components/Tooltip/index.js +0 -8
- package/dist/components/index.js +0 -17
- package/dist/components/shared/styles.js +0 -219
- package/dist/core.css +0 -1
- package/dist/helpers/checkMessage/checkMessage.test.js +0 -9
- package/dist/helpers/checkMessage/index.js +0 -8
- package/dist/index.js +0 -1
- package/dist/types/components/Alert/Alert.stories.d.ts +0 -3
- package/dist/types/components/Alert/index.d.ts +0 -9
- package/dist/types/components/Button/Button.stories.d.ts +0 -7
- package/dist/types/components/Button/index.d.ts +0 -8
- package/dist/types/components/Checkbox/Checkbox.stories.d.ts +0 -3
- package/dist/types/components/Checkbox/index.d.ts +0 -6
- package/dist/types/components/DatePicker/DatePicker.stories.d.ts +0 -5
- package/dist/types/components/DatePicker/index.d.ts +0 -9
- package/dist/types/components/Dropdown/Dropdown.stories.d.ts +0 -3
- package/dist/types/components/Dropdown/index.d.ts +0 -12
- package/dist/types/components/ImageUploader/ImageUploader.stories.d.ts +0 -3
- package/dist/types/components/ImageUploader/index.d.ts +0 -12
- package/dist/types/components/Modal/Modal.stories.d.ts +0 -3
- package/dist/types/components/Modal/index.d.ts +0 -7
- package/dist/types/components/Pagination/Pagination.stories.d.ts +0 -3
- package/dist/types/components/Pagination/index.d.ts +0 -10
- package/dist/types/components/Radio/Radio.stories.d.ts +0 -3
- package/dist/types/components/Radio/index.d.ts +0 -6
- package/dist/types/components/SearchBar/SearchBar.stories.d.ts +0 -3
- package/dist/types/components/SearchBar/index.d.ts +0 -14
- package/dist/types/components/SegmentButton/SegmentButton.stories.d.ts +0 -3
- package/dist/types/components/SegmentButton/index.d.ts +0 -7
- package/dist/types/components/Tab/Tab.stories.d.ts +0 -3
- package/dist/types/components/Tab/index.d.ts +0 -13
- package/dist/types/components/Table/Table.stories.d.ts +0 -5
- package/dist/types/components/Table/index.d.ts +0 -23
- package/dist/types/components/TextField/TextField.stories.d.ts +0 -5
- package/dist/types/components/TextField/index.d.ts +0 -18
- package/dist/types/components/TimePicker/TimePicker.stories.d.ts +0 -3
- package/dist/types/components/TimePicker/index.d.ts +0 -6
- package/dist/types/components/Toggle/Toggle.stories.d.ts +0 -3
- package/dist/types/components/Toggle/index.d.ts +0 -9
- package/dist/types/components/Tooltip/Tooltip.stories.d.ts +0 -3
- package/dist/types/components/Tooltip/index.d.ts +0 -7
- package/dist/types/components/index.d.ts +0 -17
- package/dist/types/components/shared/styles.d.ts +0 -86
- package/dist/types/helpers/checkMessage/checkMessage.test.d.ts +0 -1
- package/dist/types/helpers/checkMessage/index.d.ts +0 -1
- package/dist/types/index.d.ts +0 -1
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { useCallback, useState } from "react";
|
|
4
|
-
import { Dropzone, IMAGE_MIME_TYPE, } from "@mantine/dropzone";
|
|
5
|
-
import styles from "./styles.module.scss";
|
|
6
|
-
import ic_image_colored from "../../assets/icons/ic_image_colored.svg";
|
|
7
|
-
import ic_cancel_circle from "../../assets/icons/ic_cancel_circle.svg";
|
|
8
|
-
export const ImageUploader = ({ width, height, defaultMsg = "이미지 업로드", file, onDrop, showClearButton, onClear, ...props }) => {
|
|
9
|
-
const [fileData, setFileData] = useState(file);
|
|
10
|
-
const handleFileDataClear = useCallback(() => {
|
|
11
|
-
setFileData(undefined);
|
|
12
|
-
if (onClear) {
|
|
13
|
-
onClear();
|
|
14
|
-
}
|
|
15
|
-
}, [onClear]);
|
|
16
|
-
return (_jsxs("div", { className: styles.image_uploader_wrapper, children: [showClearButton && fileData ? (_jsx("div", { className: styles.file_clear_button, onClick: handleFileDataClear, children: _jsx("img", { src: ic_cancel_circle, alt: "clear_file_data" }) })) : null, _jsx(Dropzone, { ...props, maxFiles: 1, className: styles.image_uploader, accept: IMAGE_MIME_TYPE, onDrop: (e) => {
|
|
17
|
-
setFileData(e[0]);
|
|
18
|
-
if (onDrop) {
|
|
19
|
-
onDrop(e);
|
|
20
|
-
}
|
|
21
|
-
}, style: {
|
|
22
|
-
width,
|
|
23
|
-
height,
|
|
24
|
-
}, children: _jsx(_Fragment, { children: fileData ? (_jsx("img", { className: styles.preview, src: typeof fileData === "string"
|
|
25
|
-
? fileData
|
|
26
|
-
: URL.createObjectURL(fileData), alt: `파일명: ${typeof fileData === "string" ? fileData : fileData.name}`, title: `파일명: ${typeof fileData === "string" ? fileData : fileData.name}` })) : (_jsxs("div", { children: [_jsx("img", { src: ic_image_colored, alt: "ic_image_colored" }), _jsx("span", { children: defaultMsg })] })) }) })] }));
|
|
27
|
-
};
|
|
28
|
-
export default ImageUploader;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Modal } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/Modal",
|
|
5
|
-
component: Modal,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(Modal, { ...args });
|
|
8
|
-
export const defaultModal = Template.bind({});
|
|
9
|
-
defaultModal.args = {
|
|
10
|
-
children: "test",
|
|
11
|
-
opened: true,
|
|
12
|
-
centered: false,
|
|
13
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { Modal as MantineModal, } from "@mantine/core";
|
|
4
|
-
export const Modal = ({ size = "md", width, withCloseButton = false, ...props }) => {
|
|
5
|
-
let sizeNumber = 768;
|
|
6
|
-
if (size === "xs") {
|
|
7
|
-
sizeNumber = 360;
|
|
8
|
-
}
|
|
9
|
-
else if (size === "sm") {
|
|
10
|
-
sizeNumber = 544;
|
|
11
|
-
}
|
|
12
|
-
else if (size === "lg") {
|
|
13
|
-
sizeNumber = 1000;
|
|
14
|
-
}
|
|
15
|
-
else if (size === "xl") {
|
|
16
|
-
sizeNumber = 1200;
|
|
17
|
-
}
|
|
18
|
-
return (_jsx(MantineModal, { size: width || sizeNumber, withCloseButton: withCloseButton, ...props }));
|
|
19
|
-
};
|
|
20
|
-
export default Modal;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Pagination } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/Pagination",
|
|
5
|
-
component: Pagination,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(Pagination, { ...args });
|
|
8
|
-
export const defaultPagination = Template.bind({});
|
|
9
|
-
defaultPagination.args = {
|
|
10
|
-
currentPageIdx: 0,
|
|
11
|
-
rowsPerPage: 10,
|
|
12
|
-
totalLength: 50,
|
|
13
|
-
paginationSize: 5,
|
|
14
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useMemo, useState } from "react";
|
|
4
|
-
import chevron_left from "../../assets/icons/ic_chevron_left.svg";
|
|
5
|
-
import chevron_right from "../../assets/icons/ic_chevron_right.svg";
|
|
6
|
-
import style from "./style.module.scss";
|
|
7
|
-
export const Pagination = ({ currentPageIdx, rowsPerPage, totalLength, paginationSize, onPageChange, ...props }) => {
|
|
8
|
-
const [currentIdx, setCurrentIdx] = useState(currentPageIdx);
|
|
9
|
-
const [maxPageRows, setMaxPageRows] = useState(50);
|
|
10
|
-
const [totalrows, setTotalRows] = useState(1);
|
|
11
|
-
const [paginationLength, setPaginationLength] = useState(5);
|
|
12
|
-
useMemo(() => {
|
|
13
|
-
setCurrentIdx(currentPageIdx);
|
|
14
|
-
setMaxPageRows(rowsPerPage || 50);
|
|
15
|
-
setTotalRows(totalLength || 1);
|
|
16
|
-
setPaginationLength(paginationSize || 5);
|
|
17
|
-
}, [currentPageIdx, rowsPerPage, totalLength, paginationSize]);
|
|
18
|
-
const onClickPrev = () => {
|
|
19
|
-
if (onPageChange) {
|
|
20
|
-
onPageChange(currentIdx - ((currentIdx % paginationLength) + 1));
|
|
21
|
-
}
|
|
22
|
-
setCurrentIdx((prev) => prev - ((prev % paginationLength) + 1));
|
|
23
|
-
};
|
|
24
|
-
const onClickNext = () => {
|
|
25
|
-
if (onPageChange) {
|
|
26
|
-
onPageChange(currentIdx + paginationLength - (currentIdx % paginationLength));
|
|
27
|
-
}
|
|
28
|
-
setCurrentIdx((prev) => prev + paginationLength - (prev % paginationLength));
|
|
29
|
-
};
|
|
30
|
-
return (_jsxs("div", { ...props, className: style.pagination, children: [currentIdx >= paginationLength ? (_jsx("button", { className: style.arrow, onClick: onClickPrev, children: _jsx("img", { src: chevron_left, alt: "prev" }) })) : null, new Array(paginationLength).fill(0).map((_v, index) => {
|
|
31
|
-
const indexNumber = Math.floor(currentIdx / paginationLength) * paginationLength +
|
|
32
|
-
index +
|
|
33
|
-
1;
|
|
34
|
-
if (indexNumber > Math.ceil(totalrows / maxPageRows)) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
return (_jsx("button", { className: currentIdx === indexNumber - 1
|
|
38
|
-
? style.page_index_active
|
|
39
|
-
: style.page_index, onClick: () => {
|
|
40
|
-
setCurrentIdx(indexNumber - 1);
|
|
41
|
-
if (onPageChange) {
|
|
42
|
-
onPageChange(indexNumber - 1);
|
|
43
|
-
}
|
|
44
|
-
}, children: indexNumber }, `pagination_${index}`));
|
|
45
|
-
}), Math.floor(currentIdx / paginationLength) * paginationLength +
|
|
46
|
-
paginationLength <
|
|
47
|
-
Math.ceil(totalrows / maxPageRows) ? (_jsx("button", { className: style.arrow, onClick: onClickNext, children: _jsx("img", { src: chevron_right, alt: "next" }) })) : null] }));
|
|
48
|
-
};
|
|
49
|
-
export default Pagination;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Radio } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/Radio",
|
|
5
|
-
component: Radio,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(Radio, { ...args });
|
|
8
|
-
export const defaultRadio = Template.bind({});
|
|
9
|
-
defaultRadio.args = {
|
|
10
|
-
label: "radio label",
|
|
11
|
-
description: "description text",
|
|
12
|
-
size: "md",
|
|
13
|
-
disabled: false,
|
|
14
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { Radio as MantineRadio, } from "@mantine/core";
|
|
4
|
-
import styles from "./styles.module.scss";
|
|
5
|
-
export const Radio = ({ size = "md", ...props }) => {
|
|
6
|
-
let sizeStyle = styles.md_radio;
|
|
7
|
-
if (size === "sm") {
|
|
8
|
-
sizeStyle = styles.sm_radio;
|
|
9
|
-
}
|
|
10
|
-
else if (size === "lg") {
|
|
11
|
-
sizeStyle = styles.lg_radio;
|
|
12
|
-
}
|
|
13
|
-
return _jsx(MantineRadio, { className: sizeStyle, size: size, ...props });
|
|
14
|
-
};
|
|
15
|
-
export default Radio;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { SearchBar } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/SearchBar",
|
|
5
|
-
component: SearchBar,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(SearchBar, { ...args });
|
|
8
|
-
export const defaultSearchBar = Template.bind({});
|
|
9
|
-
defaultSearchBar.args = {
|
|
10
|
-
label: "label text",
|
|
11
|
-
labelPosition: "top",
|
|
12
|
-
size: "md",
|
|
13
|
-
required: false,
|
|
14
|
-
disabled: false,
|
|
15
|
-
data: ["select 1", "select 2", "select 3"],
|
|
16
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Autocomplete, Input, Tooltip } from "@mantine/core";
|
|
4
|
-
import ic_tooltip from "../../assets/icons/ic_tooltip.svg";
|
|
5
|
-
import ic_input_clear from "../../assets/icons/ic_input_clear.svg";
|
|
6
|
-
import ic_search from "../../assets/icons/ic_search.svg";
|
|
7
|
-
import styles from "./styles.module.scss";
|
|
8
|
-
import { useCallback, useState } from "react";
|
|
9
|
-
export const SearchBar = ({ label, labelPosition = "top", size = "md", required, tooltip, tooltipPosition = "top", errorMsg, description, onChange, onClear, ...props }) => {
|
|
10
|
-
const [textCount, setTextCount] = useState(0);
|
|
11
|
-
let labelStyle = styles.md_label;
|
|
12
|
-
let searchBarStyle = styles.md_textfield;
|
|
13
|
-
let tooltipStyle = styles.md_tooltip;
|
|
14
|
-
if (size === "sm") {
|
|
15
|
-
labelStyle = styles.sm_label;
|
|
16
|
-
searchBarStyle = styles.sm_textfield;
|
|
17
|
-
tooltipStyle = styles.sm_tooltip;
|
|
18
|
-
}
|
|
19
|
-
else if (size === "lg") {
|
|
20
|
-
labelStyle = styles.lg_label;
|
|
21
|
-
searchBarStyle = styles.lg_textfield;
|
|
22
|
-
tooltipStyle = styles.lg_tooltip;
|
|
23
|
-
}
|
|
24
|
-
const onChangeHandler = useCallback((value) => {
|
|
25
|
-
if (onChange) {
|
|
26
|
-
setTextCount(value?.length);
|
|
27
|
-
onChange(value);
|
|
28
|
-
}
|
|
29
|
-
}, [onChange]);
|
|
30
|
-
return (_jsxs("div", { className: labelPosition === "top"
|
|
31
|
-
? styles.top_label_textfield
|
|
32
|
-
: styles.left_label_textfield, children: [_jsxs("div", { children: [label && (_jsx(Input.Label, { required: required, className: labelStyle, children: label })), tooltip && (_jsx(Tooltip, { label: tooltip, position: tooltipPosition, children: _jsx("img", { className: tooltipStyle, src: ic_tooltip, alt: "tooltip_icon" }) }))] }), _jsxs("div", { children: [_jsx("div", { className: styles.textfield_wrapper, children: _jsx(Autocomplete, { ...props, size: size, error: errorMsg, className: searchBarStyle, onChange: onChangeHandler, icon: _jsx("img", { src: ic_search }), iconWidth: 48, rightSection: onClear && textCount > 0 ? (_jsx("div", { className: styles.clear_button, onClick: onClear, children: _jsx("img", { src: ic_input_clear }) })) : undefined }) }), description && (_jsx(Input.Description, { className: styles.input_description, children: description })), errorMsg && (_jsx(Input.Error, { className: styles.input_error_msg, children: errorMsg }))] })] }));
|
|
33
|
-
};
|
|
34
|
-
export default SearchBar;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { SegmentButton } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/SegmentButton",
|
|
5
|
-
component: SegmentButton,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => (_jsx(SegmentButton, { ...args }));
|
|
8
|
-
export const defaultSegmentButton = Template.bind({});
|
|
9
|
-
defaultSegmentButton.args = {
|
|
10
|
-
data: ["data1", "data2", "data3"],
|
|
11
|
-
size: "md",
|
|
12
|
-
radius: 6,
|
|
13
|
-
disabled: false,
|
|
14
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { SegmentedControl } from "@mantine/core";
|
|
4
|
-
import styles from "./styles.module.scss";
|
|
5
|
-
export const SegmentButton = ({ size = "md", radius = 6, ...props }) => {
|
|
6
|
-
let sizeStyle = styles.md_segment_button;
|
|
7
|
-
if (size === "sm") {
|
|
8
|
-
sizeStyle = styles.sm_segment_button;
|
|
9
|
-
}
|
|
10
|
-
else if (size === "lg") {
|
|
11
|
-
sizeStyle = styles.lg_segment_button;
|
|
12
|
-
}
|
|
13
|
-
return (_jsx(SegmentedControl, { className: sizeStyle, size: size, radius: radius, styles: {
|
|
14
|
-
control: {
|
|
15
|
-
borderWidth: "0 !important",
|
|
16
|
-
},
|
|
17
|
-
}, ...props }));
|
|
18
|
-
};
|
|
19
|
-
export default SegmentButton;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Tab } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/Tab",
|
|
5
|
-
component: Tab,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(Tab, { ...args });
|
|
8
|
-
export const defaultTab = Template.bind({});
|
|
9
|
-
defaultTab.args = {
|
|
10
|
-
tabList: [
|
|
11
|
-
{
|
|
12
|
-
title: "tab title 1",
|
|
13
|
-
value: "default tab 1",
|
|
14
|
-
body: _jsx(_Fragment, { children: "default tab body 1" }),
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
title: "tab title 2",
|
|
18
|
-
value: "default tab 2",
|
|
19
|
-
body: _jsx(_Fragment, { children: "default tab body 2" }),
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
title: "tab title 3",
|
|
23
|
-
value: "default tab 3",
|
|
24
|
-
body: _jsx(_Fragment, { children: "default tab body 3" }),
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
defaultValue: "default tab 1",
|
|
28
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Tabs } from "@mantine/core";
|
|
4
|
-
import styles from "./styles.module.scss";
|
|
5
|
-
export const Tab = ({ tabList = [], containerPaddingTop, ...props }) => {
|
|
6
|
-
return (_jsxs(Tabs, { ...props, children: [_jsx(Tabs.List, { className: styles.tab_title_list, children: tabList?.map((tab, index) => (_jsxs(Tabs.Tab, { value: tab.value, icon: tab.icon, children: [tab.title, _jsx("div", { className: styles.border_bottom })] }, `tab_${index}`))) }), tabList?.map((tab, index) => (_jsx(Tabs.Panel, { value: tab.value, pt: containerPaddingTop, children: tab.body }, `tab_panel_${index}`)))] }));
|
|
7
|
-
};
|
|
8
|
-
export default Tab;
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Table } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/Table",
|
|
5
|
-
component: Table,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(Table, { ...args });
|
|
8
|
-
export const defaultTable = Template.bind({});
|
|
9
|
-
defaultTable.args = {
|
|
10
|
-
headerList: ["전기", "불", "물", "풀"],
|
|
11
|
-
striped: true,
|
|
12
|
-
draggable: false,
|
|
13
|
-
tableData: [
|
|
14
|
-
{
|
|
15
|
-
electric: { cell: "피츄", sortTarget: "피츄" },
|
|
16
|
-
fire: { cell: "파이리", sortTarget: "파이리" },
|
|
17
|
-
water: { cell: "꼬부기", sortTarget: "꼬부기" },
|
|
18
|
-
leaf: { cell: "이상해씨", sortTarget: "이상해씨" },
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
electric: { cell: "피카츄", sortTarget: "피카츄" },
|
|
22
|
-
fire: { cell: "리자드", sortTarget: "리자드" },
|
|
23
|
-
water: { cell: "어니부기", sortTarget: "어니부기" },
|
|
24
|
-
leaf: { cell: "이상해풀", sortTarget: "이상해풀" },
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
electric: { cell: "라이츄", sortTarget: "라이츄" },
|
|
28
|
-
fire: { cell: "리자몽", sortTarget: "리자몽" },
|
|
29
|
-
water: { cell: "거북왕", sortTarget: "거북왕" },
|
|
30
|
-
leaf: { cell: "이상해꽃", sortTarget: "이상해꽃" },
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
electric: { cell: "찌리리공", sortTarget: "찌리리공" },
|
|
34
|
-
fire: { cell: "식스테일", sortTarget: "식스테일" },
|
|
35
|
-
water: { cell: "갸라도스", sortTarget: "갸라도스" },
|
|
36
|
-
leaf: { cell: "뚜벅초", sortTarget: "뚜벅초" },
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
};
|
|
40
|
-
export const sortableTable = Template.bind({});
|
|
41
|
-
sortableTable.args = {
|
|
42
|
-
headerList: ["전기", "불", "물", "풀", "순번", "선택(정렬테스트용)"],
|
|
43
|
-
striped: true,
|
|
44
|
-
sortable: true,
|
|
45
|
-
tableData: [
|
|
46
|
-
{
|
|
47
|
-
electric: { cell: "피츄", sortTarget: "피츄" },
|
|
48
|
-
fire: { cell: "파이리", sortTarget: "파이리" },
|
|
49
|
-
water: { cell: "꼬부기", sortTarget: "꼬부기" },
|
|
50
|
-
leaf: { cell: "이상해씨", sortTarget: "이상해씨" },
|
|
51
|
-
num: { cell: 1, sortTarget: 1 },
|
|
52
|
-
select: {
|
|
53
|
-
cell: _jsx("input", { type: "checkbox", readOnly: true, checked: true }),
|
|
54
|
-
sortTarget: true,
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
electric: { cell: "피카츄", sortTarget: "피카츄" },
|
|
59
|
-
fire: { cell: "리자드", sortTarget: "리자드" },
|
|
60
|
-
water: { cell: "어니부기", sortTarget: "어니부기" },
|
|
61
|
-
leaf: { cell: "이상해풀", sortTarget: "이상해풀" },
|
|
62
|
-
num: { cell: 2, sortTarget: 2 },
|
|
63
|
-
select: {
|
|
64
|
-
cell: _jsx("input", { type: "checkbox", readOnly: true, checked: false }),
|
|
65
|
-
sortTarget: false,
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
electric: { cell: "라이츄", sortTarget: "라이츄" },
|
|
70
|
-
fire: { cell: "리자몽", sortTarget: "리자몽" },
|
|
71
|
-
water: { cell: "거북왕", sortTarget: "거북왕" },
|
|
72
|
-
leaf: { cell: "이상해꽃", sortTarget: "이상해꽃" },
|
|
73
|
-
num: { cell: 3, sortTarget: 3 },
|
|
74
|
-
select: {
|
|
75
|
-
cell: _jsx("input", { type: "checkbox", readOnly: true, checked: true }),
|
|
76
|
-
sortTarget: true,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
electric: { cell: "찌리리공", sortTarget: "찌리리공" },
|
|
81
|
-
fire: { cell: "식스테일", sortTarget: "식스테일" },
|
|
82
|
-
water: { cell: "갸라도스", sortTarget: "갸라도스" },
|
|
83
|
-
leaf: { cell: "뚜벅초", sortTarget: "뚜벅초" },
|
|
84
|
-
num: { cell: 4, sortTarget: 4 },
|
|
85
|
-
select: {
|
|
86
|
-
cell: _jsx("input", { type: "checkbox", readOnly: true, checked: false }),
|
|
87
|
-
sortTarget: false,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
};
|
|
92
|
-
export const draggableTable = Template.bind({});
|
|
93
|
-
draggableTable.args = {
|
|
94
|
-
headerList: ["전기", "불", "물", "풀"],
|
|
95
|
-
striped: true,
|
|
96
|
-
sortable: false,
|
|
97
|
-
draggable: true,
|
|
98
|
-
onDragEnd: (rows) => {
|
|
99
|
-
console.log(rows);
|
|
100
|
-
},
|
|
101
|
-
tableData: [
|
|
102
|
-
{
|
|
103
|
-
electric: { cell: "피츄", sortTarget: "피츄", dndId: 0 },
|
|
104
|
-
fire: { cell: "파이리", sortTarget: "파이리" },
|
|
105
|
-
water: { cell: "꼬부기", sortTarget: "꼬부기" },
|
|
106
|
-
leaf: { cell: "이상해씨", sortTarget: "이상해씨" },
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
electric: { cell: "피카츄", sortTarget: "피카츄", dndId: 1 },
|
|
110
|
-
fire: { cell: "리자드", sortTarget: "리자드" },
|
|
111
|
-
water: { cell: "어니부기", sortTarget: "어니부기" },
|
|
112
|
-
leaf: { cell: "이상해풀", sortTarget: "이상해풀" },
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
electric: { cell: "라이츄", sortTarget: "라이츄", dndId: 2 },
|
|
116
|
-
fire: { cell: "리자몽", sortTarget: "리자몽" },
|
|
117
|
-
water: { cell: "거북왕", sortTarget: "거북왕" },
|
|
118
|
-
leaf: { cell: "이상해꽃", sortTarget: "이상해꽃" },
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
electric: { cell: "찌리리공", sortTarget: "찌리리공", dndId: 3 },
|
|
122
|
-
fire: { cell: "식스테일", sortTarget: "식스테일" },
|
|
123
|
-
water: { cell: "갸라도스", sortTarget: "갸라도스" },
|
|
124
|
-
leaf: { cell: "뚜벅초", sortTarget: "뚜벅초" },
|
|
125
|
-
},
|
|
126
|
-
],
|
|
127
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { createElement as _createElement } from "react";
|
|
3
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
-
import styles from "./styles.module.scss";
|
|
5
|
-
import { useCallback, useMemo, useState } from "react";
|
|
6
|
-
import { DragDropContext, Draggable, Droppable, } from "react-beautiful-dnd";
|
|
7
|
-
import ic_sortable from "../../assets/icons/ic_sortable.svg";
|
|
8
|
-
import ic_chevron_up from "../../assets/icons/ic_chevron_up.svg";
|
|
9
|
-
import ic_chevron_down from "../../assets/icons/ic_chevron_down.svg";
|
|
10
|
-
import ic_drag from "../../assets/icons/ic_drag.svg";
|
|
11
|
-
export const Table = ({ tableId, headerList, tableData, sortable, draggable = false, striped, onDragEnd, className, }) => {
|
|
12
|
-
const [rows, setRows] = useState();
|
|
13
|
-
const [sortedColIndex, setSortedColIndex] = useState();
|
|
14
|
-
const [sortedDirection, setSortedDirection] = useState();
|
|
15
|
-
const rowMaker = useCallback((sortedData) => {
|
|
16
|
-
const tableRows = sortedData?.map((data, index) => {
|
|
17
|
-
const dataKeys = Object.keys(data);
|
|
18
|
-
const row = (_jsx(_Fragment, { children: dataKeys.map((key, keyIndex) => (_jsx("td", { className: styles.td_cell, children: data[key].cell }, `table_${tableId || 0}_tr_${index}_col_${keyIndex}`))) }));
|
|
19
|
-
if (draggable && data[dataKeys[0]]?.dndId === undefined) {
|
|
20
|
-
console.error("draggable table을 사용할 때엔 tableData의 첫번째 필드에 고유한 dndId를 설정해주세요");
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
row: row,
|
|
24
|
-
dndId: data[dataKeys[0]]?.dndId,
|
|
25
|
-
trClassName: data[dataKeys[0]]?.trClassName,
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
setRows(tableRows);
|
|
29
|
-
}, [draggable, tableId]);
|
|
30
|
-
useMemo(() => {
|
|
31
|
-
// 테이블 데이터 변경시, sort option 삭제
|
|
32
|
-
setSortedColIndex(undefined);
|
|
33
|
-
setSortedDirection(undefined);
|
|
34
|
-
rowMaker(tableData);
|
|
35
|
-
}, [rowMaker, tableData]);
|
|
36
|
-
const sortingHandler = useCallback((colIndex) => {
|
|
37
|
-
if (tableData) {
|
|
38
|
-
const copyArr = tableData.slice(0);
|
|
39
|
-
// 정렬 기준 키
|
|
40
|
-
const sortBy = Object.keys(copyArr[0])[colIndex];
|
|
41
|
-
setSortedColIndex(colIndex);
|
|
42
|
-
let newSortedData;
|
|
43
|
-
/*
|
|
44
|
-
정렬 순서
|
|
45
|
-
1. 내림차순
|
|
46
|
-
2. 오름차순
|
|
47
|
-
3. 초기화
|
|
48
|
-
1, 2, 3을 반복
|
|
49
|
-
*/
|
|
50
|
-
if (!sortedDirection) {
|
|
51
|
-
newSortedData = copyArr?.sort((a, b) => String(b[sortBy].sortTarget || b[sortBy].cell).localeCompare(String(a[sortBy].sortTarget || a[sortBy].cell)));
|
|
52
|
-
setSortedDirection("desc");
|
|
53
|
-
}
|
|
54
|
-
else if (sortedDirection === "desc") {
|
|
55
|
-
newSortedData = copyArr?.sort((a, b) => String(a[sortBy].sortTarget || a[sortBy].cell).localeCompare(String(b[sortBy].sortTarget || b[sortBy].cell)));
|
|
56
|
-
setSortedDirection("asc");
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
newSortedData = copyArr;
|
|
60
|
-
setSortedColIndex(undefined);
|
|
61
|
-
setSortedDirection(undefined);
|
|
62
|
-
}
|
|
63
|
-
rowMaker(newSortedData);
|
|
64
|
-
}
|
|
65
|
-
}, [rowMaker, sortedDirection, tableData]);
|
|
66
|
-
const sortableArrow = useCallback((index) => {
|
|
67
|
-
if (!sortable) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
if (sortedColIndex === index) {
|
|
71
|
-
if (sortedDirection === "desc") {
|
|
72
|
-
return _jsx("img", { src: ic_chevron_down, alt: "ic_chevron_down" });
|
|
73
|
-
}
|
|
74
|
-
return _jsx("img", { src: ic_chevron_up, alt: "ic_chevron_up" });
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
return _jsx("img", { src: ic_sortable, alt: "ic_sortable" });
|
|
78
|
-
}
|
|
79
|
-
}, [sortable, sortedColIndex, sortedDirection]);
|
|
80
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
-
const reorder = useCallback((list, item, insertIdx) => {
|
|
82
|
-
const result = Array.from(list);
|
|
83
|
-
result.splice(insertIdx, 0, item);
|
|
84
|
-
return result;
|
|
85
|
-
}, []);
|
|
86
|
-
const onDragEndHandler = useCallback((result) => {
|
|
87
|
-
// 영역 밖에 drop한 경우
|
|
88
|
-
if (!result.destination) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
// rows가 존재하지 않는 경우
|
|
92
|
-
if (!rows) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
// reorder 처리를 위한 temp value 선언
|
|
96
|
-
const duplRows = rows?.slice(0);
|
|
97
|
-
const [newItem] = duplRows.splice(result.source.index, 1);
|
|
98
|
-
const items = reorder(duplRows, newItem, result.destination.index);
|
|
99
|
-
setRows(items);
|
|
100
|
-
if (onDragEnd) {
|
|
101
|
-
onDragEnd(items.map((el) => ({ dndId: el?.dndId })));
|
|
102
|
-
}
|
|
103
|
-
}, [onDragEnd, reorder, rows]);
|
|
104
|
-
return (_jsxs("table", { className: `${styles.table} ${className || ""}`, children: [_jsx("thead", { children: _jsxs("tr", { children: [draggable && (_jsx("th", { className: styles.th_cell, style: { padding: 0 } })), headerList?.map((header, index) => (_jsx("th", { className: sortable ? styles.th_cell_sortable : styles.th_cell, onClick: () => {
|
|
105
|
-
if (sortable) {
|
|
106
|
-
sortingHandler(index);
|
|
107
|
-
}
|
|
108
|
-
}, children: _jsxs("div", { children: [header, sortableArrow(index)] }) }, `table_header_col_${index}`)))] }) }), _jsx(DragDropContext, { onDragEnd: onDragEndHandler, children: _jsx(Droppable, { droppableId: `dnd_table_${tableId || 0}_drop_zone`, children: (dropProvided) => (_jsxs("tbody", { ref: dropProvided.innerRef, ...dropProvided.droppableProps, children: [rows?.map((rowData, index) => (_jsx(Draggable, { draggableId: `dnd_table_${tableId || 0}_drag_item_${rowData?.dndId}`, index: index, isDragDisabled: !draggable, children: (dragProvided) => (_createElement("tr", { ...dragProvided.dragHandleProps, ...dragProvided.draggableProps, ref: dragProvided.innerRef, key: `table_${tableId || 0}_tr_${index}`, className: `${striped && index % 2 === 1 ? styles.tr_gray : ""} ${rowData.trClassName}` },
|
|
109
|
-
draggable && (_jsx("td", { className: styles.td_cell, style: { padding: 0 }, children: _jsx("div", { children: _jsx("img", { src: ic_drag, alt: "ic_drag" }) }) })),
|
|
110
|
-
rowData?.row)) }, `dnd_table_${tableId || 0}_drag_item_${rowData?.dndId !== undefined ? rowData.dndId : index}`))), dropProvided.placeholder] })) }) })] }));
|
|
111
|
-
};
|
|
112
|
-
export default Table;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { TextField } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/TextField",
|
|
5
|
-
component: TextField,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(TextField, { ...args });
|
|
8
|
-
export const LabelTextField = Template.bind({});
|
|
9
|
-
LabelTextField.args = {
|
|
10
|
-
label: "label text",
|
|
11
|
-
labelPosition: "top",
|
|
12
|
-
size: "md",
|
|
13
|
-
required: false,
|
|
14
|
-
disabled: false,
|
|
15
|
-
};
|
|
16
|
-
export const ToolTipTextField = Template.bind({});
|
|
17
|
-
ToolTipTextField.args = {
|
|
18
|
-
label: "label text",
|
|
19
|
-
labelPosition: "top",
|
|
20
|
-
tooltip: "tootip text",
|
|
21
|
-
tooltipPosition: "top",
|
|
22
|
-
size: "md",
|
|
23
|
-
required: false,
|
|
24
|
-
disabled: false,
|
|
25
|
-
};
|
|
26
|
-
export const Textarea = Template.bind({});
|
|
27
|
-
Textarea.args = {
|
|
28
|
-
label: "label text",
|
|
29
|
-
labelPosition: "top",
|
|
30
|
-
size: "md",
|
|
31
|
-
required: false,
|
|
32
|
-
disabled: false,
|
|
33
|
-
textarea: true,
|
|
34
|
-
minRows: 4,
|
|
35
|
-
maxTextCount: 100,
|
|
36
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Input, Textarea, Tooltip } from "@mantine/core";
|
|
4
|
-
import ic_tooltip from "../../assets/icons/ic_tooltip.svg";
|
|
5
|
-
import ic_input_clear from "../../assets/icons/ic_input_clear.svg";
|
|
6
|
-
import styles from "./styles.module.scss";
|
|
7
|
-
import { useCallback, useState } from "react";
|
|
8
|
-
export const TextField = ({ label, labelPosition = "top", size = "md", required, tooltip, tooltipPosition = "top", errorMsg, description, textarea = false, minRows, maxTextCount, onChange, onClear, ...props }) => {
|
|
9
|
-
const [textCount, setTextCount] = useState(0);
|
|
10
|
-
let labelStyle = styles.md_label;
|
|
11
|
-
let textfieldStyle = styles.md_textfield;
|
|
12
|
-
let tooltipStyle = styles.md_tooltip;
|
|
13
|
-
if (size === "sm") {
|
|
14
|
-
labelStyle = styles.sm_label;
|
|
15
|
-
textfieldStyle = styles.sm_textfield;
|
|
16
|
-
tooltipStyle = styles.sm_tooltip;
|
|
17
|
-
}
|
|
18
|
-
else if (size === "lg") {
|
|
19
|
-
labelStyle = styles.lg_label;
|
|
20
|
-
textfieldStyle = styles.lg_textfield;
|
|
21
|
-
tooltipStyle = styles.lg_tooltip;
|
|
22
|
-
}
|
|
23
|
-
const onChangeHandler = useCallback(
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
|
-
(event) => {
|
|
26
|
-
if (maxTextCount) {
|
|
27
|
-
if (event.currentTarget?.value?.length > maxTextCount) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
setTextCount(event.currentTarget?.value?.length);
|
|
31
|
-
if (onChange) {
|
|
32
|
-
onChange(event);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (onChange) {
|
|
36
|
-
setTextCount(event.currentTarget?.value?.length);
|
|
37
|
-
onChange(event);
|
|
38
|
-
}
|
|
39
|
-
}, [maxTextCount, onChange]);
|
|
40
|
-
return (_jsxs("div", { className: labelPosition === "top"
|
|
41
|
-
? styles.top_label_textfield
|
|
42
|
-
: styles.left_label_textfield, children: [_jsxs("div", { children: [label && (_jsx(Input.Label, { required: required, className: labelStyle, children: label })), tooltip && (_jsx(Tooltip, { label: tooltip, position: tooltipPosition, children: _jsx("img", { className: tooltipStyle, src: ic_tooltip, alt: "tooltip_icon" }) }))] }), _jsxs("div", { children: [_jsxs("div", { className: styles.textfield_wrapper, children: [textarea ? (_jsx(Textarea, { className: styles.textarea, size: size, minRows: minRows, error: errorMsg, onChange: onChangeHandler, disabled: props?.disabled, ...props })) : (_jsx(Input, { className: textfieldStyle, error: errorMsg, onChange: onChangeHandler, rightSection: onClear && textCount > 0 ? (_jsx("div", { className: styles.clear_button, onClick: onClear, children: _jsx("img", { src: ic_input_clear }) })) : undefined, ...props })), maxTextCount && maxTextCount > 0 && (_jsx("span", { className: styles.text_counter, children: `${textCount}/${maxTextCount}` }))] }), description && (_jsx(Input.Description, { className: styles.input_description, children: description })), errorMsg && (_jsx(Input.Error, { className: styles.input_error_msg, children: errorMsg }))] })] }));
|
|
43
|
-
};
|
|
44
|
-
export default TextField;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { TimePicker } from ".";
|
|
3
|
-
export default {
|
|
4
|
-
title: "Core/TimePicker",
|
|
5
|
-
component: TimePicker,
|
|
6
|
-
};
|
|
7
|
-
const Template = (args) => _jsx(TimePicker, { ...args });
|
|
8
|
-
export const defaultTimePicker = Template.bind({});
|
|
9
|
-
defaultTimePicker.args = {
|
|
10
|
-
size: "md",
|
|
11
|
-
disabled: false,
|
|
12
|
-
defaultValue: `${new Date().getHours()}:${new Date().getMinutes()}`,
|
|
13
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useRef } from "react";
|
|
4
|
-
import { ActionIcon } from "@mantine/core";
|
|
5
|
-
import { TimeInput } from "@mantine/dates";
|
|
6
|
-
import ic_clock from "../../assets/icons/ic_clock.svg";
|
|
7
|
-
import styles from "./styles.module.scss";
|
|
8
|
-
export const TimePicker = ({ size = "md", ...props }) => {
|
|
9
|
-
const timeInputRef = useRef(null);
|
|
10
|
-
let sizeStyle = styles.md_textfield;
|
|
11
|
-
let iconSize = 18;
|
|
12
|
-
if (size === "sm") {
|
|
13
|
-
sizeStyle = styles.sm_textfield;
|
|
14
|
-
iconSize = 14;
|
|
15
|
-
}
|
|
16
|
-
else if (size === "lg") {
|
|
17
|
-
sizeStyle = styles.lg_textfield;
|
|
18
|
-
iconSize = 24;
|
|
19
|
-
}
|
|
20
|
-
return (_jsx(TimeInput, { ref: timeInputRef, className: sizeStyle, size: size, ...props, rightSection: _jsx(ActionIcon, { onClick: () => {
|
|
21
|
-
if (timeInputRef) {
|
|
22
|
-
timeInputRef?.current?.showPicker();
|
|
23
|
-
}
|
|
24
|
-
}, children: _jsx("img", { width: iconSize, src: ic_clock, alt: "clock_icon" }) }) }));
|
|
25
|
-
};
|
|
26
|
-
export default TimePicker;
|