Skip to content

Commit 6fd41c0

Browse files
committed
docs(examples): add headless, styled, and iframe auth examples
1 parent a2cb013 commit 6fd41c0

File tree

29 files changed

+1396
-116
lines changed

29 files changed

+1396
-116
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Headless Auth Example
2+
3+
This example demonstrates how to use `@storacha/ui-react` **headless components** with completely custom styling.
4+
5+
## What is Headless?
6+
7+
Headless components provide all the authentication logic, state management, and event handling **without any built-in styling**. This gives you complete control over the appearance while leveraging Storacha's authentication functionality.
8+
9+
## Features Demonstrated
10+
11+
- 🎨 **Custom Styling**: Chakra UI-inspired design system
12+
- 🎯 **Render Props**: Full control over component rendering
13+
- 🔧 **Headless Components**: No CSS dependencies from Storacha
14+
-**Full Functionality**: Complete auth flow with custom UI
15+
16+
## Key Concepts
17+
18+
### Using Headless Components
19+
20+
```tsx
21+
import { StorachaAuth } from '@storacha/ui-react'
22+
23+
// Provide your own className and styles
24+
<StorachaAuth.Form
25+
className="my-custom-form"
26+
renderLogo={() => <YourLogo />}
27+
renderSubmitButton={(disabled) => (
28+
<button disabled={disabled}>Sign In</button>
29+
)}
30+
/>
31+
```
32+
33+
### Component Composition
34+
35+
All components accept:
36+
- `className` - Custom CSS classes
37+
- `style` - Inline styles
38+
- `render*` props - Custom render functions
39+
40+
### Available Components
41+
42+
- `StorachaAuth.Form` - Main authentication form
43+
- `StorachaAuth.EmailInput` - Email input field
44+
- `StorachaAuth.Submitted` - Post-submission state
45+
- `StorachaAuth.CancelButton` - Cancel button
46+
- `StorachaAuth.Ensurer` - Authentication flow controller
47+
48+
## Running This Example
49+
50+
```bash
51+
# Install dependencies
52+
pnpm install
53+
54+
# Start development server
55+
pnpm dev
56+
```
57+
58+
## Styling Approaches
59+
60+
This example uses vanilla CSS, but you can use any styling solution:
61+
62+
- ✅ Tailwind CSS
63+
- ✅ Emotion / styled-components
64+
- ✅ CSS Modules
65+
- ✅ Chakra UI / MUI
66+
- ✅ Your own CSS
67+
68+
## Learn More
69+
70+
- [Storacha Documentation](https://docs.storacha.network)
71+
- [API Reference](https://github.com/storacha/upload-service)
72+
73+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "@storacha/ui-example-react-headless-auth",
3+
"private": true,
4+
"version": "0.0.1",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "vite build",
9+
"start": "vite preview",
10+
"clean": "rm -rf dist *.tsbuildinfo"
11+
},
12+
"dependencies": {
13+
"@storacha/ui-react": "workspace:^",
14+
"react": "catalog:",
15+
"react-dom": "catalog:"
16+
},
17+
"devDependencies": {
18+
"@types/react": "catalog:",
19+
"@types/react-dom": "catalog:",
20+
"@vitejs/plugin-react": "catalog:",
21+
"vite": "catalog:"
22+
}
23+
}
24+
25+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Storacha Headless Auth Example</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/src/main.tsx"></script>
11+
</body>
12+
</html>
13+
14+
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import React from 'react'
2+
import { Provider, useW3, StorachaAuth, useStorachaAuth } from '@storacha/ui-react'
3+
4+
/**
5+
* Headless Auth Example - Demonstrates custom styling with Chakra-inspired design
6+
*
7+
* This example shows how to use the headless @storacha/ui-react components
8+
* with completely custom styling. No pre-built CSS classes are used from Storacha.
9+
*/
10+
11+
function CustomAuthForm() {
12+
const [{ handleRegisterSubmit, submitted }] = useStorachaAuth()
13+
14+
return (
15+
<div className="auth-container">
16+
<StorachaAuth.Form
17+
className="auth-card"
18+
renderLogo={() => (
19+
<div className="auth-logo">
20+
<h1>🚀 Storacha</h1>
21+
<p>Headless Authentication Example</p>
22+
</div>
23+
)}
24+
renderEmailLabel={() => (
25+
<div className="auth-form-group">
26+
<label className="auth-label" htmlFor="email">
27+
Email Address
28+
</label>
29+
</div>
30+
)}
31+
renderSubmitButton={(disabled) => (
32+
<button
33+
className="auth-button"
34+
type="submit"
35+
disabled={disabled}
36+
>
37+
{disabled ? 'Sending...' : 'Sign In / Sign Up'}
38+
</button>
39+
)}
40+
>
41+
<StorachaAuth.EmailInput
42+
className="auth-input"
43+
placeholder="[email protected]"
44+
/>
45+
</StorachaAuth.Form>
46+
</div>
47+
)
48+
}
49+
50+
function CustomSubmitted() {
51+
const [{ email }] = useStorachaAuth()
52+
53+
return (
54+
<div className="auth-container">
55+
<StorachaAuth.Submitted
56+
className="auth-card auth-submitted"
57+
renderLogo={() => (
58+
<div className="auth-logo">
59+
<h1>🚀 Storacha</h1>
60+
</div>
61+
)}
62+
renderTitle={() => <h2>Check your email!</h2>}
63+
renderMessage={(email) => (
64+
<p>
65+
We sent a verification link to{' '}
66+
<span className="email-highlight">{email}</span>
67+
<br />
68+
Click the link to complete authentication.
69+
</p>
70+
)}
71+
renderCancelButton={() => (
72+
<StorachaAuth.CancelButton className="auth-button">
73+
Cancel
74+
</StorachaAuth.CancelButton>
75+
)}
76+
/>
77+
</div>
78+
)
79+
}
80+
81+
function AuthenticatedApp() {
82+
const [{ accounts }] = useW3()
83+
const [, { logout }] = useStorachaAuth()
84+
85+
return (
86+
<div className="authenticated-container">
87+
<div className="authenticated-card">
88+
<div className="authenticated-header">
89+
<h1>🎉 Welcome to Storacha!</h1>
90+
<p>You're successfully authenticated</p>
91+
</div>
92+
93+
<div className="auth-info">
94+
<p>
95+
<strong>Signed in as:</strong>
96+
<br />
97+
{accounts[0]?.toEmail()}
98+
</p>
99+
</div>
100+
101+
<button onClick={logout} className="logout-button">
102+
Sign Out
103+
</button>
104+
</div>
105+
</div>
106+
)
107+
}
108+
109+
function App() {
110+
const handleAuthEvent = (event: string, properties?: Record<string, any>) => {
111+
console.log('🔐 Auth Event:', event, properties)
112+
}
113+
114+
return (
115+
<Provider>
116+
<StorachaAuth
117+
onAuthEvent={handleAuthEvent}
118+
enableIframeSupport={false}
119+
>
120+
<StorachaAuth.Ensurer
121+
renderLoader={(type) => (
122+
<div className="auth-loader">
123+
<div className="spinner" />
124+
<p className="loader-text">
125+
{type === 'initializing' ? 'Initializing...' : 'Loading...'}
126+
</p>
127+
</div>
128+
)}
129+
renderForm={() => <CustomAuthForm />}
130+
renderSubmitted={() => <CustomSubmitted />}
131+
>
132+
<AuthenticatedApp />
133+
</StorachaAuth.Ensurer>
134+
</StorachaAuth>
135+
</Provider>
136+
)
137+
}
138+
139+
export default App
140+
141+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react'
2+
import ReactDOM from 'react-dom/client'
3+
import App from './App'
4+
import './styles.css'
5+
6+
ReactDOM.createRoot(document.getElementById('root')!).render(
7+
<React.StrictMode>
8+
<App />
9+
</React.StrictMode>,
10+
)
11+
12+

0 commit comments

Comments
 (0)