@edu-tosel/design 1.0.261 → 1.0.265

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.
Files changed (56) hide show
  1. package/board/design/Board.design.js +12 -5
  2. package/board/design/Header.design.js +3 -7
  3. package/board/template/CanvasBoard.js +6 -3
  4. package/card/design/NavCard.design.js +3 -2
  5. package/card/design/StickCard.design.d.ts +2 -0
  6. package/card/design/StickCard.design.js +40 -0
  7. package/card/index.d.ts +1 -0
  8. package/card/index.js +1 -0
  9. package/card/template/NavCard.js +2 -1
  10. package/card/template/ProgressCard/Large.js +15 -10
  11. package/card/template/StickCard.d.ts +3 -0
  12. package/card/template/StickCard.js +6 -0
  13. package/hook/index.d.ts +1 -0
  14. package/hook/index.js +1 -0
  15. package/hook/useBussinessHours.d.ts +2 -0
  16. package/hook/useBussinessHours.js +26 -0
  17. package/interface/Board.d.ts +1 -0
  18. package/interface/Card.d.ts +7 -0
  19. package/interface/Layout.d.ts +1 -0
  20. package/interface/Shelf.d.ts +5 -5
  21. package/layout/design/Shelf.design.d.ts +1 -1
  22. package/layout/design/Shelf.design.js +5 -3
  23. package/layout/template/Contact/Contact.d.ts +13 -0
  24. package/layout/template/Contact/Contact.js +16 -0
  25. package/layout/template/Contact/ContactAgency.d.ts +7 -0
  26. package/layout/template/Contact/ContactAgency.js +162 -0
  27. package/layout/template/Contact/ContactMain.d.ts +7 -0
  28. package/layout/template/Contact/ContactMain.js +66 -0
  29. package/layout/template/Contact/Header.d.ts +3 -0
  30. package/layout/template/Contact/Header.js +37 -0
  31. package/layout/template/Contact/index.d.ts +7 -0
  32. package/layout/template/Contact/index.js +7 -0
  33. package/layout/template/Gallery.js +15 -8
  34. package/layout/template/GalleryContext.d.ts +4 -0
  35. package/layout/template/GalleryContext.js +8 -0
  36. package/layout/template/Shelf.d.ts +6 -4
  37. package/layout/template/Shelf.js +33 -5
  38. package/layout/template/Tab.js +7 -7
  39. package/layout/template/dashboard/Header.d.ts +1 -1
  40. package/layout/template/dashboard/Header.js +43 -17
  41. package/layout/template/dashboard/Layout.js +11 -6
  42. package/layout/template/dashboard/Navigation.d.ts +2 -1
  43. package/layout/template/dashboard/Navigation.js +14 -3
  44. package/layout/template/dashboard/buttonClassNames.js +2 -2
  45. package/layout/template/dashboard/style.js +2 -1
  46. package/package.json +2 -1
  47. package/tailwind.config.ts +13 -1
  48. package/util/copyToClipboard.d.ts +1 -1
  49. package/util/copyToClipboard.js +4 -3
  50. package/util/formatKoreanPhoneNumber.d.ts +1 -0
  51. package/util/formatKoreanPhoneNumber.js +23 -0
  52. package/util/formatPhoneNumberToE164.d.ts +1 -0
  53. package/util/formatPhoneNumberToE164.js +18 -0
  54. package/util/index.d.ts +2 -0
  55. package/util/index.js +2 -0
  56. package/version.txt +1 -1
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn, copyToClipboard } from "../../../util";
3
+ import Header from "./Header";
4
+ export default function ContactMain() {
5
+ const container = {
6
+ display: "relative flex flex-col justify-start items-center",
7
+ sizes: "w-full h-screen",
8
+ text: "break-keep",
9
+ cursor: "cursor-default",
10
+ };
11
+ const contentsWrapper = {
12
+ displays: "flex flex-col justify-center items-center",
13
+ sizes: "w-full max-w-[1200px] h-full min-h-fit",
14
+ spacings: "px-2 pt-20 pb-5 md:px-5",
15
+ };
16
+ const cardWrapper = {
17
+ displays: "flex flex-col md:flex-row justify-center items-center",
18
+ sizes: "w-full h-fit",
19
+ spacings: "gap-5 px-0 md:mt-0 mt-5",
20
+ };
21
+ const titleWrapper = {
22
+ displays: "flex flex-col justify-center items-center",
23
+ sizes: "w-full h-fit",
24
+ spacings: "mb-20",
25
+ };
26
+ const titleStyling = {
27
+ textStyles: "font-bold text-2xl text-gray-dark text-center",
28
+ };
29
+ const subtitleStyling = {
30
+ textStyles: "font-medium text-sm text-gray-medium text-center",
31
+ };
32
+ const button = {
33
+ display: "flex justify-center items-center shrink-0",
34
+ sizes: "h-10 w-fit rounded-lg",
35
+ spacings: "px-4",
36
+ textStyle: "text-sm font-medium text-center",
37
+ cursor: "cursor-pointer",
38
+ };
39
+ return (_jsxs("div", { className: cn(container), children: [_jsx(Header, { isHome: true }), _jsxs("div", { className: cn(contentsWrapper), children: [_jsx("div", { className: "w-40", children: _jsx("img", { src: "https://resource.tosel.co.kr/images/homepage/img-contact-main-small.png", alt: "" }) }), _jsxs("div", { className: cn(titleWrapper), children: [_jsx("div", { className: cn(titleStyling), children: "\uBB34\uC2A8 \uBB38\uC81C\uAC00 \uC788\uB098\uC694?" }), _jsx("div", { className: cn(subtitleStyling), children: "\uB2E4\uC74C\uACFC \uAC19\uC740 \uBC29\uBC95\uC73C\uB85C \uD574\uACB0\uD574\uBCF4\uC138\uC694" })] }), _jsxs("div", { className: cn(cardWrapper), children: [_jsx(HelpCard, { title: "\uC9C0\uC5ED\uBCF8\uBD80 \uC5F0\uB77D\uCC98", subtitle: "\uC9C0\uC5ED\uBCF8\uBD80\uC5D0 \uC9C1\uC811 \uC5F0\uB77D\uD558\uACE0 \uC2F6\uB2E4\uBA74?", children: _jsxs("div", { className: "flex flex-col justify-center items-center w-full bg-white/80 rounded-lg h-fit min-h-30 mt-5 gap-5 py-5", children: [_jsx("div", { className: "w-full h-fit flex justify-center items-center text-green-dark", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", className: "size-10", children: _jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 3.75h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Z" }) }) }), _jsx("div", { className: cn(button, "bg-green-dark text-white hover:shadow-green hover:scale-103 duration-300"), onClick: () => {
40
+ window.location.href = "/contact/agencies";
41
+ }, children: "\uC9C0\uC5ED\uBCF8\uBD80 \uCC3E\uAE30" })] }) }), _jsx(HelpCard, { title: "\uC790\uC8FC \uBB3B\uB294 \uC9C8\uBB38", subtitle: "\uC790\uC8FC\uBB3B\uB294 \uC9C8\uBB38\uC744 \uBAA8\uC544\uBD24\uC5B4\uC694", children: _jsxs("div", { className: "flex flex-col justify-center items-center w-full bg-white/80 rounded-lg h-fit min-h-30 mt-10 gap-5 py-5", children: [_jsx("div", { className: "w-full h-fit flex justify-center items-center text-green-dark", children: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", "stroke-width": "1.5", stroke: "currentColor", className: "size-10", children: _jsx("path", { "stroke-linecap": "round", "stroke-linejoin": "round", d: "M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z" }) }) }), _jsx("div", { className: cn(button, "bg-green-dark text-white hover:shadow-green hover:scale-103 duration-300"), onClick: () => {
42
+ window.location.href = "https://tosel-faq.notion.site/";
43
+ }, children: "\uB3C4\uC6C0\uB9D0 \uBC14\uB85C\uAC00\uAE30" })] }) }), _jsx(HelpCard, { title: "\uC9C1\uC811 \uBB38\uC758\uD558\uAE30", subtitle: "\uC774\uBA54\uC77C\uC744 \uD1B5\uD574 \uBCF8\uC0AC\uB85C \uBB38\uC758\uD560 \uC218 \uC788\uC5B4\uC694.", children: _jsxs("div", { className: "w-full h-full flex flex-col sm:flex-row md:flex-col justify-center items-center gap-5", children: [_jsxs("div", { className: "relative w-full flex flex-col bg-white/80 rounded-lg py-2 gap-2 overflow-hidden", onClick: () => copyToClipboard("cs_tosel@tosel.co.kr", "개인 CS 이메일 주소가 복사되었습니다."), children: [_jsx("div", { className: "leading-none w-full text-center mt-2 font-bold text-green-dark", children: "\uAC1C\uC778" }), _jsx("div", { className: "leading-none w-full text-center mt-2 font-medium text-gray-medium", children: "tosel_cs@tosel.co.kr" }), _jsx("div", { className: "absolute flex justify-center items-center top-0 left-0 w-full h-full hover:bg-white/50 hover:backdrop-blur-sm duration-300 group", children: _jsx("div", { className: cn(button, "bg-green-dark text-green-light opacity-0 group-hover:opacity-100 duration-300"), children: "\uC8FC\uC18C\uBCF5\uC0AC" }) })] }), _jsxs("div", { className: "relative w-full flex flex-col bg-white/80 rounded-lg py-2 gap-2 overflow-hidden", onClick: () => copyToClipboard("cs_academy@tosel.co.kr", "단체 CS 이메일 주소가 복사되었습니다."), children: [_jsx("div", { className: "leading-none w-full text-center mt-2 font-bold text-green-dark", children: "\uB2E8\uCCB4" }), _jsx("div", { className: "leading-none w-full text-center mt-2 font-medium text-gray-medium text-sm", children: "tosel_academy@tosel.co.kr" }), _jsx("div", { className: "absolute flex justify-center items-center top-0 left-0 w-full h-full hover:bg-white/50 hover:backdrop-blur-sm duration-300 group", children: _jsx("div", { className: cn(button, "bg-green-dark text-green-light opacity-0 group-hover:opacity-100 duration-300"), children: "\uC8FC\uC18C\uBCF5\uC0AC" }) })] })] }) })] })] })] }));
44
+ }
45
+ export function HelpCard({ title, subtitle, children, }) {
46
+ const card = {
47
+ display: "flex flex-col justify-center items-center",
48
+ sizes: "w-full md:w-60 h-90 md:rounded-lg rounded-xl",
49
+ backgrounds: "bg-gray-light/50",
50
+ hoverAction: "hover:shadow-green duration-300 hover:scale-101",
51
+ spacings: "p-5",
52
+ };
53
+ const titleBox = {
54
+ display: "flex justify-center items-center",
55
+ sizes: "w-full h-fit shrink-0",
56
+ spacings: "px-5 py-2",
57
+ textStyle: "font-bold text-gray-medium text-base md:text-lg text-center",
58
+ };
59
+ const subTitleBox = {
60
+ display: "flex justify-center items-center",
61
+ sizes: "w-full h-fit shrink-0",
62
+ spacings: "px-5 py-2",
63
+ textStyle: "font-medium text-gray-medium text-xs md:text-sm text-center",
64
+ };
65
+ return (_jsxs("div", { className: cn(card), children: [_jsx("div", { className: cn(titleBox), children: title }), _jsx("div", { className: cn(subTitleBox), children: subtitle }), _jsx("div", { className: "h-full w-full", children: children })] }));
66
+ }
@@ -0,0 +1,3 @@
1
+ export default function Header({ isHome }: {
2
+ isHome?: boolean;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useResponsive } from "../../../hook";
3
+ import { cn, copyToClipboard } from "../../../util";
4
+ export default function Header({ isHome }) {
5
+ const isXS = useResponsive("xs");
6
+ const isXXS = useResponsive("xxs");
7
+ const container = {
8
+ display: "fixed flex flex-col justify-center items-center",
9
+ sizes: "w-full h-fit",
10
+ backgrounds: "bg-white/10 backdrop-blur-sm",
11
+ cursor: "cursor-default",
12
+ positions: "top-0 left-0 z-40",
13
+ };
14
+ const headWrapper = {
15
+ display: "flex justify-between items-center",
16
+ sizes: "w-full h-15 max-w-[1200px]",
17
+ spacings: "px-5",
18
+ };
19
+ const button = {
20
+ display: "flex justify-center items-center shrink-0",
21
+ sizes: "h-10 w-fit rounded-lg",
22
+ spacings: "px-4",
23
+ textStyle: "text-sm font-medium text-center",
24
+ cursor: "cursor-pointer",
25
+ };
26
+ const leftWrapper = {
27
+ display: "flex gap-2 justify-center items-center",
28
+ };
29
+ const rightWrapper = {
30
+ display: "flex gap-2",
31
+ };
32
+ return (_jsx("div", { className: cn(container), children: _jsxs("div", { className: cn(headWrapper), children: [_jsxs("div", { className: cn(leftWrapper), children: [_jsx("div", { className: "h-fit w-fit", children: _jsx("img", { src: "https://tosel.gcdn.ntruss.com/images/img-favicon-main.png", alt: "", className: "size-8" }) }), _jsx("div", { className: "font-medium text-lg", children: "\uACE0\uAC1D\uC13C\uD130" })] }), _jsxs("div", { className: cn(rightWrapper), children: [isXXS && (_jsx("div", { className: cn(button, "hover:bg-gray-light text-gray-medium duration-300"), onClick: () => copyToClipboard("cs_tosel@tosel.co.kr", "이메일 주소가 복사되었습니다."), children: "cs_tosel@tosel.co.kr" })), _jsx("div", { className: cn(button, "bg-gray-light text-gray-medium hover:bg-green-light hover:text-green-dark "), onClick: () => {
33
+ window.location.href = isHome
34
+ ? "https://new.tosel.org"
35
+ : "../contact";
36
+ }, children: isHome ? "홈페이지로" : "CS 홈으로" })] })] }) }));
37
+ }
@@ -0,0 +1,7 @@
1
+ import Main from "./ContactMain";
2
+ import Agencies from "./ContactAgency";
3
+ declare const Contact: {
4
+ Main: typeof Main;
5
+ Agencies: typeof Agencies;
6
+ };
7
+ export default Contact;
@@ -0,0 +1,7 @@
1
+ import Main from "./ContactMain";
2
+ import Agencies from "./ContactAgency";
3
+ const Contact = {
4
+ Main,
5
+ Agencies,
6
+ };
7
+ export default Contact;
@@ -1,16 +1,23 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { GalleryProvider } from "./GalleryContext";
2
3
  import Action from "./Action";
3
4
  import Tab from "./Tab";
4
5
  import { cn } from "../../util";
5
6
  export default function Gallery({ action, children, option, }) {
6
7
  const { text, background, boundary } = option ?? {};
7
- const tabBox = {
8
- positions: "xl:absolute xl:-bottom-18 xl:left-0 z-5",
8
+ const tabBox = {};
9
+ const container = {
10
+ displays: "relative flex flex-col-reverse xl:flex-col",
11
+ position: "top-0 justify-end xl:justify-start",
12
+ sizes: "w-full",
13
+ heightOption: action?.tabs
14
+ ? "h-[calc(100%-56px)] xl:h-[calc(100%-76px)]"
15
+ : "h-[calc(100%-76px)]",
9
16
  };
10
- return (_jsxs("div", { className: "relative w-full flex", children: [_jsx(Action.Replace, { actions: action?.replaces, children: _jsx(Action.Show, { actions: action?.shows, children: children }) }), action?.tabs && (_jsx(Tab, { tabs: action?.tabs, option: {
11
- className: cn(tabBox),
12
- text,
13
- background,
14
- boundary,
15
- } }))] }));
17
+ return (_jsx(GalleryProvider, { children: _jsxs("div", { className: cn(container), children: [_jsx(Action.Replace, { actions: action?.replaces, children: _jsx(Action.Show, { actions: action?.shows, children: children }) }), action?.tabs && (_jsx(Tab, { tabs: action?.tabs, option: {
18
+ className: cn(tabBox),
19
+ text,
20
+ background,
21
+ boundary,
22
+ } }))] }) }));
16
23
  }
@@ -0,0 +1,4 @@
1
+ export declare const useGalleryContext: () => boolean;
2
+ export declare const GalleryProvider: ({ children, }: {
3
+ children: React.ReactNode;
4
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ const GalleryContext = createContext(null);
4
+ export const useGalleryContext = () => {
5
+ const context = useContext(GalleryContext);
6
+ return context ?? false; // 기본값으로 false 반환
7
+ };
8
+ export const GalleryProvider = ({ children, }) => (_jsx(GalleryContext.Provider, { value: true, children: children }));
@@ -1,8 +1,10 @@
1
1
  import { ShelfProps } from "../../interface/Shelf";
2
- declare function Shelf({ titles, debug, children }: ShelfProps<string | number>): import("react/jsx-runtime").JSX.Element;
2
+ declare function Shelf({ titles, debug, children }: ShelfProps): import("react/jsx-runtime").JSX.Element;
3
3
  declare namespace Shelf {
4
- var Wrap: ({ className, titles, children, debug, option, }: ShelfProps<string | number>) => import("react/jsx-runtime").JSX.Element;
5
- var Row: ({ titles, children, className, debug, }: ShelfProps<string | number>) => import("react/jsx-runtime").JSX.Element;
6
- var Col: ({ titles, children, debug, className, }: ShelfProps<string | number>) => import("react/jsx-runtime").JSX.Element;
4
+ var Wrap: ({ className, titles, children, debug, option }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
5
+ var Row: ({ titles, children, className, debug }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
6
+ var Col: ({ titles, children, debug, className }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
7
+ var Fourthird: ({ titles, children, debug, className }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
8
+ var Quarter: ({ titles, children, debug, className }: ShelfProps) => import("react/jsx-runtime").JSX.Element;
7
9
  }
8
10
  export default Shelf;
@@ -15,18 +15,20 @@ function Shelf({ titles, debug, children }) {
15
15
  titleSize: "text-lg xl:text-2xl",
16
16
  }, children: children }));
17
17
  }
18
- function Wrap({ className, titles, children, debug, option, }) {
18
+ function Wrap({ className, titles, children, debug, option }) {
19
19
  const container = {
20
- displays: "flex flex-col lg:flex-row flex-wrap",
20
+ displays: "flex flex-wrap",
21
21
  gaps: gap[option?.gap ?? "xy"],
22
22
  className,
23
23
  };
24
24
  return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
25
25
  titleSize: "text-lg xl:text-2xl",
26
26
  subtitleSize: "text-sm",
27
+ width: "w-full",
28
+ isSize: true,
27
29
  }, debug: debug, children: children }));
28
30
  }
29
- function Row({ titles, children, className, debug, }) {
31
+ function Row({ titles, children, className, debug }) {
30
32
  const container = {
31
33
  displays: "flex flex-col lg:flex-row",
32
34
  className: className ?? "gap-x-7.5",
@@ -35,19 +37,45 @@ function Row({ titles, children, className, debug, }) {
35
37
  titleSize: "text-lg xl:text-2xl",
36
38
  subtitleSize: "text-sm",
37
39
  isSize: true,
40
+ width: "w-full",
41
+ }, debug: debug, children: children }));
42
+ }
43
+ function Col({ titles, children, debug, className }) {
44
+ const container = {
45
+ displays: "flex flex-col w-full lg:flex-wrap",
46
+ className: className ?? "gap-y-7.5",
47
+ };
48
+ return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
49
+ titleSize: "text-lg xl:text-2xl",
50
+ subtitleSize: "text-sm",
51
+ }, debug: debug, children: children }));
52
+ }
53
+ function Fourthird({ titles, children, debug, className }) {
54
+ const container = {
55
+ displays: "flex flex-col",
56
+ className: className ?? "gap-y-7.5",
57
+ };
58
+ return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
59
+ titleSize: "text-lg xl:text-2xl",
60
+ subtitleSize: "text-sm",
61
+ width: "basis-[990px] flex-grow w-full",
62
+ height: "h-fit",
38
63
  }, debug: debug, children: children }));
