Skip to content

Instantly share code, notes, and snippets.

@sb8244
Last active April 13, 2022 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sb8244/d1d2e05a6ef852c2ef5819b358e0a67e to your computer and use it in GitHub Desktop.
Save sb8244/d1d2e05a6ef852c2ef5819b358e0a67e to your computer and use it in GitHub Desktop.
export const SpaceLayoutEditor = {
// Not important for the integration, just something for my specific use case
recentItems: [],
mounted() {
// IMPORTANT LINE: LiveView -> React data flow
this.handleEvent("react.update_items", ({ items }: { items: string }) => {
const newItems: SpaceItem[] = JSON.parse(items)
this.mountEditor(newItems)
})
},
editorOpts(): EditorOpts {
// Create a clean interface for your React application
return {
getItems: () => this.recentItems,
onLayoutChange: this.onLayoutChange.bind(this),
startEdit: this.startEdit.bind(this),
toggleItemPanel: this.toggleItemPanel.bind(this)
}
},
destroyed() {
if (!this.unmountComponent) {
console.error('SpaceLayoutEditor unmountComponent not set')
return
}
this.unmountComponent(this.el)
},
startEdit(item: SpaceItem) {
// IMPORTANT LINE: React -> LiveView data flow
this.pushEventTo(this.el, 'ui.start_edit', { item })
},
toggleItemPanel(item: SpaceItem) {
this.pushEventTo(this.el, 'actions.toggle_item_panel', { item })
},
onLayoutChange(items: SpaceItem[]) {
this.recentItems = items
this.pushEventTo(this.el, 'actions.new_layout', { items })
window.dispatchEvent(new Event('resize'))
},
mountEditor(items: SpaceItem[]) {
this.recentItems = items
// @ts-ignore This is a webpack import, not a ES2020
import(/* webpackChunkName: "space-layout-editor-lv" */ '../entry/space-layout-editor-lv').then((mounter) => {
this.unmountComponent = mounter.default(this.el.id, {
editorOpts: this.editorOpts()
})
}).catch(console.error)
}
}
# Example of how to push down to the React component
defp push_render_items(socket = %{assigns: %{enriched_items: items}}) do
push_event(socket, "react.update_items", %{items: Jason.encode!(items)})
end
# Example of how to receive data from the React component
def handle_event("ui.start_edit", %{"id" => id}, socket = %{assigns: %{items: items}}) do
item = Enum.find(items, &(&1.id == id))
socket = assign(socket, edit_item: item)
send_update(CloveWeb.Components.Modal, id: "space-edit-modal", state: :open)
{:noreply, socket}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment