Skip to content

Commit

Permalink
improve demo and hover rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
acao committed Jun 1, 2024
1 parent 5a22761 commit 45eb768
Show file tree
Hide file tree
Showing 40 changed files with 687 additions and 338 deletions.
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
auto-install-peers=true
16 changes: 5 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ Codemirror 6 extensions that provide full [JSON Schema](https://json-schema.org/

## Features

This is now a full-featured library for both json4 (aka json) and json5 using extensions, so they should compatible with any frontend framework and/or integration library
This is now a full-featured library for json schema for `json`, `json5` and `yaml` as cm6 extensions!

- ✅ validation messages
- ✅ autocompletion with insert text
-lint validation messages from json schema
- ✅ autocompletion with insert text from json schema
- ✅ hover tooltips
- ✅ dynamic, per-editor-instance schemas using codemirror `StateField` and linting refresh
- ✅ markdown rendering for `schema.description` and custom `formatHover` and `formatError` configuration

## Resources

Expand All @@ -29,6 +30,7 @@ Based on whether you want to support json4, json5 or both, you will need to inst

### Breaking Changes:

- 0.7.0 - this version introduces markdown rendering in place of returning html strings, so any usage of `formatHover` and/or `formatError` configuration will be passed to `markdown-it` which doesn't handle html by default.
- 0.5.0 - this breaking change only impacts those following the "custom usage" approach, it _does not_ effect users using the high level, "bundled" `jsonSchema()` or `json5Schema()` modes. See the custom usages below to learn how to use the new `stateExtensions` and `handleRefresh` exports.

### json4
Expand Down Expand Up @@ -281,11 +283,3 @@ const state = EditorState.create({
`monaco-json` and `monaco-yaml` both provide json schema features for json, cson and yaml, and we want the nascent codemirror 6 to have them as well!
Also, json5 is slowly growing in usage, and it needs full language support for the browser!
## Our Goals
- working GeoJSON spec linter & completion
- working variables json mode for `cm6-graphql`, ala `monaco-graphql`
- json5 support for `graphiql` as a plugin!
- perhaps use @lezer to make a json5 language service for monaco-editor + json5?
- json5 + json4 json schema features for all!
17 changes: 13 additions & 4 deletions dev/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,21 +103,30 @@ <h1><code>codemirror-json-schema</code> demo</h1>
>
docker-compose.yml
</option>
<option value="github-workflow.json">github workflow</option>

<option value="github-action.json">github action</option>
<option value="eslintrc.json">eslintrc.json</option>
<option value="chart.json">helm chart</option>
</select>
</div>
<div class="grid-row">
<div>
<h2><code>package.json</code> demo</h2>
<div id="editor"></div>
<h2>
<code><span>package</span>.json</code> demo
</h2>
<div id="editor-json"></div>
</div>
<div>
<h2><code>package.json5</code> demo</h2>
<h2>
<code><span>package</span>.json5</code> demo
</h2>
<div id="editor-json5"></div>
</div>
<div>
<h2><code>package.yaml</code> demo</h2>
<h2>
<code><span>package</span>.yaml</code> demo
</h2>
<div id="editor-yaml"></div>
</div>
</div>
Expand Down
89 changes: 73 additions & 16 deletions dev/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
drawSelection,
keymap,
highlightActiveLineGutter,
ViewUpdate,
} from "@codemirror/view";
// import { basicSetup } from "@codemirror/basic-setup";
import { lintGutter } from "@codemirror/lint";
Expand Down Expand Up @@ -41,6 +42,7 @@ import { json5Schema } from "../src/json5";
import { yamlSchema } from "../src/yaml";

const schema = packageJsonSchema as JSONSchema7;
const ls = localStorage;

/**
* none of these are required for json4 or 5
Expand Down Expand Up @@ -74,26 +76,44 @@ const commonExtensions = [
syntaxHighlighting(oneDarkHighlightStyle),
];

const persistEditorStateOnChange = (key: string) => {
return EditorView.updateListener.of(
debounce((v: ViewUpdate) => {
if (v.docChanged) {
ls.setItem(key, v.state.doc.toString());
}
}, 300)
);
};

/**
* json4!
*/

const state = EditorState.create({
doc: jsonText,
extensions: [commonExtensions, jsonSchema(schema)],
doc: ls.getItem("json4") ?? jsonText,
extensions: [
commonExtensions,
jsonSchema(schema),
persistEditorStateOnChange("json4"),
],
});

const editor1 = new EditorView({
state,
parent: document.querySelector("#editor")!,
parent: document.querySelector("#editor-json")!,
});

/**
* json5!
*/
const json5State = EditorState.create({
doc: json5Text,
extensions: [commonExtensions, json5Schema(schema)],
doc: ls.getItem("json5") ?? json5Text,
extensions: [
commonExtensions,
json5Schema(schema),
persistEditorStateOnChange("json5"),
],
});

const editor2 = new EditorView({
Expand All @@ -105,8 +125,12 @@ const editor2 = new EditorView({
* yaml!
*/
const yamlState = EditorState.create({
doc: yamlText,
extensions: [commonExtensions, yamlSchema(schema)],
doc: ls.getItem("yaml") ?? yamlText,
extensions: [
commonExtensions,
yamlSchema(schema),
persistEditorStateOnChange("yaml"),
],
});

const editor3 = new EditorView({
Expand All @@ -120,21 +144,54 @@ const handleSchemaChange = (newSchema: JSONSchema7) => {
updateSchema(editor3, newSchema);
};

// new EditorState.fi(editor1, editor2);
// Hot Module Replacement
// if (module.hot) {
// module.hot.accept();
// }
const schemaCache = new Map<string, JSONSchema7>([["package.json", schema]]);

const getSchema = async (val: string) => {
const cachedSchema = schemaCache.get(val);
if (cachedSchema) {
handleSchemaChange(cachedSchema);
return;
}

const data = await (
await fetch(`https://json.schemastore.org/${val}`)
).json();
schemaCache.set(val, data);
handleSchemaChange(data);
};

const schemaSelect = document.getElementById("schema-selection");
const schemaValue = localStorage.getItem("selectedSchema")!;

const setFileName = (value) => {
document.querySelectorAll("h2 code span").forEach((el) => {
el.textContent = value;
});
};

if (schemaValue) {
schemaSelect!.value = schemaValue;
await getSchema(schemaValue);
document.querySelectorAll("h2 code span").forEach((el) => {
el.textContent = schemaValue.split(".")[0];
});
setFileName(schemaValue.split(".")[0]);
}

schemaSelect!.onchange = async (e) => {
const val = e.target!.value!;
if (!val) {
return;
}
const data = await (
await fetch(`https://json.schemastore.org/${val}`)
).json();
handleSchemaChange(data);
ls.setItem("selectedSchema", val);
await getSchema(val);
setFileName(val.split(".")[0]);
};

function debounce(fn: Function, ms: number) {
let timeout: number;
return function (this: any, ...args: any[]) {
clearTimeout(timeout);
timeout = window.setTimeout(() => fn.apply(this, args), ms);
};
}
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,19 @@
"homepage": "https://codemirror-json-schema.netlify.app/",
"dependencies": {
"@changesets/changelog-github": "^0.4.8",
"@codemirror/lang-yaml": "^6.0.0",
"@sagold/json-pointer": "^5.1.1",
"@shikijs/markdown-it": "^1.1.7",
"@types/json-schema": "^7.0.12",
"@types/node": "^20.4.2",
"json-schema": "^0.4.0",
"json-schema-library": "^9.1.2",
"markdown-it": "^14.0.0",
"vite-tsconfig-paths": "^4.3.1",
"yaml": "^2.3.4"
},
"optionalDependencies": {
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-yaml": "^6.0.0",
"codemirror-json5": "^1.0.3",
"json5": "^2.2.3"
},
Expand All @@ -85,10 +87,10 @@
"@codemirror/basic-setup": "^0.20.0",
"@codemirror/commands": "^6.2.4",
"@codemirror/language": "^6.8.0",
"@codemirror/lint": "^6.4.0",
"@codemirror/state": "^6.2.1",
"@codemirror/lint": "^6.5.0",
"@codemirror/state": "^6.0.0",
"@codemirror/theme-one-dark": "^6.1.2",
"@codemirror/view": "^6.14.1",
"@codemirror/view": "^6.0.0",
"@evilmartians/lefthook": "^1.4.6",
"@lezer/common": "^1.0.3",
"@types/markdown-it": "^13.0.7",
Expand All @@ -100,16 +102,16 @@
"typedoc": "^0.24.8",
"typedoc-plugin-markdown": "^3.15.3",
"typescript": "^5.1.6",
"vite": "^4.5.0",
"vite": "^5.1.4",
"vitest": "0.34.6",
"vitest-dom": "^0.1.0"
},
"scripts": {
"dev": "vite ./dev --port 3000",
"build": "pnpm tsc && tsc --module commonjs --target es2017 --outDir cjs && vite build ./dev --outDir ../public --emptyOutDir",
"build": "pnpm tsc && tsc --module commonjs --target es2017 --moduleResolution Node --outDir cjs && vite build ./dev --outDir ../public --emptyOutDir",
"test": "vitest --dom",
"test:coverage": "vitest run --dom --coverage ",
"tsc": "tsc && pnpm replace:env",
"tsc": "NODE_OPTIONS=--experimental-specifier-resolution=node tsc && pnpm replace:env",
"version-packages": "changeset version && pnpm typedoc && pnpm prettier:write CHANGELOG.md && git add package.json pnpm-lock.yaml CHANGELOG.md",
"release": "pnpm build && changeset publish",
"typedoc": "typedoc --out docs src/index.ts src/json5.ts && pnpm prettier:write docs/**/*",
Expand Down
Loading

0 comments on commit 45eb768

Please sign in to comment.