create-react-scaffold-cli 1.0.4 → 1.0.6

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.
Files changed (37) hide show
  1. package/package.json +2 -7
  2. package/templates/base/index.html +3 -3
  3. package/templates/base/public/icons/react.svg +1 -0
  4. package/templates/base/src/app/App.jsx +4 -2
  5. package/templates/base/src/app/Router.jsx +11 -3
  6. package/templates/base/src/app/index.css +36 -0
  7. package/templates/base/src/app/main.jsx +1 -1
  8. package/templates/base/src/app/routes.registry.js +2 -0
  9. package/templates/base/src/features/sample/constants/index.js +3 -0
  10. package/templates/base/src/features/sample/pages/index.js +2 -0
  11. package/templates/base/src/features/sample/sample.routes.js +2 -3
  12. package/templates/base/src/features/welcome/components/CodeLine.jsx +54 -0
  13. package/templates/base/src/features/welcome/components/Divider.jsx +7 -0
  14. package/templates/base/src/features/welcome/components/Footer.jsx +78 -0
  15. package/templates/base/src/features/welcome/components/Hero.jsx +131 -0
  16. package/templates/base/src/features/welcome/components/IconLink.jsx +18 -0
  17. package/templates/base/src/features/welcome/components/QuickStartPanel.jsx +63 -0
  18. package/templates/base/src/features/welcome/components/RingSoft.jsx +16 -0
  19. package/templates/base/src/features/welcome/components/StorySections.jsx +63 -0
  20. package/templates/base/src/features/welcome/components/WhatYouGet.jsx +49 -0
  21. package/templates/base/src/features/welcome/components/index.js +5 -0
  22. package/templates/base/src/features/welcome/constants/index.js +2 -0
  23. package/templates/base/src/features/welcome/constants/welcome.constants.js +21 -0
  24. package/templates/base/src/features/welcome/constants/welcome.navigations.js +3 -0
  25. package/templates/base/src/features/welcome/index.js +1 -0
  26. package/templates/base/src/features/welcome/pages/WelcomePage.jsx +28 -0
  27. package/templates/base/src/features/welcome/pages/index.js +3 -0
  28. package/templates/base/src/features/welcome/welcome.routes.js +12 -0
  29. package/templates/base/src/shared/theme/theme.js +26 -15
  30. package/templates/base/src/shared/ui/Box.jsx +1 -14
  31. package/templates/base/src/shared/ui/Button.jsx +4 -5
  32. package/templates/base/src/shared/ui/DropdownMenu.jsx +57 -91
  33. package/templates/base/src/shared/ui/GridItem.jsx +1 -0
  34. package/templates/base/src/shared/ui/Modal.jsx +1 -0
  35. package/templates/base/src/shared/ui/Text.jsx +3 -3
  36. package/templates/base/src/shared/ui/index.js +17 -0
  37. package/templates/base/vercel.json +3 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-react-scaffold-cli",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -26,10 +26,5 @@
26
26
  },
27
27
  "bin": {
28
28
  "create-react-scaffold-cli": "bin/index.js"
29
- },
30
- "files": [
31
- "bin",
32
- "scripts",
33
- "templates"
34
- ]
29
+ }
35
30
  }
@@ -2,15 +2,15 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
5
+ <link rel="icon" type="image/svg+xml" href="/public/icons/react.svg" />
6
6
  <meta
7
7
  name="viewport"
8
8
  content="width=device-width, initial-scale=1, viewport-fit=cover, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
9
9
  />
10
- <title>vite-project</title>
10
+ <title>React Scaffold App</title>
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
14
- <script type="module" src="/src/main.jsx"></script>
14
+ <script type="module" src="/src/app/main.jsx"></script>
15
15
  </body>
16
16
  </html>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 32 32"><g transform="matrix(.05696 0 0 .05696 .647744 2.43826)" fill="none" fill-rule="evenodd"><circle r="50.167" cy="237.628" cx="269.529" fill="#00d8ff"/><g stroke="#00d8ff" stroke-width="24"><path d="M269.53 135.628c67.356 0 129.928 9.665 177.107 25.907 56.844 19.57 91.794 49.233 91.794 76.093 0 27.99-37.04 59.503-98.083 79.728-46.15 15.29-106.88 23.272-170.818 23.272-65.554 0-127.63-7.492-174.3-23.44-59.046-20.182-94.61-52.103-94.61-79.56 0-26.642 33.37-56.076 89.415-75.616 47.355-16.51 111.472-26.384 179.486-26.384z"/><path d="M180.736 186.922c33.65-58.348 73.28-107.724 110.92-140.48C337.006 6.976 380.163-8.48 403.43 4.937c24.248 13.983 33.042 61.814 20.067 124.796-9.8 47.618-33.234 104.212-65.176 159.6-32.75 56.788-70.25 106.82-107.377 139.272-46.98 41.068-92.4 55.93-116.185 42.213-23.08-13.3-31.906-56.92-20.834-115.233 9.355-49.27 32.832-109.745 66.8-168.664z"/><path d="M180.82 289.482C147.075 231.2 124.1 172.195 114.51 123.227c-11.544-59-3.382-104.11 19.864-117.566 24.224-14.024 70.055 2.244 118.14 44.94 36.356 32.28 73.688 80.837 105.723 136.173 32.844 56.733 57.46 114.21 67.036 162.582 12.117 61.213 2.31 107.984-21.453 121.74-23.057 13.348-65.25-.784-110.24-39.5-38.013-32.71-78.682-83.253-112.76-142.115z"/></g></g></svg>
@@ -1,4 +1,4 @@
1
- import { Toaster } from '@/shared/ui';
1
+ import { Scrollable, Toaster } from '@/shared/ui';
2
2
  import { QueryProvider } from './providers';
3
3
  import { Router } from './Router';
4
4
  import { memo } from '@/shared/utils';
