@wangs-ui/create-react-app 1.0.1
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/dist/bin.js +445 -0
- package/package.json +64 -0
- package/template/README.md +114 -0
- package/template/_gitignore +25 -0
- package/template/_npmrc +3 -0
- package/template/_pnpm-workspace.yaml +6 -0
- package/template/agents/AGENTS.md +59 -0
- package/template/agents/agents.mcp.json +8 -0
- package/template/agents/kilo.mcp.json +8 -0
- package/template/agents/mcp.json +8 -0
- package/template/agents/opencode.json +9 -0
- package/template/index.html +20 -0
- package/template/oxfmt.config.ts +3 -0
- package/template/oxlint.config.ts +3 -0
- package/template/package.json +48 -0
- package/template/public/wangs_ui_logo.png +0 -0
- package/template/src/App.tsx +26 -0
- package/template/src/components/AuthLayout.tsx +31 -0
- package/template/src/components/Footer.tsx +41 -0
- package/template/src/index.css +5 -0
- package/template/src/main.tsx +36 -0
- package/template/src/pages/Landing.tsx +321 -0
- package/template/src/pages/Login.tsx +151 -0
- package/template/src/pages/Register.tsx +166 -0
- package/template/src/vite-env.d.ts +1 -0
- package/template/tsconfig.app.json +27 -0
- package/template/tsconfig.json +4 -0
- package/template/tsconfig.node.json +24 -0
- package/template/vite.config.ts +21 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# AI Agent Instructions for Wangs UI
|
|
2
|
+
|
|
3
|
+
This application is built with **Wangs UI** (`@wangs-ui/react-core`, `@wangs-ui/foundation`, `@wangs-ui/react-icons`, `@wangs-ui/react-presets`, `@wangs-ui/react-i18n`, `@wangs-ui/form`), Tailwind CSS v4, and Vite 8.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Core Principles & Strict Rules
|
|
8
|
+
|
|
9
|
+
1. **Primitive Component Rule (Mandatory)**:
|
|
10
|
+
- Always use components from `@wangs-ui/react-core` (`Button`, `Card`, `Dialog`, `Modal`, `Form`, `Field`, `Input`, `NumberInput`, `Select`, `DataTable`, etc.) and universal typography primitives from `@wangs-ui/foundation/theme` (`Text`, `Code`, `Kbd`, `Link`, `Mark`, `Blockquote`, `List`).
|
|
11
|
+
- Do NOT write unstyled raw HTML controls (`<button>`, `<input>`, `<select>`, `<form>`, `<h1-h6>`, `<p>`).
|
|
12
|
+
|
|
13
|
+
2. **Internationalization (`@wangs-ui/react-i18n`)**:
|
|
14
|
+
- All text visible to users MUST be wrapped in `t()` from `useI18n()`.
|
|
15
|
+
- Use natural English sentence keys (`t('Invoice Summary')`) and `{{variable}}` interpolation.
|
|
16
|
+
- Never hardcode raw string literals or concatenate strings in JSX.
|
|
17
|
+
- For formatting dates, times, currencies, or numbers, use `useLocaleFormatter()`:
|
|
18
|
+
```tsx
|
|
19
|
+
import { useI18n, useLocaleFormatter } from '@wangs-ui/react-i18n';
|
|
20
|
+
|
|
21
|
+
const { t } = useI18n();
|
|
22
|
+
const { formatDate, formatCurrency } = useLocaleFormatter();
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. **Typography & Styling Tokens**:
|
|
26
|
+
- Use universal typography components from `@wangs-ui/foundation/theme` (`Text`, `Code`, `Kbd`, `Link`, `Mark`, `Blockquote`, `List`) with semantic variants (`display*`, `headline*`, `title*`, `body*`, `label*`) and color roles.
|
|
27
|
+
- Use predefined 4px spacing tokens (`gap-xs`, `gap-s`, `gap-md`, `gap-m`, `gap-l`, `gap-xl`, `gap-xxl` / `p-xs` to `p-xxl`) and color tokens (`bg-primary-500`, `text-secondary-900`, `shadow-level-1` to `shadow-level-5`).
|
|
28
|
+
|
|
29
|
+
4. **MCP Component Inspection (Single Source of Truth)**:
|
|
30
|
+
- The `@wangs-ui/mcp` server is configured in this workspace.
|
|
31
|
+
- Always query the MCP server (`get-documentation`, `get-documentation-for-story`, `query_graph`) to inspect live component contracts, props, and story implementations before writing code.
|
|
32
|
+
|
|
33
|
+
5. **Specialized System Patterns Over Generic React (Crucial)**:
|
|
34
|
+
- Never assume standard React patterns (e.g., raw `useState` for forms, native `<form onSubmit>`, raw `<a href>`) apply if the design system provides a specialized architecture.
|
|
35
|
+
- For Forms, you **MUST** use `useFormControl` from `@wangs-ui/form`, wrapped in `<Form>`, and input components wrapped in `<Field>`. Do not build "dummy" forms with raw `<form>` tags or standard React controlled inputs.
|
|
36
|
+
- Always use `graphify query` or read the relevant skill files (`.agents/skills/`) to understand the Wangs UI specialized way of implementing features before writing code.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 2. Specialized Skills Reference
|
|
41
|
+
|
|
42
|
+
When performing specific tasks, consult the modular skill files in `.agents/skills/`:
|
|
43
|
+
|
|
44
|
+
- **`wangs-ui-components`**: Core component fundamentals, primitive substitution rule, subpath modular imports, and typography tokens.
|
|
45
|
+
- **`data-table`**: Real-world data grids, `TableColumn<T>[]`, `useDataTable`, `useDataTableFetch`, pagination, sorting, and exports.
|
|
46
|
+
- **`create-form`**: Form implementation, schema validation, server error mapping (`formControl.setError`), and multipart uploads.
|
|
47
|
+
- **`dialog-modal`**: Overlay selection (`Dialog` vs `Modal` vs `DialogForm`), confirmation workflows, and mutation safety.
|
|
48
|
+
- **`i18n-usage`**: Rules for JIT translation, natural English keys, dynamic variables `{{var}}`, ICU plurals, and locale formatters.
|
|
49
|
+
- **`layout-navigation`**: Application layout structure with `AppLayout`, `Sidebar`, `Breadcrumb`, and `Tabs`.
|
|
50
|
+
- **`react19-compiler-typescript`**: React 19 compiler conventions, automatic memoization, and pure rendering rules.
|
|
51
|
+
- **`typescript-strict-typing`**: Strict type discipline (no `any`, `unknown` narrowing, discriminated unions).
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 3. Code Quality & Toolchain
|
|
56
|
+
|
|
57
|
+
- **Linter**: `oxlint` (run `pnpm lint`)
|
|
58
|
+
- **Formatter**: `oxfmt` (run `pnpm format`)
|
|
59
|
+
- **Type Checker**: TypeScript with `tsc -b` (run `pnpm build`)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/png" href="/wangs_ui_logo.png" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link
|
|
10
|
+
href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&display=swap"
|
|
11
|
+
rel="stylesheet"
|
|
12
|
+
/>
|
|
13
|
+
<title>Wangs UI - Tactile & Grounded React Components</title>
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<div id="root"></div>
|
|
18
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wangs-ui-react-app",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"analyze": "ANALYZE=true vite build",
|
|
10
|
+
"preview": "vite preview",
|
|
11
|
+
"lint": "oxlint -c oxlint.config.ts",
|
|
12
|
+
"lint:fix": "oxlint -c oxlint.config.ts --fix",
|
|
13
|
+
"format": "oxfmt --write",
|
|
14
|
+
"format:check": "oxfmt --check"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@wangs-ui/animations": "workspace:*",
|
|
18
|
+
"@wangs-ui/form": "^1.0.16",
|
|
19
|
+
"@wangs-ui/foundation": "workspace:*",
|
|
20
|
+
"@wangs-ui/react-core": "workspace:*",
|
|
21
|
+
"@wangs-ui/react-i18n": "workspace:*",
|
|
22
|
+
"@wangs-ui/react-icons": "workspace:*",
|
|
23
|
+
"@wangs-ui/react-presets": "workspace:*",
|
|
24
|
+
"clsx": "^2.1.1",
|
|
25
|
+
"react": "19.2.7",
|
|
26
|
+
"react-dom": "19.2.7",
|
|
27
|
+
"react-router-dom": "7.17.0",
|
|
28
|
+
"tailwind-merge": "^3.6.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@babel/core": "^7.29.7",
|
|
32
|
+
"@fewangsit/oxlint-config-react": "^1.0.13",
|
|
33
|
+
"@rolldown/plugin-babel": "^0.2.3",
|
|
34
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
35
|
+
"@types/babel__core": "^7.20.5",
|
|
36
|
+
"@types/node": "^25.9.5",
|
|
37
|
+
"@types/react": "19.2.17",
|
|
38
|
+
"@types/react-dom": "19.2.4",
|
|
39
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
40
|
+
"babel-plugin-react-compiler": "^1.0.0",
|
|
41
|
+
"oxfmt": "^0.60.0",
|
|
42
|
+
"oxlint": "^1.78.0",
|
|
43
|
+
"rollup-plugin-visualizer": "^7.1.1",
|
|
44
|
+
"tailwindcss": "^4.3.3",
|
|
45
|
+
"typescript": "^6.0.3",
|
|
46
|
+
"vite": "^8.2.1"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { Suspense } from 'react';
|
|
2
|
+
import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
|
3
|
+
|
|
4
|
+
const Landing = React.lazy(() => import('./pages/Landing'));
|
|
5
|
+
const Login = React.lazy(() => import('./pages/Login'));
|
|
6
|
+
const Register = React.lazy(() => import('./pages/Register'));
|
|
7
|
+
|
|
8
|
+
export default function App(): React.JSX.Element {
|
|
9
|
+
return (
|
|
10
|
+
<BrowserRouter>
|
|
11
|
+
<Suspense
|
|
12
|
+
fallback={
|
|
13
|
+
<div className="bg-background flex min-h-screen items-center justify-center">
|
|
14
|
+
<div className="border-primary size-8 animate-spin rounded-full border-4 border-t-transparent"></div>
|
|
15
|
+
</div>
|
|
16
|
+
}
|
|
17
|
+
>
|
|
18
|
+
<Routes>
|
|
19
|
+
<Route path="/" element={<Landing />} />
|
|
20
|
+
<Route path="/login" element={<Login />} />
|
|
21
|
+
<Route path="/register" element={<Register />} />
|
|
22
|
+
</Routes>
|
|
23
|
+
</Suspense>
|
|
24
|
+
</BrowserRouter>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import Footer from './Footer';
|
|
4
|
+
|
|
5
|
+
interface AuthLayoutProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function AuthLayout({ children }: AuthLayoutProps): React.JSX.Element {
|
|
10
|
+
return (
|
|
11
|
+
<div className="bg-background text-on-surface font-body-md relative flex min-h-screen flex-col overflow-hidden">
|
|
12
|
+
{/* Decorative subtle background elements */}
|
|
13
|
+
<div className="pointer-events-none absolute top-0 left-0 h-full w-full opacity-[0.03]">
|
|
14
|
+
<svg height="100%" width="100%" xmlns="http://www.w3.org/2000/svg">
|
|
15
|
+
<defs>
|
|
16
|
+
<pattern height="40" id="grid" patternUnits="userSpaceOnUse" width="40">
|
|
17
|
+
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="currentColor" strokeWidth="1"></path>
|
|
18
|
+
</pattern>
|
|
19
|
+
</defs>
|
|
20
|
+
<rect fill="url(#grid)" height="100%" width="100%"></rect>
|
|
21
|
+
</svg>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<main className="relative z-10 flex grow items-center justify-center p-6 md:p-10">
|
|
25
|
+
<div className="w-full max-w-md">{children}</div>
|
|
26
|
+
</main>
|
|
27
|
+
|
|
28
|
+
<Footer />
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Link, Text } from '@wangs-ui/foundation/theme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
export default function Footer(): React.JSX.Element {
|
|
5
|
+
return (
|
|
6
|
+
<footer className="border-outline-variant bg-surface-container-lowest border-t px-6 py-12">
|
|
7
|
+
<div className="mx-auto flex max-w-7xl flex-col items-center justify-between gap-6 md:flex-row">
|
|
8
|
+
<div className="flex items-center gap-3">
|
|
9
|
+
<img
|
|
10
|
+
src="/wangs_ui_logo.png"
|
|
11
|
+
alt="Wangs UI Logo"
|
|
12
|
+
className="h-6 w-6 opacity-60 grayscale"
|
|
13
|
+
/>
|
|
14
|
+
<Text variant="bodyMedium" color="secondary">
|
|
15
|
+
© {new Date().getFullYear()} Wangs UI. All rights reserved.
|
|
16
|
+
</Text>
|
|
17
|
+
</div>
|
|
18
|
+
<div className="flex flex-wrap justify-center gap-6">
|
|
19
|
+
<Link
|
|
20
|
+
href="/"
|
|
21
|
+
className="text-on-surface-variant hover:text-primary text-body-small transition-colors"
|
|
22
|
+
>
|
|
23
|
+
Twitter
|
|
24
|
+
</Link>
|
|
25
|
+
<Link
|
|
26
|
+
href="/"
|
|
27
|
+
className="text-on-surface-variant hover:text-primary text-body-small transition-colors"
|
|
28
|
+
>
|
|
29
|
+
GitHub
|
|
30
|
+
</Link>
|
|
31
|
+
<Link
|
|
32
|
+
href="/"
|
|
33
|
+
className="text-on-surface-variant hover:text-primary text-body-small transition-colors"
|
|
34
|
+
>
|
|
35
|
+
Discord
|
|
36
|
+
</Link>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</footer>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { WangsUiProvider } from '@wangs-ui/react-core/api';
|
|
2
|
+
import { WangsUiI18nProvider } from '@wangs-ui/react-i18n';
|
|
3
|
+
import gold from '@wangs-ui/react-presets/gold';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import ReactDOM from 'react-dom/client';
|
|
6
|
+
|
|
7
|
+
import App from './App';
|
|
8
|
+
|
|
9
|
+
import './index.css';
|
|
10
|
+
|
|
11
|
+
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
|
12
|
+
<React.StrictMode>
|
|
13
|
+
<WangsUiI18nProvider defaultLocale="en">
|
|
14
|
+
<WangsUiProvider
|
|
15
|
+
configOptions={{
|
|
16
|
+
preset: gold,
|
|
17
|
+
defaultProps: {
|
|
18
|
+
divider: {
|
|
19
|
+
pt: {
|
|
20
|
+
label: {
|
|
21
|
+
className: 'tracking-wider uppercase',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}}
|
|
27
|
+
theme={{
|
|
28
|
+
palette: 'gold',
|
|
29
|
+
fontFamily: { sans: '"Hanken Grotesk", sans-serif' },
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
<App />
|
|
33
|
+
</WangsUiProvider>
|
|
34
|
+
</WangsUiI18nProvider>
|
|
35
|
+
</React.StrictMode>,
|
|
36
|
+
);
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { Text, Link as ThemeLink, Ul, Li, useTheme, cn } from '@wangs-ui/foundation/theme';
|
|
2
|
+
import Badge from '@wangs-ui/react-core/primitive/badge';
|
|
3
|
+
import Button from '@wangs-ui/react-core/primitive/button';
|
|
4
|
+
import Card from '@wangs-ui/react-core/primitive/card';
|
|
5
|
+
import CopyButton from '@wangs-ui/react-core/primitive/copybutton';
|
|
6
|
+
import Label from '@wangs-ui/react-core/primitive/label';
|
|
7
|
+
import Switch from '@wangs-ui/react-core/primitive/switch';
|
|
8
|
+
import {
|
|
9
|
+
ArrowRightLine,
|
|
10
|
+
CheckLine,
|
|
11
|
+
CodeLine,
|
|
12
|
+
GlobalLine,
|
|
13
|
+
PaletteLine,
|
|
14
|
+
MoonFill,
|
|
15
|
+
SunLine,
|
|
16
|
+
} from '@wangs-ui/react-icons';
|
|
17
|
+
import React, { useState } from 'react';
|
|
18
|
+
import { useNavigate } from 'react-router-dom';
|
|
19
|
+
|
|
20
|
+
import Footer from '../components/Footer';
|
|
21
|
+
|
|
22
|
+
function DarkModeSwitch(props: Partial<React.ComponentProps<typeof Switch>>): React.ReactElement {
|
|
23
|
+
const { mode, setMode } = useTheme();
|
|
24
|
+
return (
|
|
25
|
+
<Switch
|
|
26
|
+
{...props}
|
|
27
|
+
checked={mode === 'dark'}
|
|
28
|
+
onChange={(checked) => setMode(checked ? 'dark' : 'light')}
|
|
29
|
+
aria-label="Toggle dark mode"
|
|
30
|
+
pt={{
|
|
31
|
+
track: () => ({
|
|
32
|
+
className: [
|
|
33
|
+
'flex items-center w-16 border-transparent!',
|
|
34
|
+
mode === 'dark' ? 'bg-secondary-800!' : 'bg-general-50!',
|
|
35
|
+
],
|
|
36
|
+
}),
|
|
37
|
+
thumb: () => ({
|
|
38
|
+
className: [
|
|
39
|
+
'flex items-center justify-center',
|
|
40
|
+
mode === 'dark' ? 'bg-secondary-900!' : 'bg-white!',
|
|
41
|
+
],
|
|
42
|
+
}),
|
|
43
|
+
}}
|
|
44
|
+
size="lg"
|
|
45
|
+
thumbContent={() => {
|
|
46
|
+
const Icon = mode === 'dark' ? MoonFill : SunLine;
|
|
47
|
+
return (
|
|
48
|
+
<Icon className={cn('size-3.5', mode === 'dark' ? 'text-white' : 'text-general-500')} />
|
|
49
|
+
);
|
|
50
|
+
}}
|
|
51
|
+
trackContent={() => (
|
|
52
|
+
<span
|
|
53
|
+
className={`text-label-small flex w-full items-center p-1 font-medium transition-all ${
|
|
54
|
+
mode === 'dark' ? 'justify-start text-white' : 'text-general-500 justify-end'
|
|
55
|
+
}`}
|
|
56
|
+
>
|
|
57
|
+
{mode === 'dark' ? 'Dark' : 'Light'}
|
|
58
|
+
</span>
|
|
59
|
+
)}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default function Landing(): React.ReactElement {
|
|
65
|
+
const { mode, setMode } = useTheme();
|
|
66
|
+
const [analyticsEnabled, setAnalyticsEnabled] = useState(true);
|
|
67
|
+
const navigate = useNavigate();
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div className="bg-background text-on-background selection:bg-primary-200 selection:text-primary-900 min-h-screen antialiased">
|
|
71
|
+
{/* Header */}
|
|
72
|
+
<header className="border-outline-variant bg-surface/80 sticky top-0 z-50 flex items-center justify-between border-b px-6 py-4 backdrop-blur-md">
|
|
73
|
+
<div className="flex items-center gap-3">
|
|
74
|
+
<img src="/wangs_ui_logo.png" alt="Wangs UI Logo" className="h-8 w-8 rounded-md" />
|
|
75
|
+
<Text as="span" variant="titleMedium" weight="bold" color="on-surface">
|
|
76
|
+
Wangs UI
|
|
77
|
+
</Text>
|
|
78
|
+
</div>
|
|
79
|
+
<nav className="hidden items-center gap-6 md:flex">
|
|
80
|
+
<ThemeLink
|
|
81
|
+
href="/"
|
|
82
|
+
className="text-on-surface-variant hover:text-primary text-body-medium font-medium transition-colors"
|
|
83
|
+
>
|
|
84
|
+
Docs
|
|
85
|
+
</ThemeLink>
|
|
86
|
+
<ThemeLink
|
|
87
|
+
href="/"
|
|
88
|
+
className="text-on-surface-variant hover:text-primary text-body-medium font-medium transition-colors"
|
|
89
|
+
>
|
|
90
|
+
Components
|
|
91
|
+
</ThemeLink>
|
|
92
|
+
<ThemeLink
|
|
93
|
+
href="/"
|
|
94
|
+
className="text-on-surface-variant hover:text-primary text-body-medium font-medium transition-colors"
|
|
95
|
+
>
|
|
96
|
+
Design System
|
|
97
|
+
</ThemeLink>
|
|
98
|
+
<ThemeLink
|
|
99
|
+
href="/"
|
|
100
|
+
className="text-on-surface-variant hover:text-primary text-body-medium font-medium transition-colors"
|
|
101
|
+
>
|
|
102
|
+
GitHub
|
|
103
|
+
</ThemeLink>
|
|
104
|
+
</nav>
|
|
105
|
+
<div className="flex items-center gap-3">
|
|
106
|
+
<DarkModeSwitch />
|
|
107
|
+
<Button
|
|
108
|
+
variant="text"
|
|
109
|
+
label="Log in"
|
|
110
|
+
severity="secondary"
|
|
111
|
+
size="sm"
|
|
112
|
+
onClick={() => navigate('/login')}
|
|
113
|
+
/>
|
|
114
|
+
<Button
|
|
115
|
+
variant="filled"
|
|
116
|
+
label="Get Started"
|
|
117
|
+
severity="primary"
|
|
118
|
+
size="sm"
|
|
119
|
+
onClick={() => navigate('/register')}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
</header>
|
|
123
|
+
|
|
124
|
+
<main>
|
|
125
|
+
{/* Hero Section */}
|
|
126
|
+
<section className="relative flex flex-col items-center justify-center overflow-hidden px-6 py-32 text-center md:py-48">
|
|
127
|
+
<div className="from-primary-100/50 via-background to-background absolute inset-0 -z-10 bg-[radial-gradient(ellipse_at_top,var(--tw-gradient-stops))]" />
|
|
128
|
+
<div className="animate-fadein max-w-3xl space-y-8">
|
|
129
|
+
<Label severity="primary" variant="light" size="sm">
|
|
130
|
+
<Badge variant="dot" size="xs" className="animate-pulse" />
|
|
131
|
+
v1.0 is now live
|
|
132
|
+
</Label>
|
|
133
|
+
|
|
134
|
+
<Text
|
|
135
|
+
as="h1"
|
|
136
|
+
variant="displayLarge"
|
|
137
|
+
weight="bold"
|
|
138
|
+
color="onSurface"
|
|
139
|
+
className="font-sans"
|
|
140
|
+
>
|
|
141
|
+
Tactile. Grounded. <span className="text-primary-600">Accessible.</span>
|
|
142
|
+
</Text>
|
|
143
|
+
|
|
144
|
+
<Text
|
|
145
|
+
as="p"
|
|
146
|
+
variant="titleLarge"
|
|
147
|
+
color="onSurfaceVariant"
|
|
148
|
+
className="mx-auto max-w-2xl"
|
|
149
|
+
>
|
|
150
|
+
A premium React UI library designed for developers who value speed, accessibility, and
|
|
151
|
+
a unique earthy aesthetic. Build distinct digital experiences.
|
|
152
|
+
</Text>
|
|
153
|
+
|
|
154
|
+
<div className="flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row">
|
|
155
|
+
<Button
|
|
156
|
+
variant="filled"
|
|
157
|
+
severity="primary"
|
|
158
|
+
size="lg"
|
|
159
|
+
label="Explore Components"
|
|
160
|
+
icon={<ArrowRightLine />}
|
|
161
|
+
/>
|
|
162
|
+
<Button
|
|
163
|
+
variant="outline"
|
|
164
|
+
severity="secondary"
|
|
165
|
+
size="lg"
|
|
166
|
+
label="Read Documentation"
|
|
167
|
+
icon={<CodeLine />}
|
|
168
|
+
/>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div className="border-outline-variant bg-surface-container-low shadow-level-1 mx-auto mt-12 flex max-w-md items-center justify-center rounded-xl border p-4 font-mono text-sm">
|
|
172
|
+
<Text variant="bodyMedium" color="onSurfaceVariant" className="mr-4 select-none">
|
|
173
|
+
$
|
|
174
|
+
</Text>
|
|
175
|
+
<Text variant="bodyMedium" color="onSurface">
|
|
176
|
+
pnpm create @wangs-ui/react-app my-app
|
|
177
|
+
</Text>
|
|
178
|
+
<CopyButton className="ml-auto" text="pnpm create @wangs-ui/react-app my-app" />
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
</section>
|
|
182
|
+
|
|
183
|
+
{/* Features Grid */}
|
|
184
|
+
<section className="bg-surface-container-lowest border-outline-variant border-y px-6 py-24">
|
|
185
|
+
<div className="mx-auto max-w-7xl">
|
|
186
|
+
<div className="mb-16 text-center">
|
|
187
|
+
<Text as="h2" variant="headlineMedium" weight="bold" color="on-surface">
|
|
188
|
+
Designed for the modern web
|
|
189
|
+
</Text>
|
|
190
|
+
<Text variant="bodyLarge" color="secondary" className="mt-4">
|
|
191
|
+
Everything you need to build stunning, production-ready applications.
|
|
192
|
+
</Text>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div className="grid grid-cols-1 gap-8 md:grid-cols-3">
|
|
196
|
+
{[
|
|
197
|
+
{
|
|
198
|
+
icon: <GlobalLine className="h-6 w-6" />,
|
|
199
|
+
title: 'Accessible by Default',
|
|
200
|
+
desc: 'Built with ARIA support, focus management, and keyboard navigation at its core. 100/100 Lighthouse scores guaranteed.',
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
icon: <PaletteLine className="h-6 w-6" />,
|
|
204
|
+
title: 'Themable Design System',
|
|
205
|
+
desc: 'Powered by a robust token system. Easily adapt roundness, typography, and organic color palettes like our signature Gold.',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
icon: <CodeLine className="h-6 w-6" />,
|
|
209
|
+
title: 'Developer Experience',
|
|
210
|
+
desc: 'Strictly typed, thoroughly documented, and lightweight with zero bloat. Seamlessly integrated with Tailwind CSS v4.',
|
|
211
|
+
},
|
|
212
|
+
].map((feature, i) => (
|
|
213
|
+
<div
|
|
214
|
+
key={i}
|
|
215
|
+
className="border-outline-variant bg-surface shadow-level-1 hover:border-primary-300 flex flex-col gap-4 rounded-2xl border p-8 transition-transform hover:-translate-y-1"
|
|
216
|
+
>
|
|
217
|
+
<div className="bg-primary-100 text-primary-700 flex h-12 w-12 items-center justify-center rounded-xl">
|
|
218
|
+
{feature.icon}
|
|
219
|
+
</div>
|
|
220
|
+
<Text variant="titleLarge" weight="bold" color="on-surface">
|
|
221
|
+
{feature.title}
|
|
222
|
+
</Text>
|
|
223
|
+
<Text variant="bodyMedium" color="secondary" className="leading-relaxed">
|
|
224
|
+
{feature.desc}
|
|
225
|
+
</Text>
|
|
226
|
+
</div>
|
|
227
|
+
))}
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
</section>
|
|
231
|
+
|
|
232
|
+
{/* Interactive Showcase */}
|
|
233
|
+
<section className="px-6 py-24">
|
|
234
|
+
<div className="mx-auto max-w-5xl">
|
|
235
|
+
<div className="grid grid-cols-1 items-center gap-16 lg:grid-cols-2">
|
|
236
|
+
<div className="space-y-6">
|
|
237
|
+
<Text as="h2" variant="headlineMedium" weight="bold" color="on-surface">
|
|
238
|
+
Premium aesthetics out of the box
|
|
239
|
+
</Text>
|
|
240
|
+
<Text variant="bodyLarge" color="secondary" className="leading-relaxed">
|
|
241
|
+
Notice the tactile feel, the carefully calibrated spacing, and the warm, grounded
|
|
242
|
+
colors. Wangs UI breaks away from cold, generic material trends to give your
|
|
243
|
+
product a distinct soul.
|
|
244
|
+
</Text>
|
|
245
|
+
<Ul spacing="tight" className="pt-4">
|
|
246
|
+
{[
|
|
247
|
+
'Hanken Grotesk typography',
|
|
248
|
+
'4px unified roundness tokens',
|
|
249
|
+
'Earthy & organic gold palette',
|
|
250
|
+
].map((item, i) => (
|
|
251
|
+
<Li
|
|
252
|
+
key={i}
|
|
253
|
+
icon={
|
|
254
|
+
<div className="bg-success-100 text-success-700 flex h-6 w-6 items-center justify-center rounded-full">
|
|
255
|
+
<CheckLine className="h-4 w-4" />
|
|
256
|
+
</div>
|
|
257
|
+
}
|
|
258
|
+
>
|
|
259
|
+
<Text variant="bodyMedium" weight="medium" color="on-surface">
|
|
260
|
+
{item}
|
|
261
|
+
</Text>
|
|
262
|
+
</Li>
|
|
263
|
+
))}
|
|
264
|
+
</Ul>
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
<Card className="shadow-level-3 border-outline before:from-primary-300 before:to-primary-600 bg-surface relative mx-auto flex w-full max-w-md flex-col gap-6 p-8 before:absolute before:-inset-0.5 before:-z-10 before:rounded-3xl before:bg-linear-to-tr before:opacity-20 before:blur-xl before:transition-all before:duration-500 hover:before:opacity-40 hover:before:blur-2xl">
|
|
268
|
+
<div className="flex items-center justify-between">
|
|
269
|
+
<div className="flex items-center gap-4">
|
|
270
|
+
<div className="bg-primary-100 text-primary-700 flex h-12 w-12 items-center justify-center rounded-full text-lg font-bold">
|
|
271
|
+
WU
|
|
272
|
+
</div>
|
|
273
|
+
<div>
|
|
274
|
+
<Text variant="titleMedium" weight="bold" color="on-surface">
|
|
275
|
+
Organization Settings
|
|
276
|
+
</Text>
|
|
277
|
+
<Text variant="labelSmall" color="secondary">
|
|
278
|
+
Manage your workspace preferences
|
|
279
|
+
</Text>
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
</div>
|
|
283
|
+
|
|
284
|
+
<div className="border-outline-variant space-y-4 border-t pt-4">
|
|
285
|
+
<Switch
|
|
286
|
+
checked={analyticsEnabled}
|
|
287
|
+
onChange={setAnalyticsEnabled}
|
|
288
|
+
aria-label="Enable Analytics"
|
|
289
|
+
label="Enable Analytics"
|
|
290
|
+
labelPosition="before"
|
|
291
|
+
className="text-label-small w-full justify-between"
|
|
292
|
+
/>
|
|
293
|
+
<Switch
|
|
294
|
+
checked={mode === 'dark'}
|
|
295
|
+
onChange={(checked) => setMode(checked ? 'dark' : 'light')}
|
|
296
|
+
aria-label="Toggle dark mode"
|
|
297
|
+
label="Dark Mode"
|
|
298
|
+
labelPosition="before"
|
|
299
|
+
className="text-label-small w-full justify-between"
|
|
300
|
+
/>
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<div className="border-outline-variant flex gap-3 border-t pt-6">
|
|
304
|
+
<Button
|
|
305
|
+
className="flex-1"
|
|
306
|
+
variant="filled"
|
|
307
|
+
severity="primary"
|
|
308
|
+
label="Save Changes"
|
|
309
|
+
/>
|
|
310
|
+
<Button variant="outline" severity="secondary" label="Cancel" />
|
|
311
|
+
</div>
|
|
312
|
+
</Card>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
</section>
|
|
316
|
+
</main>
|
|
317
|
+
|
|
318
|
+
<Footer />
|
|
319
|
+
</div>
|
|
320
|
+
);
|
|
321
|
+
}
|