Skip to content

Commit 8b716c9

Browse files
committed
...
1 parent a9fc1d9 commit 8b716c9

File tree

26 files changed

+576
-213
lines changed

26 files changed

+576
-213
lines changed

.claude/settings.local.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"mcp__playwright__browser_close",
4444
"Bash(npx webpack --mode development)",
4545
"Bash(tree:*)",
46-
"Bash(grep:*)"
46+
"Bash(grep:*)",
47+
"WebSearch"
4748
],
4849
"deny": [],
4950
"ask": []
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
---
2-
import { themeVariablesToCSS, defaultPreset } from 'cx-theme-variables';
2+
import { themeVariablesToCSS } from 'cx-theme-variables';
3+
import homedocsLightPreset from '../styles/homedocsLight';
4+
import homedocsDarkPreset from '../styles/homedocsDark';
35
4-
interface Props {
5-
theme?: typeof defaultPreset;
6-
}
7-
8-
const { theme = defaultPreset } = Astro.props;
9-
const css = themeVariablesToCSS(theme);
6+
const css = themeVariablesToCSS(homedocsLightPreset)
7+
+ "\n"
8+
+ themeVariablesToCSS(homedocsDarkPreset, ".dark");
109
---
1110

1211
<style set:html={css}></style>

homedocs/src/examples/layout/TabsExample.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default (
5555
Disabled
5656
</Tab>
5757
</div>
58-
<div className="border border-border bg-white p-4" text={m.tab} />
58+
<div className="border cxm-cover p-4" text={m.tab} />
5959
</div>
6060
</div>
6161
);

homedocs/src/examples/layout/TooltipExample.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const m = createModel<PageModel>();
1414

1515
// @index
1616
export default (
17-
<div style={{ display: "flex", flexDirection: "column", gap: "24px" }}>
17+
<div class="flex flex-col gap-6 items-start">
1818
<div tooltip="This is a basic tooltip." style={{ cursor: "help" }}>
1919
Basic tooltip
2020
</div>

homedocs/src/examples/theme-editor/ThemeEditor.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Controller } from "cx/ui";
2-
import { Button, LookupField } from "cx/widgets";
2+
import { Button, enableTooltips, LookupField } from "cx/widgets";
33

44
import "../../icons/lucide";
55
import { m, ThemeEditorModel } from "./model";
@@ -14,8 +14,12 @@ import { Sidebar } from "./Sidebar";
1414
import { VariableEditor } from "./VariableEditor";
1515
import { Preview } from "./Preview";
1616

17+
enableTooltips();
18+
1719
class ThemeEditorController extends Controller<ThemeEditorModel> {
1820
onInit() {
21+
const saved = this.loadState();
22+
if (saved) this.store.init(saved);
1923
this.store.init(m.activeCategory, "colors");
2024
this.store.init(m.presetName, "default");
2125

@@ -43,6 +47,29 @@ class ThemeEditorController extends Controller<ThemeEditorModel> {
4347
},
4448
true,
4549
);
50+
51+
this.addTrigger(
52+
"save-state",
53+
[m.presetName, m.rounding, m.density, m.font, m.activeCategory],
54+
(presetName, rounding, density, font, activeCategory) => {
55+
this.saveState({ presetName, rounding, density, font, activeCategory });
56+
},
57+
);
58+
}
59+
60+
loadState() {
61+
try {
62+
const json = localStorage.getItem("cx-theme-editor");
63+
return json ? JSON.parse(json) : null;
64+
} catch {
65+
return null;
66+
}
67+
}
68+
69+
saveState(state: Record<string, string>) {
70+
try {
71+
localStorage.setItem("cx-theme-editor", JSON.stringify(state));
72+
} catch {}
4673
}
4774

