@stevederico/skateboard-ui 0.9.1 → 0.9.2
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/CHANGELOG.md +9 -0
- package/README.md +55 -1
- package/SignInView.jsx +55 -64
- package/SignUpView.jsx +71 -60
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,8 +1,62 @@
|
|
|
1
1
|
# skateboard-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React component library built with TailwindCSS and shadcn/ui for rapid application development.
|
|
4
4
|
|
|
5
|
+
## Installation
|
|
5
6
|
|
|
7
|
+
```bash
|
|
8
|
+
npm install @stevederico/skateboard-ui
|
|
9
|
+
```
|
|
6
10
|
|
|
11
|
+
## Components
|
|
7
12
|
|
|
13
|
+
### Core Components
|
|
14
|
+
- **AppSidebar** - Application sidebar navigation
|
|
15
|
+
- **DynamicIcon** - Dynamic icon rendering from lucide-react
|
|
16
|
+
- **Header** - Application header component
|
|
17
|
+
- **Layout** - Page layout wrapper
|
|
18
|
+
- **TabBar** - Tab navigation bar
|
|
19
|
+
- **ThemeToggle** - Dark/light mode toggle
|
|
20
|
+
- **Sheet** - Slide-out panel component
|
|
21
|
+
- **UpgradeSheet** - Premium upgrade UI
|
|
22
|
+
|
|
23
|
+
### View Components
|
|
24
|
+
- **LandingView** - Landing page template
|
|
25
|
+
- **SettingsView** - Settings page template
|
|
26
|
+
- **SignInView** - Authentication sign-in page
|
|
27
|
+
- **SignUpView** - Authentication sign-up page
|
|
28
|
+
- **StripeView** - Stripe payment integration
|
|
29
|
+
- **TextView** - Text display view
|
|
30
|
+
- **NotFound** - 404 error page
|
|
31
|
+
|
|
32
|
+
### shadcn/ui Components
|
|
33
|
+
Full set of shadcn/ui primitives available at `@stevederico/skateboard-ui/shadcn/ui/*`
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
import { Button } from '@stevederico/skateboard-ui/shadcn/ui/button'
|
|
39
|
+
import { Layout } from '@stevederico/skateboard-ui/Layout'
|
|
40
|
+
import { ThemeToggle } from '@stevederico/skateboard-ui/ThemeToggle'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Utilities
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
import { cn } from '@stevederico/skateboard-ui/shadcn/lib/utils'
|
|
47
|
+
import { useMobile } from '@stevederico/skateboard-ui/shadcn/hooks/use-mobile'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Dependencies
|
|
51
|
+
|
|
52
|
+
Built on:
|
|
53
|
+
- React 19.1+
|
|
54
|
+
- Radix UI primitives
|
|
55
|
+
- TailwindCSS
|
|
56
|
+
- lucide-react icons
|
|
57
|
+
- class-variance-authority
|
|
58
|
+
|
|
59
|
+
## Repository
|
|
60
|
+
|
|
61
|
+
https://github.com/stevederico/skateboard-ui
|
|
8
62
|
|
package/SignInView.jsx
CHANGED
|
@@ -72,70 +72,61 @@ export default function LoginForm({
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
|
-
<div className={cn("flex flex-col gap-6 p-4
|
|
76
|
-
<
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<div className="mt-6 text-center text-sm">
|
|
131
|
-
Don't have an account?{" "}
|
|
132
|
-
<span onClick={() => navigate('/signup')} className="underline underline-offset-4 cursor-pointer">
|
|
133
|
-
Sign Up
|
|
134
|
-
</span>
|
|
135
|
-
</div>
|
|
136
|
-
</form>
|
|
137
|
-
</CardContent>
|
|
138
|
-
</Card>
|
|
75
|
+
<div className={cn("flex flex-col gap-6 p-4 max-w-lg mx-auto mt-20", className)} {...props}>
|
|
76
|
+
<div className="flex flex-row items-center justify-center mb-4">
|
|
77
|
+
<div className="bg-app dark:border rounded-2xl flex aspect-square size-16 items-center justify-center">
|
|
78
|
+
<DynamicIcon name={constants.appIcon} size={32} color="white" strokeWidth={2} />
|
|
79
|
+
</div>
|
|
80
|
+
<div className="font-bold ml-3 text-5xl">{constants.appName}</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
{errorMessage && (
|
|
84
|
+
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg text-sm text-center">
|
|
85
|
+
{errorMessage}
|
|
86
|
+
</div>
|
|
87
|
+
)}
|
|
88
|
+
|
|
89
|
+
<form onSubmit={signInClicked} className="flex flex-col gap-4">
|
|
90
|
+
<Input
|
|
91
|
+
id="email"
|
|
92
|
+
type="email"
|
|
93
|
+
placeholder="Email"
|
|
94
|
+
className="py-7 px-4 placeholder:text-gray-400 rounded-lg"
|
|
95
|
+
style={{ fontSize: '20px' }}
|
|
96
|
+
required
|
|
97
|
+
value={email}
|
|
98
|
+
onChange={(e) => {
|
|
99
|
+
setEmail(e.target.value);
|
|
100
|
+
setErrorMessage('');
|
|
101
|
+
}}
|
|
102
|
+
/>
|
|
103
|
+
|
|
104
|
+
<Input
|
|
105
|
+
id="password"
|
|
106
|
+
type="password"
|
|
107
|
+
placeholder="Password"
|
|
108
|
+
className="py-7 px-4 placeholder:text-gray-400 rounded-lg"
|
|
109
|
+
style={{ fontSize: '20px' }}
|
|
110
|
+
required
|
|
111
|
+
value={password}
|
|
112
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
113
|
+
/>
|
|
114
|
+
|
|
115
|
+
<Button
|
|
116
|
+
type="submit"
|
|
117
|
+
className="w-full cursor-pointer py-6 text-base font-medium rounded-lg"
|
|
118
|
+
disabled={isSubmitting}
|
|
119
|
+
>
|
|
120
|
+
{isSubmitting ? "Signing in..." : "Sign In"}
|
|
121
|
+
</Button>
|
|
122
|
+
|
|
123
|
+
<div className="mt-4 text-center text-base">
|
|
124
|
+
<span className="text-gray-600 italic">Don't have an account?</span>{" "}
|
|
125
|
+
<span onClick={() => navigate('/signup')} className="cursor-pointer hover:underline">
|
|
126
|
+
Sign Up
|
|
127
|
+
</span>
|
|
128
|
+
</div>
|
|
129
|
+
</form>
|
|
139
130
|
</div>
|
|
140
131
|
);
|
|
141
132
|
}
|
package/SignUpView.jsx
CHANGED
|
@@ -67,75 +67,86 @@ export default function LoginForm({
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
return (
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
70
|
+
<div className={cn("flex flex-col gap-6 p-4 max-w-lg mx-auto mt-20", className)} {...props}>
|
|
71
|
+
<div className="flex flex-row items-center justify-center mb-4">
|
|
72
|
+
<div className="bg-app dark:border rounded-2xl flex aspect-square size-16 items-center justify-center">
|
|
73
|
+
<DynamicIcon name={constants.appIcon} size={32} color="white" strokeWidth={2} />
|
|
74
|
+
</div>
|
|
75
|
+
<div className="font-bold ml-3 text-5xl">{constants.appName}</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
{errorMessage !== '' && (
|
|
79
|
+
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg text-sm text-center">
|
|
80
|
+
{errorMessage}
|
|
81
|
+
</div>
|
|
82
|
+
)}
|
|
83
|
+
|
|
84
|
+
<form className="flex flex-col gap-4">
|
|
85
|
+
<Input
|
|
86
|
+
id="name"
|
|
87
|
+
placeholder="Name"
|
|
88
|
+
className="py-7 px-4 placeholder:text-gray-400 rounded-lg"
|
|
89
|
+
style={{ fontSize: '20px' }}
|
|
90
|
+
required
|
|
91
|
+
value={name}
|
|
92
|
+
onChange={(e) => {
|
|
93
|
+
setName(e.target.value);
|
|
94
|
+
setErrorMessage('');
|
|
95
|
+
}}
|
|
96
|
+
/>
|
|
97
|
+
|
|
98
|
+
<Input
|
|
99
|
+
id="email"
|
|
100
|
+
type="email"
|
|
101
|
+
placeholder="Email"
|
|
102
|
+
className="py-7 px-4 placeholder:text-gray-400 rounded-lg"
|
|
103
|
+
style={{ fontSize: '20px' }}
|
|
104
|
+
required
|
|
105
|
+
value={email}
|
|
106
|
+
onChange={(e) => {
|
|
107
|
+
setEmail(e.target.value);
|
|
108
|
+
setErrorMessage('');
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
|
|
112
|
+
<Input
|
|
113
|
+
id="password"
|
|
114
|
+
type="password"
|
|
115
|
+
placeholder="Password"
|
|
116
|
+
className="py-7 px-4 placeholder:text-gray-400 rounded-lg"
|
|
117
|
+
style={{ fontSize: '20px' }}
|
|
118
|
+
required
|
|
119
|
+
value={password}
|
|
120
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
121
|
+
/>
|
|
122
|
+
|
|
123
|
+
<Button
|
|
124
|
+
onClick={(e) => { e.preventDefault(); signUpClicked() }}
|
|
125
|
+
className="w-full cursor-pointer py-6 text-base font-medium rounded-lg"
|
|
126
|
+
>
|
|
127
|
+
Sign Up
|
|
128
|
+
</Button>
|
|
122
129
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
130
|
+
<div className="mt-4 text-center text-base">
|
|
131
|
+
<span className="text-gray-600 italic">Already have an account?</span>{" "}
|
|
132
|
+
<span onClick={(e) => { e.preventDefault(); navigate('/signin'); }} className="cursor-pointer hover:underline">
|
|
133
|
+
Sign In
|
|
134
|
+
</span>
|
|
135
|
+
</div>
|
|
136
|
+
</form>
|
|
126
137
|
|
|
127
|
-
<div className="mt-6 text-center text-sm">
|
|
138
|
+
<div className="mt-6 text-center text-sm max-w-none">
|
|
128
139
|
By registering you agree to our
|
|
129
|
-
<span onClick={(e) => { e.preventDefault(); navigate('/terms'); }} className="ml-1 underline underline-offset-4 cursor-pointer">
|
|
140
|
+
<span onClick={(e) => { e.preventDefault(); navigate('/terms'); }} className="ml-1 underline underline-offset-4 cursor-pointer whitespace-nowrap">
|
|
130
141
|
Terms of Service
|
|
131
142
|
</span>,
|
|
132
|
-
<span onClick={(e) => { e.preventDefault(); navigate('/eula'); }} className="ml-1 underline underline-offset-4 cursor-pointer">
|
|
143
|
+
<span onClick={(e) => { e.preventDefault(); navigate('/eula'); }} className="ml-1 underline underline-offset-4 cursor-pointer whitespace-nowrap">
|
|
133
144
|
EULA
|
|
134
145
|
</span>,
|
|
135
|
-
<span onClick={(e) => { e.preventDefault(); navigate('/privacy'); }} className="ml-1 underline underline-offset-4 cursor-pointer">
|
|
146
|
+
<span onClick={(e) => { e.preventDefault(); navigate('/privacy'); }} className="ml-1 underline underline-offset-4 cursor-pointer whitespace-nowrap">
|
|
136
147
|
Privacy Policy
|
|
137
148
|
</span>
|
|
138
149
|
</div>
|
|
139
|
-
</div>
|
|
150
|
+
</div>
|
|
140
151
|
);
|
|
141
152
|
}
|