- 概要
- サンプルの選択
- プラグイン「Locofy Lightning」の選択
- プロジェクトの作成(Locofy)
- ソースコードの生成
- ソースコードの同期
- Locofy管理画面で確認
- ソースコードのダウンロード
- プロジェクトを作成(NextJS)
- サーバーを起動
- ブラウザで確認
- プロジェクトにダウンロードファイルをコピー
- ブラウザで確認(コピー後)
- 備考
- 参考
1. 概要
今回はLocofyプラグインを使い、NextJSソースコードを自動生成してローカルで確認する内容となります。
2. サンプルの選択
2-1. 新しいページを作成
- FigmaToCode
2-2. サンプルを選択
- Assets
- Material 3 Design Kit
- Home-Web
- Material 3 Design Kit
3. プラグイン「Locofy Lightning」の選択
3-1. Locofy Lightning
- Plugins
- 「locofy」で検索
- 「アカウント作成」を済ます
- Connect Account
4. プロジェクトの作成(Locofy)
4-1. Dashboardからプロジェクトを作成
5. ソースコードの生成
5-1. Figma上でFrame「Examples/Home-Web」を選択
- ソースコードの自動生成対象
5-2. プラグイン「Locofy Lightning」を選択
5-3. 「Locofy Lightning」が立ち上がったらプロジェクトを選択
- Examples/Home-Web
5-4. 「Convert to Code」をクリック
- プレビュー
- 画面イメージ
- ソースコード
6. ソースコードの同期
6-1. FigmaからLocofyへ同期
- 右上の「Sync」
- Locofy Builder
- Sync to Builder
- Locofy Builder
- Go to Builder
7. Locofy管理画面で確認
7-1. Locofy管理画面
7-2. ファイル構成
8. ソースコードのダウンロード
8-1. 右上「Sync / Export / Deploy」
- 下記を選択
- EXPORT OPTIONS
- Export – ExamplesHomeWeb
- EXPORT OPTIONS
- ファイルがダウンロードされる
8-2. ダウンロードのファイル
- Examaples_Home-Web.zip
8-3. ファイル構成
- zipを解凍
.
├── components
│ ├── background.module.css
│ ├── background.tsx
│ ├── carousel.module.css
│ ├── carousel.tsx
│ ├── f-a-b.module.css
│ ├── f-a-b.tsx
│ ├── header.module.css
│ ├── header.tsx
│ ├── icon-button.module.css
│ ├── icon-button.tsx
│ ├── index.module.css
│ ├── index.tsx
│ ├── nav-item.module.css
│ ├── nav-item.tsx
│ ├── navigation-rail.module.css
│ ├── navigation-rail.tsx
│ ├── top-app-bar.module.css
│ └── top-app-bar.tsx
├── package.json
├── pages
│ └── global.css
└── public
├── account-circle.svg
├── avatar@2x.png
├── back.svg
├── forward.svg
├── icon-1.svg
├── icon-11.svg
├── icon-2.svg
├── icon-3.svg
├── icon-9.svg
├── icon.svg
├── image@2x.png
├── item1@3x.png
├── item2@3x.png
├── item3@3x.png
├── item@2x.png
├── itemlast@3x.png
├── lock.svg
├── more.svg
├── notifications.svg
├── refresh.svg
├── settings.svg
└── star.svg
3 directories, 42 files
8-4. 自動生成ソースコードの一部
- carousel.tsx
import type { NextPage } from "next";
import styles from "./carousel.module.css";
export type CarouselType = {
className?: string;
textContent?: boolean;
};
const Carousel: NextPage<CarouselType> = ({
className = "",
textContent = false,
}) => {
return (
<div className={[styles.carousel, className].join(" ")}>
<div className={styles.item1}>
{textContent && (
<div className={styles.itemTextLast}>
<div className={styles.content}>
<div className={styles.label}>Label</div>
</div>
</div>
)}
</div>
<div className={styles.item2}>
<div className={styles.itemTextLast}>
<div className={styles.content}>
<div className={styles.label}>Label</div>
</div>
</div>
</div>
<div className={styles.item3}>
<div className={styles.itemTextLast}>
<div className={styles.content}>
<div className={styles.label}>Label</div>
</div>
</div>
</div>
<div className={styles.itemLast}>
<div className={styles.itemTextLast}>
<div className={styles.content}>
<div className={styles.label3}>Label</div>
</div>
</div>
</div>
</div>
);
};
export default Carousel;
- carousel.module.css
.label {
position: relative;
letter-spacing: 0.15px;
line-height: 24px;
font-weight: 500;
}
.content {
position: absolute;
height: 100%;
width: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 0),
rgba(0, 0, 0, 0.5)
);
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-end;
padding: var(--padding-base);
box-sizing: border-box;
}
.item1,
.item2 {
height: 205px;
flex: 1;
border-radius: var(--br-9xl);
overflow: hidden;
background-size: cover;
background-repeat: no-repeat;
background-position: top;
min-width: 185px;
}
.item1 {
position: relative;
background-image: url(/item1@3x.png);
}
.item2 {
background-image: url(/item2@3x.png);
}
.item2,
.item3,
.label3 {
position: relative;
}
.item3 {
width: 120px;
border-radius: var(--br-9xl);
overflow: hidden;
flex-shrink: 0;
background-image: url(/item3@3x.png);
background-size: cover;
background-repeat: no-repeat;
background-position: top;
}
.label3 {
letter-spacing: 0.15px;
line-height: 24px;
font-weight: 500;
display: none;
}
.itemTextLast {
position: absolute;
height: 100%;
width: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none;
}
.itemLast {
width: 56px;
position: relative;
border-radius: var(--br-9xl);
overflow: hidden;
flex-shrink: 0;
background-image: url(/itemlast@3x.png);
background-size: cover;
background-repeat: no-repeat;
background-position: top;
}
.carousel {
align-self: stretch;
overflow: hidden;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
flex-wrap: wrap;
align-content: flex-start;
padding: var(--padding-5xs) var(--padding-5xl);
gap: var(--gap-5xs);
text-align: left;
font-size: var(--m3-body-large-size);
color: var(--m3-white);
font-family: var(--m3-body-large);
}
9. プロジェクトを作成(NextJS)
9-1. プロジェクトを作成
npx create-next-app@latest
✔ What is your project named? … figma-example
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
✔ What import alias would you like configured? … @/*
9-2. ファイル構成
.
├── README.md
├── next-env.d.ts
├── next.config.mjs
├── package-lock.json
├── package.json
├── pages
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── api
│ │ └── hello.ts
│ ├── fonts
│ │ ├── GeistMonoVF.woff
│ │ └── GeistVF.woff
│ └── index.tsx
├── public
│ └── favicon.ico
├── styles
│ ├── Home.module.css
│ └── globals.css
└── tsconfig.json
5 directories, 15 files
10. サーバーを起動
npm run dev
11. ブラウザで確認
- http://localhost:3000
12. プロジェクトにダウンロードファイルをコピー
12-1. 対応内容
- 「components」ディレクトリをコピー
- 「public」内のファイルをコピー
- 「pages」の編集
- 「global.css」をコピー
- 「_app.tsx」を編集
- 「index.tsx」を編集
12-2. _app.tsx
import "./global.css";
import type { AppProps } from "next/app";
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
12-3. index.tsx
import ExamplesHomeWeb from "@/components";
export default function Home() {
return <ExamplesHomeWeb />;
}
12-4. ファイル構成
.
├── README.md
├── components
│ ├── background.module.css
│ ├── background.tsx
│ ├── carousel.module.css
│ ├── carousel.tsx
│ ├── f-a-b.module.css
│ ├── f-a-b.tsx
│ ├── header.module.css
│ ├── header.tsx
│ ├── icon-button.module.css
│ ├── icon-button.tsx
│ ├── index.module.css
│ ├── index.tsx
│ ├── nav-item.module.css
│ ├── nav-item.tsx
│ ├── navigation-rail.module.css
│ ├── navigation-rail.tsx
│ ├── top-app-bar.module.css
│ └── top-app-bar.tsx
├── next-env.d.ts
├── next.config.mjs
├── package-lock.json
├── package.json
├── pages
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── api
│ │ └── hello.ts
│ ├── fonts
│ │ ├── GeistMonoVF.woff
│ │ └── GeistVF.woff
│ ├── global.css
│ └── index.tsx
├── public
│ ├── account-circle.svg
│ ├── avatar@2x.png
│ ├── back.svg
│ ├── favicon.ico
│ ├── forward.svg
│ ├── icon-1.svg
│ ├── icon-11.svg
│ ├── icon-2.svg
│ ├── icon-3.svg
│ ├── icon-9.svg
│ ├── icon.svg
│ ├── image@2x.png
│ ├── item1@3x.png
│ ├── item2@3x.png
│ ├── item3@3x.png
│ ├── item@2x.png
│ ├── itemlast@3x.png
│ ├── lock.svg
│ ├── more.svg
│ ├── notifications.svg
│ ├── refresh.svg
│ ├── settings.svg
│ └── star.svg
├── styles
│ ├── Home.module.css
│ └── globals.css
└── tsconfig.json
6 directories, 56 files
13. ブラウザで確認(コピー後)
- http://localhost:3000
14. 備考
今回はLocofyプラグインを使い、NextJSのソースコードを自動生成する内容でした。
15. 参考
- Figma: The Collaborative Interface Design Tool
- Material Design
- Introducing Material Design Guidance for Large Screens – Material Design
- Start Here: 5 Exercises to Prepare Your App for Large Screens – Material Design
- Understanding layout – Material Design
- グリッドを使用したよくあるレイアウトの実現 – CSS: カスケーディングスタイルシート | MDN (mozilla.org)
- WEBデザイン・プログラミング関連の情報発信を手掛ける STAND4U (stand-4u.com)
- Locofy.ai – ship your products 10x faster — with low code
投稿者プロフィール
-
開発好きなシステムエンジニアです。
卓球にハマってます。