4875
copyToClipboard() {

homedocs/src/examples/theme-editor/VariableEditor.tsx

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@ import {
66
PrivateStore,
77
Prop,
88
} from "cx/ui";
9-
import { ColorPicker, Dropdown, Repeater, TextField } from "cx/widgets";
9+
import {
10+
ColorPicker,
11+
Dropdown,
12+
Icon,
13+
Repeater,
14+
TextField,
15+
Tooltip,
16+
} from "cx/widgets";
17+
import { variableMap, ThemeVarsDiv, defaultPreset } from "cx-theme-variables";
1018
import { m } from "./model";
1119

1220
interface ColorSwatchProps {
@@ -19,8 +27,10 @@ const ColorSwatch = createFunctionalComponent(({ value }: ColorSwatchProps) => {
1927
<PrivateStore data={{ value }}>
2028
<div class="relative">
2129
<div
22-
class="w-9 h-9 rounded-md border border-border shrink-0 cursor-pointer hover:border-foreground transition-colors"
23-
style={computable(state.value, (v) => ({ background: v }))}
30+
class="w-8 h-8 rounded-md border border-border shrink-0 cursor-pointer hover:border-foreground transition-colors"
31+
style={computable(state.value, (v) => ({
32+
background: v,
33+
}))}
2434
onClick={(e: any, { store }: any) => store.toggle(state.open)}
2535
/>
2636
<Dropdown
@@ -45,7 +55,15 @@ const ColorSwatch = createFunctionalComponent(({ value }: ColorSwatchProps) => {
4555
});
4656

4757
export const VariableEditor = createFunctionalComponent(() => (
48-
<div class="w-80 border-r border-border p-4 overflow-y-auto bg-background">
58+
<ThemeVarsDiv
59+
theme={{
60+
...defaultPreset,
61+
inputPaddingX: "6px",
62+
inputPaddingY: "6px",
63+
inputLineHeight: "18px",
64+
}}
65+
class="w-80 border-r border-border p-4 overflow-y-auto bg-background"
66+
>
4967
<Repeater records={m.categories} recordAlias={m.$category} keyField="id">
5068
<div
5169
visible={expr(
@@ -70,12 +88,31 @@ export const VariableEditor = createFunctionalComponent(() => (
7088

7189
<Repeater records={m.$category.variables} recordAlias={m.$variable}>
7290
<div class="mb-5">
73-
<div
74-
class="text-xs text-foreground mb-1"
75-
text={m.$variable.label}
76-
/>
77-
<div class="flex gap-2 items-center">
78-
<TextField value={m.$variable.value} style="flex: 1;" />
91+
<div class="flex items-center gap-1">
92+
<div class="text-xs text-foreground" text={m.$variable.label} />
93+
<div
94+
class="text-muted-foreground cursor-help"
95+
tooltip={{
96+
title: m.$variable.key,
97+
text: computable(
98+
m.$variable.key,
99+
(key) => `var(${variableMap[key]})`,
100+
),
101+
placement: "up",
102+
}}
103+
>
104+
<Icon
105+
name="info"
106+
style="width: 14px; height: 14px; display: block"
107+
/>
108+
</div>
109+
</div>
110+
<div class="flex gap-2 items-center mt-1">
111+
<TextField
112+
value={m.$variable.value}
113+
style="flex: 1;"
114+
inputStyle="font-family: monospace"
115+
/>
79116
<ColorSwatch
80117
value={m.$variable.value}
81118
visible={expr(m.$variable.type, (type) => type === "color")}
@@ -85,5 +122,5 @@ export const VariableEditor = createFunctionalComponent(() => (
85122
</Repeater>
86123
</div>
87124
</Repeater>
88-
</div>
125+
</ThemeVarsDiv>
89126
));

homedocs/src/examples/theme-editor/data.ts

Lines changed: 98 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
densityTweaks,
1010
fontTweaks,
1111
} from "cx-theme-variables";
12+
import homedocsLightPreset from "../../styles/homedocsLight";
13+
import homedocsDarkPreset from "../../styles/homedocsDark";
1214

1315
// Variable metadata - maps ThemeVariables keys to labels, types, and categories
1416
const variableMetadata: Array<{
@@ -24,6 +26,18 @@ const variableMetadata: Array<{
2426
type: "color",
2527
category: "colors",
2628
},
29+
{
30+
key: "primaryTextColor",
31+
label: "Primary text color",
32+
type: "color",
33+
category: "colors",
34+
},
35+
{
36+
key: "primaryBorderColor",
37+
label: "Primary border color",
38+
type: "text",
39+
category: "colors",
40+
},
2741
{
2842
key: "accentColor",
2943
label: "Accent color",
@@ -36,6 +50,18 @@ const variableMetadata: Array<{
3650
type: "color",
3751
category: "colors",
3852
},
53+
{
54+
key: "dangerTextColor",
55+
label: "Danger text color",
56+
type: "color",
57+
category: "colors",
58+
},
59+
{
60+
key: "dangerBorderColor",
61+
label: "Danger border color",
62+
type: "text",
63+
category: "colors",
64+
},
3965
{ key: "textColor", label: "Text color", type: "color", category: "colors" },
4066
{
4167
key: "backgroundColor",
@@ -55,14 +81,20 @@ const variableMetadata: Array<{
5581
type: "color",
5682
category: "colors",
5783
},
58-
{
59-
key: "activeStateColor",
60-
label: "Hover overlay (black/white)",
61-
type: "color",
62-
category: "colors",
63-
},
6484

6585
// Inputs
86+
{
87+
key: "inputWidth",
88+
label: "Width",
89+
type: "size",
90+
category: "inputs",
91+
},
92+
{
93+
key: "inputColor",
94+
label: "Color",
95+
type: "text",
96+
category: "inputs",
97+
},
6698
{
6799
key: "inputBackgroundColor",
68100
label: "Background",
@@ -99,11 +131,30 @@ const variableMetadata: Array<{
99131
type: "size",
100132
category: "inputs",
101133
},
134+
// Checks & Switches
102135
{
103136
key: "checkboxSize",
104137
label: "Checkbox/Radio size",
105138
type: "size",
106-
category: "inputs",
139+
category: "checks",
140+
},
141+
{
142+
key: "switchAxisSize",
143+
label: "Switch axis size",
144+
type: "size",
145+
category: "checks",
146+
},
147+
{
148+
key: "switchHandleSize",
149+
label: "Switch handle size",
150+
type: "size",
151+
category: "checks",
152+
},
153+
{
154+
key: "switchWidth",
155+
label: "Switch width",
156+
type: "size",
157+
category: "checks",
107158
},
108159

109160
// Buttons
@@ -161,6 +212,42 @@ const variableMetadata: Array<{
161212
type: "text",
162213
category: "buttons",
163214
},
215+
{
216+
key: "buttonBorderRadius",
217+
label: "Border radius",
218+
type: "text",
219+
category: "buttons",
220+
},
221+
{
222+
key: "buttonHoverBoxShadow",
223+
label: "Hover box shadow",
224+
type: "text",
225+
category: "buttons",
226+
},
227+
{
228+
key: "buttonHoverStateMixColor",
229+
label: "Hover mix color",
230+
type: "text",
231+
category: "buttons",
232+
},
233+
{
234+
key: "buttonHoverStateMixAmount",
235+
label: "Hover mix amount",
236+
type: "text",
237+
category: "buttons",
238+
},
239+
{
240+
key: "buttonActiveStateMixColor",
241+
label: "Active mix color",
242+
type: "text",
243+
category: "buttons",
244+
},
245+
{
246+
key: "buttonActiveStateMixAmount",
247+
label: "Active mix amount",
248+
type: "text",
249+
category: "buttons",
250+
},
164251

165252
// Grids
166253
{
@@ -230,18 +317,6 @@ const variableMetadata: Array<{
230317
category: "effects",
231318
},
232319
{ key: "transition", label: "Transition", type: "text", category: "effects" },
233-
{
234-
key: "activeStateHoverAmount",
235-
label: "Hover amount",
236-
type: "text",
237-
category: "effects",
238-
},
239-
{
240-
key: "activeStatePressedAmount",
241-
label: "Pressed amount",
242-
type: "text",
243-
category: "effects",
244-
},
245320

246321
// Calendar
247322
{
@@ -256,8 +331,9 @@ const categoryMetadata = [
256331
{ id: "colors", name: "Colors", icon: "palette", group: "Theme" },
257332
{ id: "sizing", name: "Sizing", icon: "move", group: "Theme" },
258333
{ id: "effects", name: "Effects", icon: "zap", group: "Theme" },
259-
{ id: "inputs", name: "Inputs", icon: "text-cursor-input", group: "Components" },
260334
{ id: "buttons", name: "Buttons", icon: "square", group: "Components" },
335+
{ id: "inputs", name: "Inputs", icon: "text-cursor-input", group: "Components" },
336+
{ id: "checks", name: "Checks & Switches", icon: "toggle-left", group: "Components" },
261337
{ id: "grids", name: "Grids", icon: "table", group: "Components" },
262338
{ id: "calendar", name: "Calendar", icon: "calendar", group: "Components" },
263339
];
@@ -309,6 +385,8 @@ export const defaultCategories = themeToCategories(defaultPreset);
309385

310386
export const presets = [
311387
{ id: "default", text: "Default", theme: defaultPreset },
388+
{ id: "docs-light", text: "Docs Light", theme: homedocsLightPreset },
389+
{ id: "docs-dark", text: "Docs Dark", theme: homedocsDarkPreset },
312390
{ id: "darkBlue", text: "Dark Blue", theme: darkBluePreset },
313391
{ id: "darkGray", text: "Dark Gray", theme: darkGrayPreset },
314392
{ id: "ocean", text: "Ocean", theme: oceanPreset },

0 commit comments

Comments
 (0)