monaco pmo

This commit is contained in:
2026-01-06 18:41:58 +01:00
parent 41da79611c
commit 801f30de0b
6 changed files with 201 additions and 7 deletions

View File

@@ -7,12 +7,14 @@ import ThemeDropdown from '~/components/ui/ThemeDropdown.vue';
<div>
<header class="flex justify-end p-4 space-x-4">
<ThemeDropdown />
<SignedOut>
<SignInDialog />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
<ClientOnly>
<SignedOut>
<SignInDialog />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
</ClientOnly>
</header>
<slot />
</div>

56
app/pages/presets/new.vue Normal file
View File

@@ -0,0 +1,56 @@
<template>
<ClientOnly>
<div ref="editorContainer" class="h-96 w-full border rounded-md overflow-hidden"></div>
</ClientOnly>
</template>
<script setup lang="ts">
import mocha from "@catppuccin/vscode/themes/mocha.json";
const editorContainer = ref<HTMLElement | null>(null);
const editorInstance = shallowRef<any>(null);
const monaco = useMonaco();
const value = ref('');
onMounted(() => {
if (!monaco.value) return;
// Transformation logic for VS Code -> Monaco
const rules = (mocha as any).tokenColors.flatMap((color: any) => {
const scopes = Array.isArray(color.scope) ? color.scope : [color.scope];
return scopes.map((scope: string) => ({
token: scope || '',
foreground: color.settings.foreground,
fontStyle: color.settings.fontStyle,
}));
});
monaco.value.editor.defineTheme('catppuccin-mocha', {
base: 'vs-dark',
inherit: true,
rules: rules,
colors: (mocha as any).colors
});
if (editorContainer.value) {
editorInstance.value = monaco.value.editor.create(editorContainer.value, {
value: value.value,
language: 'typescript',
theme: 'catppuccin-mocha',
automaticLayout: true,
minimap: { enabled: false },
scrollBeyondLastLine: false,
});
// Sync value changes back to ref
editorInstance.value.onDidChangeModelContent(() => {
value.value = editorInstance.value.getValue();
});
}
});
onBeforeUnmount(() => {
editorInstance.value?.dispose();
});
</script>

14
debug-theme.js Normal file
View File

@@ -0,0 +1,14 @@
import fs from 'fs';
import path from 'path';
const themePath = 'node_modules/.pnpm/@catppuccin+vscode@3.18.1/node_modules/@catppuccin/vscode/themes/mocha.json';
const content = fs.readFileSync(themePath, 'utf8');
const json = JSON.parse(content);
console.log('Keys:', Object.keys(json));
if (json.tokenColors) {
console.log('First tokenColor:', JSON.stringify(json.tokenColors[0], null, 2));
console.log('Type of scope:', typeof json.tokenColors[0].scope);
} else {
console.log('tokenColors not found!');
}

View File

@@ -11,7 +11,7 @@ export default defineNuxtConfig({
tailwindcss(),
],
},
modules: ['shadcn-nuxt', '@nuxtjs/color-mode', '@pinia/nuxt', 'nuxt-cron', '@clerk/nuxt'],
modules: ['shadcn-nuxt', '@nuxtjs/color-mode', '@pinia/nuxt', 'nuxt-cron', '@clerk/nuxt', 'nuxt-monaco-editor'],
colorMode: {
classSuffix: ''
},

View File

