josdejong / svelte-jsoneditor

A web-based tool to view, edit, format, repair, query, transform, and validate JSON
https://jsoneditoronline.org
Other
897 stars 108 forks source link

How to customize the render to truncate string values #182

Closed lionelhorn closed 1 year ago

lionelhorn commented 1 year ago

Hello Jos.

I was wondering if it was possible to customize the node render depending of the node content. To be able to truncate (only show part of) a string for instance. With a clickable ... that would show the full content of the string.

https://codesandbox.io/s/svelte-jsoneditor-react-forked-fojk0z?file=/src/SvelteJSONEditor.js

I've seen https://github.com/josdejong/svelte-jsoneditor/issues/147 What I'm trying to do seems a bit different as it's IMO not really a node collapse but a partial view.

josdejong commented 1 year ago

Yes, you can implement a custom component to render a value truncated using onRenderValue. If this is a common request, we can think through if we want to built this in the editor itself. It is an interesting idea.

This is similar to the custom "password" example component in the following Svelte example (you render something different than the original text, in this case stars *****, and in this case, when double clicking, you can edit the password and see the real text):

https://github.com/josdejong/svelte-jsoneditor/blob/main/src/routes/examples/custom_value_renderer/%2Bpage.svelte

afbeelding

In Svelte it is quite straightforward: you can implement your own custom component to render a value and plug that into the editor using onRenderValue.

In React I'm not sure what the handiest way is. One way is to create create a little Svelte project in the side line which contains your custom value renderer, built that, and use the generated code in your React project (just like using vanillla-jsoneditor in React). It may also be possible to "mimic" a Svelte component straight from React, Svelte components have a very clearly defined interface. I have no clue though if that is possible, that would be interesting to figure out.

josdejong commented 1 year ago

Closing this due to lack of response, I assume this answers the question. If not please reopen the issue.

hybridwebdev commented 12 months ago

I am using vue 3 and looking to do something like this as well. My goal is to render a select field. Can you provide any suggestions on how I'd use onRenderValue to achieve this? It's really hard to find any concrete documentation on this.

josdejong commented 11 months ago

It's a good question. In Svelte it is straightforward: you can create a Svelte component and use that.

I haven't tried myself yet to do custom rendering with the vanilla library in say Vue or React or so. I suppose it may work if you implement some object with the API that Svelte expects, but this is not documented anywhere so a bit experimental.

Alternatively you could maybe create a mini svelte project that generates the component that you need, build that, and then use it in the editor.

Anyone able to do some experimentation with this? Help would be welcome.

hybridwebdev commented 11 months ago

Alternatively you could maybe create a mini svelte project that generates the component that you need, build that, and then use it in the editor.

I think it's quite unreasonable for developers to have to create a svelte package outside of the framework they are using the json editor in, just to extend it. I don't think I need to point out how many different ways that solution isn't practical, nor scalable.

I haven't done a full deep dive into the core code, but from what I've seen the editor resolves nodes against a svelte component when rendering the value. I think the best solution, would be to create an optional callback function. The function would take the nodes arguments, and be expected to return an instance of HTMLElement.

Regardless of the implementation details, this is a very important feature this package currently lacks. I've seen lots of discussion about it, so clearly it's a popular request.

josdejong commented 11 months ago

Agree. I simply haven't had the time to look into this. I'm not sure if it already works or needs work. We can probably use Svelte Actions here.

Are you interested in implementing this?

hybridwebdev commented 11 months ago

Are you interested in implementing this?

Unfortunately while I've played with Svelte a bit, my skills lie in VUE, not Svelte.

I did look at the documentation you linked, and I'm not sure how exactly it'd apply to this scenario. What I am suggesting, is implementing some kind of "flag" that could be passed, that indicates that in the editor, instead of returning a Svelte component for rendering the node, it'd simply call the provided function that is expected to return an HTML element. Kind of like how you have renderJSONSchemaEnum and renderValue that can be used in the onRenderValue callback.

Given you can use either of the 2 above functions, I imagine the logic for this is at least somewhat implemented already. It's just a matter of figuring out how to extend the existing logic.

josdejong commented 11 months ago

Yes, maybe we can use a flag. It may also be possible to automatically distinguish whether onRenderValue returns a Svelte component or some "vanilla" HTML element. First step I think is looking into Svelte Actions to see if that can result in a good solution.

akpinar commented 4 months ago

Hi, Is it possible to render a dom element using onRenderValue? if so, is there an example for this? Unfortunately, I did not get the result I wanted when I returned a direct dom element.

or

How can I change the background color of the value using condition without doing this?

@josdejong

josdejong commented 4 months ago

Is it possible to render a dom element using onRenderValue

Yes, you can define a SvelteActionRenderer as described in the docs. It would be nice to include an example of that, I'll see if I can create one.

How can I change the background color of the value using condition without doing this?

You can use onClassName to dynamically give certain values a custom class name. Then, you can define a custom background color for that class name in CSS.

josdejong commented 4 months ago

I've added an example examples/browser/custom_value_renderer.html demonstrating how to use it with the standalone version of the editor.