Skip to content

Commit c0eb4ca

Browse files
Merge pull request #127 from QueryaHub/issue/96-theme-custom-json-schema
docs(theme): querya.theme.v1 custom JSON schema (#96)
2 parents fe36e04 + 6ade631 commit c0eb4ca

3 files changed

Lines changed: 281 additions & 0 deletions

File tree

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Index of Querya Desktop documentation, grouped by audience.
1414
- [Architecture](architecture.md)`lib/` layout and module responsibilities.
1515
- [Theme system](theme.md) — runtime theming and VS Code theme tokens.
1616
- [Theme import](theme-import.md) — supported `colors` keys and merge behavior.
17+
- [Custom theme JSON](theme-custom-json.md)`querya.theme.v1` schema and fallback rules.
1718
- [Performance baseline](perf-baseline.md) — per-milestone DevTools checklist.
1819

1920
## For release managers

docs/theme-custom-json.md

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
# Querya custom theme JSON (`querya.theme.v1`)
2+
3+
Querya supports two theme file formats:
4+
5+
| Format | Root marker | Import | Docs |
6+
|--------|-------------|--------|------|
7+
| **Querya custom** | `"schema": "querya.theme.v1"` | Planned (theme registry) | this document |
8+
| **VS Code** | `"colors"` object (no `schema`) | **Supported today** | [theme-import.md](theme-import.md) |
9+
10+
VS Code JSON/JSONC import remains fully supported. The custom format is a first-class
11+
Querya schema with explicit `shadcn_colors` and `editor_colors` sections instead of
12+
VS Code workbench key names.
13+
14+
## Purpose
15+
16+
- Ship themes that map directly to Querya runtime models (`ColorScheme`,
17+
`QueryaEditorTheme`, `QueryaWorkbenchTheme`) without VS Code key indirection.
18+
- Keep theme list scans lightweight: read metadata and color maps as strings; build
19+
`QueryaTheme` only when a theme is selected.
20+
- Scale to 50+ installed themes with predictable fallback behavior.
21+
22+
Implementation (planned): `lib/core/theme/parser/querya_theme_manifest.dart` and
23+
registry services described in
24+
[theme-parser-implementation-tasks.md](theme-parser-implementation-tasks.md).
25+
26+
## Root object
27+
28+
### Required fields
29+
30+
| Field | Type | Description |
31+
|-------|------|-------------|
32+
| `schema` | string | Must be exactly `querya.theme.v1`. |
33+
| `id` | string | Stable machine id (slug). Used for filenames and settings. Lowercase letters, digits, hyphens recommended. |
34+
| `name` | string | Human-readable label shown in Preferences. |
35+
| `type` | string | `"dark"` or `"light"`. Selects fallback preset (`QueryaTheme.darkDefault` / `QueryaTheme.lightDefault`). |
36+
| `shadcn_colors` | object | String map → shadcn `ColorScheme` tokens. May be `{}`; missing keys fall back to the preset. |
37+
| `editor_colors` | object | String map → editor and workbench tokens. May be `{}`; missing keys fall back to the preset. |
38+
39+
### Optional fields
40+
41+
| Field | Type | Description |
42+
|-------|------|-------------|
43+
| `tokenColors` | array | VS Code–compatible syntax rules (same shape as VS Code themes). Applied to SQL/JSON highlighting. |
44+
| `description` | string | Short summary for theme picker / marketplace. |
45+
| `author` | string | Author or org name. |
46+
| `version` | string | Theme package version (informational). |
47+
48+
Unknown root fields are ignored. In debug builds the parser may log skipped keys.
49+
50+
## Color string formats
51+
52+
All color values are hex strings. The parser reuses `parseVsCodeColor` (via a thin
53+
Querya wrapper) and accepts:
54+
55+
| Format | Example | Notes |
56+
|--------|---------|-------|
57+
| `#RRGGBB` | `"#22D3EE"` | Most common |
58+
| `RRGGBB` | `"22D3EE"` | `#` optional |
59+
| `#RRGGBBAA` | `"#FF22D3EE"` | Alpha last (VS Code style) |
60+
| `RRGGBBAA` | `"FF22D3EE"` | `#` optional |
61+
| `#RGB` | `"#F0A"` | Expanded to `#FF00AA` |
62+
| `#RGBA` | `"#F0A8"` | Expanded to `#FF00AA88` |
63+
64+
Invalid optional color values are **skipped** for that key; the fallback preset value
65+
is used instead. Empty strings are treated as invalid.
66+
67+
## `shadcn_colors` keys
68+
69+
Maps to `shadcn_flutter.ColorScheme` (see `QueryaTheme.colorScheme`).
70+
71+
| Key | Role |
72+
|-----|------|
73+
| `background` | App / page background |
74+
| `foreground` | Primary text |
75+
| `card` | Card surface |
76+
| `cardForeground` | Text on cards |
77+
| `popover` | Popover / dropdown surface |
78+
| `popoverForeground` | Text on popovers |
79+
| `primary` | Primary actions |
80+
| `primaryForeground` | Text on primary |
81+
| `secondary` | Secondary surfaces |
82+
| `secondaryForeground` | Text on secondary |
83+
| `muted` | Muted surfaces |
84+
| `mutedForeground` | Muted labels |
85+
| `accent` | Hover / accent fills |
86+
| `accentForeground` | Text on accent |
87+
| `destructive` | Destructive actions |
88+
| `destructiveForeground` | Text on destructive |
89+
| `border` | Borders |
90+
| `input` | Input borders / fills |
91+
| `ring` | Focus ring |
92+
| `chart1``chart5` | Chart palette |
93+
94+
Brightness comes from `type`, not from individual colors.
95+
96+
## `editor_colors` keys
97+
98+
One map feeds both `QueryaEditorTheme` and `QueryaWorkbenchTheme`.
99+
100+
### Editor (syntax surface)
101+
102+
| Key | Target |
103+
|-----|--------|
104+
| `background` | Editor background |
105+
| `foreground` | Default text |
106+
| `lineHighlight` | Current line highlight |
107+
| `selection` | Selection background |
108+
| `lineNumber` | Gutter numbers |
109+
| `bracketMatch` | Matching bracket highlight |
110+
| `widgetBorder` | Editor chrome border |
111+
| `comment` | Comment token (fallback when no `tokenColors` match) |
112+
| `keyword` | Keyword token |
113+
| `string` | String token |
114+
| `number` | Numeric token |
115+
| `operator` | Operator token |
116+
| `function` | Function token |
117+
| `type` | Type name token |
118+
119+
### Workbench (chrome)
120+
121+
| Key | Target |
122+
|-----|--------|
123+
| `canvas` | Main app canvas (title bar, status areas) |
124+
| `surface` | Raised panels, tabs |
125+
| `sidebarBackground` | Explorer / sidebar |
126+
| `editorBackground` | Editor pane chrome (may differ from syntax `background`) |
127+
| `mutedForeground` | Secondary labels |
128+
| `accent` | Brand / focus accent |
129+
| `onAccent` | Text/icons on accent |
130+
| `borderSubtle` | Subtle dividers |
131+
| `destructive` | Error / delete emphasis |
132+
| `success` | Success state |
133+
| `warning` | Warning state |
134+
| `gitModified` | Git modified decoration |
135+
| `gitUntracked` | Git untracked decoration |
136+
137+
If `background` appears without `canvas`, the parser does **not** auto-map it unless
138+
explicitly documented in a future schema revision. Prefer `canvas` and
139+
`editorBackground`.
140+
141+
## `tokenColors`
142+
143+
Same structure as VS Code themes: array of objects with `scope` (string or array),
144+
optional `name`, and `settings.foreground` / `settings.background` / `settings.fontStyle`.
145+
146+
Querya applies these through `TokenStyleResolver` → SQL/JSON highlighters. See
147+
[theme-import.md](theme-import.md) for behavior notes.
148+
149+
## Fallback and error handling
150+
151+
| Situation | Behavior |
152+
|-----------|----------|
153+
| Missing optional color key | Use value from `QueryaTheme.darkDefault` or `QueryaTheme.lightDefault` (based on `type`). |
154+
| Invalid optional color | Skip key; use fallback value. |
155+
| Missing required root field (`schema`, `id`, `name`, `type`, `shadcn_colors`, `editor_colors`) | Parsing fails; theme is not loaded. |
156+
| Wrong `schema` value | Parsing fails. |
157+
| Invalid `type` | Parsing fails. |
158+
| Broken file at startup (selected theme) | App starts with **Querya Dark**; error surfaced in Preferences (planned). User setting is not deleted. |
159+
| Broken file in directory scan | Skipped or shown as disabled in picker (planned); scan does not crash the app. |
160+
161+
## JSONC
162+
163+
Comments and trailing commas are allowed in `.jsonc` files. The shared preprocessor
164+
`stripJsonc` runs before `jsonDecode` (same as VS Code import).
165+
166+
## Minimal example
167+
168+
Only required fields; all colors come from Querya Dark defaults:
169+
170+
```json
171+
{
172+
"schema": "querya.theme.v1",
173+
"id": "querya-dark-clone",
174+
"name": "Querya Dark (minimal)",
175+
"type": "dark",
176+
"shadcn_colors": {},
177+
"editor_colors": {}
178+
}
179+
```
180+
181+
## Full example (dark)
182+
183+
```json
184+
{
185+
"schema": "querya.theme.v1",
186+
"id": "cyberpunk-neon",
187+
"name": "Cyberpunk Neon",
188+
"type": "dark",
189+
"description": "Neon cyberpunk preset for Querya workbench and SQL editor.",
190+
"author": "QueryaHub",
191+
"version": "1.0.0",
192+
"shadcn_colors": {
193+
"background": "#09090B",
194+
"foreground": "#F8FAFC",
195+
"card": "#111113",
196+
"cardForeground": "#F8FAFC",
197+
"popover": "#111113",
198+
"popoverForeground": "#F8FAFC",
199+
"primary": "#00F5FF",
200+
"primaryForeground": "#020617",
201+
"secondary": "#18181B",
202+
"secondaryForeground": "#F8FAFC",
203+
"muted": "#18181B",
204+
"mutedForeground": "#94A3B8",
205+
"accent": "#FF2A6D",
206+
"accentForeground": "#F8FAFC",
207+
"destructive": "#EF4444",
208+
"destructiveForeground": "#F8FAFC",
209+
"border": "#27272A",
210+
"input": "#27272A",
211+
"ring": "#00F5FF",
212+
"chart1": "#00F5FF",
213+
"chart2": "#FF2A6D",
214+
"chart3": "#FCEE09",
215+
"chart4": "#BD00FF",
216+
"chart5": "#39FF14"
217+
},
218+
"editor_colors": {
219+
"background": "#0A0A14",
220+
"foreground": "#E8F4FF",
221+
"selection": "#FF2A6D44",
222+
"lineNumber": "#4A3F7A",
223+
"bracketMatch": "#00F5FF33",
224+
"widgetBorder": "#00F5FF66",
225+
"canvas": "#050508",
226+
"surface": "#14102A",
227+
"sidebarBackground": "#0C0820",
228+
"editorBackground": "#0A0A14",
229+
"mutedForeground": "#8B7CF8",
230+
"accent": "#00F5FF",
231+
"onAccent": "#020617",
232+
"borderSubtle": "#27272A",
233+
"destructive": "#EF4444",
234+
"gitModified": "#FCEE09",
235+
"gitUntracked": "#39FF14"
236+
},
237+
"tokenColors": [
238+
{
239+
"name": "Comments",
240+
"scope": ["comment", "comment.line"],
241+
"settings": { "foreground": "#5C4D8A", "fontStyle": "italic" }
242+
},
243+
{
244+
"name": "Keywords",
245+
"scope": ["keyword", "keyword.control"],
246+
"settings": { "foreground": "#FF2A6D", "fontStyle": "bold" }
247+
},
248+
{
249+
"name": "Strings",
250+
"scope": ["string"],
251+
"settings": { "foreground": "#FCEE09" }
252+
}
253+
]
254+
}
255+
```
256+
257+
## VS Code format vs Querya custom
258+
259+
| | VS Code JSON/JSONC | Querya custom |
260+
|--|-------------------|---------------|
261+
| Detection | No `schema`; has `colors` | `"schema": "querya.theme.v1"` |
262+
| UI colors | VS Code keys (`editor.background`, `sideBar.background`, …) | `shadcn_colors` + `editor_colors` Querya keys |
263+
| Stable id | File name only | Required `id` field |
264+
| Import today | **Yes** — Preferences → Import theme | Planned via theme registry |
265+
| Syntax tokens | `tokenColors` | `tokenColors` (same) |
266+
267+
To convert a VS Code theme manually, map keys using
268+
[theme-import.md](theme-import.md) and place workbench values into `editor_colors`;
269+
derive shadcn tokens from your palette or leave `{}` to use preset defaults.
270+
271+
## Related docs
272+
273+
- [Theme import (VS Code)](theme-import.md)
274+
- [Theme system overview](theme.md)
275+
- [Implementation plan](theme-parser-implementation-tasks.md)
276+
- Sample VS Code themes: `themes/samples/cyberpunk-neon.json`

docs/theme-import.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
Querya can apply a **subset** of VS Code theme JSON / JSONC `colors` to
44
`QueryaWorkbenchTheme`, `QueryaEditorTheme`, and the shadcn `ColorScheme`.
55

6+
For the native Querya custom format (`querya.theme.v1`), see
7+
**[theme-custom-json.md](theme-custom-json.md)**. Both formats will coexist; VS Code
8+
import remains supported.
9+
610
Imported `tokenColors` are persisted with the theme file and applied to SQL/JSON
711
syntax highlighting via `TokenStyleResolver``HighlighterTheme` (issue #46).
812

0 commit comments

Comments
 (0)