@wangs-ui/create-react-app 1.0.50 → 1.0.51
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 +22 -1222
- package/package.json +3 -3
- package/template/agents/AGENTS.md +5 -0
- package/template/index.html +4 -3
- package/template/package.json +14 -11
- package/template/src/App.tsx +21 -61
- package/template/src/components/AuthLayout.tsx +31 -0
- package/template/src/components/Footer.tsx +41 -0
- package/template/src/index.css +1 -1
- package/template/src/main.tsx +19 -2
- package/template/src/pages/Landing.tsx +312 -0
- package/template/src/pages/Login.tsx +151 -0
- package/template/src/pages/Register.tsx +165 -0
- package/template/tsconfig.app.json +3 -2
- package/template/vite.config.ts +14 -1
- package/template/agents/CLAUDE.md +0 -22
- /package/template/{pnpm-workspace.yaml → _pnpm-workspace.yaml} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wangs-ui/create-react-app",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.51",
|
|
4
4
|
"description": "Scaffold a modern React app with Wangs UI, Vite 8, Oxlint, Oxfmt, and AI Agent MCP integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"antigravity",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"template/vite.config.ts",
|
|
41
41
|
"template/_gitignore",
|
|
42
42
|
"template/_npmrc",
|
|
43
|
-
"template/
|
|
43
|
+
"template/_pnpm-workspace.yaml",
|
|
44
44
|
"template/src",
|
|
45
45
|
"template/agents",
|
|
46
46
|
"template/README.md"
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@clack/prompts": "^1.7.0",
|
|
55
|
-
"@wangs-ui/skills": "1.0.
|
|
55
|
+
"@wangs-ui/skills": "1.0.51"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {},
|
|
58
58
|
"scripts": {
|
|
@@ -30,6 +30,11 @@ This application is built with **Wangs UI** (`@wangs-ui/react-core`, `@wangs-ui/
|
|
|
30
30
|
- The `@wangs-ui/mcp` server is configured in this workspace.
|
|
31
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
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
|
+
|
|
33
38
|
---
|
|
34
39
|
|
|
35
40
|
## 2. Specialized Skills Reference
|
package/template/index.html
CHANGED
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/png" href="/wangs_ui_logo.png" />
|
|
5
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
7
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
7
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
8
9
|
<link
|
|
9
|
-
href="https://fonts.googleapis.com/css2?family=
|
|
10
|
+
href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&display=swap"
|
|
10
11
|
rel="stylesheet"
|
|
11
12
|
/>
|
|
12
|
-
<title>Wangs UI React
|
|
13
|
+
<title>Wangs UI - Tactile & Grounded React Components</title>
|
|
13
14
|
</head>
|
|
14
15
|
|
|
15
|
-
<body
|
|
16
|
+
<body>
|
|
16
17
|
<div id="root"></div>
|
|
17
18
|
<script type="module" src="/src/main.tsx"></script>
|
|
18
19
|
</body>
|
package/template/package.json
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
|
-
"build": "
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"analyze": "ANALYZE=true vite build",
|
|
9
10
|
"preview": "vite preview",
|
|
10
11
|
"lint": "oxlint -c oxlint.config.ts",
|
|
11
12
|
"lint:fix": "oxlint -c oxlint.config.ts --fix",
|
|
@@ -13,15 +14,16 @@
|
|
|
13
14
|
"format:check": "oxfmt --check"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
|
-
"@wangs-ui/animations": "^1.0.
|
|
17
|
-
"@wangs-ui/foundation": "^1.0.
|
|
18
|
-
"@wangs-ui/react-core": "^1.0.
|
|
19
|
-
"@wangs-ui/react-i18n": "^1.0.
|
|
20
|
-
"@wangs-ui/react-icons": "^1.0.
|
|
21
|
-
"@wangs-ui/react-presets": "^1.0.
|
|
17
|
+
"@wangs-ui/animations": "^1.0.51",
|
|
18
|
+
"@wangs-ui/foundation": "^1.0.51",
|
|
19
|
+
"@wangs-ui/react-core": "^1.0.51",
|
|
20
|
+
"@wangs-ui/react-i18n": "^1.0.51",
|
|
21
|
+
"@wangs-ui/react-icons": "^1.0.51",
|
|
22
|
+
"@wangs-ui/react-presets": "^1.0.51",
|
|
22
23
|
"clsx": "^2.1.1",
|
|
23
|
-
"react": "
|
|
24
|
-
"react-dom": "
|
|
24
|
+
"react": "19.2.7",
|
|
25
|
+
"react-dom": "19.2.7",
|
|
26
|
+
"react-router-dom": "7.17.0",
|
|
25
27
|
"tailwind-merge": "^3.6.0"
|
|
26
28
|
},
|
|
27
29
|
"devDependencies": {
|
|
@@ -31,12 +33,13 @@
|
|
|
31
33
|
"@tailwindcss/vite": "^4.3.3",
|
|
32
34
|
"@types/babel__core": "^7.20.5",
|
|
33
35
|
"@types/node": "^25.9.5",
|
|
34
|
-
"@types/react": "
|
|
35
|
-
"@types/react-dom": "
|
|
36
|
+
"@types/react": "19.2.17",
|
|
37
|
+
"@types/react-dom": "19.2.4",
|
|
36
38
|
"@vitejs/plugin-react": "^6.0.5",
|
|
37
39
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
38
40
|
"oxfmt": "^0.60.0",
|
|
39
41
|
"oxlint": "^1.78.0",
|
|
42
|
+
"rollup-plugin-visualizer": "^7.1.1",
|
|
40
43
|
"tailwindcss": "^4.3.3",
|
|
41
44
|
"typescript": "^6.0.3",
|
|
42
45
|
"vite": "^8.2.1"
|
package/template/src/App.tsx
CHANGED
|
@@ -1,66 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import Card from '@wangs-ui/react-core/primitive/card';
|
|
4
|
-
import { useI18n, useLocaleFormatter } from '@wangs-ui/react-i18n';
|
|
5
|
-
import { AddLine, RefreshLine } from '@wangs-ui/react-icons';
|
|
6
|
-
import React, { useState } from 'react';
|
|
1
|
+
import React, { Suspense } from 'react';
|
|
2
|
+
import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const [count, setCount] = useState<number>(0);
|
|
4
|
+
const Landing = React.lazy(() => import('./pages/Landing'));
|
|
5
|
+
const Login = React.lazy(() => import('./pages/Login'));
|
|
6
|
+
const Register = React.lazy(() => import('./pages/Register'));
|
|
12
7
|
|
|
8
|
+
export default function App(): React.JSX.Element {
|
|
13
9
|
return (
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
</
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<Text variant="titleLarge" weight="bold" color="primary" className="font-mono">
|
|
30
|
-
{count}
|
|
31
|
-
</Text>
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<div className="flex gap-3">
|
|
35
|
-
<Button
|
|
36
|
-
className="flex-1"
|
|
37
|
-
icon={<AddLine />}
|
|
38
|
-
label={t('Increment')}
|
|
39
|
-
severity="primary"
|
|
40
|
-
variant="filled"
|
|
41
|
-
onClick={() => setCount((c) => c + 1)}
|
|
42
|
-
/>
|
|
43
|
-
<Button
|
|
44
|
-
icon={<RefreshLine />}
|
|
45
|
-
label={t('Reset')}
|
|
46
|
-
severity="secondary"
|
|
47
|
-
variant="outline"
|
|
48
|
-
onClick={() => setCount(0)}
|
|
49
|
-
/>
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
<div className="border-secondary-200 flex items-center justify-between border-t pt-4">
|
|
53
|
-
<Text variant="labelSmall" color="secondary">
|
|
54
|
-
{t('Language: {0}', locale.toUpperCase())}
|
|
55
|
-
</Text>
|
|
56
|
-
<Button
|
|
57
|
-
variant="text"
|
|
58
|
-
size="xs"
|
|
59
|
-
label={t('Switch to {0}', locale === 'en' ? 'Bahasa Indonesia' : 'English')}
|
|
60
|
-
onClick={() => setLocale(locale === 'en' ? 'id' : 'en')}
|
|
61
|
-
/>
|
|
62
|
-
</div>
|
|
63
|
-
</Card>
|
|
64
|
-
</div>
|
|
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>
|
|
65
25
|
);
|
|
66
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
|
+
}
|
package/template/src/index.css
CHANGED
package/template/src/main.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WangsUiProvider } from '@wangs-ui/react-core/api';
|
|
2
2
|
import { WangsUiI18nProvider } from '@wangs-ui/react-i18n';
|
|
3
|
-
import
|
|
3
|
+
import gold from '@wangs-ui/react-presets/gold';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import ReactDOM from 'react-dom/client';
|
|
6
6
|
|
|
@@ -11,7 +11,24 @@ import './index.css';
|
|
|
11
11
|
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
|
12
12
|
<React.StrictMode>
|
|
13
13
|
<WangsUiI18nProvider defaultLocale="en">
|
|
14
|
-
<WangsUiProvider
|
|
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
|
+
>
|
|
15
32
|
<App />
|
|
16
33
|
</WangsUiProvider>
|
|
17
34
|
</WangsUiI18nProvider>
|
|
@@ -0,0 +1,312 @@
|
|
|
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
|
+
className="text-on-surface font-sans text-5xl font-extrabold tracking-tight md:text-7xl"
|
|
137
|
+
>
|
|
138
|
+
Tactile. Grounded. <span className="text-primary-600">Accessible.</span>
|
|
139
|
+
</Text>
|
|
140
|
+
|
|
141
|
+
<Text
|
|
142
|
+
as="p"
|
|
143
|
+
className="text-on-surface-variant mx-auto max-w-2xl text-lg font-medium md:text-xl"
|
|
144
|
+
>
|
|
145
|
+
A premium React UI library designed for developers who value speed, accessibility, and
|
|
146
|
+
a unique earthy aesthetic. Build distinct digital experiences.
|
|
147
|
+
</Text>
|
|
148
|
+
|
|
149
|
+
<div className="flex flex-col items-center justify-center gap-4 pt-4 sm:flex-row">
|
|
150
|
+
<Button
|
|
151
|
+
variant="filled"
|
|
152
|
+
severity="primary"
|
|
153
|
+
size="lg"
|
|
154
|
+
label="Explore Components"
|
|
155
|
+
icon={<ArrowRightLine />}
|
|
156
|
+
/>
|
|
157
|
+
<Button
|
|
158
|
+
variant="outline"
|
|
159
|
+
severity="secondary"
|
|
160
|
+
size="lg"
|
|
161
|
+
label="Read Documentation"
|
|
162
|
+
icon={<CodeLine />}
|
|
163
|
+
/>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<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">
|
|
167
|
+
<span className="text-on-surface-variant mr-4 select-none">$</span>
|
|
168
|
+
<span className="text-on-surface">pnpm create @wangs-ui/react-app my-app</span>
|
|
169
|
+
<CopyButton className="ml-auto" text="pnpm create @wangs-ui/react-app my-app" />
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</section>
|
|
173
|
+
|
|
174
|
+
{/* Features Grid */}
|
|
175
|
+
<section className="bg-surface-container-lowest border-outline-variant border-y px-6 py-24">
|
|
176
|
+
<div className="mx-auto max-w-7xl">
|
|
177
|
+
<div className="mb-16 text-center">
|
|
178
|
+
<Text as="h2" variant="headlineMedium" weight="bold" color="on-surface">
|
|
179
|
+
Designed for the modern web
|
|
180
|
+
</Text>
|
|
181
|
+
<Text variant="bodyLarge" color="secondary" className="mt-4">
|
|
182
|
+
Everything you need to build stunning, production-ready applications.
|
|
183
|
+
</Text>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<div className="grid grid-cols-1 gap-8 md:grid-cols-3">
|
|
187
|
+
{[
|
|
188
|
+
{
|
|
189
|
+
icon: <GlobalLine className="h-6 w-6" />,
|
|
190
|
+
title: 'Accessible by Default',
|
|
191
|
+
desc: 'Built with ARIA support, focus management, and keyboard navigation at its core. 100/100 Lighthouse scores guaranteed.',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
icon: <PaletteLine className="h-6 w-6" />,
|
|
195
|
+
title: 'Themable Design System',
|
|
196
|
+
desc: 'Powered by a robust token system. Easily adapt roundness, typography, and organic color palettes like our signature Gold.',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
icon: <CodeLine className="h-6 w-6" />,
|
|
200
|
+
title: 'Developer Experience',
|
|
201
|
+
desc: 'Strictly typed, thoroughly documented, and lightweight with zero bloat. Seamlessly integrated with Tailwind CSS v4.',
|
|
202
|
+
},
|
|
203
|
+
].map((feature, i) => (
|
|
204
|
+
<div
|
|
205
|
+
key={i}
|
|
206
|
+
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"
|
|
207
|
+
>
|
|
208
|
+
<div className="bg-primary-100 text-primary-700 flex h-12 w-12 items-center justify-center rounded-xl">
|
|
209
|
+
{feature.icon}
|
|
210
|
+
</div>
|
|
211
|
+
<Text variant="titleLarge" weight="bold" color="on-surface">
|
|
212
|
+
{feature.title}
|
|
213
|
+
</Text>
|
|
214
|
+
<Text variant="bodyMedium" color="secondary" className="leading-relaxed">
|
|
215
|
+
{feature.desc}
|
|
216
|
+
</Text>
|
|
217
|
+
</div>
|
|
218
|
+
))}
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</section>
|
|
222
|
+
|
|
223
|
+
{/* Interactive Showcase */}
|
|
224
|
+
<section className="px-6 py-24">
|
|
225
|
+
<div className="mx-auto max-w-5xl">
|
|
226
|
+
<div className="grid grid-cols-1 items-center gap-16 lg:grid-cols-2">
|
|
227
|
+
<div className="space-y-6">
|
|
228
|
+
<Text as="h2" variant="headlineMedium" weight="bold" color="on-surface">
|
|
229
|
+
Premium aesthetics out of the box
|
|
230
|
+
</Text>
|
|
231
|
+
<Text variant="bodyLarge" color="secondary" className="leading-relaxed">
|
|
232
|
+
Notice the tactile feel, the carefully calibrated spacing, and the warm, grounded
|
|
233
|
+
colors. Wangs UI breaks away from cold, generic material trends to give your
|
|
234
|
+
product a distinct soul.
|
|
235
|
+
</Text>
|
|
236
|
+
<Ul spacing="tight" className="pt-4">
|
|
237
|
+
{[
|
|
238
|
+
'Hanken Grotesk typography',
|
|
239
|
+
'4px unified roundness tokens',
|
|
240
|
+
'Earthy & organic gold palette',
|
|
241
|
+
].map((item, i) => (
|
|
242
|
+
<Li
|
|
243
|
+
key={i}
|
|
244
|
+
icon={
|
|
245
|
+
<div className="bg-success-100 text-success-700 flex h-6 w-6 items-center justify-center rounded-full">
|
|
246
|
+
<CheckLine className="h-4 w-4" />
|
|
247
|
+
</div>
|
|
248
|
+
}
|
|
249
|
+
>
|
|
250
|
+
<Text variant="bodyMedium" weight="medium" color="on-surface">
|
|
251
|
+
{item}
|
|
252
|
+
</Text>
|
|
253
|
+
</Li>
|
|
254
|
+
))}
|
|
255
|
+
</Ul>
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<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">
|
|
259
|
+
<div className="flex items-center justify-between">
|
|
260
|
+
<div className="flex items-center gap-4">
|
|
261
|
+
<div className="bg-primary-100 text-primary-700 flex h-12 w-12 items-center justify-center rounded-full text-lg font-bold">
|
|
262
|
+
WU
|
|
263
|
+
</div>
|
|
264
|
+
<div>
|
|
265
|
+
<Text variant="titleMedium" weight="bold" color="on-surface">
|
|
266
|
+
Organization Settings
|
|
267
|
+
</Text>
|
|
268
|
+
<Text variant="labelSmall" color="secondary">
|
|
269
|
+
Manage your workspace preferences
|
|
270
|
+
</Text>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
<div className="border-outline-variant space-y-4 border-t pt-4">
|
|
276
|
+
<Switch
|
|
277
|
+
checked={analyticsEnabled}
|
|
278
|
+
onChange={setAnalyticsEnabled}
|
|
279
|
+
aria-label="Enable Analytics"
|
|
280
|
+
label="Enable Analytics"
|
|
281
|
+
labelPosition="before"
|
|
282
|
+
className="text-label-small w-full justify-between"
|
|
283
|
+
/>
|
|
284
|
+
<Switch
|
|
285
|
+
checked={mode === 'dark'}
|
|
286
|
+
onChange={(checked) => setMode(checked ? 'dark' : 'light')}
|
|
287
|
+
aria-label="Toggle dark mode"
|
|
288
|
+
label="Dark Mode"
|
|
289
|
+
labelPosition="before"
|
|
290
|
+
className="text-label-small w-full justify-between"
|
|
291
|
+
/>
|
|
292
|
+
</div>
|
|
293
|
+
|
|
294
|
+
<div className="border-outline-variant flex gap-3 border-t pt-6">
|
|
295
|
+
<Button
|
|
296
|
+
className="flex-1"
|
|
297
|
+
variant="filled"
|
|
298
|
+
severity="primary"
|
|
299
|
+
label="Save Changes"
|
|
300
|
+
/>
|
|
301
|
+
<Button variant="outline" severity="secondary" label="Cancel" />
|
|
302
|
+
</div>
|
|
303
|
+
</Card>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
</section>
|
|
307
|
+
</main>
|
|
308
|
+
|
|
309
|
+
<Footer />
|
|
310
|
+
</div>
|
|
311
|
+
);
|
|
312
|
+
}
|