paperclip-theme 0.1.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 +47 -0
- package/dist/constants.d.ts +82 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +644 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +4 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +31 -0
- package/dist/manifest.js.map +1 -0
- package/dist/ui/index.js +815 -0
- package/dist/ui/index.js.map +7 -0
- package/dist/worker.d.ts +4 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +73 -0
- package/dist/worker.js.map +1 -0
- package/package.json +44 -0
- package/scripts/build-ui.mjs +24 -0
- package/src/constants.ts +668 -0
- package/src/index.ts +2 -0
- package/src/manifest.ts +39 -0
- package/src/ui/index.tsx +914 -0
- package/src/worker.ts +105 -0
- package/tsconfig.json +21 -0
package/src/worker.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
definePlugin,
|
|
3
|
+
runWorker,
|
|
4
|
+
type PaperclipPlugin,
|
|
5
|
+
type PluginContext,
|
|
6
|
+
type PluginHealthDiagnostics,
|
|
7
|
+
} from "@paperclipai/plugin-sdk";
|
|
8
|
+
import {
|
|
9
|
+
PLUGIN_ID,
|
|
10
|
+
STATE_KEYS,
|
|
11
|
+
DATA_ENDPOINTS,
|
|
12
|
+
ACTION_NAMES,
|
|
13
|
+
THEME_PRESETS,
|
|
14
|
+
type ThemeConfig,
|
|
15
|
+
} from "./constants.js";
|
|
16
|
+
|
|
17
|
+
let currentContext: PluginContext | null = null;
|
|
18
|
+
|
|
19
|
+
async function readTheme(ctx: PluginContext): Promise<ThemeConfig | null> {
|
|
20
|
+
return (await ctx.state.get({
|
|
21
|
+
scopeKind: "instance",
|
|
22
|
+
stateKey: STATE_KEYS.activeTheme,
|
|
23
|
+
})) as ThemeConfig | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function writeTheme(
|
|
27
|
+
ctx: PluginContext,
|
|
28
|
+
theme: ThemeConfig,
|
|
29
|
+
): Promise<void> {
|
|
30
|
+
await ctx.state.set(
|
|
31
|
+
{ scopeKind: "instance", stateKey: STATE_KEYS.activeTheme },
|
|
32
|
+
theme,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const plugin: PaperclipPlugin = definePlugin({
|
|
37
|
+
async setup(ctx) {
|
|
38
|
+
currentContext = ctx;
|
|
39
|
+
|
|
40
|
+
ctx.data.register(DATA_ENDPOINTS.activeTheme, async () => {
|
|
41
|
+
return await readTheme(ctx);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
ctx.data.register(DATA_ENDPOINTS.presets, async () => {
|
|
45
|
+
return THEME_PRESETS;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
ctx.actions.register(ACTION_NAMES.applyTheme, async (params) => {
|
|
49
|
+
const incoming = params as Partial<ThemeConfig> & { id?: string };
|
|
50
|
+
|
|
51
|
+
if (!incoming.id) {
|
|
52
|
+
throw new Error("Theme id is required");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const preset = THEME_PRESETS.find((p) => p.id === incoming.id);
|
|
56
|
+
|
|
57
|
+
const theme: ThemeConfig = preset
|
|
58
|
+
? {
|
|
59
|
+
...preset,
|
|
60
|
+
tokens: { ...preset.tokens, ...(incoming.tokens ?? {}) },
|
|
61
|
+
radius: incoming.radius ?? preset.radius,
|
|
62
|
+
updatedAt: new Date().toISOString(),
|
|
63
|
+
}
|
|
64
|
+
: {
|
|
65
|
+
id: incoming.id,
|
|
66
|
+
name: incoming.name ?? "Custom Theme",
|
|
67
|
+
description: incoming.description ?? "",
|
|
68
|
+
author: incoming.author ?? "User",
|
|
69
|
+
isDark: incoming.isDark ?? true,
|
|
70
|
+
tokens: incoming.tokens ?? {},
|
|
71
|
+
radius: incoming.radius ?? "0",
|
|
72
|
+
createdAt: incoming.createdAt ?? new Date().toISOString(),
|
|
73
|
+
updatedAt: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
await writeTheme(ctx, theme);
|
|
77
|
+
return theme;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
ctx.actions.register(ACTION_NAMES.resetTheme, async () => {
|
|
81
|
+
const defaultTheme = THEME_PRESETS[0];
|
|
82
|
+
if (!defaultTheme) {
|
|
83
|
+
throw new Error("No default preset found");
|
|
84
|
+
}
|
|
85
|
+
await writeTheme(ctx, defaultTheme);
|
|
86
|
+
return defaultTheme;
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
async onHealth(): Promise<PluginHealthDiagnostics> {
|
|
91
|
+
const ctx = currentContext;
|
|
92
|
+
const activeTheme = ctx ? await readTheme(ctx) : null;
|
|
93
|
+
return {
|
|
94
|
+
status: "ok",
|
|
95
|
+
message: "Theme Customizer ready",
|
|
96
|
+
details: {
|
|
97
|
+
activePreset: activeTheme?.name ?? "Default (unset)",
|
|
98
|
+
presetsAvailable: THEME_PRESETS.length,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
export default plugin;
|
|
105
|
+
runWorker(plugin, import.meta.url);
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"rootDir": "./src",
|
|
11
|
+
"strict": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"jsx": "react-jsx",
|
|
17
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"]
|
|
18
|
+
},
|
|
19
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
20
|
+
"exclude": ["node_modules", "dist", "src/ui/**/*"]
|
|
21
|
+
}
|