diff --git a/docs/package.json b/docs/package.json index 5c7a7e4..74d325f 100644 --- a/docs/package.json +++ b/docs/package.json @@ -12,6 +12,7 @@ }, "packageManager": "pnpm@11.15.0+sha512.266f8957a30d2be6e9468e5e66bcdedd35a794175f71b067ba8504d686cce1d0c0f429b33c323c3c569ad4891e667574a49ff71d1b89a22cc66f13c65818c578", "dependencies": { + "lucide-static": "^1.25.0", "monaco-editor": "^0.55.1", "shiki": "^4.3.1" } diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index ebb01ee..be038e8 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + lucide-static: + specifier: ^1.25.0 + version: 1.25.0 monaco-editor: specifier: ^0.55.1 version: 0.55.1 @@ -1027,6 +1030,9 @@ packages: resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} engines: {node: 20 || >=22} + lucide-static@1.25.0: + resolution: {integrity: sha512-uJTdyP8vxKELd+Kqk45ahUvOA1rv3Ehy6ZUP7JlBt8UJwmzHgFFts0OZNU3C6/4MDKsssgR9Jrut7GnuqGgYmg==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -2341,6 +2347,8 @@ snapshots: lru-cache@11.5.2: {} + lucide-static@1.25.0: {} + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 diff --git a/docs/src/pages/playground.astro b/docs/src/pages/playground.astro index d3313e9..87c49ff 100644 --- a/docs/src/pages/playground.astro +++ b/docs/src/pages/playground.astro @@ -1,4 +1,6 @@ --- +import settingsIcon from "lucide-static/icons/settings.svg?raw"; + const baseHref = import.meta.env.BASE_URL; --- @@ -93,9 +95,17 @@ const baseHref = import.meta.env.BASE_URL; import EditorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker"; import { createHighlighter } from "shiki"; import { examples } from "../playground/examples.js"; + import { + gleamConfiguration, + gleamLanguage, + } from "../playground/gleam-monarch.js"; self.MonacoEnvironment = { getWorker: () => new EditorWorker() }; + monaco.languages.register({ id: "gleam" }); + monaco.languages.setMonarchTokensProvider("gleam", gleamLanguage); + monaco.languages.setLanguageConfiguration("gleam", gleamConfiguration); + // ---- brand colors, shared by the editor and the output ---- const colors = { bg: "#1c1824", @@ -119,6 +129,7 @@ const baseHref = import.meta.env.BASE_URL; { token: "number", foreground: colors.number.slice(1) }, { token: "comment", foreground: colors.comment.slice(1) }, { token: "predefined", foreground: colors.func.slice(1) }, + { token: "type.identifier", foreground: colors.func.slice(1) }, ], colors: { "editor.background": colors.bg, @@ -365,8 +376,11 @@ const baseHref = import.meta.env.BASE_URL; } .button { cursor: pointer; } .button:hover { border-color: var(--violet-solid); } + .button.icon { display: flex; align-items: center; padding: 0.3rem 0.45rem; } + .button.icon svg { width: 15px; height: 15px; stroke: currentColor; } .settings-wrap { position: relative; } + .popover[hidden] { display: none; } .popover { position: absolute; right: 0; diff --git a/docs/src/playground/examples.js b/docs/src/playground/examples.js index b0a6fdb..3f2ce56 100644 --- a/docs/src/playground/examples.js +++ b/docs/src/playground/examples.js @@ -74,7 +74,7 @@ pub async fn delete_rule(pool: &PgPool, team: Uuid, id: Uuid) -> sqlx::Result<() { label: "Gleam ยท sqlight", host: "gleam", - monacoLang: "plaintext", + monacoLang: "gleam", shikiLang: "gleam", source: `pub fn list_users(db: sqlight.Connection, org: Int) { sqlight.query("select id,name from users where org = ? order by name", on: db, with: [sqlight.int(org)]) diff --git a/docs/src/playground/gleam-monarch.js b/docs/src/playground/gleam-monarch.js new file mode 100644 index 0000000..3a04154 --- /dev/null +++ b/docs/src/playground/gleam-monarch.js @@ -0,0 +1,60 @@ +// Monaco has no built-in Gleam support; a small Monarch grammar covers +// the input-editor basics (keywords, strings, numbers, comments, types). + +export const gleamConfiguration = { + comments: { lineComment: "//" }, + brackets: [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ], + autoClosingPairs: [ + { open: "{", close: "}" }, + { open: "[", close: "]" }, + { open: "(", close: ")" }, + { open: '"', close: '"' }, + ], + surroundingPairs: [ + { open: "{", close: "}" }, + { open: "[", close: "]" }, + { open: "(", close: ")" }, + { open: '"', close: '"' }, + ], +}; + +export const gleamLanguage = { + defaultToken: "", + keywords: [ + "as", + "assert", + "case", + "const", + "echo", + "else", + "fn", + "if", + "import", + "let", + "opaque", + "panic", + "pub", + "todo", + "type", + "use", + ], + tokenizer: { + root: [ + [/\/\/\/?.*$/, "comment"], + [/"(?:[^"\\]|\\.)*"/, "string"], + [/\b0[bB][01_]+\b/, "number"], + [/\b0[xX][0-9a-fA-F_]+\b/, "number"], + [/\b\d[\d_]*(\.\d+)?(e-?\d+)?\b/, "number"], + [/\b[A-Z][A-Za-z0-9]*\b/, "type.identifier"], + [ + /\b[a-z_][a-z0-9_]*\b/, + { cases: { "@keywords": "keyword", "@default": "identifier" } }, + ], + [/\|>|<-|->|<>|[=<>!+\-*/%]=?|\.\.|\|/, "operator"], + ], + }, +};