๐จ Fullpage.js + Next.js + TypeScript๋ก ๋ฉ์ง ์นํ์ด์ง ๋ง๋ค๊ธฐ
ยท 4 min read
Fullpage.js + Next.js + TypeScript๋ก ๋ฉ์ง ์นํ์ด์ง ๋ง๋ค๊ธฐ ๐โ
์๋ ํ์ธ์! ์ค๋์ Fullpage.js, Next.js, ๊ทธ๋ฆฌ๊ณ TypeScript๋ฅผ ํจ๊ป ์ฌ์ฉํ์ฌ ๋ฉ์ง ์น ํ์ด์ง๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๊ณต์ ํ๋ ค๊ณ ํฉ๋๋ค. ์ธํฐ๋ท์์ ์ด ์ธ ๊ฐ์ง ๊ธฐ์ ์ ํจ๊ป ์ฌ์ฉํ๋ ์์ ๋ฅผ ์ฐพ๊ธฐ ์ด๋ ค์ ์ด๋ ๊ฒ ๋ธ๋ก๊ทธ์ ์์ฑํ๊ฒ ๋์์ต๋๋ค.
๐ ์ฐธ๊ณ ์๋ฃโ
๐ ๏ธ ์ค๋น๋ฌผโ
๋จผ์ , ํ๋ก์ ํธ์ ํ์ํ ํจํค์ง๋ค์ ์ค์นํด์ผ ํฉ๋๋ค:
npx create-next-app@latest --typescript
npm install react-bootstrap bootstrap
npm install @fullpage/react-fullpage
๐ฆ package.jsonโ
{
"name": "fullpage_nextjs_typescript",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"license": "gpl-3.0",
"dependencies": {
"@fullpage/react-fullpage": "^0.1.38",
"@types/node": "18.15.11",
"@types/react": "18.0.34",
"@types/react-dom": "18.0.11",
"bootstrap": "^5.2.3",
"next": "13.3.0",
"react": "18.2.0",
"react-bootstrap": "^2.7.2",
"react-dom": "18.2.0",
"typescript": "5.0.4"
}
}
๐ป ๊ตฌํํ๊ธฐโ
components/fullpageExample.tsx๋ผ๋ ํ์ผ์ ์์ฑํ๊ณ ์๋์ ์ฝ๋๋ฅผ ์ ๋ ฅํฉ๋๋ค.
[์ด์ ์ฝ๋์ ๋์ผํ TypeScript ์ฝ๋ ๋ธ๋ก]
import React, { useState } from "react";
import ReactFullpage, { fullpageOptions } from "@fullpage/react-fullpage";
import { Navbar, Nav, Button } from "react-bootstrap";
interface Section {
text: string;
id?: number;
}
const originalColors = [
"blue",
"#0798ec",
"#fc6c7c",
"#435b71",
"orange",
"blue",
"purple",
"yellow",
];
type Credits = {
enabled?: boolean;
label?: string;
position?: "left" | "right";
};
const pluginWrapper = () => {
/*
* require('../static/fullpage.scrollHorizontally.min.js'); // Optional. Required when using the "scrollHorizontally" extension.
*/
};
const FullpageJsExample = () => {
const [sectionsColor, setSectionsColor] = useState([...originalColors]);
const [fullpages, setFullpages] = useState<Section[]>([
{
text: "Section 1",
},
{
text: "Section 2",
},
{
text: "Section 3",
},
]);
const onLeave = (origin: any, destination: any, direction: any) => {
console.log("onLeave", { origin, destination, direction });
};
const handleChangeColors = () => {
const newColors =
sectionsColor[0] === "yellow" ? [...originalColors] : ["yellow", "blue", "white"];
setSectionsColor(newColors);
};
const handleAddSection = () => {
setFullpages((prevFullpages) => [
...prevFullpages,
{
text: `section ${prevFullpages.length + 1}`,
id: Math.random(),
},
]);
};
const handleRemoveSection = () => {
setFullpages((prevFullpages) => {
const newPages = [...prevFullpages];
newPages.pop();
return newPages;
});
};
if (!fullpages.length) {
return null;
}
const Menu = () => (
<Navbar bg="light" expand="lg" fixed="top">
<Navbar.Brand href="#home" className="mx-2">
Fullpage.js + Next.js + Typescript
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Item>
<Button onClick={handleAddSection} className="mr-2, mx-1">
ADD SECTION
</Button>
</Nav.Item>
<Nav.Item>
<Button onClick={handleRemoveSection} className="mr-2, mx-1">
REMOVE SECTION
</Button>
</Nav.Item>
<Nav.Item>
<Button onClick={handleChangeColors}>CHANGE SECTION</Button>
</Nav.Item>
</Nav>
</Navbar.Collapse>
</Navbar>
);
const credits: Credits = {
enabled: true,
label: "my custom",
position: "left",
};
return (
<div className="App">
<Menu />
<ReactFullpage
licenseKey={"OPEN-SOURCE-GPLV3-LICENSE"}
navigation
onLeave={onLeave}
sectionsColor={sectionsColor}
pluginWrapper={pluginWrapper}
debug={false}
credits={credits}
render={(comp: any) => (
<ReactFullpage.Wrapper>
{fullpages.map(({ text }) => (
<div key={text} className="section">
<h1>{text}</h1>
</div>
))}
</ReactFullpage.Wrapper>
)}
/>
</div>
);
};
export default FullpageJsExample;
์ฝ๋ ์ค๋ช ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- React ๋ฐ ํ์ํ ๋ชจ๋์ import ํฉ๋๋ค.
- ๊ฐ ์น์ ์ ์ ๋ณด์ ์์์ ์ ์ฅํ๋ ์ํ๋ฅผ ์์ฑํฉ๋๋ค.
- ์น์ ์ ์ถ๊ฐํ๊ณ ์ญ์ ํ๊ฑฐ๋ ์์์ ๋ณ๊ฒฝํ๋ ํจ์๋ฅผ ๊ตฌํํฉ๋๋ค.
- React-Bootstrap์ ์ฌ์ฉํ์ฌ ์๋จ ๋ฉ๋ด๋ฅผ ๊ตฌํํฉ๋๋ค.
- Fullpage.js์ ์ต์ ์ ์ค์ ํ๊ณ , ๊ฐ ์น์ ์ ๋ ๋๋งํฉ๋๋ค.
