add custom theme to json editor
This commit is contained in:
parent
5551ac6ced
commit
3c8ac17617
|
|
@ -0,0 +1,72 @@
|
||||||
|
.editor-container {
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
--gap: 8px;
|
||||||
|
|
||||||
|
h1 {}
|
||||||
|
h2 {}
|
||||||
|
h3 {}
|
||||||
|
p {
|
||||||
|
margin: 0 0 var(--gap) 0;
|
||||||
|
}
|
||||||
|
input[type=text],
|
||||||
|
input[type=email] {
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.3;
|
||||||
|
padding: var(--gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// override theme-default
|
||||||
|
.je-indented-panel {
|
||||||
|
padding-left: var(--gap);
|
||||||
|
margin-left: var(--gap);
|
||||||
|
border-left: 1px solid #ccc
|
||||||
|
}
|
||||||
|
|
||||||
|
.je-indented-panel--top {
|
||||||
|
padding-left: var(--gap);
|
||||||
|
margin-left: var(--gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.je-object__container {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
margin-bottom: var(--gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.je-form-input-label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: calc(var(--gap) / 2);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.je-form-input-description {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.je-child-editor-holder {
|
||||||
|
margin-bottom: var(--gap);
|
||||||
|
}
|
||||||
|
.je-header-button-holder {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.je-table {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.je-textarea {
|
||||||
|
height: 150px;
|
||||||
|
min-height: 150px;
|
||||||
|
max-height: 500px;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
<h1>JSONCV Editor</h1>
|
<h1>JSONCV Editor</h1>
|
||||||
|
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<div class="left" id="editor-container"></div>
|
<div class="left editor-container"></div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div id="editor-toc"></div>
|
<div class="editor-toc"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
|
import objectPath from 'object-path';
|
||||||
|
|
||||||
import { JSONEditor } from '@json-editor/json-editor/dist/jsoneditor';
|
import { JSONEditor } from '@json-editor/json-editor/dist/jsoneditor';
|
||||||
|
|
||||||
import * as exampleData from '../sample.resume.json';
|
import * as exampleData from '../sample.resume.json';
|
||||||
import * as jsoncvSchema from '../schema/jsoncv.schema.json';
|
import * as jsoncvSchema from '../schema/jsoncv.schema.json';
|
||||||
|
import { registerTheme } from './theme';
|
||||||
import { createElement } from './utils';
|
import { createElement } from './utils';
|
||||||
|
|
||||||
const propertiesInOrder = ['basics', 'education', 'work', 'skills', 'projects', 'languages', 'interests', 'references', 'awards', 'publications', 'volunteer']
|
const propertiesInOrder = ['basics', 'education', 'work', 'skills', 'projects', 'languages', 'interests', 'references', 'awards', 'publications', 'volunteer']
|
||||||
const basicsPropertiesInOrder = ['name', 'label', 'email', 'phone', 'url', 'summary', 'image', 'location', 'profiles']
|
const basicsPropertiesInOrder = ['name', 'label', 'email', 'phone', 'url', 'summary', 'image', 'location', 'profiles']
|
||||||
|
|
||||||
// toc elements
|
// toc elements
|
||||||
const elToc = document.querySelector('#editor-toc')
|
const elToc = document.querySelector('.editor-toc')
|
||||||
const tocUl = createElement('ul', {
|
const tocUl = createElement('ul', {
|
||||||
parent: elToc
|
parent: elToc
|
||||||
})
|
})
|
||||||
|
|
@ -47,10 +50,20 @@ basicsPropertiesInOrder.forEach((name, index) => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// add format to schema
|
||||||
|
const keyFormatMap = {
|
||||||
|
'basics.properties.summary': 'textarea',
|
||||||
|
}
|
||||||
|
for (const [key, format] of Object.entries(keyFormatMap)) {
|
||||||
|
objectPath.get(jsoncvSchema.properties, key).format = format
|
||||||
|
}
|
||||||
|
|
||||||
// initialize editor
|
// initialize editor
|
||||||
const elEditorContainer = document.querySelector('#editor-container')
|
registerTheme(JSONEditor)
|
||||||
|
const elEditorContainer = document.querySelector('.editor-container')
|
||||||
const editor = new JSONEditor(elEditorContainer, {
|
const editor = new JSONEditor(elEditorContainer, {
|
||||||
schema: jsoncvSchema,
|
schema: jsoncvSchema,
|
||||||
|
theme: 'mytheme',
|
||||||
});
|
});
|
||||||
editor.on('ready',() => {
|
editor.on('ready',() => {
|
||||||
editor.setValue(exampleData)
|
editor.setValue(exampleData)
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,24 @@
|
||||||
|
@use 'json-editor';
|
||||||
|
|
||||||
#main {
|
#main {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
padding-right: 16px;
|
||||||
}
|
}
|
||||||
.right {
|
.right {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#editor-container {
|
.editor-container {
|
||||||
[data-schemapath]:target {
|
[data-schemapath]:target {
|
||||||
animation: bgFade 2s forwards;
|
animation: bgFade 2s forwards;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#editor-toc {
|
.editor-toc {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { AbstractTheme } from '@json-editor/json-editor/src/theme.js';
|
||||||
|
|
||||||
|
export class MyTheme extends AbstractTheme {
|
||||||
|
getFormInputLabel (text, req) {
|
||||||
|
const el = super.getFormInputLabel(text, req)
|
||||||
|
el.classList.add('je-form-input-label')
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormInputDescription (text) {
|
||||||
|
const el = super.getFormInputDescription(text)
|
||||||
|
el.classList.add('je-form-input-description')
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
getIndentedPanel () {
|
||||||
|
const el = super.getIndentedPanel()
|
||||||
|
el.classList.add('je-indented-panel')
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
getTopIndentedPanel () {
|
||||||
|
return this.getIndentedPanel()
|
||||||
|
}
|
||||||
|
|
||||||
|
getChildEditorHolder () {
|
||||||
|
const el = super.getChildEditorHolder()
|
||||||
|
el.classList.add('je-child-editor-holder')
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
getHeaderButtonHolder () {
|
||||||
|
const el = this.getButtonHolder()
|
||||||
|
el.classList.add('je-header-button-holder')
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
getTable () {
|
||||||
|
const el = super.getTable()
|
||||||
|
el.classList.add('je-table')
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
addInputError (input, text) {
|
||||||
|
const group = this.closest(input, '.form-control') || input.controlgroup
|
||||||
|
|
||||||
|
if (!input.errmsg) {
|
||||||
|
input.errmsg = document.createElement('div')
|
||||||
|
input.errmsg.setAttribute('class', 'errmsg')
|
||||||
|
input.errmsg.style = input.errmsg.style || {}
|
||||||
|
input.errmsg.style.color = 'red'
|
||||||
|
group.appendChild(input.errmsg)
|
||||||
|
} else {
|
||||||
|
input.errmsg.style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
input.errmsg.innerHTML = ''
|
||||||
|
input.errmsg.appendChild(document.createTextNode(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
removeInputError (input) {
|
||||||
|
if (input.style) {
|
||||||
|
input.style.borderColor = ''
|
||||||
|
}
|
||||||
|
if (input.errmsg) input.errmsg.style.display = 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerTheme(JSONEditor) {
|
||||||
|
JSONEditor.defaults.themes['mytheme'] = MyTheme
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue