robodev 0.45.0 → 0.46.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/package.json +2 -2
- package/src/api.ts +13 -0
- package/src/collect-files.ts +7 -0
- package/src/config.ts +1 -0
- package/src/emit-starter.test.ts +58 -0
- package/src/index.ts +8 -0
- package/src/mcp-protocol.ts +120 -0
- package/src/mcp-tools.ts +178 -0
- package/src/mcp.test.ts +336 -0
- package/src/mcp.ts +281 -0
- package/templates/auth-chat/.rulesync/skills/povio-ui-styling/SKILL.md +3 -0
- package/templates/auth-chat/apps/fe/src/styles/base.css +0 -19
- package/templates/auth-chat/package.json +1 -1
- package/templates/backend/package.json +1 -1
- package/templates/catalog.json +5 -0
- package/templates/empty/package.json +1 -1
- package/templates/marketplace/.rulesync/skills/povio-ui-styling/SKILL.md +3 -0
- package/templates/marketplace/apps/fe/src/styles/base.css +0 -19
- package/templates/marketplace/package.json +1 -1
- package/templates/shadcn/README.md +20 -0
- package/templates/shadcn/components.json +21 -0
- package/templates/shadcn/index.html +12 -0
- package/templates/shadcn/orval.config.ts +14 -0
- package/templates/shadcn/package.json +29 -0
- package/templates/shadcn/postcss.config.js +6 -0
- package/templates/shadcn/robodev/api/health.ts +7 -0
- package/templates/shadcn/robodev/database.ts +14 -0
- package/templates/shadcn/robodev/package.json +4 -0
- package/templates/shadcn/src/App.tsx +35 -0
- package/templates/shadcn/src/api/generated/endpoints.ts +54 -0
- package/templates/shadcn/src/api/generated/model/healthResponse.ts +11 -0
- package/templates/shadcn/src/api/generated/model/index.ts +9 -0
- package/templates/shadcn/src/api/openapi.json +42 -0
- package/templates/shadcn/src/app.css +117 -0
- package/templates/shadcn/src/components/ui/button.tsx +39 -0
- package/templates/shadcn/src/lib/utils.ts +3 -0
- package/templates/shadcn/src/main.tsx +5 -0
- package/templates/shadcn/tailwind.config.ts +42 -0
- package/templates/shadcn/tsconfig.json +16 -0
- package/templates/shadcn/vite.config.ts +20 -0
- package/templates/space/.rulesync/skills/povio-ui-styling/SKILL.md +3 -0
- package/templates/space/apps/fe/src/styles/base.css +0 -19
- package/templates/space/package.json +1 -1
|
@@ -132,6 +132,9 @@ Do not create a CSS file for ordinary spacing, flex/grid layout, a simple hover,
|
|
|
132
132
|
| Generated design tokens | Figma-generated `theme.css` |
|
|
133
133
|
| Handwritten global token or browser rule | `base.css` or `globals.css` |
|
|
134
134
|
|
|
135
|
+
Retheming the app means overriding tokens in `globals.css`, in `@layer base`, after the
|
|
136
|
+
`theme.css` import — nowhere else redeclares them, so the last declaration in that layer wins.
|
|
137
|
+
|
|
135
138
|
## Guardrails
|
|
136
139
|
|
|
137
140
|
- Use `@povio/ui` before creating a custom primitive.
|
|
@@ -82,22 +82,3 @@ html {
|
|
|
82
82
|
.flex-fill {
|
|
83
83
|
flex: 1 0 0;
|
|
84
84
|
}
|
|
85
|
-
|
|
86
|
-
:root {
|
|
87
|
-
--elevation-fill-default-2-base: 248 249 249;
|
|
88
|
-
--elevation-outline-default-1-base: 218 220 221;
|
|
89
|
-
--elevation-outline-default-2-base: 198 200 201;
|
|
90
|
-
--interactive-contained-primary-idle-base: 0 90 154;
|
|
91
|
-
--interactive-contained-primary-hover-base: 46 142 210;
|
|
92
|
-
--interactive-contained-primary-pressed-base: 95 170 224;
|
|
93
|
-
--interactive-contained-primary-disabled-base: 155 194 221;
|
|
94
|
-
--interactive-contained-primary-focus-base: 95 170 224;
|
|
95
|
-
--interactive-outlined-primary-on-idle-base: 0 90 154;
|
|
96
|
-
--interactive-outlined-primary-outline-idle-base: 0 90 154;
|
|
97
|
-
--interactive-outlined-primary-outline-hover-base: 46 142 210;
|
|
98
|
-
--interactive-text-primary-idle-base: 0 90 154;
|
|
99
|
-
--interactive-text-primary-hover-base: 46 142 210;
|
|
100
|
-
--text-default-1-base: 25 26 27;
|
|
101
|
-
--text-default-2-base: 79 85 88;
|
|
102
|
-
--text-default-3-base: 111 114 116;
|
|
103
|
-
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# {{NAME}}
|
|
2
|
+
|
|
3
|
+
Blank `robodev/database.ts` and `GET /api/health` plus a hosted Welcome page with shadcn and an orval client. No sample schema.
|
|
4
|
+
|
|
5
|
+
The project App URL serves the hosted Welcome page. Edit `index.html` and `src/`, then `robodev deploy` (or Code + Save).
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
robodev create my-app --template shadcn
|
|
9
|
+
robodev dev # local APIs
|
|
10
|
+
pnpm run dev:fe # optional local Vite
|
|
11
|
+
pnpm run generate:api # regenerate the orval client from src/api/openapi.json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`robodev create` without `--template` / `--starter` / `--empty` still uses Empty. Pass `--template shadcn` (or `--starter shadcn`) for this starter.
|
|
15
|
+
|
|
16
|
+
Do not write a `frontend` block in `robodev/.robodev` — that block is for Tiny `apps/fe`. Root `index.html` + `src/` deploy as hosted React.
|
|
17
|
+
|
|
18
|
+
Hosted compile does not run Tailwind. `src/app.css` is plain CSS so Welcome works on the project host. `tailwind.config.ts` and `postcss.config.js` are for local `shadcn add` / Vite only. The orval client under `src/api/generated/` is committed; regenerate it after API changes.
|
|
19
|
+
|
|
20
|
+
Docs: https://robodev.povio.dev/docs
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"rsc": false,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "tailwind.config.ts",
|
|
8
|
+
"css": "src/app.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true,
|
|
11
|
+
"prefix": ""
|
|
12
|
+
},
|
|
13
|
+
"aliases": {
|
|
14
|
+
"components": "@/components",
|
|
15
|
+
"utils": "@/lib/utils",
|
|
16
|
+
"ui": "@/components/ui",
|
|
17
|
+
"lib": "@/lib",
|
|
18
|
+
"hooks": "@/hooks"
|
|
19
|
+
},
|
|
20
|
+
"iconLibrary": "lucide"
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
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>{{NAME}}</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from "orval";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
api: {
|
|
5
|
+
input: "src/api/openapi.json",
|
|
6
|
+
output: {
|
|
7
|
+
mode: "split",
|
|
8
|
+
target: "src/api/generated/endpoints.ts",
|
|
9
|
+
schemas: "src/api/generated/model",
|
|
10
|
+
client: "fetch",
|
|
11
|
+
clean: true,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PACKAGE_NAME}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "robodev dev",
|
|
8
|
+
"deploy": "robodev deploy",
|
|
9
|
+
"dev:fe": "vite",
|
|
10
|
+
"build": "vite build",
|
|
11
|
+
"generate:api": "orval"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@robodev-ai/sdk": "^0.13.0",
|
|
15
|
+
"@robodev-ai/client": "^0.5.0",
|
|
16
|
+
"react": "^18.3.1",
|
|
17
|
+
"react-dom": "^18.3.1"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"autoprefixer": "^10.4.21",
|
|
21
|
+
"orval": "^7.11.2",
|
|
22
|
+
"postcss": "^8.5.6",
|
|
23
|
+
"robodev": "^0.46.0",
|
|
24
|
+
"shadcn": "^2.10.0",
|
|
25
|
+
"tailwindcss": "^3.4.17",
|
|
26
|
+
"typescript": "^5.9.2",
|
|
27
|
+
"vite": "^6.0.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placeholder schema. Replace this table or add tables, then `robodev deploy`.
|
|
3
|
+
*/
|
|
4
|
+
import { defineDatabase, pgTable, text, uuid } from "@robodev-ai/sdk";
|
|
5
|
+
|
|
6
|
+
export const items = pgTable("items", {
|
|
7
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
8
|
+
name: text("name").notNull(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export default defineDatabase({
|
|
12
|
+
name: "app",
|
|
13
|
+
tables: { items },
|
|
14
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { getHealth } from "@/api/generated/endpoints";
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
|
|
5
|
+
export function App() {
|
|
6
|
+
const [status, setStatus] = useState("Checking health…");
|
|
7
|
+
|
|
8
|
+
async function loadHealth() {
|
|
9
|
+
try {
|
|
10
|
+
const result = await getHealth();
|
|
11
|
+
if (result.status !== 200 || result.data.ok !== true) {
|
|
12
|
+
setStatus(`Request failed (${result.status})`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
setStatus("{ ok: true }");
|
|
16
|
+
} catch (error) {
|
|
17
|
+
setStatus(error instanceof Error ? error.message : "Request failed");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
void loadHealth();
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<main>
|
|
27
|
+
<h1>Welcome</h1>
|
|
28
|
+
<p>Your app is ready.</p>
|
|
29
|
+
<Button type="button" onClick={() => void loadHealth()}>
|
|
30
|
+
Check health
|
|
31
|
+
</Button>
|
|
32
|
+
<p>{status}</p>
|
|
33
|
+
</main>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated by orval v7.21.0 🍺
|
|
3
|
+
* Do not edit manually.
|
|
4
|
+
* app
|
|
5
|
+
* Committed snapshot of Empty GET /api/health.
|
|
6
|
+
* OpenAPI spec version: 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
import type {
|
|
9
|
+
HealthResponse
|
|
10
|
+
} from './model';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @summary Health
|
|
15
|
+
*/
|
|
16
|
+
export type getHealthResponse200 = {
|
|
17
|
+
data: HealthResponse
|
|
18
|
+
status: 200
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type getHealthResponseSuccess = (getHealthResponse200) & {
|
|
22
|
+
headers: Headers;
|
|
23
|
+
};
|
|
24
|
+
;
|
|
25
|
+
|
|
26
|
+
export type getHealthResponse = (getHealthResponseSuccess)
|
|
27
|
+
|
|
28
|
+
export const getGetHealthUrl = () => {
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
return `/api/health`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const getHealth = async ( options?: RequestInit): Promise<getHealthResponse> => {
|
|
37
|
+
|
|
38
|
+
const res = await fetch(getGetHealthUrl(),
|
|
39
|
+
{
|
|
40
|
+
...options,
|
|
41
|
+
method: 'GET'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
const body = [204, 205, 304].includes(res.status) ? null : await res.text();
|
|
48
|
+
|
|
49
|
+
const data: getHealthResponse['data'] = body ? JSON.parse(body) : {}
|
|
50
|
+
return { data, status: res.status, headers: res.headers } as getHealthResponse
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.0.3",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "app",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "Committed snapshot of Empty GET /api/health."
|
|
7
|
+
},
|
|
8
|
+
"paths": {
|
|
9
|
+
"/api/health": {
|
|
10
|
+
"get": {
|
|
11
|
+
"operationId": "getHealth",
|
|
12
|
+
"summary": "Health",
|
|
13
|
+
"responses": {
|
|
14
|
+
"200": {
|
|
15
|
+
"description": "OK",
|
|
16
|
+
"content": {
|
|
17
|
+
"application/json": {
|
|
18
|
+
"schema": {
|
|
19
|
+
"$ref": "#/components/schemas/HealthResponse"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"components": {
|
|
29
|
+
"schemas": {
|
|
30
|
+
"HealthResponse": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"required": ["ok"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"ok": {
|
|
35
|
+
"type": "boolean",
|
|
36
|
+
"enum": [true]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--background: 0 0% 100%;
|
|
3
|
+
--foreground: 240 10% 3.9%;
|
|
4
|
+
--primary: 240 5.9% 10%;
|
|
5
|
+
--primary-foreground: 0 0% 98%;
|
|
6
|
+
--secondary: 240 4.8% 95.9%;
|
|
7
|
+
--secondary-foreground: 240 5.9% 10%;
|
|
8
|
+
--muted: 240 4.8% 95.9%;
|
|
9
|
+
--muted-foreground: 240 3.8% 46.1%;
|
|
10
|
+
--accent: 240 4.8% 95.9%;
|
|
11
|
+
--accent-foreground: 240 5.9% 10%;
|
|
12
|
+
--destructive: 0 84.2% 60.2%;
|
|
13
|
+
--destructive-foreground: 0 0% 98%;
|
|
14
|
+
--border: 240 5.9% 90%;
|
|
15
|
+
--ring: 240 5.9% 10%;
|
|
16
|
+
--radius: 0.5rem;
|
|
17
|
+
color: hsl(var(--foreground));
|
|
18
|
+
font-family: system-ui, sans-serif;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
body {
|
|
22
|
+
margin: 0;
|
|
23
|
+
background: hsl(var(--background));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
main {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
align-items: flex-start;
|
|
30
|
+
gap: 1rem;
|
|
31
|
+
padding: 2rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.btn {
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
gap: 0.5rem;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
border-radius: calc(var(--radius) - 2px);
|
|
41
|
+
font-size: 0.875rem;
|
|
42
|
+
font-weight: 500;
|
|
43
|
+
border: 1px solid transparent;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
transition:
|
|
46
|
+
background-color 0.15s ease,
|
|
47
|
+
color 0.15s ease,
|
|
48
|
+
border-color 0.15s ease;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.btn:focus-visible {
|
|
52
|
+
outline: 2px solid hsl(var(--ring));
|
|
53
|
+
outline-offset: 2px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.btn:disabled {
|
|
57
|
+
pointer-events: none;
|
|
58
|
+
opacity: 0.5;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.btn-default {
|
|
62
|
+
background: hsl(var(--primary));
|
|
63
|
+
color: hsl(var(--primary-foreground));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.btn-default:hover {
|
|
67
|
+
background: hsl(var(--primary) / 0.9);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.btn-destructive {
|
|
71
|
+
background: hsl(var(--destructive));
|
|
72
|
+
color: hsl(var(--destructive-foreground));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.btn-outline {
|
|
76
|
+
border-color: hsl(var(--border));
|
|
77
|
+
background: hsl(var(--background));
|
|
78
|
+
color: hsl(var(--foreground));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.btn-secondary {
|
|
82
|
+
background: hsl(var(--secondary));
|
|
83
|
+
color: hsl(var(--secondary-foreground));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.btn-ghost {
|
|
87
|
+
background: transparent;
|
|
88
|
+
color: hsl(var(--foreground));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.btn-link {
|
|
92
|
+
background: transparent;
|
|
93
|
+
color: hsl(var(--primary));
|
|
94
|
+
text-decoration: underline;
|
|
95
|
+
text-underline-offset: 4px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.btn-size-default {
|
|
99
|
+
height: 2.25rem;
|
|
100
|
+
padding: 0 1rem;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.btn-size-sm {
|
|
104
|
+
height: 2rem;
|
|
105
|
+
padding: 0 0.75rem;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.btn-size-lg {
|
|
109
|
+
height: 2.5rem;
|
|
110
|
+
padding: 0 2rem;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.btn-size-icon {
|
|
114
|
+
height: 2.25rem;
|
|
115
|
+
width: 2.25rem;
|
|
116
|
+
padding: 0;
|
|
117
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes } from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
const variantClasses = {
|
|
5
|
+
default: "btn btn-default",
|
|
6
|
+
destructive: "btn btn-destructive",
|
|
7
|
+
outline: "btn btn-outline",
|
|
8
|
+
secondary: "btn btn-secondary",
|
|
9
|
+
ghost: "btn btn-ghost",
|
|
10
|
+
link: "btn btn-link",
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
const sizeClasses = {
|
|
14
|
+
default: "btn-size-default",
|
|
15
|
+
sm: "btn-size-sm",
|
|
16
|
+
lg: "btn-size-lg",
|
|
17
|
+
icon: "btn-size-icon",
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
21
|
+
variant?: keyof typeof variantClasses;
|
|
22
|
+
size?: keyof typeof sizeClasses;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function Button({
|
|
26
|
+
className,
|
|
27
|
+
variant = "default",
|
|
28
|
+
size = "default",
|
|
29
|
+
type = "button",
|
|
30
|
+
...props
|
|
31
|
+
}: ButtonProps) {
|
|
32
|
+
return (
|
|
33
|
+
<button
|
|
34
|
+
type={type}
|
|
35
|
+
className={cn(variantClasses[variant], sizeClasses[size], className)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Config } from "tailwindcss";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
darkMode: ["class"],
|
|
5
|
+
content: ["./index.html", "./src/**/*.{ts,tsx}"],
|
|
6
|
+
theme: {
|
|
7
|
+
extend: {
|
|
8
|
+
borderRadius: {
|
|
9
|
+
lg: "var(--radius)",
|
|
10
|
+
md: "calc(var(--radius) - 2px)",
|
|
11
|
+
sm: "calc(var(--radius) - 4px)",
|
|
12
|
+
},
|
|
13
|
+
colors: {
|
|
14
|
+
background: "hsl(var(--background))",
|
|
15
|
+
foreground: "hsl(var(--foreground))",
|
|
16
|
+
primary: {
|
|
17
|
+
DEFAULT: "hsl(var(--primary))",
|
|
18
|
+
foreground: "hsl(var(--primary-foreground))",
|
|
19
|
+
},
|
|
20
|
+
secondary: {
|
|
21
|
+
DEFAULT: "hsl(var(--secondary))",
|
|
22
|
+
foreground: "hsl(var(--secondary-foreground))",
|
|
23
|
+
},
|
|
24
|
+
muted: {
|
|
25
|
+
DEFAULT: "hsl(var(--muted))",
|
|
26
|
+
foreground: "hsl(var(--muted-foreground))",
|
|
27
|
+
},
|
|
28
|
+
accent: {
|
|
29
|
+
DEFAULT: "hsl(var(--accent))",
|
|
30
|
+
foreground: "hsl(var(--accent-foreground))",
|
|
31
|
+
},
|
|
32
|
+
destructive: {
|
|
33
|
+
DEFAULT: "hsl(var(--destructive))",
|
|
34
|
+
foreground: "hsl(var(--destructive-foreground))",
|
|
35
|
+
},
|
|
36
|
+
border: "hsl(var(--border))",
|
|
37
|
+
ring: "hsl(var(--ring))",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
plugins: [],
|
|
42
|
+
} satisfies Config;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"baseUrl": ".",
|
|
11
|
+
"paths": {
|
|
12
|
+
"@/*": ["./src/*"]
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"include": ["robodev/**/*.ts", "src"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { dirname, resolve } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { defineConfig } from "vite";
|
|
4
|
+
|
|
5
|
+
const root = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
esbuild: { jsx: "automatic" },
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
"@": resolve(root, "src"),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
server: {
|
|
15
|
+
proxy: {
|
|
16
|
+
"/api": "http://localhost:4000",
|
|
17
|
+
"/openapi.json": "http://localhost:4000",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -132,6 +132,9 @@ Do not create a CSS file for ordinary spacing, flex/grid layout, a simple hover,
|
|
|
132
132
|
| Generated design tokens | Figma-generated `theme.css` |
|
|
133
133
|
| Handwritten global token or browser rule | `base.css` or `globals.css` |
|
|
134
134
|
|
|
135
|
+
Retheming the app means overriding tokens in `globals.css`, in `@layer base`, after the
|
|
136
|
+
`theme.css` import — nowhere else redeclares them, so the last declaration in that layer wins.
|
|
137
|
+
|
|
135
138
|
## Guardrails
|
|
136
139
|
|
|
137
140
|
- Use `@povio/ui` before creating a custom primitive.
|
|
@@ -82,22 +82,3 @@ html {
|
|
|
82
82
|
.flex-fill {
|
|
83
83
|
flex: 1 0 0;
|
|
84
84
|
}
|
|
85
|
-
|
|
86
|
-
:root {
|
|
87
|
-
--elevation-fill-default-2-base: 248 249 249;
|
|
88
|
-
--elevation-outline-default-1-base: 218 220 221;
|
|
89
|
-
--elevation-outline-default-2-base: 198 200 201;
|
|
90
|
-
--interactive-contained-primary-idle-base: 0 90 154;
|
|
91
|
-
--interactive-contained-primary-hover-base: 46 142 210;
|
|
92
|
-
--interactive-contained-primary-pressed-base: 95 170 224;
|
|
93
|
-
--interactive-contained-primary-disabled-base: 155 194 221;
|
|
94
|
-
--interactive-contained-primary-focus-base: 95 170 224;
|
|
95
|
-
--interactive-outlined-primary-on-idle-base: 0 90 154;
|
|
96
|
-
--interactive-outlined-primary-outline-idle-base: 0 90 154;
|
|
97
|
-
--interactive-outlined-primary-outline-hover-base: 46 142 210;
|
|
98
|
-
--interactive-text-primary-idle-base: 0 90 154;
|
|
99
|
-
--interactive-text-primary-hover-base: 46 142 210;
|
|
100
|
-
--text-default-1-base: 25 26 27;
|
|
101
|
-
--text-default-2-base: 79 85 88;
|
|
102
|
-
--text-default-3-base: 111 114 116;
|
|
103
|
-
}
|