@framed-dev/react 0.1.6 → 0.2.0
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/README.md +233 -62
- package/dist/index.cjs +71919 -57937
- package/dist/index.d.cts +483 -25
- package/dist/index.d.ts +483 -25
- package/dist/index.js +71510 -57979
- package/dist/styles/framed.css +6474 -0
- package/package.json +62 -8
- package/styles.css +525 -0
- package/tailwind.config.js +207 -0
- package/tailwind.preset.js +86 -0
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,36 +1,83 @@
|
|
|
1
|
-
# @framed/react
|
|
1
|
+
# @framed-dev/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Self-hosted website feedback and specification platform.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@framed/react)
|
|
5
|
+
[](https://www.npmjs.com/package/@framed-dev/react)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
|
|
9
|
-
## What
|
|
9
|
+
## What is Framed?
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
11
|
+
Framed is a complete feedback and project specification platform that you can self-host in your own Supabase project. It includes:
|
|
12
|
+
|
|
13
|
+
- **Feedback Widget** - Visual feedback collection with screenshots, element selection, and annotations
|
|
14
|
+
- **Dashboard** - Project overview and task management
|
|
15
|
+
- **AI Export** - Copy structured prompts for Bolt, Lovable, Cursor, or any AI coding assistant
|
|
15
16
|
|
|
16
17
|
## Quick Start
|
|
17
18
|
|
|
19
|
+
### 1. Initialize (sets up database)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx @framed-dev/cli init
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This will:
|
|
26
|
+
- Detect your project type (Next.js, Vite, etc.)
|
|
27
|
+
- Collect your Supabase credentials
|
|
28
|
+
- Scaffold basic route files
|
|
29
|
+
|
|
30
|
+
Then run migrations:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @framed-dev/cli migrate
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This creates all required database tables, RLS policies, and storage buckets in your Supabase project.
|
|
37
|
+
|
|
38
|
+
### 2. Install SDK
|
|
39
|
+
|
|
18
40
|
```bash
|
|
19
|
-
npm install @framed/react
|
|
41
|
+
npm install @framed-dev/react
|
|
42
|
+
# or
|
|
43
|
+
pnpm add @framed-dev/react
|
|
20
44
|
```
|
|
21
45
|
|
|
46
|
+
### 3. Configure Tailwind
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
// tailwind.config.js
|
|
50
|
+
const framedPreset = require('@framed-dev/react/tailwind');
|
|
51
|
+
|
|
52
|
+
/** @type {import('tailwindcss').Config} */
|
|
53
|
+
module.exports = {
|
|
54
|
+
presets: [framedPreset],
|
|
55
|
+
content: [
|
|
56
|
+
'./app/**/*.{js,ts,jsx,tsx}',
|
|
57
|
+
'./node_modules/@framed-dev/react/dist/**/*.{js,mjs}',
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 4. Add Provider & Widget
|
|
63
|
+
|
|
22
64
|
```tsx
|
|
23
|
-
// app/layout.tsx
|
|
24
|
-
import { FramedProvider, FeedbackWidget } from '@framed/react';
|
|
65
|
+
// app/layout.tsx (Next.js App Router)
|
|
66
|
+
import { FramedProvider, FeedbackWidget } from '@framed-dev/react';
|
|
25
67
|
|
|
26
|
-
export default function
|
|
68
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
27
69
|
return (
|
|
28
70
|
<html lang="en">
|
|
29
71
|
<body>
|
|
30
72
|
<FramedProvider
|
|
31
73
|
config={{
|
|
32
|
-
|
|
33
|
-
|
|
74
|
+
projectId: 'my-project',
|
|
75
|
+
mode: 'sync',
|
|
76
|
+
auth: { mode: 'dev' }, // Change to 'magic_link' for production
|
|
77
|
+
sync: {
|
|
78
|
+
supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
79
|
+
apiKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
80
|
+
},
|
|
34
81
|
}}
|
|
35
82
|
>
|
|
36
83
|
{children}
|
|
@@ -42,78 +89,202 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
|
|
42
89
|
}
|
|
43
90
|
```
|
|
44
91
|
|
|
92
|
+
### 5. Add Framed Routes (Recommended)
|
|
93
|
+
|
|
94
|
+
Use `FramedApp` with a catch-all route for the complete wizard experience:
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// app/framed/[[...slug]]/page.tsx
|
|
98
|
+
"use client";
|
|
99
|
+
|
|
100
|
+
import { FramedApp } from '@framed-dev/react';
|
|
101
|
+
import '@framed-dev/react/widget-styles.css';
|
|
102
|
+
|
|
103
|
+
export default function FramedPage() {
|
|
104
|
+
return <FramedApp basename="/framed" />;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This provides all routes automatically:
|
|
109
|
+
- `/framed` - Dashboard
|
|
110
|
+
- `/framed/wizard/:id/phase1` - Discovery (Phase 1)
|
|
111
|
+
- `/framed/wizard/:id/phase2` - Detailing (Phase 2)
|
|
112
|
+
- `/framed/wizard/:id/phase3` - Overview (Phase 3)
|
|
113
|
+
- `/framed/wizard/:id/phase4` - Review & Feedback (Phase 4)
|
|
114
|
+
- `/framed/wizard/:id/phase5` - Manage & Maintain (Phase 5)
|
|
115
|
+
- `/framed/wizard/:id/build-spec` - AI Export
|
|
116
|
+
|
|
45
117
|
## Environment Variables
|
|
46
118
|
|
|
47
119
|
```env
|
|
120
|
+
# Required
|
|
48
121
|
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
|
49
|
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=
|
|
122
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
|
|
123
|
+
|
|
124
|
+
# Only needed for migrations (not in client code)
|
|
125
|
+
SUPABASE_SERVICE_ROLE_KEY=eyJ...
|
|
126
|
+
|
|
127
|
+
# Optional: Premium features via Framed.dev API
|
|
128
|
+
NEXT_PUBLIC_FRAMED_LICENSE_KEY=framed_lic_xxx
|
|
50
129
|
```
|
|
51
130
|
|
|
52
|
-
##
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
for all using (auth.role() = 'authenticated');
|
|
131
|
+
## Configuration Options
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
interface FramedConfig {
|
|
135
|
+
projectId: string; // Your project identifier
|
|
136
|
+
mode: 'local' | 'sync'; // 'local' for localStorage, 'sync' for Supabase
|
|
137
|
+
|
|
138
|
+
auth: {
|
|
139
|
+
mode: 'dev' | 'local' | 'magic_link';
|
|
140
|
+
loginRoute?: string; // Custom login page route
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
sync?: {
|
|
144
|
+
supabaseUrl: string;
|
|
145
|
+
apiKey: string; // Supabase anon key
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
widget?: {
|
|
149
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
150
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
151
|
+
hotkey?: string;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
76
154
|
```
|
|
77
155
|
|
|
78
|
-
##
|
|
156
|
+
## Route Helpers
|
|
79
157
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
158
|
+
Use the built-in route helpers for consistent navigation:
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import { framedRoutes } from '@framed-dev/react';
|
|
162
|
+
|
|
163
|
+
// Routes
|
|
164
|
+
framedRoutes.dashboard // '/framed'
|
|
165
|
+
framedRoutes.login // '/framed/login'
|
|
166
|
+
framedRoutes.project('123') // '/framed/project/123'
|
|
167
|
+
framedRoutes.review('123') // '/framed/project/123/review'
|
|
168
|
+
framedRoutes.build('123') // '/framed/project/123/build'
|
|
169
|
+
framedRoutes.manage('123') // '/framed/project/123/manage'
|
|
170
|
+
```
|
|
86
171
|
|
|
87
172
|
## Hooks
|
|
88
173
|
|
|
174
|
+
### useFramed
|
|
175
|
+
|
|
176
|
+
Access the full Framed context:
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
import { useFramed } from '@framed-dev/react';
|
|
180
|
+
|
|
181
|
+
function MyComponent() {
|
|
182
|
+
const {
|
|
183
|
+
tasks,
|
|
184
|
+
openTasks,
|
|
185
|
+
isAuthenticated,
|
|
186
|
+
refreshTasks,
|
|
187
|
+
saveTask,
|
|
188
|
+
features,
|
|
189
|
+
} = useFramed();
|
|
190
|
+
|
|
191
|
+
return <div>{openTasks.length} open tasks</div>;
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### useFramedTasks
|
|
196
|
+
|
|
197
|
+
Simplified access to tasks:
|
|
198
|
+
|
|
89
199
|
```tsx
|
|
90
|
-
import {
|
|
200
|
+
import { useFramedTasks } from '@framed-dev/react';
|
|
91
201
|
|
|
92
202
|
function TaskList() {
|
|
93
|
-
const { tasks, openTasks,
|
|
203
|
+
const { tasks, openTasks, completedTasks, markDone } = useFramedTasks();
|
|
94
204
|
|
|
95
205
|
return (
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
206
|
+
<ul>
|
|
207
|
+
{openTasks.map(task => (
|
|
208
|
+
<li key={task.id}>
|
|
209
|
+
{task.feedback.raw}
|
|
210
|
+
<button onClick={() => markDone(task.id)}>Done</button>
|
|
211
|
+
</li>
|
|
212
|
+
))}
|
|
213
|
+
</ul>
|
|
100
214
|
);
|
|
101
215
|
}
|
|
102
216
|
```
|
|
103
217
|
|
|
104
|
-
|
|
218
|
+
## Components
|
|
105
219
|
|
|
106
|
-
|
|
107
|
-
- `useFramed()` — Access full provider context
|
|
220
|
+
### FeedbackWidget
|
|
108
221
|
|
|
109
|
-
|
|
222
|
+
The main feedback collection widget:
|
|
110
223
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
3. Paste in Bolt, Lovable, or Cursor
|
|
114
|
-
4. AI implements the changes
|
|
224
|
+
```tsx
|
|
225
|
+
import { FeedbackWidget } from '@framed-dev/react';
|
|
115
226
|
|
|
116
|
-
|
|
227
|
+
<FeedbackWidget
|
|
228
|
+
position="bottom-right"
|
|
229
|
+
theme="light"
|
|
230
|
+
hotkey="f"
|
|
231
|
+
/>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### TasksReadyPanel
|
|
235
|
+
|
|
236
|
+
Display pending tasks with AI export:
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
import { TasksReadyPanel } from '@framed-dev/react';
|
|
240
|
+
|
|
241
|
+
<TasksReadyPanel
|
|
242
|
+
showCopyPrompt
|
|
243
|
+
onTaskClick={(task) => console.log(task)}
|
|
244
|
+
/>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Premium Features
|
|
248
|
+
|
|
249
|
+
Get a license key at [framed.dev](https://framed.dev) for:
|
|
250
|
+
|
|
251
|
+
- **AI-powered task parsing** - Natural language to structured tasks
|
|
252
|
+
- **PageSpeed analysis** - Automated performance reports
|
|
253
|
+
- **SEO audits** - Comprehensive site analysis
|
|
254
|
+
- **Analytics dashboard** - Usage and engagement metrics
|
|
255
|
+
- **White-label branding** - Custom widget appearance
|
|
256
|
+
|
|
257
|
+
## Local Development Mode
|
|
258
|
+
|
|
259
|
+
For development without Supabase:
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
<FramedProvider
|
|
263
|
+
config={{
|
|
264
|
+
projectId: 'dev',
|
|
265
|
+
mode: 'local', // Uses localStorage
|
|
266
|
+
auth: { mode: 'dev' },
|
|
267
|
+
}}
|
|
268
|
+
>
|
|
269
|
+
{children}
|
|
270
|
+
<FeedbackWidget />
|
|
271
|
+
</FramedProvider>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
This stores all data in localStorage - perfect for prototyping.
|
|
275
|
+
|
|
276
|
+
## CLI Commands
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Initialize Framed in your project
|
|
280
|
+
npx @framed-dev/cli init
|
|
281
|
+
|
|
282
|
+
# Run database migrations
|
|
283
|
+
npx @framed-dev/cli migrate
|
|
284
|
+
|
|
285
|
+
# Show migrations without executing
|
|
286
|
+
npx @framed-dev/cli migrate --dry-run
|
|
287
|
+
```
|
|
117
288
|
|
|
118
289
|
## License
|
|
119
290
|
|
|
@@ -123,4 +294,4 @@ MIT
|
|
|
123
294
|
|
|
124
295
|
- [GitHub](https://github.com/framed-dev/framed-widget)
|
|
125
296
|
- [Issues](https://github.com/framed-dev/framed-widget/issues)
|
|
126
|
-
-
|
|
297
|
+
- [Framed.dev](https://framed.dev) - Premium features
|