-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
added an ability to set custom css classes for Node's field and value #604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Custom classes allow styling each node in a different way |
|
Thanks for your PR @maestr0 . The upgrade to gulp 4 is great, thanks for that. I can accept that PR right away though I prefer an exact type As for the custom css classes: I really like your idea to allow for custom classes, that will be quite powerful in allowing custom styling and matching. I would love to discuss a different approach for this though. So far the public API of JSONEditor doesn't contain the internal nodes or their methods. Instead of exposing a method on the internal nodes, we could take a similar approach as the const options = {
onClassName = function (node) {
const field = node.field
const value = node.value
const path = node.path // array with strings and numbers
if (last(path) === 'customer') {
return 'my-customer-class'
}
return undefined
}
}
const editor = new JSONEditor(container, options, json)What do you think? |
|
Ok, I will PR the gulp changes separately and implement the css class changes in the way you suggested. |
|
Awesome! Looking forward to it. |
|
@josdejong I came across this PR and was thinking that maybe it will be better to go for a more general purpose solution that will allow adding additional attributes and hooks to the node dom element, something like: const options = {
onDomField = function (node, domField) {
const field = node.field
const value = node.value
const path = node.path // array with strings and numbers
if (last(path) === 'customer' && domField) {
domField.classList.add('my-customer-class');
}
}
}
const editor = new JSONEditor(container, options, json)WDYT? |
|
I like this idea but I'm not that familiar with the code so I leave it to @josdejong |
|
It's an interesting and very powerful idea @meirotstein, thanks. The downside is that we're fully opening up the internal DOM, which requires knowledge on the users side about it and a lot of documentation on the side of the editor. Whilst I would love to have such a powerful API, I think the current implementation is not suitable for such hooks (The react based v6 is built with support for such hooks in mind, though it's far from ready). So, in short, for how I prefer a simple to understand |
|
@maestr0 what do you think? |
|
@josdejong I agree that exposing the internal DOM is not the best idea in this case. It can lead to many issues. I will implement |
|
@josdejong this is essentially the implementation you suggested. I added an example of how to implement a JSON diff view using this new feature. |
|
Thanks @maestr0! The code looks good and straight forward at first sight, I will check it out and run it locally within a couple of days I expect. |
|
@maestr0 I've tested your PR, I really like your diffing example, that's really cool :) I have some feedback points:
|
|
1,3 and 4 done. Working on 2 |
|
2 sort of works now but it's not completed yet. The problem is that currently there's no way to remove a class when a node has changed. I can only add a new class which is not what we want. I have to find a way to toggle classes or maybe return two values, classes to be added and classes to be removed. |
|
@josdejong how about something like this Node.prototype._updateCssClassName = function () {
// set custom css classes
if(this.dom.field
&& this.editor
&& this.editor.options
&& typeof this.editor.options.onClassName ==='function'
&& this.dom.tree){
const { removeClasses, addClasses } = this.editor.options.onClassName({ path: this.getPath(), field: this.field, value: this.value });
util.addClassName(this.dom.tree, addClasses);
util.removeClassName(this.dom.tree, removeClasses)
}
} |
|
Cool @maestr0, looks good! Good point about being able to remove a class name again. I'm not really fond of having to specify classes to add and to remove (imperative approach). Would it be possible to simply completely replace the class names with the newly returned result from |
|
The problem with replacing all existing classes with ones returned from We could always add |
Yes indeed, I think we should do that. |
|
ping @maestr0 |
|
@josdejong updated the PR util.removeAllClassNames(this.dom.tree);
const addClasses = this.editor.options.onClassName({ path: this.getPath(), field: this.field, value: this.value }) || "";
util.addClassName(this.dom.tree, "jsoneditor-values " + addClasses); |
|
@maestr0 I've done some testing, it works like a charm now 👍 I was wondering about one thing: the example suggests that both editors dynamically highlight the changes between the two JSON documents. When I rename for example "number" in the left editor, it highlights it in the left editor but not in the right editor because that editor doesn't get any trigger. It may be tricky to get that working though. Do you have any ideas? And one small practical thing: You've committed a new file |
|
@josdejong removed yarn.lock and updated the example. I didn't know there was a |
Ah, good find 😎 I hadn't thought of that. The method |
|
The feature |
No description provided.