vue-json-pretty icon indicating copy to clipboard operation
vue-json-pretty copied to clipboard

Add carets next to brackets for expanding/collapsing

Open vincerubinetti opened this issue 2 years ago • 3 comments

Currently, you have to click directly on the brackets to expand/collapse. As far as I know, this UI behavior does not exist in any other product/program for a tree display like this. The Chrome dev tools shows nested objects with little ▸ symbols, for example. I don't think users will know to click on the brackets, and their mouse hitboxes are small enough that they may never hover over them by accident.

Adding ▸ and ▾ carets would be a good idea, and or making the hitbox for expanding/collapsing the whole row instead of just the bracket <span>.

vincerubinetti avatar May 31 '22 21:05 vincerubinetti

For now, I've done this dirty hack (Vue 3, composition api):

<template>
  <VueJsonPretty
    ref="vjp"
    :data="data"
  />
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import VueJsonPretty from "vue-json-pretty";
import "vue-json-pretty/lib/styles.css";
import { useMutationObserver } from "@vueuse/core";

const vjp = ref(null);

const updateBrackets = () => {
  for (const element of document.querySelectorAll(".vjs-tree__brackets")) {
    const bracket = element as HTMLElement;
    const text = bracket.innerText.trim();
    const starts = text.startsWith("{") || text.startsWith("[");
    const ends = text.endsWith("}") || text.endsWith("]");
    bracket.dataset.debug = [text, starts, ends].join(" ");
    if (starts && ends) bracket.dataset.action = "expand";
    else if (starts) bracket.dataset.action = "collapse";
    else bracket.dataset.action = "";
  }
};

watch(vjp, updateBrackets);

useMutationObserver(vjp, updateBrackets, { subtree: true, childList: true });
</script>

<style lang="scss">
.vjs-tree__brackets[data-action="collapse"]:before {
  content: "▾ ";
}
.vjs-tree__brackets[data-action="expand"]:before {
  content: "▸ ";
}
</style>

If a fix doesn't get implemented, hopefully this will help someone. It just listens for any change to the component (with mutation observer, very inefficient in this case), and tags each bracket with whether it should have an "expand" or a "collapse" arrow, then adds the arrow with CSS.

vincerubinetti avatar May 31 '22 21:05 vincerubinetti

@vincerubinetti Great idea, is it possible to turn your code into a configurable prop and contribute a PR to the project?

leezng avatar Jun 09 '22 07:06 leezng

The part about adding the carets via a CSS pseudo element I think is a good idea, but the rest of the code is a hack. Shouldn't need to use a mutation observer when there's actual Vue lifecycle hooks to listen to.

So the above code can't be (shouldn't be) copied and pasted into a PR, no. I can try to look at the code to do a real PR, but I have no familiarity with the code and don't have much time.

vincerubinetti avatar Jun 10 '22 16:06 vincerubinetti