@edu-tosel/design 1.0.128-f → 1.0.130
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/asset/fonts/PretendardVariable.ttf +0 -0
- package/globals.css +5 -0
- package/hook/index.d.ts +2 -0
- package/hook/index.js +2 -0
- package/hook/useScroll.d.ts +3 -0
- package/hook/useScroll.js +16 -0
- package/hook/useSmoothScroll.d.ts +2 -0
- package/hook/useSmoothScroll.js +105 -0
- package/layout/index.d.ts +1 -0
- package/layout/index.js +1 -0
- package/layout/template/Archive/Container.js +1 -0
- package/layout/template/Archive/Header.d.ts +3 -1
- package/layout/template/Archive/Header.js +39 -5
- package/layout/template/Olympiad/Banner.js +1 -1
- package/layout/template/Olympiad/Conditions.d.ts +1 -0
- package/layout/template/Olympiad/Conditions.js +11 -0
- package/layout/template/Olympiad/Olympiad.layout.d.ts +1 -0
- package/layout/template/Olympiad/Olympiad.layout.js +18 -0
- package/layout/template/Olympiad/index.d.ts +2 -0
- package/layout/template/Olympiad/index.js +2 -0
- package/layout/template/home/layout/Footer.js +9 -9
- package/package.json +1 -1
- package/tailwind.config.ts +1 -0
- package/version.txt +1 -1
- package/widget/template/Select/Select.js +2 -20
|
Binary file
|
package/globals.css
CHANGED
|
@@ -42,6 +42,11 @@
|
|
|
42
42
|
src: url("./asset/fonts/TimesNewerRoman-BoldItalic.otf") format("opentype");
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
@font-face {
|
|
46
|
+
font-family: "PretendardVariable";
|
|
47
|
+
src: url("./asset/fonts/PretendardVariable.ttf") format("truetype");
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
input[type="date"]::-webkit-inner-spin-button,
|
|
46
51
|
input[type="date"]::-webkit-calendar-picker-indicator {
|
|
47
52
|
display: none;
|
package/hook/index.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ export { default as useEase } from "./useEase";
|
|
|
2
2
|
export { default as useEvents } from "./useEvents";
|
|
3
3
|
export { default as useFlag } from "./useFlag";
|
|
4
4
|
export { default as useResponsive } from "./useResponsive";
|
|
5
|
+
export { default as useScroll } from "./useScroll";
|
|
6
|
+
export { default as useSmoothScroll } from "./useSmoothScroll";
|
package/hook/index.js
CHANGED
|
@@ -2,3 +2,5 @@ export { default as useEase } from "./useEase";
|
|
|
2
2
|
export { default as useEvents } from "./useEvents";
|
|
3
3
|
export { default as useFlag } from "./useFlag";
|
|
4
4
|
export { default as useResponsive } from "./useResponsive";
|
|
5
|
+
export { default as useScroll } from "./useScroll";
|
|
6
|
+
export { default as useSmoothScroll } from "./useSmoothScroll";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
export default function useScroll() {
|
|
3
|
+
const [scroll, setScroll] = useState(undefined);
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (typeof window !== "undefined")
|
|
6
|
+
setScroll(window.scrollY);
|
|
7
|
+
const handleScroll = () => {
|
|
8
|
+
setScroll(window.scrollY);
|
|
9
|
+
};
|
|
10
|
+
window.addEventListener("scroll", handleScroll);
|
|
11
|
+
return () => {
|
|
12
|
+
window.removeEventListener("scroll", handleScroll);
|
|
13
|
+
};
|
|
14
|
+
}, [scroll]);
|
|
15
|
+
return { scroll };
|
|
16
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
function useSmoothScroll(duration = 300, scrollMultiplier = 3.2) {
|
|
3
|
+
const animationFrameId = useRef(null);
|
|
4
|
+
const startPosition = useRef(0);
|
|
5
|
+
const targetPosition = useRef(0);
|
|
6
|
+
const startTime = useRef(0);
|
|
7
|
+
const lastScrollTime = useRef(0);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const handleWheelScroll = (event) => {
|
|
10
|
+
event.preventDefault();
|
|
11
|
+
const now = performance.now();
|
|
12
|
+
const timeElapsed = now - startTime.current;
|
|
13
|
+
const timeRemaining = Math.max(duration - timeElapsed, 0);
|
|
14
|
+
// Check if the new input should be integrated into the ongoing animation
|
|
15
|
+
if (timeRemaining <= duration / 3) {
|
|
16
|
+
// Update target position
|
|
17
|
+
targetPosition.current += event.deltaY * scrollMultiplier;
|
|
18
|
+
// Adjust the start time and position to continue smoothly
|
|
19
|
+
startPosition.current = window.scrollY;
|
|
20
|
+
startTime.current = now - (duration - timeElapsed);
|
|
21
|
+
// If no animation is running or has just been reset
|
|
22
|
+
if (animationFrameId.current === null) {
|
|
23
|
+
const smoothScroll = (currentTime) => {
|
|
24
|
+
const elapsedTime = currentTime - startTime.current;
|
|
25
|
+
const progress = Math.min(elapsedTime / duration, 1);
|
|
26
|
+
const ease = easeOutSlippery(progress);
|
|
27
|
+
window.scrollTo(0, startPosition.current +
|
|
28
|
+
(targetPosition.current - startPosition.current) * ease);
|
|
29
|
+
if (progress < 1) {
|
|
30
|
+
animationFrameId.current = requestAnimationFrame(smoothScroll);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
animationFrameId.current = null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
animationFrameId.current = requestAnimationFrame(smoothScroll);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Resume animation with updated target position
|
|
40
|
+
const smoothScroll = (currentTime) => {
|
|
41
|
+
const elapsedTime = currentTime - startTime.current;
|
|
42
|
+
const progress = Math.min(elapsedTime / duration, 1);
|
|
43
|
+
const ease = easeOutSlippery(progress);
|
|
44
|
+
window.scrollTo(0, startPosition.current +
|
|
45
|
+
(targetPosition.current - startPosition.current) * ease);
|
|
46
|
+
if (progress < 1) {
|
|
47
|
+
animationFrameId.current = requestAnimationFrame(smoothScroll);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
animationFrameId.current = null;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
animationFrameId.current = requestAnimationFrame(smoothScroll);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Ignore scroll inputs that come too early
|
|
58
|
+
startPosition.current = window.scrollY;
|
|
59
|
+
targetPosition.current += event.deltaY * scrollMultiplier;
|
|
60
|
+
startTime.current = now;
|
|
61
|
+
if (animationFrameId.current !== null) {
|
|
62
|
+
cancelAnimationFrame(animationFrameId.current);
|
|
63
|
+
animationFrameId.current = null;
|
|
64
|
+
}
|
|
65
|
+
// Start a new animation with the new input
|
|
66
|
+
const smoothScroll = (currentTime) => {
|
|
67
|
+
const elapsedTime = currentTime - startTime.current;
|
|
68
|
+
const progress = Math.min(elapsedTime / duration, 1);
|
|
69
|
+
const ease = easeOutSlippery(progress);
|
|
70
|
+
window.scrollTo(0, startPosition.current +
|
|
71
|
+
(targetPosition.current - startPosition.current) * ease);
|
|
72
|
+
if (progress < 1) {
|
|
73
|
+
animationFrameId.current = requestAnimationFrame(smoothScroll);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
animationFrameId.current = null;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
animationFrameId.current = requestAnimationFrame(smoothScroll);
|
|
80
|
+
}
|
|
81
|
+
lastScrollTime.current = now;
|
|
82
|
+
};
|
|
83
|
+
window.addEventListener("wheel", handleWheelScroll, { passive: false });
|
|
84
|
+
return () => {
|
|
85
|
+
if (animationFrameId.current !== null) {
|
|
86
|
+
cancelAnimationFrame(animationFrameId.current);
|
|
87
|
+
}
|
|
88
|
+
window.removeEventListener("wheel", handleWheelScroll);
|
|
89
|
+
};
|
|
90
|
+
}, [duration, scrollMultiplier]);
|
|
91
|
+
function cubicBezier(t, p0, p1, p2, p3) {
|
|
92
|
+
const cX = 3 * (p1 - p0);
|
|
93
|
+
const bX = 3 * (p2 - p1) - cX;
|
|
94
|
+
const aX = p3 - p0 - cX - bX;
|
|
95
|
+
return ((aX * t + bX) * t + cX) * t + p0;
|
|
96
|
+
}
|
|
97
|
+
function easeOutSlippery(t) {
|
|
98
|
+
const p0 = 0;
|
|
99
|
+
const p1 = 0.5; // Start slow
|
|
100
|
+
const p2 = 0.9; // End smoothly
|
|
101
|
+
const p3 = 1;
|
|
102
|
+
return cubicBezier(t, p0, p1, p2, p3);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export default useSmoothScroll;
|
package/layout/index.d.ts
CHANGED
|
@@ -13,3 +13,4 @@ export { default as Row } from "./template/Row";
|
|
|
13
13
|
export { default as Shelf } from "./template/Shelf";
|
|
14
14
|
export { default as Tab } from "./template/Tab";
|
|
15
15
|
export { default as TextBox } from "./template/TextBox";
|
|
16
|
+
export { default as OlympiadLayout } from "./template/Olympiad/Olympiad.layout";
|
package/layout/index.js
CHANGED
|
@@ -13,3 +13,4 @@ export { default as Row } from "./template/Row";
|
|
|
13
13
|
export { default as Shelf } from "./template/Shelf";
|
|
14
14
|
export { default as Tab } from "./template/Tab";
|
|
15
15
|
export { default as TextBox } from "./template/TextBox";
|
|
16
|
+
export { default as OlympiadLayout } from "./template/Olympiad/Olympiad.layout";
|
|
@@ -19,5 +19,6 @@ export default function Container({ contents, state: [search, _], }) {
|
|
|
19
19
|
.map(({ titles, description, extension, onClick }) => (_jsx(Archive.Content, { titles: {
|
|
20
20
|
title: titles.title,
|
|
21
21
|
subtitle: titles.subtitle,
|
|
22
|
+
subtitleColor: titles.subtitleColor,
|
|
22
23
|
}, onClick: onClick, description: description, extension: extension }, titles.title + titles.subtitle + description))) }) }));
|
|
23
24
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { State } from "../../../interface";
|
|
2
|
-
export default function Header({ state }: {
|
|
2
|
+
export default function Header({ state, seriesState, levelState, }: {
|
|
3
3
|
state: State<string>;
|
|
4
|
+
seriesState: State<string | undefined>;
|
|
5
|
+
levelState: State<string | undefined>;
|
|
4
6
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,17 +1,51 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../../util";
|
|
3
|
-
import { Input } from "../../../widget";
|
|
3
|
+
import { Input, Select } from "../../../widget";
|
|
4
4
|
import { useResponsive } from "../../../hook";
|
|
5
|
-
export default function Header({ state }) {
|
|
5
|
+
export default function Header({ state, seriesState, levelState, }) {
|
|
6
6
|
const container = {
|
|
7
7
|
displays: "flex justify-between items-start",
|
|
8
8
|
sizes: "w-full h-15",
|
|
9
9
|
boundaries: "px-5 pb-5",
|
|
10
10
|
};
|
|
11
11
|
const res = useResponsive();
|
|
12
|
-
return (_jsxs("div", { className: cn(container), children: [_jsx(Input, { state: state, placeholder: res ? "키워드를 입력하세요" : "", option: {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
return (_jsxs("div", { className: cn(container), children: [_jsxs("div", { className: "flex gap-x-3.5", children: [_jsx(Input, { state: state, placeholder: res ? "키워드를 입력하세요" : "", option: {
|
|
13
|
+
width: "sm",
|
|
14
|
+
} }), _jsx(Select, { selectOptions: [
|
|
15
|
+
["TOSEL VOCA Series", "Voca Series"],
|
|
16
|
+
["Story Series", "Story Series"],
|
|
17
|
+
["Listening Series", "Listening Series"],
|
|
18
|
+
["Speaking Series", "Speaking Series"],
|
|
19
|
+
["실전문제집1", "실전문제집1"],
|
|
20
|
+
["TOSEL 실전문제집2", "실전문제집2"],
|
|
21
|
+
["유형분석집", "유형분석집1"],
|
|
22
|
+
["유형분석집2", "유형분석집2"],
|
|
23
|
+
["예상문제집", "예상문제집"],
|
|
24
|
+
["심화문제집", "심화문제집"],
|
|
25
|
+
["기출연습", "기출연습"],
|
|
26
|
+
["기출모의고사", "기출모의고사"],
|
|
27
|
+
], state: seriesState, placeholder: "\uC2DC\uB9AC\uC988" }), _jsx(Select, { selectOptions: [
|
|
28
|
+
{
|
|
29
|
+
title: "Pre-Starter",
|
|
30
|
+
value: "PS",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
title: "Starter",
|
|
34
|
+
value: "ST",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
title: "Basic",
|
|
38
|
+
value: "BA",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
title: "Junior",
|
|
42
|
+
value: "JR",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
title: "High Junior",
|
|
46
|
+
value: "HJ",
|
|
47
|
+
},
|
|
48
|
+
], state: levelState, placeholder: "\uB808\uBCA8" })] }), _jsx(ContentBox, { contents: [
|
|
15
49
|
{
|
|
16
50
|
title: "교재 음원",
|
|
17
51
|
onClick: () => { },
|
|
@@ -27,5 +27,5 @@ export default function Banner() {
|
|
|
27
27
|
hoveractions: "hover:bg-green-dark hover:text-white",
|
|
28
28
|
animations: "duration-300",
|
|
29
29
|
};
|
|
30
|
-
return (_jsx("div", { className: cn(container), children: _jsxs("div", { className: "flex flex-col w-full justify-start max-w-6xl", children: [_jsxs("div", { className: cn(explainer), children: ["\uD559\uC0DD\uC774\uB77C\uBA74, ", _jsx("br", {}), "\uC804\uAD6D \uC5B4\uB514\uC5D0\uC11C\uB098 \uCC38\uC5EC \uAC00\uB2A5\uD55C"] }), _jsx("div", { className: cn(brandTextCore), children: "VOCA" }), _jsx("div", { className: cn(brandTextSub), children: "\uC62C\uB9BC\uD53C\uC544\uB4DC" }), _jsx("a", { href: "https://olympiad.tosel.co.kr/", className: cn(AdvertButton), children: "\uC9C0\uAE08 \uC811\uC218\uD558\uAE30" })] }) }));
|
|
30
|
+
return (_jsx("div", { className: cn(container), children: _jsxs("div", { className: "flex flex-col w-full justify-start max-w-6xl", children: [_jsxs("div", { className: cn(explainer), children: ["\uD559\uC0DD\uC774\uB77C\uBA74, ", _jsx("br", {}), "\uC804\uAD6D \uC5B4\uB514\uC5D0\uC11C\uB098 \uCC38\uC5EC \uAC00\uB2A5\uD55C"] }), _jsx("div", { className: cn(brandTextCore), children: "VOCA" }), _jsx("div", { className: cn(brandTextSub), children: "\uC62C\uB9BC\uD53C\uC544\uB4DC" }), _jsx("a", { href: "https://olympiad.tosel.co.kr/dashboard", className: cn(AdvertButton), children: "\uC9C0\uAE08 \uC811\uC218\uD558\uAE30" })] }) }));
|
|
31
31
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function Conditions(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../../util";
|
|
3
|
+
export default function Conditions() {
|
|
4
|
+
const container = {
|
|
5
|
+
sizes: "w-full h-screen",
|
|
6
|
+
displays: "flex justify-center items-center",
|
|
7
|
+
spacings: "px-5",
|
|
8
|
+
textstyles: "antialiased font-pretendard-var",
|
|
9
|
+
};
|
|
10
|
+
return _jsx("div", { className: cn(container), children: "\u314E\u3147" });
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function OlympiadLayout(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import { Olympiad } from "../../../layout";
|
|
4
|
+
import { cn } from "../../../util";
|
|
5
|
+
export default function OlympiadLayout() {
|
|
6
|
+
const ref = useRef(null);
|
|
7
|
+
const container = {
|
|
8
|
+
sizes: "min-h-screen w-full",
|
|
9
|
+
textoptions: "break-keep",
|
|
10
|
+
// test: "border-4 border-red-500",
|
|
11
|
+
};
|
|
12
|
+
// const { scroll } = useScroll();
|
|
13
|
+
// const a = useSmoothScroll(800);
|
|
14
|
+
// useEffect(() => {
|
|
15
|
+
// console.log(scroll);
|
|
16
|
+
// }, [scroll]);
|
|
17
|
+
return (_jsxs("div", { className: cn(container), children: [_jsx(Olympiad.Banner, {}), _jsx(Olympiad.Sponsors, {}), _jsx(Olympiad.Features, {}), _jsx(Olympiad.Prizes, {}), _jsx(Olympiad.Conditions, {}), _jsx(Olympiad.Videoset, {})] }));
|
|
18
|
+
}
|
|
@@ -3,11 +3,13 @@ import Sponsors from "./Sponsors";
|
|
|
3
3
|
import Features from "./Features";
|
|
4
4
|
import Prizes from "./Prizes";
|
|
5
5
|
import Videoset from "./Videoset";
|
|
6
|
+
import Conditions from "./Conditions";
|
|
6
7
|
declare const Olympiad: {
|
|
7
8
|
Banner: typeof Banner;
|
|
8
9
|
Sponsors: typeof Sponsors;
|
|
9
10
|
Features: typeof Features;
|
|
10
11
|
Prizes: typeof Prizes;
|
|
12
|
+
Conditions: typeof Conditions;
|
|
11
13
|
Videoset: typeof Videoset;
|
|
12
14
|
};
|
|
13
15
|
export default Olympiad;
|
|
@@ -3,11 +3,13 @@ import Sponsors from "./Sponsors";
|
|
|
3
3
|
import Features from "./Features";
|
|
4
4
|
import Prizes from "./Prizes";
|
|
5
5
|
import Videoset from "./Videoset";
|
|
6
|
+
import Conditions from "./Conditions";
|
|
6
7
|
const Olympiad = {
|
|
7
8
|
Banner,
|
|
8
9
|
Sponsors,
|
|
9
10
|
Features,
|
|
10
11
|
Prizes,
|
|
12
|
+
Conditions,
|
|
11
13
|
Videoset,
|
|
12
14
|
};
|
|
13
15
|
export default Olympiad;
|
|
@@ -14,13 +14,13 @@ export default function Footer() {
|
|
|
14
14
|
return (_jsx("div", { className: cn(container), children: _jsxs("div", { className: cn(body), children: [_jsxs("div", { className: "flex items-center gap-9.5", children: [_jsx("img", { src: "/images/logos/tosel.png", width: 147, height: 31.93 }), _jsx("img", { src: "/images/logos/itc-script.png", width: 122, height: 51 })] }), _jsxs("div", { className: "flex justify-between items-center border-b-1 border-gray-dark pb-4 mt-11.5", children: [_jsx("div", { children: "Copyright TOSEL. \u24D2 All Rights Reserved." }), _jsx("div", { className: "flex gap-5", children: buttons.map((button, index) => (_jsx("div", { children: button.title }, index))) })] }), _jsxs("div", { className: "flex flex-col mt-4", children: [_jsx("div", { children: "\uB300\uD45C\uBC88\uD638 02-923-0505" }), _jsx("div", { children: "\uAC1C\uC778 \uBB38\uC758: tosel_cs@tosel.co.kr" }), _jsx("div", { children: "\uB2E8\uCCB4 \uBB38\uC758: tosel_academy@tosel.co.kr" }), _jsx("div", { children: "\uC11C\uC6B8\uC2DC \uC131\uBD81\uAD6C \uC548\uC554\uB85C 145 \uACE0\uB824\uB300\uD559\uAD50 \uB77C\uC774\uC2DC\uC6C0 4\uCE35" }), _jsx("div", { children: "Lyceum Korea University, 145 Anam Ro, Seongbuk-Gu, Seoul, Korea 02841" })] })] }) }));
|
|
15
15
|
}
|
|
16
16
|
const buttons = [
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
// {
|
|
18
|
+
// title: "이용약관",
|
|
19
|
+
// },
|
|
20
|
+
// {
|
|
21
|
+
// title: "개인정보 처리방침",
|
|
22
|
+
// },
|
|
23
|
+
// {
|
|
24
|
+
// title: "FAQ",
|
|
25
|
+
// },
|
|
26
26
|
];
|
package/package.json
CHANGED
package/tailwind.config.ts
CHANGED
|
@@ -16,6 +16,7 @@ export default {
|
|
|
16
16
|
"pretendard-medium": ["pretendard-medium"],
|
|
17
17
|
"pretendard-bold": ["pretendard-bold"],
|
|
18
18
|
"pretendard-light": ["pretendard-light"],
|
|
19
|
+
"pretendard-var": ["PretendardVariable"],
|
|
19
20
|
kostar: ["kostar"],
|
|
20
21
|
nicomoji: ["nicomoji"],
|
|
21
22
|
megrim: ["megrim"],
|
package/version.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.130
|
|
@@ -23,26 +23,8 @@ export default function Select({ state, selectOptions: selectOptionsInput, place
|
|
|
23
23
|
const [search, setSearch] = useState("");
|
|
24
24
|
const [isOpen, setIsOpen] = useState(false);
|
|
25
25
|
const [isHover, setIsHover] = useState(false);
|
|
26
|
-
const [filteredOptions, setFilterdOptions] = useState();
|
|
27
26
|
const [index, setIndex] = useState();
|
|
28
27
|
useFlag({ state: [false, setIsOpen], safe: "overlay" });
|
|
29
|
-
const onKeyDown = (e) => {
|
|
30
|
-
if (!filteredOptions)
|
|
31
|
-
return;
|
|
32
|
-
if (typeof index === "undefined")
|
|
33
|
-
return setIndex(0);
|
|
34
|
-
if (e.key === "Enter") {
|
|
35
|
-
setText(String(filteredOptions[index]?.title));
|
|
36
|
-
return setValue(filteredOptions[index]?.value);
|
|
37
|
-
}
|
|
38
|
-
if (e.key === "ArrowDown")
|
|
39
|
-
return setIndex((index + 1) % filteredOptions.length);
|
|
40
|
-
if (e.key === "ArrowUp")
|
|
41
|
-
return setIndex((index - 1 + filteredOptions.length) % filteredOptions.length);
|
|
42
|
-
};
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
setFilterdOptions(selectOptions?.filter(({ title }) => text.includes(String(title))));
|
|
45
|
-
}, [search, selectOptions]);
|
|
46
28
|
// scrollIntoViews
|
|
47
29
|
const listRef = useRef(null);
|
|
48
30
|
const itemRefs = useRef([]);
|
|
@@ -109,9 +91,9 @@ export default function Select({ state, selectOptions: selectOptionsInput, place
|
|
|
109
91
|
duration: 0,
|
|
110
92
|
},
|
|
111
93
|
});
|
|
112
|
-
return (_jsxs("div", { className: cn(container),
|
|
94
|
+
return (_jsxs("div", { className: cn(container), onClick: () => setIsOwn(true), children: [_jsx("button", { onClick: () => setIsOpen(!isOpen), className: cn(button), onMouseEnter: () => setIsHover(true), onMouseLeave: () => setIsHover(false), children: value ? (_jsx("div", { className: cn(label), children: selectOptions?.find((option) => value === option.value)?.title })) : (_jsx("div", { className: "text-xs pl-1", children: placeholder ?? "선택해주세요" })) }), inputTransition((styles, item) => isLong &&
|
|
113
95
|
item && (_jsx(animated.input, { style: styles, placeholder: "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD558\uC138\uC694", className: cn(input), onChange: (e) => setSearch(e.target.value) }))), bodyTransitions((styles, item) => {
|
|
114
|
-
return (item && (_jsx(animated.div, { style: styles, className: cn(body), ref: listRef, children:
|
|
96
|
+
return (item && (_jsx(animated.div, { style: styles, className: cn(body), ref: listRef, children: selectOptions?.map(({ value, title }, order) => (_jsx("section", { children: _jsx("button", { ref: (el) => (itemRefs.current[order] = el), onClick: () => {
|
|
115
97
|
setValue(value);
|
|
116
98
|
setText(String(title));
|
|
117
99
|
return setIsOpen(false);
|