commit df422fc505bc876012dadc84a2cf201c6f535e10
Author: pqcqaq <905739777@qq.com>
Date: Tue Jul 16 12:12:33 2024 +0800
first commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..32e280c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+node_modules
+demo/out
+lib
+npm-debug.log.*
+dist
+.DS_Store
+bundle-stats.html
+.next
+.out
+.history/
+stats.html
+/.idea
+/packages/react-live/LICENSE
+/packages/react-live/README.md
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..7e6449b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Vite + React + TS
+
+
+
+
+
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..48b7bbb
--- /dev/null
+++ b/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "demo",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-live": "file:../react-live"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.31",
+ "@types/react-dom": "^18.0.11",
+ "@typescript-eslint/eslint-plugin": "^5.57.1",
+ "@typescript-eslint/parser": "^5.57.1",
+ "@vitejs/plugin-react": "^4.0.0",
+ "autoprefixer": "^10.4.14",
+ "eslint": "^8.38.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "eslint-plugin-react-refresh": "^0.3.4",
+ "postcss": "^8.4.21",
+ "sass": "^1.77.8",
+ "tailwindcss": "^3.2.7",
+ "typescript": "^4.9.5",
+ "vite": "^4.3.2"
+ }
+}
diff --git a/postcss.config.cjs b/postcss.config.cjs
new file mode 100644
index 0000000..12a703d
--- /dev/null
+++ b/postcss.config.cjs
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/public/theme/nerd.css b/public/theme/nerd.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app.tsx b/src/app.tsx
new file mode 100644
index 0000000..fc0baf7
--- /dev/null
+++ b/src/app.tsx
@@ -0,0 +1,305 @@
+import { LiveProvider, LivePreview, LiveError, LiveEditor } from "react-live";
+import { ThemeProvider } from "./components/ThemePrivider";
+import { useState } from "react";
+
+const functionBlockList = [
+ `
+const cpn = () => {
+ function handleClick() {
+ console.log("Hi there!");
+ }
+
+ return (
+
+
+
+ AI智能建站助手
+
+
+ 让我们帮助您快速构建和优化您的网站
+
+
+
+
+ );
+};
+`,
+ `
+const cpn = () => {
+ return (
+
+
+
+ 功能介绍
+
+
+ AI智能建站助手提供多种功能,帮助您轻松创建和管理网站
+
+
+
+
+ 自动布局
+
+
+ 通过AI技术自动生成最优的网页布局,提高用户体验
+
+
+
+
+ 智能优化
+
+
+ 利用大数据分析和优化工具提升网站性能和SEO排名
+
+
+
+
+ 个性化定制
+
+
+ 提供多种定制选项,让您的网站独一无二
+
+
+
+
+
+ );
+};
+`,
+ `
+const cpn = () => {
+ return (
+
+
+
+ 使用案例
+
+
+ 了解其他用户如何利用我们的工具创建令人惊叹的网站
+
+
+
+
+ 案例一
+
+
+ 某公司利用我们的AI工具创建了一个高效、美观的企业官网
+
+
+
+
+ 案例二
+
+
+ 某设计师通过我们的平台轻松构建了一个个人作品展示网站
+
+
+
+
+
+ );
+};
+`,
+ `
+const cpn = () => {
+ return (
+
+
+
+ 用户评价
+
+
+ 我们的用户对我们的工具评价很高
+
+
+
+
+ 用户A
+
+
+ “AI智能建站助手帮助我节省了大量时间,让我的网站更专业。”
+
+
+
+
+ 用户B
+
+
+ “非常容易使用,功能强大,效果出色!”
+
+
+
+
+
+ );
+};
+`,
+ `
+const cpn = () => {
+ return (
+
+
+
+ 常见问题
+
+
+ 解答您在使用过程中可能遇到的问题
+
+
+
+
+ 问题一:如何开始使用AI智能建站助手?
+
+
+ 您只需注册一个账号,选择一个模板即可开始构建您的网站。
+
+
+
+
+ 问题二:是否支持移动端?
+
+
+ 是的,我们的所有模板都是响应式设计,兼容各类设备。
+
+
+
+
+ 问题三:如何获取技术支持?
+
+
+ 您可以通过我们的客服系统或者发送邮件获取技术支持。
+
+
+
+
+
+ );
+};
+`,
+ `
+const cpn = () => {
+ return (
+
+
+
+ 联系我们
+
+
+ 如果您有任何问题或建议,请随时与我们联系
+
+
+
+
+ );
+};
+`,
+];
+
+const code = (func: string) => `
+${func}
+render(cpn)
+`;
+
+const editor = (
+ func: string,
+ setShowEdit: React.Dispatch>
+) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export const DemoApp = () => {
+ const [theme, setTheme] = useState<"system" | "dark" | "light">("system");
+
+ const [showEdit, setShowEdit] = useState(false);
+
+ return (
+
+
+ {showEdit && editor(functionBlockList.join("\n"), setShowEdit)}
+ {/* 主题切换页面和代码动态编辑页面 */}
+ {!showEdit && (
+ <>
+
+
+
+
+ {/* 打开代码编辑框 */}
+
+
+ >
+ )}
+ {functionBlockList.map((func, index) => {
+ return (
+
+
+
+
+ );
+ })}
+
+
+ );
+};
diff --git a/src/components/ThemePrivider.tsx b/src/components/ThemePrivider.tsx
new file mode 100644
index 0000000..ace0ed9
--- /dev/null
+++ b/src/components/ThemePrivider.tsx
@@ -0,0 +1,99 @@
+import { createContext, useContext, useEffect, useState } from "react";
+
+type ThemeSection = "dark" | "light" | "system";
+
+const themeMap: Record = {
+ dark: "theme-color-dark",
+ light: "theme-color-light",
+ system: "",
+} as const;
+
+type ThemeProviderProps = {
+ children: React.ReactNode;
+ defaultTheme?: ThemeSection;
+ activeTheme?: ThemeSection;
+ storageKey?: string;
+};
+
+type ThemeProviderState = {
+ theme: ThemeSection;
+ setTheme: (theme: ThemeSection) => void;
+};
+
+const initialState: ThemeProviderState = {
+ theme: "system",
+ setTheme: () => null,
+};
+
+const ThemeProviderContext = createContext(initialState);
+
+export function ThemeProvider({
+ children,
+ defaultTheme = "system",
+ storageKey = "app-theme",
+ activeTheme,
+ ...props
+}: ThemeProviderProps) {
+ const [theme, setTheme] = useState(
+ () => (localStorage.getItem(storageKey) as ThemeSection) || defaultTheme
+ );
+
+ useEffect(() => {
+ localStorage.setItem(storageKey, theme);
+ }, [theme]);
+
+ // 在组件退出前监听系统主题变化,实时切换主题
+ useEffect(() => {
+ const listener = (e: MediaQueryListEvent) => {
+ if (e.matches) {
+ setTheme("dark");
+ } else {
+ setTheme("light");
+ }
+ };
+ if (theme === "system") {
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
+ mediaQuery.matches ? setTheme("dark") : setTheme("light");
+ mediaQuery.addEventListener("change", listener);
+ return () => mediaQuery.removeEventListener("change", listener);
+ }
+ }, []);
+
+ useEffect(() => {
+ const root = window.document.documentElement;
+ root.classList.remove(themeMap.dark, themeMap.light);
+ if (theme !== "system") {
+ root.classList.add(themeMap[theme]);
+ }
+ }, [theme]);
+
+ // 若外部更新了activeTheme,则更新theme
+ useEffect(() => {
+ if (activeTheme && activeTheme !== "system") {
+ setTheme(activeTheme);
+ }
+ }, [activeTheme]);
+
+ const value = {
+ theme,
+ setTheme: (theme: ThemeSection) => {
+ localStorage.setItem(storageKey, theme);
+ setTheme(theme);
+ },
+ };
+
+ return (
+
+ {children}
+
+ );
+}
+
+export const useTheme = () => {
+ const context = useContext(ThemeProviderContext);
+
+ if (context === undefined)
+ throw new Error("useTheme必须在ThemeProvider中使用");
+
+ return context;
+};
diff --git a/src/index.scss b/src/index.scss
new file mode 100644
index 0000000..29f9aa1
--- /dev/null
+++ b/src/index.scss
@@ -0,0 +1,187 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/* 导入主题 */
+@import "./theme/index.scss";
+
+/* 下面是统一的颜色定义 */
+ /* 默认的主题样式 */
+ :root {
+ background-color: var(--color-bg-1);
+ color: var(--color-text-1);
+ }
+
+ button {
+ background-color: var(--primary-6);
+ color: var(--color-bg-white);
+ border: var(--border-1) solid var(--color-border-3);
+ border-radius: var(--border-radius-small);
+ padding: var(--size-3) var(--size-4);
+ font-size: var(--font-size-body-3);
+ box-shadow: var(--shadow1-center);
+ }
+
+ button:hover {
+ background-color: var(--primary-5);
+ border-color: var(--color-border-4);
+ }
+
+ button:active {
+ background-color: var(--primary-7);
+ border-color: var(--color-border-4);
+ }
+
+ input, textarea {
+ background-color: var(--color-fill-1);
+ color: var(--color-text-1);
+ border: var(--border-1) solid var(--color-border-2);
+ border-radius: var(--border-radius-small);
+ padding: var(--size-3);
+ font-size: var(--font-size-body-3);
+ box-shadow: var(--shadow1-center);
+ }
+
+ .card {
+ background-color: var(--color-bg-2);
+ color: var(--color-text-1);
+ border: var(--border-1) solid var(--color-border-1);
+ border-radius: var(--border-radius-large);
+ padding: var(--size-5);
+ box-shadow: var(--shadow2-center);
+ font-size: var(--font-size-body-3);
+ }
+
+ a {
+ color: var(--link-6);
+ text-decoration: none;
+ }
+
+ a:hover {
+ color: var(--link-5);
+ text-decoration: underline;
+ }
+
+ h1, h2, h3, h4, h5, h6 {
+ color: var(--color-text-1);
+ }
+
+ p {
+ color: var(--color-text-1);
+ font-size: var(--font-size-body-3);
+ }
+
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ }
+
+ th, td {
+ border: var(--border-1) solid var(--color-border-2);
+ padding: var(--size-3);
+ text-align: left;
+ }
+
+ thead {
+ background-color: var(--color-bg-2);
+ }
+
+ .alert {
+ background-color: var(--danger-1);
+ color: var(--danger-6);
+ border: var(--border-1) solid var(--danger-4);
+ border-radius: var(--border-radius-small);
+ padding: var(--size-3);
+ }
+
+ .success {
+ background-color: var(--success-1);
+ color: var(--success-6);
+ border: var(--border-1) solid var(--success-4);
+ border-radius: var(--border-radius-small);
+ padding: var(--size-3);
+ }
+
+ .warning {
+ background-color: var(--warning-1);
+ color: var(--warning-6);
+ border: var(--border-1) solid var(--warning-4);
+ border-radius: var(--border-radius-small);
+ padding: var(--size-3);
+ }
+
+:root {
+/* .font-size-global { */
+ --font-size-body-3: 14px;
+ --font-size-body-2: 13px;
+ --font-size-body-1: 12px;
+ --font-size-caption: 12px;
+ --font-size-title-1: 16px;
+ --font-size-title-2: 20px;
+ --font-size-title-3: 24px;
+ --font-size-display-1: 36px;
+ --font-size-display-2: 48px;
+ --font-size-display-3: 56px;
+
+/* .font-weight-global { */
+ --font-weight-light: 300;
+ --font-weight-normal: 400;
+ --font-weight-medium: 500;
+ --font-weight-bold: 700;
+ --font-weight-100: 100;
+ --font-weight-200: 200;
+ --font-weight-300: 300;
+ --font-weight-400: 400;
+ --font-weight-500: 500;
+ --font-weight-600: 600;
+ --font-weight-700: 700;
+ --font-weight-800: 800;
+ --font-weight-900: 900;
+
+/* size-N:(4 * N)px */
+/* .size-global { */
+ --size-none: 0;
+ --size-1: 4px;
+ --size-2: 8px;
+ --size-3: 12px;
+ --size-4: 16px;
+ --size-5: 20px;
+ --size-6: 24px;
+ --size-7: 28px;
+ --size-8: 32px;
+ --size-9: 36px;
+ --size-10: 40px;
+ --size-11: 44px;
+ --size-12: 48px;
+ --size-13: 52px;
+ --size-14: 56px;
+ --size-15: 60px;
+ --size-16: 64px;
+ --size-17: 68px;
+ --size-18: 72px;
+ --size-19: 76px;
+ --size-20: 80px;
+ --size-mini: var(--size-6);
+ --size-small: var(--size-7);
+ --size-default: var(--size-8);
+ --size-large: var(--size-9);
+
+/* .border-global { */
+ --border-none: 0;
+ --border-1: 1px;
+ --border-2: 2px;
+ --border-3: 3px;
+
+/* .border-radius-global { */
+ --border-radius-none: 0;
+ --border-radius-small: 2px;
+ --border-radius-medium: 4px;
+ --border-radius-large: 8px;
+ --border-radius-circle: 50%;
+
+/* .shadow-global { */
+ --shadow-special: 0 0 1px rgba(0, 0, 0, 0.3);
+ --shadow1-center: 0 -2px 5px rgba(0, 0, 0, 0.1);
+ --shadow2-center: 0 0 10px rgba(0, 0, 0, 0.1);
+ --shadow3-center: 0 0 20px rgba(0, 0, 0, 0.1);
+}
\ No newline at end of file
diff --git a/src/main.tsx b/src/main.tsx
new file mode 100644
index 0000000..866ca42
--- /dev/null
+++ b/src/main.tsx
@@ -0,0 +1,10 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import "./index.scss";
+import { DemoApp } from "./app";
+
+ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
+
+
+
+);
diff --git a/src/theme/dark/index.scss b/src/theme/dark/index.scss
new file mode 100644
index 0000000..0bdbd29
--- /dev/null
+++ b/src/theme/dark/index.scss
@@ -0,0 +1,78 @@
+// 定义主体名称变量
+$theme-name: dark;
+
+.theme-color-dark {
+ --primary-7:rgb( 104,159,255);
+ --primary-6:rgb( 60,126,255);
+ --primary-5:rgb( 48,111,255);
+ --primary-4:rgb( 29, 77,210);
+ --primary-3:rgb( 14, 50,166);
+ --primary-2:rgb( 4, 27,121);
+ --primary-1:rgb( 0, 13, 77);
+ --success-7:rgb( 80,210,102);
+ --success-6:rgb( 39,195, 70);
+ --success-5:rgb( 29,180, 64);
+ --success-4:rgb( 18,154, 55);
+ --success-3:rgb( 10,128, 45);
+ --success-2:rgb( 4,102, 37);
+ --success-1:rgb( 0, 77, 28);
+ --warning-7:rgb( 255,179, 87);
+ --warning-6:rgb( 255,150, 38);
+ --warning-5:rgb( 255,141, 31);
+ --warning-4:rgb( 210,105, 19);
+ --warning-3:rgb( 166, 75, 10);
+ --warning-2:rgb( 121, 48, 4);
+ --warning-1:rgb( 77, 27, 0);
+ --danger-7 :rgb( 249,141,134);
+ --danger-6 :rgb( 247,105,101);
+ --danger-5 :rgb( 245, 78, 78);
+ --danger-4 :rgb( 203, 46, 52);
+ --danger-3 :rgb( 161, 22, 31);
+ --danger-2 :rgb( 119, 6, 17);
+ --danger-1 :rgb( 77, 0, 10);
+ --link-7: rgb( 104,159,255);
+ --link-6: rgb( 60,126,255);
+ --link-5: rgb( 48,111,255);
+ --link-4: rgb( 29, 77,210);
+ --link-3: rgb( 14, 50,166);
+ --link-2: rgb( 4, 27,121);
+ --link-1: rgb( 0, 13, 77);
+ --data-1: rgb( 48,111,255);
+ --data-2: rgb( 14, 50,166);
+ --data-3: rgb( 70,154,250);
+ --data-4: rgb( 19, 76,163);
+ --data-5: rgb( 255,150, 38);
+ --data-6: rgb( 166, 75, 10);
+ --data-7: rgb( 18,154, 55);
+ --data-8: rgb( 10,128, 45);
+ --data-9: rgb( 90, 37,176);
+ --data-10: rgb( 62, 19,143);
+ --data-11: rgb( 249,204, 68);
+ --data-12: rgb( 204,150, 31);
+ --data-13: rgb( 184,226, 75);
+ --data-14: rgb( 132,183, 35);
+ --data-15: rgb( 203, 43,136);
+ --data-16: rgb( 161, 23,108);
+ --data-17: rgb( 63,212,207);
+ --data-18: rgb( 17,131,139);
+ --data-19: rgb( 176, 27,182);
+ --data-20: rgb( 101, 3,112);
+ --color-border-1:rgb( 46, 46, 48);
+ --color-border-2:rgb( 72, 72, 73);
+ --color-border-3:rgb( 95, 95, 96);
+ --color-border-4:rgb( 146,146,147);
+ --color-fill-1:rgb( 23, 23, 26);
+ --color-fill-2:rgb( 46, 46, 48);
+ --color-fill-3:rgb( 72, 72, 73);
+ --color-fill-4:rgb( 95, 95, 96);
+ --color-text-1: rgb( 246,246,246);
+ --color-text-2: rgb( 197,197,197);
+ --color-text-3: rgb( 146,146,147);
+ --color-text-4: rgb( 95, 95, 96);
+ --color-bg-1:rgb( 23, 23, 26);
+ --color-bg-2:rgb( 35, 35, 36);
+ --color-bg-3:rgb( 42, 42, 43);
+ --color-bg-4:rgb( 49, 49, 50);
+ --color-bg-5:rgb( 55, 55, 57);
+ --color-bg-white:rgb( 246,246,246);
+}
\ No newline at end of file
diff --git a/src/theme/index.scss b/src/theme/index.scss
new file mode 100644
index 0000000..9f3c7a2
--- /dev/null
+++ b/src/theme/index.scss
@@ -0,0 +1,2 @@
+@import "./dark/index.scss";
+@import "./light/index.scss"
\ No newline at end of file
diff --git a/src/theme/light/index.scss b/src/theme/light/index.scss
new file mode 100644
index 0000000..9416bc8
--- /dev/null
+++ b/src/theme/light/index.scss
@@ -0,0 +1,78 @@
+// 定义主体名称变量
+$theme-name: light;
+
+.theme-color-light {
+ --primary-7:rgb( 14, 66,210);
+ --primary-6:rgb( 22, 93,255);
+ --primary-5:rgb( 64,128,255);
+ --primary-4:rgb( 106,161,255);
+ --primary-3:rgb( 148,191,255);
+ --primary-2:rgb( 190,218,255);
+ --primary-1:rgb( 232,243,255);
+ --success-7:rgb( 0,154, 41);
+ --success-6:rgb( 0,180, 42);
+ --success-5:rgb( 35,195, 67);
+ --success-4:rgb( 76,210, 99);
+ --success-3:rgb( 123,225,136);
+ --success-2:rgb( 175,240,181);
+ --success-1:rgb( 232,255,234);
+ --warning-7:rgb( 210, 95, 0);
+ --warning-6:rgb( 255,125, 0);
+ --warning-5:rgb( 255,154, 46);
+ --warning-4:rgb( 255,182, 93);
+ --warning-3:rgb( 255,207,139);
+ --warning-2:rgb( 255,228,186);
+ --warning-1:rgb( 255,247,232);
+ --danger-7 :rgb( 203, 39, 45);
+ --danger-6 :rgb( 245, 63, 63);
+ --danger-5 :rgb( 247,101, 96);
+ --danger-4 :rgb( 249,137,129);
+ --danger-3 :rgb( 251,172,163);
+ --danger-2 :rgb( 253,205,197);
+ --danger-1 :rgb( 255,236,232);
+ --link-7: rgb( 14, 66,210);
+ --link-6: rgb( 22, 93,255);
+ --link-5: rgb( 64,128,255);
+ --link-4: rgb( 106,161,255);
+ --link-3: rgb( 148,191,255);
+ --link-2: rgb( 190,218,255);
+ --link-1: rgb( 232,243,255);
+ --data-1: rgb( 64,128,255);
+ --data-2: rgb( 190,218,255);
+ --data-3: rgb( 85,197,253);
+ --data-4: rgb( 156,220,252);
+ --data-5: rgb( 255,125, 0);
+ --data-6: rgb( 255,207,139);
+ --data-7: rgb( 76,210, 99);
+ --data-8: rgb( 175,240,181);
+ --data-9: rgb( 168,113,227);
+ --data-10: rgb( 221,190,246);
+ --data-11: rgb( 247,186, 30);
+ --data-12: rgb( 250,220,109);
+ --data-13: rgb( 159,219, 29);
+ --data-14: rgb( 201,233,104);
+ --data-15: rgb( 249,121,183);
+ --data-16: rgb( 251,157,199);
+ --data-17: rgb( 20,201,201);
+ --data-18: rgb( 137,233,224);
+ --data-19: rgb( 232,101,223);
+ --data-20: rgb( 247,186,239);
+ --color-border-1:rgb( 242,243,245);
+ --color-border-2:rgb( 229,230,235);
+ --color-border-3:rgb( 201,205,212);
+ --color-border-4:rgb( 134,144,156);
+ --color-fill-1:rgb( 247,248,250);
+ --color-fill-2:rgb( 242,243,245);
+ --color-fill-3:rgb( 229,230,235);
+ --color-fill-4:rgb( 201,205,212).;
+ --color-text-1:rgb( 29, 33, 41);
+ --color-text-2:rgb( 78, 89,105);
+ --color-text-3:rgb( 134,144,156);
+ --color-text-4:rgb( 201,205,212);
+ --color-bg-1:rgb( 255,255,255);
+ --color-bg-2:rgb( 255,255,255);
+ --color-bg-3:rgb( 255,255,255);
+ --color-bg-4:rgb( 255,255,255);
+ --color-bg-5:rgb( 255,255,255);
+ --color-bg-white:rgb( 255,255,255);
+}
\ No newline at end of file
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
new file mode 100644
index 0000000..36a6e14
--- /dev/null
+++ b/tailwind.config.cjs
@@ -0,0 +1,115 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
+ theme: {
+ colors: {
+ blue: "#1fb6ff",
+ purple: "#7e5bef",
+ pink: "#ff49db",
+ orange: "#ff7849",
+ green: "#13ce66",
+ yellow: "#ffc82c",
+ "gray-dark": "#273444",
+ gray: "#8492a6",
+ "gray-light": "#d3dce6",
+ transparent: "transparent",
+ current: "currentColor",
+ white: "#ffffff",
+ midnight: "#121063",
+ metal: "#565584",
+ tahiti: "#3ab7bf",
+ silver: "#ecebff",
+ "bubble-gum": "#ff77e9",
+ bermuda: "#78dcca",
+ },
+ fontFamily: {
+ sans: ["Graphik", "sans-serif"],
+ serif: ["Merriweather", "serif"],
+ },
+ extend: {
+ spacing: {
+ "8xl": "96rem",
+ "9xl": "128rem",
+ },
+ borderRadius: {
+ "4xl": "2rem",
+ },
+ fontFamily: {
+ display: "Oswald, ui-serif ", // Adds a new `font-display` class
+ },
+ colors: {
+ primary: {
+ 1: "var(--primary-1)",
+ 2: "var(--primary-2)",
+ 3: "var(--primary-3)",
+ 4: "var(--primary-4)",
+ 5: "var(--primary-5)",
+ 6: "var(--primary-6)",
+ 7: "var(--primary-7)",
+ },
+ success: {
+ 1: "var(--success-1)",
+ 2: "var(--success-2)",
+ 3: "var(--success-3)",
+ 4: "var(--success-4)",
+ 5: "var(--success-5)",
+ 6: "var(--success-6)",
+ 7: "var(--success-7)",
+ },
+ warning: {
+ 1: "var(--warning-1)",
+ 2: "var(--warning-2)",
+ 3: "var(--warning-3)",
+ 4: "var(--warning-4)",
+ 5: "var(--warning-5)",
+ 6: "var(--warning-6)",
+ 7: "var(--warning-7)",
+ },
+ danger: {
+ 1: "var(--danger-1)",
+ 2: "var(--danger-2)",
+ 3: "var(--danger-3)",
+ 4: "var(--danger-4)",
+ 5: "var(--danger-5)",
+ 6: "var(--danger-6)",
+ 7: "var(--danger-7)",
+ },
+ link: {
+ 1: "var(--link-1)",
+ 2: "var(--link-2)",
+ 3: "var(--link-3)",
+ 4: "var(--link-4)",
+ 5: "var(--link-5)",
+ 6: "var(--link-6)",
+ 7: "var(--link-7)",
+ },
+ background: {
+ 1: "var(--color-bg-1)",
+ 2: "var(--color-bg-2)",
+ 3: "var(--color-bg-3)",
+ 4: "var(--color-bg-4)",
+ 5: "var(--color-bg-5)",
+ white: "var(--color-bg-white)",
+ },
+ text: {
+ 1: "var(--color-text-1)",
+ 2: "var(--color-text-2)",
+ 3: "var(--color-text-3)",
+ 4: "var(--color-text-4)",
+ },
+ border: {
+ 1: "var(--color-border-1)",
+ 2: "var(--color-border-2)",
+ 3: "var(--color-border-3)",
+ 4: "var(--color-border-4)",
+ },
+ fill: {
+ 1: "var(--color-fill-1)",
+ 2: "var(--color-fill-2)",
+ 3: "var(--color-fill-3)",
+ 4: "var(--color-fill-4)",
+ },
+ },
+ },
+ },
+};
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..8c8ba5e
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "node",
+ "allowSyntheticDefaultImports": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..081c8d9
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,6 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+
+export default defineConfig({
+ plugins: [react()],
+});