flauwekeul / honeycomb

Create hex grids easily, in node or the browser.
https://abbekeultjes.nl/honeycomb
MIT License
630 stars 57 forks source link

Honeycomb compatibility with VueJs #87

Closed toiim closed 1 year ago

toiim commented 1 year ago

Hello Abbe,

Thanks for putting together such a lovely library. I've enjoyed using your library in vanilla JS but am having issues using it alongside the rest of my app is VueJS. Whenever I use Vue's reactivity on top of honeycomb, I get the type error TypeError: Cannot read from private field. I believe this behaviour is expected because of the private class implemented by honeycomb under the hood.

What I'm not sure about is how I'm able to actually reference the grid created by new Grid in a way that is reactive and will reflect changes in the template. Is there a preferred way of exposing Honeycomb to other JS libraries? Is there something unique going on here or am I missing something obvious. Below is a simple example of what I'm talking about.

<script setup lang="ts">
import { ref, computed } from 'vue'
import { defineHex, Grid, rectangle } from 'honeycomb-grid'

const Tile = defineHex({ dimensions: 30 })
const gridRaw = new Grid(Tile, rectangle({ width: 5, height: 5 }))
const grid = ref(gridRaw)) // doesn't work
const coordinatesRaw = computed(() => { return gridRaw.toJSON().coordinates }
const coordinates = computed(() => { return grid.value.toJSON().coordinates }) // doesn't work
</script>

<template>
  {{gridRaw.toJSON().coordinates}} <!--This works -->
  {{grid.toJSON().coordinates}} <!--This does not -->
  {{ coordinatesRaw }} <!-- This works -->
  {{ coordinates }} <!--This does not -->
</template>

I know this is not an issue with your library specifically but any help would be appreciated.

etodanik commented 1 year ago

@toiim are you using the latest beta?

toiim commented 1 year ago

@israelidanny The dependancy in my package.json is "honeycomb-grid": "4.0.0-beta.8"

flauwekeul commented 1 year ago

Maybe you can use shallowRef?

const Tile = defineHex({ dimensions: 30 })
const grid = new Grid(Tile, rectangle({ width: 5, height: 5 }))
const reactiveGrid = shallowRef(grid))
const coordinates = computed(() => reactiveGrid.value.toJSON().coordinates)

If that doesn't meet your needs I suggest you only make the properties you need reactive. I haven't tested this, but it should work:

const Tile = defineHex({ dimensions: 30 })
const grid = new Grid(Tile, rectangle({ width: 5, height: 5 }))
const coordinates = computed(() => grid.toJSON().coordinates)
flauwekeul commented 1 year ago

Closing this because I assume the issue is fixed.