@@ -6,7 +6,9 @@ import { memo } from '@/shared/utils';
6
6
  export const App = memo(() => {
7
7
  return (
8
8
  <QueryProvider>
9
- <Router />
9
+ <Scrollable>
10
+ <Router />
11
+ </Scrollable>
10
12
  <Toaster />
11
13
  </QueryProvider>
12
14
  );
@@ -3,6 +3,7 @@ import { featureRoutes } from './routes.registry';
3
3
  import { AuthMiddleware } from './middlewares';
4
4
  import { Layouts } from '@/shared/constants';
5
5
  import { memo } from '@/shared/utils';
6
+ import React from 'react';
6
7
 
7
8
  const layoutMap = {
8
9
  dashboard: null,
@@ -15,13 +16,20 @@ export const Router = memo(() => {
15
16
  <Routes>
16
17
  {featureRoutes.map((route, index) => {
17
18
  const Layout = layoutMap[route.layout ?? Layouts.None];
19
+ const Page = route.element;
18
20
 
19
- let element = <Layout>{route.element}</Layout>;
21
+ let element = (
22
+ <Layout>
23
+ <Page />
24
+ </Layout>
25
+ );
20
26
 
21
27
  if (route.protected) {
22
28
  element = (
23
29
  <AuthMiddleware>
24
- <Layout>{route.element}</Layout>
30
+ <Layout>
31
+ <Page />
32
+ </Layout>
25
33
  </AuthMiddleware>
26
34
  );
27
35
  }
@@ -29,7 +37,7 @@ export const Router = memo(() => {
29
37
  return <Route key={index} path={route.path} element={element} />;
30
38
  })}
31
39
 
32
- <Route path="/*" element={<Navigate to="/login" replace />} />
40
+ <Route path="/*" element={<Navigate to="/welcome" replace />} />
33
41
  </Routes>
34
42
  </BrowserRouter>
35
43
  );
@@ -1 +1,37 @@
1
1
  @import 'tailwindcss';
2
+ @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap');
3
+ @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
4
+
5
+ @theme {
6
+ /* Colors */
7
+ --color-primary: #3452ff;
8
+ --color-primary-foreground: #ffffff;
9
+ --color-badge: #fef1a7;
10
+
11
+ --color-bg: #ffffff;
12
+ --color-surface: #f7f7f7;
13
+
14
+ --color-ink: #03003e;
15
+ --color-muted: #797979;
16
+
17
+ --color-ring: color-mix(in oklab, var(--color-primary) 35%, transparent);
18
+ --color-border: color-mix(in oklab, var(--color-ink) 10%, transparent);
19
+ --color-soft: color-mix(in oklab, var(--color-primary) 10%, transparent);
20
+
21
+ /* Fonts */
22
+ --font-plus-jakarta-sans:
23
+ 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
24
+ --font-inter: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
25
+ }
26
+
27
+ :root {
28
+ color: var(--color-ink);
29
+ background: var(--color-bg);
30
+ text-rendering: optimizeLegibility;
31
+ -webkit-font-smoothing: antialiased;
32
+ -moz-osx-font-smoothing: grayscale;
33
+ }
34
+
35
+ body {
36
+ font-family: var(--font-inter);
37
+ }
@@ -1,7 +1,7 @@
1
1
  import { StrictMode } from 'react';
2
2
  import { createRoot } from 'react-dom/client';
3
- import App from './App.jsx';
4
3
  import './index.css';
4
+ import { App } from './App';
5
5
 
6
6
  createRoot(document.getElementById('root')).render(
7
7
  <StrictMode>
@@ -1,6 +1,8 @@
1
1
  import { sampleRoutes } from '@/features/sample';
2
+ import { welcomeRoutes } from '@/features/welcome';
2
3
 
3
4
  export const featureRoutes = [
4
5
  ...sampleRoutes,
6
+ ...welcomeRoutes,
5
7
  // ...anotherFeatureRoutes
6
8
  ];
@@ -0,0 +1,3 @@
1
+ export { SampleAssets } from './sample.assets';
2
+ export { SampleNavigation, SampleSearchParamsKey } from './sample.navigations';
3
+ export { sampleQueryKey } from './sample.queryKeys';
@@ -1 +1,3 @@
1
+ import React from 'react';
2
+
1
3
  export const SamplePage = React.lazy(() => import('./SamplePage'));
@@ -1,12 +1,11 @@
1
- import React from 'react';
2
1
  import { Layouts } from '@/shared/constants';
3
- import { SampleNavigation } from './constants/sample.navigations';
4
2
  import { SamplePage } from './pages';
3
+ import { SampleNavigation } from './constants';
5
4
 
6
5
  export const sampleRoutes = [
7
6
  {
8
7
  path: SampleNavigation.Sample,
9
- element: <SamplePage />,
8
+ element: SamplePage,
10
9
  protected: true,
11
10
  layout: Layouts.None,
12
11
  },
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import { PiCopySimpleBold, PiCheckBold } from 'react-icons/pi';
3
+ import { Flex } from '@/shared/ui/Flex';
4
+ import { Text } from '@/shared/ui/Text';
5
+ import { useToggleState } from '@/shared/hooks';
6
+ import { Box, FlexItem } from '@/shared/ui';
7
+ import { cn } from '@/shared/libs';
8
+
9
+ export const CodeLine = React.memo(({ value, isStorySection }) => {
10
+ const [copied, toggleCopied] = useToggleState();
11
+
12
+ const onCopy = React.useCallback(async () => {
13
+ try {
14
+ await navigator.clipboard.writeText(value);
15
+ } catch {
16
+ const ta = document.createElement('textarea');
17
+ ta.value = value;
18
+ document.body.appendChild(ta);
19
+ ta.select();
20
+ document.execCommand('copy');
21
+ document.body.removeChild(ta);
22
+ }
23
+ toggleCopied();
24
+ window.setTimeout(() => toggleCopied(), 1200);
25
+ }, [toggleCopied]);
26
+
27
+ return (
28
+ <Box
29
+ radius="xl"
30
+ padding={{ x: 4, y: 2 }}
31
+ className={cn('ring-1 ring-border/50', isStorySection ? 'bg-surface' : 'bg-bg/80 ')}
32
+ >
33
+ <Flex gap={3} align="center" justify="between">
34
+ <FlexItem className="min-w-0">
35
+ <Text size="sm" color="ink" truncate>
36
+ {value}
37
+ </Text>
38
+ </FlexItem>
39
+
40
+ <FlexItem>
41
+ <button
42
+ type="button"
43
+ onClick={onCopy}
44
+ className="shrink-0 inline-flex size-9 items-center justify-center rounded-lg bg-black/5 text-ink hover:bg-black/10 transition-colors cursor-pointer"
45
+ aria-label={copied ? 'Copied' : 'Copy command'}
46
+ title={copied ? 'Copied' : 'Copy'}
47
+ >
48
+ {copied ? <PiCheckBold className="size-4" /> : <PiCopySimpleBold className="size-4" />}
49
+ </button>
50
+ </FlexItem>
51
+ </Flex>
52
+ </Box>
53
+ );
54
+ });
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { cn } from '@/shared/libs';
3
+ import { Box } from '@/shared/ui';
4
+
5
+ export const Divider = React.memo(({ className = '' }) => {
6
+ return <Box className={cn('h-px w-full bg-border/70', className)} />;
7
+ });
@@ -0,0 +1,78 @@
1
+ import React from 'react';
2
+ import { Box, Flex, FlexItem, Text } from '@/shared/ui';
3
+ import { Links } from '../constants';
4
+ import { Divider } from './Divider';
5
+
6
+ export const Footer = React.memo(() => {
7
+ return (
8
+ <Box className="mt-12 pt-8">
9
+ <Divider className="mb-6" />
10
+
11
+ <Flex
12
+ gap={4}
13
+ align={{ md: 'center' }}
14
+ justify={{ md: 'between' }}
15
+ direction={{ base: 'column', md: 'row' }}
16
+ >
17
+ <FlexItem>
18
+ <Text size="sm" color="muted">
19
+ <span className="font-semibold text-ink">React Scaffold</span>
20
+ <>
21
+ <span className="mx-2">•</span>
22
+ Created by{' '}
23
+ <a
24
+ href={Links.CreatorGithub}
25
+ target="_blank"
26
+ rel="noreferrer"
27
+ className="font-semibold text-ink hover:text-primary transition-colors"
28
+ >
29
+ {Links.CreatorName}
30
+ </a>
31
+ </>
32
+ </Text>
33
+ </FlexItem>
34
+
35
+ <FlexItem>
36
+ <Flex gap={5} className="flex-wrap text-sm font-medium">
37
+ <a
38
+ className="text-muted hover:text-primary"
39
+ href={Links.AppGithub}
40
+ target="_blank"
41
+ rel="noreferrer"
42
+ >
43
+ Project Repo
44
+ </a>
45
+ <a
46
+ className="text-muted hover:text-primary"
47
+ href={Links.CliGithub}
48
+ target="_blank"
49
+ rel="noreferrer"
50
+ >
51
+ CLI Repo
52
+ </a>
53
+ <a
54
+ className="text-muted hover:text-primary"
55
+ href={Links.NpmPackage}
56
+ target="_blank"
57
+ rel="noreferrer"
58
+ >
59
+ NPM Package
60
+ </a>
61
+
62
+ <>
63
+ <span className="text-border">|</span>
64
+ <a
65
+ className="text-muted hover:text-primary"
66
+ href={Links.CreatorLinkedIn}
67
+ target="_blank"
68
+ rel="noreferrer"
69
+ >
70
+ Creator
71
+ </a>
72
+ </>
73
+ </Flex>
74
+ </FlexItem>
75
+ </Flex>
76
+ </Box>
77
+ );
78
+ });
@@ -0,0 +1,131 @@
1
+ import React from 'react';
2
+ import { Box, Button, Flex, FlexItem, Grid, Text } from '@/shared/ui';
3
+ import { FaGithub, FaLinkedin, FaNpm } from 'react-icons/fa';
4
+ import { QuickStartPanel } from './QuickStartPanel';
5
+ import { Links } from '../constants';
6
+ import { IconLink } from './IconLink';
7
+
8
+ export const Hero = React.memo(() => {
9
+ return (
10
+ <Grid
11
+ align="start"
12
+ gap={{ base: 10, md: 12 }}
13
+ className="md:grid-cols-[1.25fr_0.75fr] md:gap-12"
14
+ >
15
+ <Flex gap={5} direction="column">
16
+ <Box padding={{ x: 3, y: 1 }} width="fit" className="rounded-full bg-badge">
17
+ <Flex gap={2} align="center">
18
+ <FlexItem>
19
+ <Box radius="full" className="size-1.5 bg-primary" />
20
+ </FlexItem>
21
+ <FlexItem>
22
+ <Text size="sm" weight="semibold">
23
+ React Scaffold
24
+ </Text>
25
+ </FlexItem>
26
+ </Flex>
27
+ </Box>
28
+
29
+ <Flex gap={2} align="center" className="-mt-2">
30
+ <FlexItem>
31
+ <Text size="sm" color="muted">
32
+ Created by
33
+ </Text>
34
+ </FlexItem>
35
+ <FlexItem>
36
+ <a
37
+ href={Links.CreatorGithub}
38
+ target="_blank"
39
+ rel="noreferrer"
40
+ className="font-semibold text-ink hover:text-primary transition-colors"
41
+ >
42
+ {Links.CreatorName}
43
+ </a>
44
+ </FlexItem>
45
+ </Flex>
46
+
47
+ <FlexItem>
48
+ <Text
49
+ weight="black"
50
+ font="plus-jakarta-sans"
51
+ size={{ base: '4xl', lg: '5xl', '2xl': '6xl' }}
52
+ className="tracking-tight bg-linear-to-r from-ink to-primary bg-clip-text text-transparent"
53
+ >
54
+ Start building with React Scaffold
55
+ </Text>
56
+ </FlexItem>
57
+
58
+ <FlexItem>
59
+ <Text size="base" color="muted" className="max-w-xl text-base leading-relaxed">
60
+ A modern, opinionated starter that keeps your codebase clean as it grows — feature-first
61
+ structure, shared UI primitives, and best-practice tooling out of the box.
62
+ </Text>
63
+ </FlexItem>
64
+
65
+ <FlexItem>
66
+ <Text size="sm" color="muted" className="max-w-xl">
67
+ This is the default starter page. Replace it with your product UI when you’re ready.
68
+ </Text>
69
+ </FlexItem>
70
+
71
+ <FlexItem>
72
+ <Flex gap={3} direction={{ base: 'column', md: 'row' }} className="mt-2">
73
+ <FlexItem>
74
+ <Button
75
+ className="rounded-full"
76
+ onClick={() => window.open(Links.AppGithub, '_blank', 'noopener,noreferrer')}
77
+ >
78
+ Open Project Repo
79
+ </Button>
80
+ </FlexItem>
81
+
82
+ <FlexItem>
83
+ <Button
84
+ variant="outline"
85
+ className="rounded-full"
86
+ onClick={() => window.open(Links.NpmPackage, '_blank', 'noopener,noreferrer')}
87
+ >
88
+ View NPM Package
89
+ </Button>
90
+ </FlexItem>
91
+ </Flex>
92
+ </FlexItem>
93
+
94
+ <FlexItem>
95
+ <Flex gap={2} align="center">
96
+ <FlexItem>
97
+ <IconLink
98
+ href={Links.AppGithub}
99
+ label="App Repo"
100
+ icon={<FaGithub className="size-4" />}
101
+ />
102
+ </FlexItem>
103
+ <FlexItem>
104
+ <IconLink
105
+ href={Links.CliGithub}
106
+ label="CLI Repo"
107
+ icon={<FaGithub className="size-4" />}
108
+ />
109
+ </FlexItem>
110
+ <FlexItem>
111
+ <IconLink href={Links.NpmPackage} label="NPM" icon={<FaNpm className="size-4" />} />
112
+ </FlexItem>
113
+
114
+ <>
115
+ <span className="text-border -mt-1">•</span>
116
+ <FlexItem>
117
+ <IconLink
118
+ href={Links.CreatorLinkedIn}
119
+ label="Creator"
120
+ icon={<FaLinkedin className="size-4" />}
121
+ />
122
+ </FlexItem>
123
+ </>
124
+ </Flex>
125
+ </FlexItem>
126
+ </Flex>
127
+
128
+ <QuickStartPanel />
129
+ </Grid>
130
+ );
131
+ });
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { Text } from '@/shared/ui';
3
+
4
+ export const IconLink = React.memo(({ href, icon, label }) => {
5
+ return (
6
+ <a
7
+ href={href}
8
+ target="_blank"
9
+ rel="noreferrer"
10
+ className="inline-flex items-center gap-2 text-muted hover:text-primary transition-colors"
11
+ >
12
+ <span className="text-primary">{icon}</span>
13
+ <Text size="sm" className="leading-none">
14
+ {label}
15
+ </Text>
16
+ </a>
17
+ );
18
+ });
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import { Box, Flex, FlexItem, Text } from '@/shared/ui';
3
+ import { RingSoft } from './RingSoft';
4
+ import { CodeLine } from './CodeLine';
5
+ import { Commands } from '../constants';
6
+
7
+ function StepLight({ label, children }) {
8
+ return (
9
+ <Box>
10
+ <Text className="text-sm font-semibold text-ink">{label}</Text>
11
+ <Box className="mt-2">{children}</Box>
12
+ </Box>
13
+ );
14
+ }
15
+
16
+ export const QuickStartPanel = React.memo(() => {
17
+ return (
18
+ <Box className="relative overflow-hidden rounded-2xl bg-surface/70 p-6 md:p-7 ring-1 ring-border">
19
+ <Box className="pointer-events-none absolute inset-0 opacity-100">
20
+ <RingSoft className="right-[-7rem] top-[-6rem]" size="22rem" />
21
+ <RingSoft className="right-[-5rem] top-[9rem]" size="14rem" />
22
+ <RingSoft className="right-[-3.5rem] top-[16rem]" size="6rem" />
23
+ </Box>
24
+
25
+ <Box className="relative z-10 space-y-6">
26
+ <Flex gap={1} direction="column">
27
+ <FlexItem>
28
+ <Text
29
+ size="base"
30
+ weight="bold"
31
+ font="plus-jakarta-sans"
32
+ className="tracking-tight bg-linear-to-r from-primary to-ink bg-clip-text text-transparent"
33
+ >
34
+ Quick start
35
+ </Text>
36
+ </FlexItem>
37
+ <FlexItem>
38
+ <Text size="sm" color="muted">
39
+ Create an app in seconds — clean architecture, ready to scale.
40
+ </Text>
41
+ </FlexItem>
42
+ </Flex>
43
+
44
+ <Flex gap={4} direction="column">
45
+ <FlexItem>
46
+ <StepLight label="1) Scaffold">
47
+ <CodeLine value={Commands.Scaffold} variant="light" />
48
+ </StepLight>
49
+ </FlexItem>
50
+ <FlexItem>
51
+ <StepLight label="2) Run">
52
+ <CodeLine value={Commands.Run} variant="light" />
53
+ </StepLight>
54
+ </FlexItem>
55
+ </Flex>
56
+
57
+ <Text size="sm" color="muted">
58
+ Tip: add your first feature inside your feature modules and delete this page when ready.
59
+ </Text>
60
+ </Box>
61
+ </Box>
62
+ );
63
+ });
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { Box } from '@/shared/ui/Box';
3
+ import { cn } from '@/shared/libs';
4
+
5
+ export const RingSoft = React.memo(({ className, size }) => {
6
+ return (
7
+ <Box
8
+ className={cn('absolute rounded-full', className)}
9
+ style={{
10
+ width: size,
11
+ height: size,
12
+ border: '1px solid rgba(52, 82, 255, 0.22)',
13
+ }}
14
+ />
15
+ );
16
+ });
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import { Divider } from './Divider';
3
+ import { CodeLine } from './CodeLine';
4
+ import { Box, Flex, FlexItem, Grid, GridItem, Text } from '@/shared/ui';
5
+ import { Commands } from '../constants';
6
+
7
+ function Block({ title, body }) {
8
+ return (
9
+ <Box>
10
+ <Text className="text-sm font-bold tracking-tight">{title}</Text>
11
+ <Text className="mt-2 text-muted leading-relaxed">{body}</Text>
12
+ </Box>
13
+ );
14
+ }
15
+
16
+ export function StorySections() {
17
+ return (
18
+ <Grid gap={{ base: 10, md: 12 }} columns={{ base: 1, md: 2 }}>
19
+ <GridItem>
20
+ <Flex gap={2} direction="column">
21
+ <FlexItem>
22
+ <Text
23
+ weight="black"
24
+ font="plus-jakarta-sans"
25
+ size={{ base: '2xl', md: '3xl' }}
26
+ className="tracking-tight bg-linear-to-r from-primary to-ink bg-clip-text text-transparent"
27
+ >
28
+ Why this exists
29
+ </Text>
30
+ </FlexItem>
31
+
32
+ <FlexItem className="max-w-2xl">
33
+ <Text size="base" color="muted">
34
+ Less starter bloat, more clarity. You get patterns that keep apps maintainable as
35
+ teams grow.
36
+ </Text>
37
+ </FlexItem>
38
+ </Flex>
39
+ </GridItem>
40
+ <GridItem className="space-y-7">
41
+ <Block
42
+ title="Project purpose"
43
+ body="React Scaffold helps teams start real apps fast—with structure, shared UI primitives, and a clean foundation for long-term maintainability."
44
+ />
45
+ <Divider />
46
+ <Block
47
+ title="Problem it solves"
48
+ body="Most starters don’t scale. This scaffold enforces patterns so features stay isolated, UI stays consistent, and refactoring remains safe."
49
+ />
50
+ <Divider />
51
+ <Box>
52
+ <Text size="sm" className="font-bold tracking-tight">
53
+ How to start
54
+ </Text>
55
+ <Box className="mt-3 space-y-3">
56
+ <CodeLine isStorySection value={Commands.Scaffold} />
57
+ <CodeLine isStorySection value={Commands.Run} />
58
+ </Box>
59
+ </Box>
60
+ </GridItem>
61
+ </Grid>
62
+ );
63
+ }
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { SOLUTIONS } from '../constants';
3
+ import { Flex, FlexItem, Text } from '@/shared/ui';
4
+
5
+ export const WhatYouGet = React.memo(() => {
6
+ return (
7
+ <Flex gap={2} direction="column">
8
+ <FlexItem>
9
+ <Text
10
+ weight="black"
11
+ font="plus-jakarta-sans"
12
+ size={{ base: '2xl', md: '3xl' }}
13
+ className="tracking-tight bg-linear-to-r from-primary to-ink bg-clip-text text-transparent"
14
+ >
15
+ What you get
16
+ </Text>
17
+ </FlexItem>
18
+
19
+ <FlexItem className="max-w-2xl">
20
+ <Text size="base" color="muted">
21
+ A real-world scaffold: structure + UI foundations + modern stack.
22
+ </Text>
23
+ </FlexItem>
24
+ <FlexItem>
25
+ <Flex gap={2} className="mt-4 flex-wrap">
26
+ {SOLUTIONS.map((x) => (
27
+ <Flex
28
+ gap={2}
29
+ key={x.label}
30
+ align="center"
31
+ className="inline-flex items-center gap-2 rounded-full bg-surface/80 px-4 py-2"
32
+ >
33
+ <FlexItem>
34
+ <Text size="sm" color="muted">
35
+ {x.label}:
36
+ </Text>
37
+ </FlexItem>
38
+ <FlexItem>
39
+ <Text color="ink" weight="semibold">
40
+ {x.value}
41
+ </Text>
42
+ </FlexItem>
43
+ </Flex>
44
+ ))}
45
+ </Flex>
46
+ </FlexItem>
47
+ </Flex>
48
+ );
49
+ });
@@ -0,0 +1,5 @@
1
+ export { Hero } from './Hero';
2
+ export { Divider } from './Divider';
3
+ export { WhatYouGet } from './WhatYouGet';
4
+ export { StorySections } from './StorySections';
5
+ export { Footer } from './Footer';
@@ -0,0 +1,2 @@
1
+ export * from './welcome.constants';
2
+ export { WelcomeNavigation } from './welcome.navigations';
@@ -0,0 +1,21 @@
1
+ export const Links = {
2
+ CliGithub: 'https://github.com/arsalanirshad57/create-react-scaffold-cli',
3
+ AppGithub: 'https://github.com/arsalanirshad57/react-scaffold-app',
4
+ NpmPackage: 'https://www.npmjs.com/package/create-react-scaffold-cli',
5
+
6
+ CreatorName: 'Muhammad Arsalan',
7
+ CreatorGithub: 'https://github.com/arsalanirshad57',
8
+ CreatorLinkedIn: 'https://www.linkedin.com/in/heyarsalanhere/',
9
+ };
10
+
11
+ export const Commands = {
12
+ Scaffold: 'npx create-react-scaffold-cli',
13
+ Run: 'npm run dev',
14
+ };
15
+
16
+ export const SOLUTIONS = [
17
+ { label: 'Architecture', value: 'Feature-first' },
18
+ { label: 'UI System', value: 'Primitives + Radix' },
19
+ { label: 'Data', value: 'React Query + Axios' },
20
+ { label: 'Tooling', value: 'ESLint + Prettier + Husky' },
21
+ ];
@@ -0,0 +1,3 @@
1
+ export const WelcomeNavigation = {
2
+ Root: '/welcome',
3
+ };
@@ -0,0 +1 @@
1
+ export { welcomeRoutes } from './welcome.routes';
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { Box } from '@/shared/ui';
3
+ import { Divider, Footer, Hero, StorySections, WhatYouGet } from '../components';
4
+
5
+ const WelcomePage = React.memo(() => {
6
+ return (
7
+ <Box className="min-h-screen bg-bg text-ink ">
8
+ <Box
9
+ className="mx-auto max-w-6xl"
10
+ padding={{ x: { base: 4, md: 6 }, y: { base: 10, md: 14 } }}
11
+ >
12
+ <Hero />
13
+
14
+ <Divider className="my-10 md:my-12" />
15
+
16
+ <WhatYouGet />
17
+
18
+ <Divider className="my-10 md:my-12" />
19
+
20
+ <StorySections />
21
+
22
+ <Footer />
23
+ </Box>
24
+ </Box>
25
+ );
26
+ });
27
+
28
+ export default WelcomePage;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+
3
+ export const WelcomePage = React.lazy(() => import('./WelcomePage'));
@@ -0,0 +1,12 @@
1
+ import { Layouts } from '@/shared/constants';
2
+ import { WelcomePage } from './pages';
3
+ import { WelcomeNavigation } from './constants';
4
+
5
+ export const welcomeRoutes = [
6
+ {
7
+ path: WelcomeNavigation.Root,
8
+ element: WelcomePage,
9
+ protected: false,
10
+ layout: Layouts.None,
11
+ },
12
+ ];
@@ -2073,7 +2073,8 @@ export const size2xlLookup = {
2073
2073
 
2074
2074
  export const colorLookup = {
2075
2075
  primary: 'text-primary',
2076
- secondary: 'text-secondary',
2076
+ ink: 'text-ink',
2077
+ muted: 'text-muted',
2077
2078
  success: 'text-green-500',
2078
2079
  danger: 'text-red-500',
2079
2080
  white: 'text-white',
@@ -2082,7 +2083,8 @@ export const colorLookup = {
2082
2083
 
2083
2084
  export const color2XlLookup = {
2084
2085
  primary: '2xl:text-primary',
2085
- secondary: '2xl:text-secondary',
2086
+ ink: '2xl:text-ink',
2087
+ muted: 'xl:text-muted',
2086
2088
  success: '2xl:text-green-500',
2087
2089
  danger: '2xl:text-red-500',
2088
2090
  white: '2xl:text-white',
@@ -2091,7 +2093,8 @@ export const color2XlLookup = {
2091
2093
 
2092
2094
  export const colorXlLookup = {
2093
2095
  primary: 'xl:text-primary',
2094
- secondary: 'xl:text-secondary',
2096
+ ink: 'xl:text-ink',
2097
+ muted: 'xl:text-muted',
2095
2098
  success: 'xl:text-green-500',
2096
2099
  danger: 'xl:text-red-500',
2097
2100
  white: 'xl:text-white',
@@ -2100,7 +2103,8 @@ export const colorXlLookup = {
2100
2103
 
2101
2104
  export const colorLgLookup = {
2102
2105
  primary: 'lg:text-primary',
2103
- secondary: 'lg:text-secondary',
2106
+ ink: 'lg:text-ink',
2107
+ muted: 'lg:text-muted',
2104
2108
  success: 'lg:text-green-500',
2105
2109
  danger: 'lg:text-red-500',
2106
2110
  white: 'lg:text-white',
@@ -2109,7 +2113,8 @@ export const colorLgLookup = {
2109
2113
 
2110
2114
  export const colorMdLookup = {
2111
2115
  primary: 'md:text-primary',
2112
- secondary: 'md:text-secondary',
2116
+ ink: 'md:text-ink',
2117
+ muted: 'md:text-muted',
2113
2118
  success: 'md:text-green-500',
2114
2119
  danger: 'md:text-red-500',
2115
2120
  white: 'md:text-white',
@@ -2123,16 +2128,22 @@ export const bgColorLookup = {
2123
2128
  danger: 'bg-red-500',
2124
2129
  };
2125
2130
 
2126
- export const fontFamilyLookup = {};
2131
+ export const fontFamilyLookup = {
2132
+ 'plus-jakarta-sans': 'font-plus-jakarta-sans',
2133
+ inter: 'font-inter',
2134
+ };
2127
2135
 
2128
- export const fontFamilyMdLookup = Object.fromEntries(
2129
- Object.entries(fontFamilyLookup).map(([k, v]) => [k, `md:${v}`])
2130
- );
2136
+ export const fontFamilyMdLookup = {
2137
+ 'plus-jakarta-sans': 'md:font-plus-jakarta-sans',
2138
+ inter: 'md:font-inter',
2139
+ };
2131
2140
 
2132
- export const fontFamilyLgLookup = Object.fromEntries(
2133
- Object.entries(fontFamilyLookup).map(([k, v]) => [k, `lg:${v}`])
2134
- );
2141
+ export const fontFamilyLgLookup = {
2142
+ 'plus-jakarta-sans': 'lg:font-plus-jakarta-sans',
2143
+ inter: 'lg:font-inter',
2144
+ };
2135
2145
 
2136
- export const fontFamilyXlLookup = Object.fromEntries(
2137
- Object.entries(fontFamilyLookup).map(([k, v]) => [k, `xl:${v}`])
2138
- );
2146
+ export const fontFamilyXlLookup = {
2147
+ 'plus-jakarta-sans': 'xl:font-plus-jakarta-sans',
2148
+ inter: 'xl:font-inter',
2149
+ };
@@ -27,10 +27,6 @@ import {
27
27
  paddingXXlLookup,
28
28
  paddingYXlLookup,
29
29
  marginXlgLookup,
30
- AnimationLookup,
31
- AnimationMdLookup,
32
- AnimationLgLookup,
33
- AnimationXlLookup,
34
30
  radiusLookup,
35
31
  radiusMdLookup,
36
32
  radiusLgLookup,
@@ -122,15 +118,11 @@ import { cn } from '../libs';
122
118
  * | Record<Axis, Record<Breakpoint, Padding>>} [padding]
123
119
  * @property {Width | Record<Breakpoint, Width>} [width]
124
120
  * @property {Radius} [radius]
125
- * @property {Animation} [animation]
126
121
  * @param {React.ComponentProps<'div'> & ComponentProps} props
127
122
  * @returns {JSX.Element}
128
123
  */
129
124
 
130
- const Component = (
131
- { hide, grow, margin, radius, padding, width, animation, className, ...rest },
132
- ref
133
- ) => {
125
+ const Component = ({ hide, grow, margin, radius, padding, width, className, ...rest }, ref) => {
134
126
  return (
135
127
  <div
136
128
  ref={ref}
@@ -180,11 +172,6 @@ const Component = (
180
172
  getClassName(width?.base, widthLookup),
181
173
  getClassName(width?.md, widthMdLookup),
182
174
  getClassName(width?.lg, widthLgLookup),
183
- typeof font !== 'object' && getClassName(animation, AnimationLookup),
184
- getClassName(animation?.base, AnimationLookup),
185
- getClassName(animation?.md, AnimationMdLookup),
186
- getClassName(animation?.lg, AnimationLgLookup),
187
- getClassName(animation?.xl, AnimationXlLookup),
188
175
  typeof radius !== 'object' && getClassName(radius, radiusLookup),
189
176
  getClassName(radius?.base, radiusLookup),
190
177
  getClassName(radius?.md, radiusMdLookup),
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { PiSpinnerBold } from 'react-icons/pi';
3
3
  import {
4
- AnimationLookup,
5
4
  colorLookup,
6
5
  fieldSize2XlLookup,
7
6
  fieldSizeLgLookup,
@@ -25,13 +24,14 @@ import {
25
24
  radiusXlLookup,
26
25
  } from '../theme';
27
26
  import { getClassName, memo } from '../utils';
27
+ import { cn } from '../libs';
28
28
 
29
29
  const variantLookup = {
30
30
  primary:
31
31
  'text-primary-foreground bg-primary hover:bg-primary/90 disabled:text-primary-foreground/70 disabled:bg-primary/50',
32
32
  outline:
33
33
  'border text-primary bg-primary-foreground hover:bg-neutral-50 disabled:text-primary/70 disabled:bg-neutral-50/50',
34
- pill: 'text-primary-foreground bg-primary hover:bg-primary/90 disabled:text-primary-foreground/70 disabled:bg-primary/50 rounded-lg',
34
+ pill: 'text-primary-foreground bg-primary hover:bg-primary/90 disabled:text-primary-foreground/70 disabled:bg-primary/50',
35
35
  };
36
36
 
37
37
  /**
@@ -97,7 +97,6 @@ const Component = (
97
97
  color,
98
98
  isLoading,
99
99
  className,
100
- animation,
101
100
  type = 'button',
102
101
  children,
103
102
  ...rest
@@ -108,7 +107,8 @@ const Component = (
108
107
  <button
109
108
  ref={ref}
110
109
  className={cn(
111
- 'h-12 px-4 w-full rounded-lg text-base font-inter font-semibold disabled:cursor-not-allowed transition-colors flex justify-center items-center',
110
+ 'h-14 px-8 inline-flex w-full items-center justify-center gap-2 transition-colors disabled:cursor-not-allowed text-primary-foreground cursor-pointer!',
111
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30',
112
112
  typeof fontSize !== 'object' && getClassName(fontSize, fontSizeLookup),
113
113
  getClassName(fontSize?.base, fontSizeLookup),
114
114
  getClassName(fontSize?.md, fontSizeMdLookup),
@@ -135,7 +135,6 @@ const Component = (
135
135
  variantLookup[variant],
136
136
  fontFamilyLookup[font],
137
137
  colorLookup[color],
138
- AnimationLookup[animation],
139
138
  className
140
139
  )}
141
140
  type={type}
@@ -1,46 +1,40 @@
1
1
  import React from 'react';
2
2
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
3
3
  import { FaChevronRight } from 'react-icons/fa';
4
- import { memo } from '@/utils';
5
- import { cn } from '@/libs';
4
+ import { memo } from '../utils';
5
+ import { cn } from '../libs';
6
6
 
7
7
  const DropdownMenuRoot = DropdownMenuPrimitive.Root;
8
8
 
9
9
  const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
10
10
 
11
- const DropdownMenuSubTrigger = React.forwardRef(
12
- ({ className, inset, children, ...props }, ref) => (
13
- <DropdownMenuPrimitive.SubTrigger
14
- ref={ref}
15
- className={cn(
16
- 'flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
17
- inset && 'pl-8',
18
- className
19
- )}
20
- {...props}
21
- >
22
- {children}
23
- <FaChevronRight className="ml-auto" />
24
- </DropdownMenuPrimitive.SubTrigger>
25
- )
26
- );
27
- DropdownMenuSubTrigger.displayName =
28
- DropdownMenuPrimitive.SubTrigger.displayName;
11
+ const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
12
+ <DropdownMenuPrimitive.SubTrigger
13
+ ref={ref}
14
+ className={cn(
15
+ 'flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
16
+ inset && 'pl-8',
17
+ className
18
+ )}
19
+ {...props}
20
+ >
21
+ {children}
22
+ <FaChevronRight className="ml-auto" />
23
+ </DropdownMenuPrimitive.SubTrigger>
24
+ ));
25
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
29
26
 
30
- const DropdownMenuSubContent = React.forwardRef(
31
- ({ className, ...props }, ref) => (
32
- <DropdownMenuPrimitive.SubContent
33
- ref={ref}
34
- className={cn(
35
- 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
36
- className
37
- )}
38
- {...props}
39
- />
40
- )
41
- );
42
- DropdownMenuSubContent.displayName =
43
- DropdownMenuPrimitive.SubContent.displayName;
27
+ const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => (
28
+ <DropdownMenuPrimitive.SubContent
29
+ ref={ref}
30
+ className={cn(
31
+ 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
32
+ className
33
+ )}
34
+ {...props}
35
+ />
36
+ ));
37
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
44
38
 
45
39
  const DropdownMenuContent = React.forwardRef(
46
40
  ({ className, sideOffset = 4, contentClassName, ...props }, ref) => (
@@ -61,53 +55,40 @@ const DropdownMenuContent = React.forwardRef(
61
55
  );
62
56
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
63
57
 
64
- const DropdownMenuItem = React.forwardRef(
65
- ({ className, inset, ...props }, ref) => (
66
- <DropdownMenuPrimitive.Item
67
- ref={ref}
68
- className={cn(
69
- 'relative flex select-none items-center gap-2 font-inter cursor-pointer rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',
70
- inset && 'pl-8',
71
- className
72
- )}
73
- {...props}
74
- />
75
- )
76
- );
58
+ const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (
59
+ <DropdownMenuPrimitive.Item
60
+ ref={ref}
61
+ className={cn(
62
+ 'relative flex select-none items-center gap-2 font-inter cursor-pointer rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',
63
+ inset && 'pl-8',
64
+ className
65
+ )}
66
+ {...props}
67
+ />
68
+ ));
77
69
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
78
70
 
79
- const DropdownMenuLabel = React.forwardRef(
80
- ({ className, inset, ...props }, ref) => (
81
- <DropdownMenuPrimitive.Label
82
- ref={ref}
83
- className={cn(
84
- 'px-2 py-1.5 text-sm font-semibold font-inter',
85
- inset && 'pl-8',
86
- className
87
- )}
88
- {...props}
89
- />
90
- )
91
- );
71
+ const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
72
+ <DropdownMenuPrimitive.Label
73
+ ref={ref}
74
+ className={cn('px-2 py-1.5 text-sm font-semibold font-inter', inset && 'pl-8', className)}
75
+ {...props}
76
+ />
77
+ ));
92
78
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
93
79
 
94
- const DropdownMenuSeparator = React.forwardRef(
95
- ({ className, ...props }, ref) => (
96
- <DropdownMenuPrimitive.Separator
97
- ref={ref}
98
- className={cn('-mx-1 my-1 h-px bg-muted', className)}
99
- {...props}
100
- />
101
- )
102
- );
80
+ const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (
81
+ <DropdownMenuPrimitive.Separator
82
+ ref={ref}
83
+ className={cn('-mx-1 my-1 h-px bg-muted', className)}
84
+ {...props}
85
+ />
86
+ ));
103
87
  DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
104
88
 
105
89
  const DropdownMenuShortcut = ({ className, ...props }) => {
106
90
  return (
107
- <span
108
- className={cn('ml-auto text-xs tracking-widest opacity-60', className)}
109
- {...props}
110
- />
91
+ <span className={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...props} />
111
92
  );
112
93
  };
113
94
  DropdownMenuShortcut.displayName = 'DropdownMenuShortcut';
@@ -121,19 +102,9 @@ DropdownMenuShortcut.displayName = 'DropdownMenuShortcut';
121
102
  * @returns {JSX.Element}
122
103
  */
123
104
 
124
- const Component = ({
125
- open,
126
- onOpenChange,
127
- content,
128
- children,
129
- contentClassName,
130
- }) => {
105
+ const Component = ({ open, onOpenChange, content, children, contentClassName }) => {
131
106
  return (
132
- <DropdownMenuRoot
133
- className="border w-full "
134
- open={open}
135
- onOpenChange={onOpenChange}
136
- >
107
+ <DropdownMenuRoot className="border w-full " open={open} onOpenChange={onOpenChange}>
137
108
  <DropdownMenuTrigger className="w-full">{children}</DropdownMenuTrigger>
138
109
  <DropdownMenuContent align="end" contentClassName={contentClassName}>
139
110
  {content}
@@ -144,9 +115,4 @@ const Component = ({
144
115
 
145
116
  const DropdownMenu = memo(Component);
146
117
 
147
- export {
148
- DropdownMenu,
149
- DropdownMenuLabel,
150
- DropdownMenuSeparator,
151
- DropdownMenuItem,
152
- };
118
+ export { DropdownMenu, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuItem };
@@ -14,6 +14,7 @@ import {
14
14
  } from '../theme';
15
15
  import { getClassName, memo } from '../utils';
16
16
  import { cn } from '../libs';
17
+ import React from 'react';
17
18
 
18
19
  /**
19
20
  * @typedef {'base' | 'md' | 'lg' | 'xl'} Breakpoint
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import * as Dialog from '@radix-ui/react-dialog';
3
3
  import { Scrollable } from './Scrollable';
4
4
  import { cn } from '../libs';
5
+ import { memo } from '../utils';
5
6
 
6
7
  /**
7
8
  * @typedef {object} ComponentProps
@@ -24,7 +24,7 @@ import {
24
24
  colorXlLookup,
25
25
  } from '../theme';
26
26
  import { cn } from '../libs';
27
- import { getClassName } from '../utils';
27
+ import { getClassName, memo } from '../utils';
28
28
 
29
29
  /**
30
30
  * @typedef {'base' | 'md' | 'lg' | 'xl' | '2xl'} Breakpoint
@@ -57,9 +57,9 @@ import { getClassName } from '../utils';
57
57
  * | 'black'} Weight
58
58
  *
59
59
  *
60
- * @typedef {''} Font
60
+ * @typedef {'plus-jakarta-sans' | 'inter'} Font
61
61
  *
62
- * @typedef {'primary' | 'secondary' | 'success' | 'danger' | 'white' | 'black'} Color
62
+ * @typedef {'primary' | 'ink' | 'muted' | 'success' | 'danger' | 'white' | 'black'} Color
63
63
  *
64
64
  * @typedef {object} ComponentProps
65
65
  * @property {Size | Record<Breakpoint, Size>} [size]
@@ -1 +1,18 @@
1
+ export { Box } from './Box';
2
+ export { Button } from './Button';
3
+ export { Checkbox } from './Checkbox';
4
+ export { Flex } from './Flex';
5
+ export { FlexItem } from './FlexItem';
6
+ export { FormField } from './FormField';
7
+ export { Grid } from './Grid';
8
+ export { GridItem } from './GridItem';
9
+ export { Modal } from './Modal';
1
10
  export { Toaster } from './Toaster';
11
+ export { Text } from './Text';
12
+ export { Scrollable } from './Scrollable';
13
+ export {
14
+ DropdownMenu,
15
+ DropdownMenuItem,
16
+ DropdownMenuLabel,
17
+ DropdownMenuSeparator,
18
+ } from './DropdownMenu';
@@ -0,0 +1,3 @@
1
+ {
2
+ "rewrites": [{ "source": "/(.*)", "destination": "/" }]
3
+ }