39
64
  }
40
- function Col({ titles, children, debug, className, }) {
65
+ function Quarter({ titles, children, debug, className }) {
41
66
  const container = {
42
- displays: "flex flex-col lg:flex-wrap",
67
+ displays: "flex flex-col",
43
68
  className: className ?? "gap-y-7.5",
44
69
  };
45
70
  return (_jsx(ShelfDesign, { titles: titles, className: cn(container), option: {
46
71
  titleSize: "text-lg xl:text-2xl",
47
72
  subtitleSize: "text-sm",
73
+ width: "flex-grow basis-[450px] max-w-full min-w-[450px]",
48
74
  }, debug: debug, children: children }));
49
75
  }
50
76
  Shelf.Wrap = Wrap;
51
77
  Shelf.Row = Row;
52
78
  Shelf.Col = Col;
79
+ Shelf.Fourthird = Fourthird;
80
+ Shelf.Quarter = Quarter;
53
81
  export default Shelf;
@@ -15,15 +15,15 @@ export default function Tab({ tabs, option, state, }) {
15
15
  ? state
16
16
  : useState(tabs.map((_, i) => i === 0));
17
17
  const container = {
18
- className,
19
- positions: "absolute",
20
- displays: "hidden sm:flex xl:items-center xl:gap-2.5",
21
- sizes: "w-auto ",
22
- paddings: "p-2.5",
23
- backgrounds: boundary ?? "bg-gray-light",
24
- styles: "rounded-xl ",
18
+ displays: "flex shrink-0",
19
+ sizes: "w-full xl:w-fit h-fit",
20
+ spacings: "xl:mt-2.5 p-2.5 gap-2.5",
21
+ backgrounds: boundary ?? "bg-white/50 xl:bg-white/30",
22
+ styles: "rounded-0 xl:rounded-xl",
23
+ scrollStyling: "overflow-y-scroll scrollbar-hidden",
25
24
  };
26
25
  const button = {
26
+ displays: "flex shrink-0 justify-center items-center",
27
27
  styles: "rounded-md duration-500 ",
28
28
  sizes: `${heightSize[height ?? "lg"]} ${widthSize[width ?? "lg"]}`,
29
29
  font: text ?? "text-green-dark",
@@ -1,2 +1,2 @@
1
1
  import { DashboardHeaderProps } from "../../../interface";
2
- export declare function Header({ title, logo, notification, menu, option, }: DashboardHeaderProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function Header({ title, logo, notification, menu, option, isOpen, }: DashboardHeaderProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { cn, gradient } from "../../../util";
3
3
  import { useActionStore } from "../../../store";
4
4
  import Menu from "./Menu";
@@ -6,29 +6,55 @@ import { Action } from "../..";
6
6
  import Notification from "./Notification";
7
7
  import SVG from "../../../asset/SVG";
8
8
  import { Label } from "../../../widget";
9
- export function Header({ title, logo, notification, menu, option, }) {
9
+ import { useState } from "react";
10
+ import { useResponsive } from "../../../hook";
11
+ export function Header({ title, logo, notification, menu, option, isOpen, }) {
10
12
  const { setView, setIsOwn } = useActionStore();
11
13
  const { notifications, flag, onClick } = notification;
12
14
  const { text, background, className, iconColor } = option ?? {};
15
+ const [isExpanded, setIsExpanded] = useState(false);
16
+ const toggleMenu = () => {
17
+ setIsExpanded(!isExpanded);
18
+ setView("dashboardMenu");
19
+ };
20
+ const isSM = useResponsive("sm");
13
21
  const container = {
14
- positions: "fixed xl:static top-0 left-0 z-40",
15
- displays: "flex items-center justify-between ",
22
+ positions: "fixed top-0 left-0 z-45",
23
+ displays: "flex items-center justify-between gap-0 xl:gap-7.5",
16
24
  sizes: "h-15 w-full",
17
25
  background: `${background ?? "bg-white"}`,
18
26
  text: `${text ?? "text-black"} `,
19
- styles: "px-5 xl:px-8 2xl:px-16 box-shadow",
27
+ styles: "px-5 xl:px-8 2xl:px-16 shadow-main",
20
28
  className,
21
29
  };
22
- return (_jsxs("div", { className: cn(container), children: [_jsxs("div", { className: "flex h-12 items-center gap-8 xl:gap-24 2xl:gap-26", children: [logo ? _jsx(_Fragment, { children: logo }) : _jsx("div", { className: "text-2xl", children: "TOSEL" }), _jsx("div", { className: "hidden lg:flex text-3xl font-pretendard-bold", children: title })] }), _jsx("div", { className: "relative flex gap-5.25", children: _jsx(Action.Show, { actions: [
23
- ["notification", _jsx(Notification, { notifications: notifications })],
24
- [menu ? "menu" : false, menu && _jsx(Menu, { ...menu })],
25
- ], children: menu?.profile ? (_jsx(SVG.Profile, { onClick: () => {
26
- setIsOwn(true);
27
- return setView("menu");
28
- }, color: iconColor })) : (_jsx(Label.Button, { title: "\uB85C\uADF8\uC778", onClick: () => option?.onClick && option.onClick(), option: {
29
- width: "sm",
30
- height: "xs",
31
- background: gradient.bg.greenToRed,
32
- text: "text-white",
33
- } })) }) })] }));
30
+ const leftHeaderWrapper = {
31
+ displays: "flex flex-row justify-start items-center",
32
+ sizes: "w-[184px] h-fit shrink-0",
33
+ spacings: "gap-3",
34
+ };
35
+ const menuButton = {
36
+ displays: "flex mmd:hidden justify-center items-center",
37
+ spacings: "p-2",
38
+ };
39
+ const rightHeaderWrapper = {
40
+ displays: "flex flex-row justify-end sm:justify-between items-center",
41
+ sizes: "h-fit w-full",
42
+ };
43
+ const titleStyling = {
44
+ displays: "flex",
45
+ font: "font-pretendard-var font-bold text-2xl leading-none",
46
+ spacings: "pl-5",
47
+ };
48
+ return (_jsxs("div", { className: cn(container), children: [_jsxs("div", { className: cn(leftHeaderWrapper), children: [_jsx("div", { className: cn(menuButton), onClick: () => toggleMenu(), children: _jsx("div", { className: "w-6 h-6", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: [!isOpen && (_jsx("path", { id: "menu", fill: "currentColor", d: "M4.118 6.2h16a1.2 1.2 0 100-2.4h-16a1.2 1.2 0 100 2.4m16 4.6h-16a1.2 1.2 0 100 2.4h16a1.2 1.2 0 100-2.4m0 7h-16a1.2 1.2 0 100 2.4h16a1.2 1.2 0 100-2.4", "fill-rule": "evenodd" })), isOpen && (_jsx("path", { id: "close", fill: "currentColor", "fill-rule": "evenodd", d: "M13.815 12l5.651-5.651a1.2 1.2 0 00-1.697-1.698l-5.651 5.652-5.652-5.652a1.201 1.201 0 00-1.697 1.698L10.421 12l-5.652 5.651a1.202 1.202 0 00.849 2.049c.307 0 .614-.117.848-.351l5.652-5.652 5.651 5.652a1.198 1.198 0 001.697 0 1.2 1.2 0 000-1.698L13.815 12z" }))] }) }) }), logo ? _jsx(_Fragment, { children: logo }) : _jsx("div", { className: "text-2xl", children: "TOSEL" })] }), _jsxs("div", { className: cn(rightHeaderWrapper), children: [isSM && _jsx("div", { className: cn(titleStyling), children: title }), _jsx("div", { className: "relative flex gap-5.25", children: _jsx(Action.Show, { actions: [
49
+ ["notification", _jsx(Notification, { notifications: notifications })],
50
+ [menu ? "menu" : false, menu && _jsx(Menu, { ...menu })],
51
+ ], children: menu?.profile ? (_jsx(SVG.Profile, { onClick: () => {
52
+ setIsOwn(true);
53
+ return setView("menu");
54
+ }, color: iconColor })) : (_jsx(Label.Button, { title: "\uB85C\uADF8\uC778", onClick: () => option?.onClick && option.onClick(), option: {
55
+ width: "sm",
56
+ height: "xs",
57
+ background: gradient.bg.greenToRed,
58
+ text: "text-white",
59
+ } })) }) })] })] }));
34
60
  }
@@ -5,23 +5,28 @@ import { cn } from "../../../util";
5
5
  import { useActionStore } from "../../../store";
6
6
  import Navigation from "./Navigation";
7
7
  export default function Layout({ header, navigations, children, option, }) {
8
- const { isDark, flag, setFlag, isOwn, setIsOwn, clearView } = useActionStore();
8
+ const { events, flag, setFlag, isOwn, setIsOwn, clearView } = useActionStore();
9
9
  const { title, option: headerOption, logo, notification, menu } = header;
10
10
  const { background } = option ?? {};
11
+ const isOpen = events.some((event) => event.event === "dashboardMenu");
11
12
  useEffect(() => {
12
13
  if (isOwn)
13
14
  return setIsOwn(false);
14
15
  return clearView();
15
16
  }, [flag]);
16
17
  const container = {
17
- sizes: "min-h-screen h-screen xl:h-auto",
18
+ sizes: "h-screen",
18
19
  background: `${background ?? "bg-gray-light"} `,
19
20
  styles: "font-pretendard-medium",
20
21
  };
22
+ const spacer = {
23
+ displays: "flex shrink-0",
24
+ sizes: "w-full h-15 xl:h-22.5",
25
+ };
21
26
  const body = {
22
- sizes: "h-full ",
23
- displays: "flex gap-12 xl:gap-7.5 ",
24
- paddings: "pt-15 xl:pl-2 2xl:pl-12 2xl:pr-11.25 xl:pt-7.5",
27
+ sizes: "h-[calc(100%-60px)] xl:h-[calc(100%-90px)]",
28
+ displays: "flex gap-0 xl:gap-7.5 relative",
29
+ paddings: "xl:px-5 2xl:pl-12 2xl:pr-11.25",
25
30
  };
26
- return (_jsxs("div", { className: cn(container), onClick: setFlag, children: [_jsx(Header, { title: title, notification: notification, menu: menu, option: headerOption, logo: logo }), _jsxs("div", { className: cn(body), children: [_jsx(Navigation.Container, { children: navigations.map((nav, index) => (_jsx(Fragment, { children: nav }, index))) }), children] })] }));
31
+ return (_jsxs("div", { className: cn(container), onClick: setFlag, children: [_jsx(Header, { title: title, notification: notification, menu: menu, option: headerOption, isOpen: isOpen, logo: logo }), _jsx("div", { className: cn(spacer) }), _jsxs("div", { className: cn(body), children: [_jsx(Navigation.Container, { children: navigations.map((nav, index) => (_jsx(Fragment, { children: nav }, index))) }), children] })] }));
27
32
  }
@@ -1,5 +1,6 @@
1
+ import { ReactNode } from "react";
1
2
  declare function Container({ children }: {
2
- children: React.ReactNode;
3
+ children: ReactNode;
3
4
  }): import("react/jsx-runtime").JSX.Element;
4
5
  declare const Navigation: {
5
6
  Container: typeof Container;
@@ -1,10 +1,21 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../../../util";
3
+ import Action from "../Action";
4
+ import { useResponsive } from "../../../hook";
3
5
  function Container({ children }) {
6
+ const isMmd = useResponsive("mmd");
7
+ return (_jsx(Action.Show, { actions: [[isMmd || "dashboardMenu", _jsx(Contents, { children: children })]], children: null }));
8
+ }
9
+ function Contents({ children, showAction, }) {
4
10
  const container = {
5
- positions: "fixed xl:static bottom-0 left-0 z-40",
6
- displays: "flex flex-row xl:flex-col",
7
- sizes: "w-full xl:w-auto",
11
+ positions: "absolute mmd:relative top-0 left-0 shrink-0 mmd:flex ",
12
+ displays: "flex-col",
13
+ spacings: "z-40",
14
+ sizes: showAction?.isVisible
15
+ ? "w-[204px] h-full"
16
+ : "w-0 overflow-hidden h-full",
17
+ animations: "duration-300",
18
+ colors: "bg-white/50 mmd:bg-white/0 backdrop-blur shadow-main mmd:shadow-none",
8
19
  };
9
20
  return (_jsxs("div", { className: cn(container), children: [children, _jsx(Copyright, {})] }));
10
21
  }
@@ -5,8 +5,8 @@ const buttonClassNames = (href, nowPath, color) => {
5
5
  const { isDark } = useActionStore();
6
6
  const [bg, [text, selectedText]] = color ?? ["white", ["white", "black"]];
7
7
  const container = {
8
- displays: "flex flex-row items-center justify-center xl:justify-start gap-2.5",
9
- sizes: " w-full xl:w-51 h-11 ",
8
+ displays: "flex flex-row items-center justify-start gap-2.5",
9
+ sizes: " w-full xl:w-51 h-11",
10
10
  styles: "xl:rounded-lg xl:pl-5 font-pretendard-bold",
11
11
  };
12
12
  const toggle = checkPathMatch(href, nowPath)
@@ -1,8 +1,9 @@
1
1
  import { checkPathMatch, cn } from "../../../util";
2
2
  const navigatorStyle = ({ href, nowPath, background = "bg-white", text = "text-white", }) => {
3
3
  const style = {
4
- displays: "flex flex-row items-center justify-center xl:justify-start gap-2.5",
4
+ displays: "flex flex-row items-center justify-start gap-2.5",
5
5
  sizes: " w-full xl:w-51 h-11 ",
6
+ spacings: "pl-5 xl:p-0",
6
7
  styles: "xl:rounded-lg xl:pl-5 font-pretendard-bold",
7
8
  texts: checkPathMatch(href, nowPath)
8
9
  ? [background, text].join(" ")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edu-tosel/design",
3
- "version": "1.0.261",
3
+ "version": "1.0.265",
4
4
  "description": "UI components for International TOSEL Committee",
5
5
  "keywords": [
6
6
  "jsx",
@@ -19,6 +19,7 @@
19
19
  "date-fns": "^2.30.0",
20
20
  "date-fns-tz": "^2.0.1",
21
21
  "dayjs": "^1.11.12",
22
+ "es-hangul": "^2.2.4",
22
23
  "gsap": "^3.12.5",
23
24
  "moment-timezone": "^0.5.45",
24
25
  "react": "^18.2.0",
@@ -75,7 +75,6 @@ export default {
75
75
  to: { width: "0%" },
76
76
  },
77
77
  },
78
-
79
78
  animation: {
80
79
  grow: "grow 0.2s ease-in-out forwards",
81
80
  shrink: "shrink 0.2s ease-in-out forwards",
@@ -431,6 +430,7 @@ export default {
431
430
  },
432
431
  scale: {
433
432
  101: "1.01",
433
+ 103: "1.03",
434
434
  110: "1.1",
435
435
  120: "1.2",
436
436
  200: "2",
@@ -681,6 +681,18 @@ export default {
681
681
  "-ms-overflow-style": "none", // For Internet Explorer and Edge
682
682
  "scrollbar-width": "none", // For Firefox
683
683
  },
684
+ ".scrollbar-custom": {
685
+ /* Fully custom scrollbar style */
686
+ "&::-webkit-scrollbar": {
687
+ width: "8px",
688
+ },
689
+
690
+ "&::-webkit-scrollbar-thumb": {
691
+ backgroundColor: "#BABABA",
692
+ borderRadius: "10px",
693
+ margin: "4px",
694
+ },
695
+ },
684
696
  ".page-break": {
685
697
  "@media print": {
686
698
  "page-break-before": "always",
@@ -1 +1 @@
1
- export default function copyToClipboard(value: string | undefined): void;
1
+ export default function copyToClipboard(value: string | undefined, customMessage?: string): void;
@@ -1,16 +1,17 @@
1
- export default function copyToClipboard(value) {
1
+ export default function copyToClipboard(value, customMessage) {
2
2
  const textToCopy = value ?? "";
3
3
  if (textToCopy) {
4
4
  navigator.clipboard
5
5
  .writeText(textToCopy)
6
6
  .then(() => {
7
- alert(`클립보드에 복사되었습니다.`); // 복사된 값을 alert로 출력
7
+ const message = customMessage ?? `클립보드에 복사되었습니다: ${textToCopy}`;
8
+ alert(message); // 복사 성공 메시지 출력
8
9
  })
9
10
  .catch((err) => {
10
11
  console.error("복사에 실패했습니다:", err);
11
12
  });
12
13
  }
13
14
  else {
14
- alert("서비스 준비 중입니다."); // 값이 없을 경우 alert로 알림
15
+ alert("서비스 준비 중입니다."); // 값이 없을 경우 기본 메시지 출력
15
16
  }
16
17
  }
@@ -0,0 +1 @@
1
+ export default function formatKoreanPhoneNumber(phoneNumber: string): string;
@@ -0,0 +1,23 @@
1
+ export default function formatKoreanPhoneNumber(phoneNumber) {
2
+ const cleanedNumber = phoneNumber.replace(/[^\d]/g, "");
3
+ if (/^02\d{7,8}$/.test(cleanedNumber)) {
4
+ return cleanedNumber.length === 9
5
+ ? `${cleanedNumber.slice(0, 2)}-${cleanedNumber.slice(2, 5)}-${cleanedNumber.slice(5)}`
6
+ : `${cleanedNumber.slice(0, 2)}-${cleanedNumber.slice(2, 6)}-${cleanedNumber.slice(6)}`;
7
+ }
8
+ else if (/^0[3-9]\d{8}$/.test(cleanedNumber)) {
9
+ return `${cleanedNumber.slice(0, 3)}-${cleanedNumber.slice(3, 7)}-${cleanedNumber.slice(7)}`;
10
+ }
11
+ else if (/^010\d{8}$/.test(cleanedNumber)) {
12
+ return `${cleanedNumber.slice(0, 3)}-${cleanedNumber.slice(3, 7)}-${cleanedNumber.slice(7)}`;
13
+ }
14
+ else if (/^1\d{4,9}$/.test(cleanedNumber)) {
15
+ return `${cleanedNumber.slice(0, 4)}-${cleanedNumber.slice(4)}`;
16
+ }
17
+ return phoneNumber;
18
+ }
19
+ // console.log(formatKoreanPhoneNumber("01012345678")); // 010-1234-5678
20
+ // console.log(formatKoreanPhoneNumber("0212345678")); // 02-123-4567
21
+ // console.log(formatKoreanPhoneNumber("0311234567")); // 031-123-4567
22
+ // console.log(formatKoreanPhoneNumber("15881234")); // 1588-1234
23
+ // console.log(formatKoreanPhoneNumber("03011123456")); // 030-111-23456
@@ -0,0 +1 @@
1
+ export default function formatPhoneNumberToE164(phoneNumber: string, countryCode?: string): string;
@@ -0,0 +1,18 @@
1
+ export default function formatPhoneNumberToE164(phoneNumber, countryCode = "KR") {
2
+ const countryCodes = {
3
+ KR: "+82",
4
+ US: "+1",
5
+ JP: "+81",
6
+ CN: "+86",
7
+ };
8
+ const defaultAreaCodes = {
9
+ KR: "0",
10
+ };
11
+ const cleanedNumber = phoneNumber.replace(/[^\d]/g, "");
12
+ const countryCodePrefix = countryCodes[countryCode] || "+82";
13
+ const defaultAreaCode = defaultAreaCodes[countryCode] || "0";
14
+ const normalizedNumber = cleanedNumber.startsWith(defaultAreaCode)
15
+ ? cleanedNumber.slice(defaultAreaCode.length)
16
+ : cleanedNumber;
17
+ return `${countryCodePrefix}${normalizedNumber}`;
18
+ }
package/util/index.d.ts CHANGED
@@ -9,6 +9,8 @@ export { default as compareDates } from "./compareDates";
9
9
  export { default as convertDateToString } from "./convertDateToString";
10
10
  export { default as copyToClipboard } from "./copyToClipboard";
11
11
  export { default as createRecord } from "./createRecord";
12
+ export { default as formatMobileNum } from "./formatPhoneNumberToE164";
13
+ export { default as formatKorPhoneNum } from "./formatKoreanPhoneNumber";
12
14
  export * from "../style/colors";
13
15
  export * from "./pattern";
14
16
  export * from "./shape";
package/util/index.js CHANGED
@@ -9,6 +9,8 @@ export { default as compareDates } from "./compareDates";
9
9
  export { default as convertDateToString } from "./convertDateToString";
10
10
  export { default as copyToClipboard } from "./copyToClipboard";
11
11
  export { default as createRecord } from "./createRecord";
12
+ export { default as formatMobileNum } from "./formatPhoneNumberToE164";
13
+ export { default as formatKorPhoneNum } from "./formatKoreanPhoneNumber";
12
14
  export * from "../style/colors";
13
15
  export * from "./pattern";
14
16
  export * from "./shape";