Skip to content

Commit

Permalink
fead: add support for code editor
Browse files Browse the repository at this point in the history
  • Loading branch information
silvester-pari committed Jan 31, 2025
1 parent d6f4bc0 commit 5b36b90
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 0 deletions.
1 change: 1 addition & 0 deletions elements/jsonform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"dependencies": {
"@eox/elements-utils": "^0.1.5",
"@json-editor/json-editor": "^2.11.0",
"ace-builds": "^1.37.5",
"easymde": "^2.18.0",
"isomorphic-dompurify": "^2.4.0",
"lit": "^3.2.0",
Expand Down
15 changes: 15 additions & 0 deletions elements/jsonform/src/helpers/editor.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { JSONEditor } from "@json-editor/json-editor/src/core.js";
import { SimplemdeEditor } from "@json-editor/json-editor/src/editors/simplemde.js";
import EasyMDE from "easymde/dist/easymde.min.js";
import AceEditor from "ace-builds";
import "ace-builds/esm-resolver.js";
import addCustomInputs from "../custom-inputs";

// using a drop-in replacement for EasyMDE,
// see https://github.com/json-editor/json-editor/issues/1093
window.SimpleMDE = EasyMDE;

// using Ace editor for code
// see https://github.com/json-editor/json-editor/tree/master?tab=readme-ov-file#specialized-string-editors
window.ace = AceEditor;
window.ace.config.set("useWorker", false);

/**
* Create the editor instance
*
Expand Down Expand Up @@ -67,6 +74,14 @@ export const createEditor = (element) => {
`;
element.renderRoot.insertBefore(style, element.renderRoot.firstChild);
}

// Check if any editor requires AceEditor
const aceUsed = Object.values(editor.editors).find((e) => e.ace_container);
if (aceUsed && !element.noShadow) {
// Attach to shadow root
aceUsed.ace_editor_instance.renderer.attachToShadowRoot();
aceUsed.ace_editor_instance.resize();
}
});
return editor;
};
Expand Down
9 changes: 9 additions & 0 deletions elements/jsonform/src/style.eox.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ export const styleEOX = `
border-radius: 2px !important;
}
/* Ace Editor */
.ace_editor,
.ace_editor * {
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Droid Sans Mono", "Consolas", monospace !important;
}
.ace_editor {
background: transparent;
}
/* Buttons overrides */
button {
vertical-align: middle;
Expand Down
19 changes: 19 additions & 0 deletions elements/jsonform/stories/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Story demonstrating the Ace editor
*/
import codeSchema from "./public/codeSchema.json";

const Code = {
args: {
schema: codeSchema,
value: {
code: `// Some code here
function sayHello() {
console.log("Hello World!");
}
sayHello();`,
},
},
};
export default Code;
1 change: 1 addition & 0 deletions elements/jsonform/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export { default as WKTStory } from "./wkt"; // Input form based on Drawtools th
export { default as GeoJSONStory } from "./geojson"; // Input form based on Drawtools that returns GeoJSON
export { default as CustomEditorInterfacesStory } from "./custom-editor-interfaces"; // Custom editor interfaces
export { default as ValidationStory } from "./validation";
export { default as CodeStory } from "./code";
6 changes: 6 additions & 0 deletions elements/jsonform/stories/jsonform.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
LineStory,
CustomEditorInterfacesStory,
ValidationStory,
CodeStory,
} from "./index.js";

export default {
Expand Down Expand Up @@ -46,6 +47,11 @@ export const Primary = PrimaryStory;
*/
export const Validation = ValidationStory;

/**
* Example showing the usage of Ace editor for code editing
*/
export const Code = CodeStory;

/**
* JSON Form based on STAC Catalog config
*/
Expand Down
18 changes: 18 additions & 0 deletions elements/jsonform/stories/public/codeSchema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "object",
"properties": {
"code": {
"type": "string",
"title": "Code editor powered by <a href='https://ace.c9.io/'>Ace</a>",
"description": "See the <a href='https://github.com/ajaxorg/ace/wiki/Configuring-Ace'>configuration options</a> and <a href='https://github.com/ajaxorg/ace/tree/master/src/theme'>themes</a> that can be passed to <code>options.ace</code>",
"format": "javascript",
"options": {
"ace": {
"tabSize": 2,
"useSoftTabs": true,
"wrap": true
}
}
}
}
}
1 change: 1 addition & 0 deletions elements/jsonform/test/cases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { default as loadExternalSchemaTest } from "./load-external-schema";
export { default as loadExternalValueTest } from "./load-external-value";
export { default as loadReRenderFormOnChangeTest } from "./re-render-form-on-change";
export { default as loadMarkdownTest } from "./load-markdown";
export { default as loadCodeTest } from "./load-code";
export { default as triggerChangeEventTest } from "./trigger-change-event";
export { default as loadValuesTest } from "./load-values";
export { default as loadMisMatchingValuesTest } from "./load-mismatching-values";
Expand Down
54 changes: 54 additions & 0 deletions elements/jsonform/test/cases/load-code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { html } from "lit";
import { TEST_SELECTORS } from "../../src/enums";

// Destructure TEST_SELECTORS object
const { jsonForm } = TEST_SELECTORS;

const testVals = {
key: "foo",
value: "bar",
number: 7,
};
/**
* Test to verify if the code editor loads successfully.
*/
const loadCodeTest = () => {
cy.mount(
html`<eox-jsonform
.schema=${{
type: "object",
properties: {
[testVals.key]: {
type: "string",
format: "json",
options: {
ace: {
tabSize: testVals.number,
},
},
},
},
}}
.value=${{
[testVals.key]: testVals.value,
}}
></eox-jsonform>`,
).as(jsonForm);
// Find the jsonForm element and access its shadow DOM
cy.get(jsonForm)
.shadow()
.within(() => {
// Check if Ace editor has loaded
cy.get(".ace_editor").should("exist");
// Check if text was rendered correctly
cy.get(".ace_line").invoke("text").should("eq", testVals.value);
});
cy.get(jsonForm).and(($el) => {
// Check if editor settings were applied
expect(
$el[0].editor.editors[`root.${testVals.key}`].options.ace.tabSize,
).to.eq(testVals.number);
});
};

export default loadCodeTest;
2 changes: 2 additions & 0 deletions elements/jsonform/test/general.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
renderDrawtools,
loadCustomEditorInterfaceTest,
loadSubmitButtonTest,
loadCodeTest,
} from "./cases";

// Test suite for Jsonform
Expand All @@ -26,6 +27,7 @@ describe("Jsonform", () => {
it("loads value from url", () => loadExternalValueTest());
it("re-renders form on change", () => loadReRenderFormOnChangeTest());
it("loads the markdown editor", () => loadMarkdownTest());
it("loads the code editor", () => loadCodeTest());
it("triggers a change event when typing", () => triggerChangeEventTest());
it("loads values", () => loadValuesTest());
it("loads mismatching values", () => loadMisMatchingValuesTest());
Expand Down
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5b36b90

Please sign in to comment.