bits-ui 는 melt-ui 를 기반으로 작성된 headless UI 이다. 이를 다시 tailwind 변수들과 스타일 속성을 결합한 shadch-svelte 라이브러리를 살펴본다. 이와 함께 웹사이트 레이아웃을 추출하여 분석해본다.
bits-ui, shadcn-svelte 라이브러리는 유튜버 Huntabyte 가 작성했다.
bun create svelte@latest svltk2-shadcn-app
# - Skeleton project
# - Typescript
# - Prettier
cd svltk2-shadcn-app
bun install
# bun runtime
bun --bun dev
작업 목록
.prettierrc
설정 : svelte, tailwindvite.config.ts
설정 (highlight.js 클래스 제거 방지)tailwind.config.js
설정 : 폰트, pluginssrc/app.html
설정 : 폰트, themesrc/app.pcss
설정 : 폰트, Tailwind directivessrc/+layout.svelte
: app.pcss 연결src/+page.svelte
: 데모 코드 작성후 확인작업 로그
# tailwind 설치
bun add -d tailwindcss postcss autoprefixer
# bun add -d @tailwindcss/typography @tailwindcss/forms
bun add tailwind-variants clsx tailwind-merge
# tailwind plugins, icons, faker 설치
bun add -d vite-plugin-tailwind-purgecss
bun add -d prettier-plugin-tailwindcss
bun add -d lucide-svelte
bun add -d @faker-js/faker
bunx tailwindcss init -p
# prettier 에 tailwind 플러그인 추가
sed -i '' 's/"prettier-plugin-svelte"\]/"prettier-plugin-svelte","prettier-plugin-tailwindcss"\]/' .prettierrc
# purgecss 설정
cat <<EOF > vite.config.ts
import { purgeCss } from 'vite-plugin-tailwind-purgecss';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
sveltekit(),
purgeCss({ safelist: {greedy: [/^hljs-/] }}),
]
});
EOF
# default fonts, typography, forms 설정
cat <<EOF > tailwind.config.js
const defaultTheme = require('tailwindcss/defaultTheme');
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {
fontFamily: {
sans: ['"Noto Sans KR"', ...defaultTheme.fontFamily.sans],
serif: ['"Noto Serif KR"', ...defaultTheme.fontFamily.serif],
mono: ['D2Coding', ...defaultTheme.fontFamily.mono],
},
},
},
plugins: [
// require('@tailwindcss/typography'),
// require('@tailwindcss/forms'),
],
};
EOF
# lang, D2Coding 폰트 추가
cat <<EOF > src/app.html
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link href="http://cdn.jsdelivr.net/gh/joungkyun/font-d2coding/d2coding.css" rel="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
EOF
# Tailwind 설정, 폰트 추가 (Noto 한글 및 Emoji)
cat <<EOF > src/app.pcss
/* fonts: Noto Color Emoji, Noto Sans KR, Noto Serif KR */
@import url('https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&family=Noto+Sans+KR:wght@300;400;500;700&family=Noto+Serif+KR:wght@400;700&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
EOF
cat <<EOF > src/routes/+layout.svelte
<script lang="ts">
import '../app.pcss';
</script>
<slot />
EOF
src/+page.svelte
# tailwind container 데모
cat <<EOF > src/routes/+page.svelte
<script>
import { BookOpen } from 'lucide-svelte';
import { faker } from '@faker-js/faker/locale/ko';
</script>
<header class="container px-4 lg:flex mt-10 items-center h-full lg:mt-0">
<div class="w-full">
<h1 class="text-4xl lg:text-6xl font-bold">
Hello,
<span class="text-green-700">SvelteKit + TailwindCSS</span>
</h1>
<div class="w-40 h-2 bg-green-700 my-4"></div>
<p class="text-xl mb-10">{faker.lorem.paragraph(5)}</p>
<button class="bg-green-500 hover:bg-green-700 text-white text-2xl font-medium px-4 py-2 rounded shadow inline-flex items-center">
<BookOpen size="2rem" />
<span class="ml-2">Learn more</span>
</button>
</div>
</header>
EOF
shadcn-svelte 는 bits-ui 를 tailwind 변수들과 잘 짜집기 한 컴포넌트 파일셋 중 필요한 파일들만 추출하여 가져오는 방식으로 설치한다. (components.json
에 가져올 코드셋에 대한 정보가 설정된다)
bits-ui 를 설치하고, 필요한 components/ui 파일들을 복사해 와도 된다.
tailwind.config.js
설정 : theme, colors, fontsrc/app.pcss
설정 : color 변수값, base 레이어$lib/utils.ts
생성 : 코드 복사src/routes/+layout.svelte
: app.pcss 연결bun add bits-ui
# 필수 tailwind 라이브러리
bun add tailwind-variants clsx tailwind-merge
default
스타일인 경우 lucid icon 을 사용한다.
$ bunx shadcn-svelte@latest init
This command assumes a SvelteKit project with TypeScript and Tailwind CSS.
If you don't have these, follow the manual steps at https://shadcn-svelte.com/docs/installation.
✔ Running this command will install dependencies and overwrite your existing tailwind.config.[cjs|js|ts] & app.pcss file. Proceed? … yes
✔ Which style would you like to use? › Default
✔ Which color would you like to use as base color? › Slate
✔ Where is your global CSS file? … src/app.pcss
✔ Where is your tailwind.config.[cjs|js|ts] located? … tailwind.config.js
✔ Configure the import alias for components: … $lib/components
✔ Configure the import alias for utils: … $lib/utils
✔ Write configuration to components.json. Proceed? … yes
✔ Writing components.json...
✔ Initializing project...
✔ Installing dependencies...
Success! Project initialization completed.
Don't forget to add the aliases you configured to your svelte.config.js!
$ _
desktop 스크린샷
mobile 스크린샷
sidebar 메뉴 스크린샷
search dialog 스크린샷
+layout.svelte
<script lang="ts">
import { page } from '$app/stores';
import { dev, browser } from '$app/environment';
import { Metadata, SiteFooter, SiteHeader } from '$lib/components/docs';
import { updateTheme } from '$lib/utils';
import '../app.pcss';
import { config } from '$lib/stores';
import { ModeWatcher } from 'mode-watcher';
import { Toaster as DefaultSonner } from '$lib/components/ui/sonner';
$: updateTheme($config.theme, $page.url.pathname);
</script>
<ModeWatcher />
<Metadata />
<DefaultSonner />
<div class="relative flex min-h-screen flex-col" id="page">
<SiteHeader />
<div class="flex-1">
<slot />
</div>
<SiteFooter />
</div>
MainNav
MobileNav
CommandMenu
svelte 유틸리티 컴포넌트
끝!