ux icon indicating copy to clipboard operation
ux copied to clipboard

[LiveComponents] Hello Component JS Object

Open weaverryan opened this issue 3 years ago • 0 comments

Q A
Bug fix? no
New feature? yes
Tickets Fix None
License MIT

Hi!

This is effectively a rewrite of the LiveComponents frontend (with minimal effect on users). It introduces:

A) A Component object that "mirrors" your PHP component object and lives in a __component property of your element - this allows you to do cool things like:

const component = document.getElementById('component-id').__component

// set the firstName property and re-render
// effectively set the firstName property on your PHP object
component.firstName = 'Ryan';

// trigger the "save" LiveAction
component.save();

B) Logic is much more organized between live_controller.ts (mostly event listening & initialization), Component.ts (model+action & Ajax handling) and a number of "plugins" that add loading, polling, etc).

C) Child handling (which still has some TODOs) is more intelligent: child components will NOT re-render when their parent component re-renders, unless the data passed into the child has changed. It does this by generating a "fingerprint" (checksum) of the values that are passed into a child component when {{ component() }} is called. Then, when a parent re-renders, the "fingerprints" if its children are sent with the request. If any of those fingerprints are seen to have changed during the re-render, then we know the "input" to a child has changed and the child should be re-rendered (which is done basically by sending a signal to the child component to re-render itself with a new set of props).

TODOs:

  • [x] 1) Update CHANGELOG
  • [ ] 2) add some sort of v-model (previously called data-model-map) ability: where a child can communicate a model change to its parent
  • [X] 3) BACKEND: pass data (writable props) & props separately as live controller values
  • [x] 4) BACKEND: pass the a deterministic data-live-id attribute to the child unless manually specified
  • [x] 5) BACKEND: pass a "fingerprint" value to Stimulus (fingerprint is a checksum of the values passed IN when creating a component)
  • [x] 6) BACKEND: read childrenFingerprints data for GET (JSON-encoded query param) and POST (request body). Use this to compare to the NEW fingerprint value for each child. If not changed, render the child as an empty element (with only data-live-id). If changed, render an empty element, but with data-live-id, the new fingerprint data- value and the new data-live-props-value.
  • [ ] 7) DOCS: Add at least one new example to ux.symfony.com
  • [ ] 8) DOCS: add example with data-live-id manually being set on a child so it re-renders under some situation
  • [ ] 9) Find better example for the custom Stimulus controller that goes around the component in the docs
  • [ ] 10) (Maybe later) a way for a child component to trigger a re-render on the parent (without a model in the parent needing to change)

Cheers!

weaverryan avatar Oct 10 '22 01:10 weaverryan