@@ -12,6 +12,7 @@
"db:migrate": "drizzle-kit generate && drizzle-kit migrate"
},
"dependencies": {
"@catppuccin/vscode": "^3.18.1",
"@clerk/nuxt": "^1.13.10",
"@clerk/themes": "^2.4.46",
"@neondatabase/serverless": "^1.0.2",
@@ -24,6 +25,7 @@
"drizzle-orm": "^0.45.1",
"lucide-vue-next": "^0.548.0",
"nuxt": "^4.2.0",
"nuxt-monaco-editor": "^1.4.0",
"pinia": "^3.0.3",
"reka-ui": "^2.6.0",
"shadcn-nuxt": "2.3.2",

120
pnpm-lock.yaml generated
View File

@@ -8,6 +8,9 @@ importers:
.:
dependencies:
'@catppuccin/vscode':
specifier: ^3.18.1
version: 3.18.1
'@clerk/nuxt':
specifier: ^1.13.10
version: 1.13.10(magicast@0.5.0)(react@19.2.3)(vue@3.5.22(typescript@5.9.3))
@@ -44,6 +47,9 @@ importers:
nuxt:
specifier: ^4.2.0
version: 4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4(drizzle-orm@0.45.1(@neondatabase/serverless@1.0.2)(@types/pg@8.16.0)(kysely@0.28.9)))(drizzle-orm@0.45.1(@neondatabase/serverless@1.0.2)(@types/pg@8.16.0)(kysely@0.28.9))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(rollup@4.52.5)(terser@5.44.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))(yaml@2.8.1)
nuxt-monaco-editor:
specifier: ^1.4.0
version: 1.4.0(magicast@0.5.0)(monaco-editor@0.55.1)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))
pinia:
specifier: ^3.0.3
version: 3.0.3(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))
@@ -219,6 +225,13 @@ packages:
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
engines: {node: '>=6.9.0'}
'@catppuccin/palette@1.7.1':
resolution: {integrity: sha512-aRc1tbzrevOTV7nFTT9SRdF26w/MIwT4Jwt4fDMc9itRZUDXCuEDBLyz4TQMlqO9ZP8mf5Hu4Jr6D03NLFc6Gw==}
'@catppuccin/vscode@3.18.1':
resolution: {integrity: sha512-aVG6vUN0RXPd8wX9X9RSiyGkwsBeGulifmwwFkYQgdEiyR2ERmv0Z/y0KADlUJMU/cDLrRxmRRbXPC5Ni+ctvQ==}
engines: {node: '>=22.0.0'}
'@clerk/backend@2.29.0':
resolution: {integrity: sha512-cw4CK6ZHgeFROirlIOawelqRBxZAyH6v3GPSYZEEzYAL0WWUHx7cMXzoQcTMruH7w6UM7s3Ox+uUcINESWkQPA==}
engines: {node: '>=18.17.0'}
@@ -1678,6 +1691,9 @@ packages:
'@types/resolve@1.20.2':
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
'@types/web-bluetooth@0.0.21':
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
@@ -1920,6 +1936,10 @@ packages:
resolution: {integrity: sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==}
hasBin: true
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
@@ -1973,6 +1993,10 @@ packages:
caniuse-lite@1.0.30001751:
resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
chokidar@4.0.3:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
@@ -2234,6 +2258,9 @@ packages:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'}
dompurify@3.2.7:
resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==}
domutils@3.2.2:
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
@@ -2624,6 +2651,10 @@ packages:
iron-webcrypto@1.2.1:
resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
is-core-module@2.16.1:
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
engines: {node: '>= 0.4'}
@@ -2907,6 +2938,11 @@ packages:
magicast@0.5.0:
resolution: {integrity: sha512-D0cxqnb8DpO66P4LkD9ME6a4AhRK6A+xprXksD5vtsJN6G4zbzdI10vDaWCIyj3eLwjNZrQxUYB20FDhKrMEKQ==}
marked@14.0.0:
resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==}
engines: {node: '>= 18'}
hasBin: true
mdn-data@2.0.28:
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
@@ -2971,6 +3007,9 @@ packages:
mocked-exports@0.1.1:
resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==}
monaco-editor@0.55.1:
resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==}
mrmime@2.0.1:
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
engines: {node: '>=10'}
@@ -3065,6 +3104,11 @@ packages:
nuxt-cron@1.8.0:
resolution: {integrity: sha512-XgNdounfdXNHOVlYTFDhc28yerwBP7+MP4Tk8GmC6GkxWo3nCWZ/pmqpan+tCmVVhUn6ltpe5KSCChWgl5P3kg==}
nuxt-monaco-editor@1.4.0:
resolution: {integrity: sha512-uRvPr3FbuSFV4LIHNUJMTAJnrfggBVP+o8WsIJiN8iRK5u+ejN4Nhuz1u5bM90et30p0S3YYvvB/YNPsNKoD0g==}
peerDependencies:
monaco-editor: '*'
nuxt@4.2.0:
resolution: {integrity: sha512-4qzf2Ymf07dMMj50TZdNZgMqCdzDch8NY3NO2ClucUaIvvsr6wd9+JrDpI1CckSTHwqU37/dIPFpvIQZoeHoYA==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -3130,6 +3174,10 @@ packages:
peerDependencies:
oxc-parser: '>=0.72.0'
p-map@7.0.4:
resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==}
engines: {node: '>=18'}
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
@@ -3466,6 +3514,10 @@ packages:
readdir-glob@1.1.3:
resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==}
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
@@ -4011,6 +4063,12 @@ packages:
'@nuxt/kit':
optional: true
vite-plugin-static-copy@3.1.4:
resolution: {integrity: sha512-iCmr4GSw4eSnaB+G8zc2f4dxSuDjbkjwpuBLLGvQYR9IW7rnDzftnUjOH5p4RYR+d4GsiBqXRvzuFhs5bnzVyw==}
engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies:
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
vite-plugin-vue-tracer@1.0.1:
resolution: {integrity: sha512-L5/vAhT6oYbH4RSQYGLN9VfHexWe7SGzca1pJ7oPkL6KtxWA1jbGeb3Ri1JptKzqtd42HinOq4uEYqzhVWrzig==}
peerDependencies:
@@ -4358,6 +4416,12 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@catppuccin/palette@1.7.1': {}
'@catppuccin/vscode@3.18.1':
dependencies:
'@catppuccin/palette': 1.7.1
'@clerk/backend@2.29.0(react@19.2.3)':
dependencies:
'@clerk/shared': 3.41.1(react@19.2.3)
@@ -5668,6 +5732,9 @@ snapshots:
'@types/resolve@1.20.2': {}
'@types/trusted-types@2.0.7':
optional: true
'@types/web-bluetooth@0.0.21': {}
'@unhead/vue@2.0.19(vue@3.5.22(typescript@5.9.3))':
@@ -5980,6 +6047,8 @@ snapshots:
baseline-browser-mapping@2.8.20: {}
binary-extensions@2.3.0: {}
bindings@1.5.0:
dependencies:
file-uri-to-path: 1.0.0
@@ -6062,6 +6131,18 @@ snapshots:
caniuse-lite@1.0.30001751: {}
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
braces: 3.0.3
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
chokidar@4.0.3:
dependencies:
readdirp: 4.1.2
@@ -6294,6 +6375,10 @@ snapshots:
dependencies:
domelementtype: 2.3.0
dompurify@3.2.7:
optionalDependencies:
'@types/trusted-types': 2.0.7
domutils@3.2.2:
dependencies:
dom-serializer: 2.0.0
@@ -6685,6 +6770,10 @@ snapshots:
iron-webcrypto@1.2.1: {}
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
is-core-module@2.16.1:
dependencies:
hasown: 2.0.2
@@ -6924,6 +7013,8 @@ snapshots:
'@babel/types': 7.28.5
source-map-js: 1.2.1
marked@14.0.0: {}
mdn-data@2.0.28: {}
mdn-data@2.12.2: {}
@@ -6974,6 +7065,11 @@ snapshots:
mocked-exports@0.1.1: {}
monaco-editor@0.55.1:
dependencies:
dompurify: 3.2.7
marked: 14.0.0
mrmime@2.0.1: {}
ms@2.1.3: {}
@@ -7135,6 +7231,16 @@ snapshots:
transitivePeerDependencies:
- magicast
nuxt-monaco-editor@1.4.0(magicast@0.5.0)(monaco-editor@0.55.1)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)):
dependencies:
'@nuxt/kit': 4.2.0(magicast@0.5.0)
defu: 6.1.4
monaco-editor: 0.55.1
vite-plugin-static-copy: 3.1.4(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))
transitivePeerDependencies:
- magicast
- vite
nuxt@4.2.0(@parcel/watcher@2.5.1)(@types/node@24.9.2)(@vue/compiler-sfc@3.5.22)(db0@0.3.4(drizzle-orm@0.45.1(@neondatabase/serverless@1.0.2)(@types/pg@8.16.0)(kysely@0.28.9)))(drizzle-orm@0.45.1(@neondatabase/serverless@1.0.2)(@types/pg@8.16.0)(kysely@0.28.9))(ioredis@5.8.2)(lightningcss@1.30.2)(magicast@0.5.0)(rollup@4.52.5)(terser@5.44.0)(tsx@4.21.0)(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))(yaml@2.8.1):
dependencies:
'@dxup/nuxt': 0.2.0(magicast@0.5.0)
@@ -7375,6 +7481,8 @@ snapshots:
magic-regexp: 0.10.0
oxc-parser: 0.95.0
p-map@7.0.4: {}
package-json-from-dist@1.0.1: {}
package-manager-detector@1.5.0: {}
@@ -7682,6 +7790,10 @@ snapshots:
dependencies:
minimatch: 5.1.6
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
readdirp@4.1.2: {}
redis-errors@1.2.0: {}
@@ -8239,6 +8351,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
vite-plugin-static-copy@3.1.4(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)):
dependencies:
chokidar: 3.6.0
p-map: 7.0.4
picocolors: 1.1.1
tinyglobby: 0.2.15
vite: 7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1)
vite-plugin-vue-tracer@1.0.1(vite@7.1.12(@types/node@24.9.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1))(vue@3.5.22(typescript@5.9.3)):
dependencies:
estree-walker: 3.0.3