Web Components + Virtual DOM: web standards for powerful UIs
Bot releases are hidden (Show)
Published by tdumitrescu over 3 years ago
key
or tag change forces the creation of a new element), update DOMPatcher's internal element reference to point to itinsert
hook since it didn't insert any new element into the DOM, so we run the hook from DOMPatcher directly if it's been set on the root nodePublished by tdumitrescu almost 4 years ago
"Contexts" allow Panel components to inject arbitrary class/object dependencies into all descendants at runtime, similarly to React Context ("Context provides a way to pass data through the component tree without having to pass props down manually at every level"). This is especially useful for data which needs to be shared globally.
Components can provide named "default contexts" for themselves and descendants in their config objects. Components similarly declare which contexts they need by providing their names in the contexts
config entry. Contexts can be accessed with the getContext()
method, for example for use in view templates:
get config() {
return {
// provided to all descendants, including itself
defaultContexts: {
apiCache: new SharedCache(),
moreSharedData: {foo: `bar`},
},
// used in this component
contexts: [`apiCache`, `moreSharedData`],
// calling a method on a context provided to the current component
template: () => h(`p`, {}, `A value from the API Cache: ${this.getContext('apiCache').someMethod()}`),
};
}
Published by tdumitrescu over 5 years ago
state
is now initialized with the defaultState
config value in the constructor, ensuring that default values are set even before the element is attached to the DOMchild
components made before they enter the component tree are automatically flushed up to the shared state when the child is attached. (This now matches the existing behavior of the appState
partial shared state mechanism.)Published by tdumitrescu almost 6 years ago
Published by tdumitrescu almost 6 years ago
This will restore history.pushState
/history.replaceState
/popstate
behavior when a Component that registered route handlers is removed from the DOM. Particularly useful for test suites which create/remove apps for individual test cases.
Published by tdumitrescu almost 6 years ago
For components that accept HTML attributes, attrsSchema
lets them define names, types, and default values which will be populated automatically in the component's attrs
prop. For example:
class MyWidget extends Component {
static get attrsSchema() {
return {
...super.attrsSchema,
'closeable': `boolean`,
'complex-stuff': `json`,
'title-text': {type: `string`, default: `Hello world`},
};
}
}
// access within component code:
this.attrs.closeable // false
// also accessible within templates via $attrs:
$attrs[`complex-stuff`] // pre-parsed from JSON
This is an optional mechanism that helps standardize attribute-parsing and reduce attributeChangedCallback
boilerplate.
Published by tdumitrescu over 6 years ago
Published by tdumitrescu over 6 years ago
Adds the ProxyComponent
wrapper for switching between different component implementations at runtime, e.g.:
class MyWidget extends ProxyComponent {
getTargetElementTag() {
if (window.location.search.includes('enable_beta') {
return 'my-widget-v2';
} else {
return 'my-widget-v1';
}
}
}
Other optional component utilities such as StateController
and ControlledComponent
have been moved into lib/component-utils
, but are still exported at top level (so can still be imported like import {ProxyComponent, StateController} from 'panel';
). This will however affect consumers which import directly from panel/build/
(which is not a public API and is not recommended).
Published by tdumitrescu over 6 years ago
This obviates the need to override the Component update()
method in order to run code on every state update (for instance for logging state changes). Overriding update()
potentially required explicit overrides for every component in the tree, whereas the hooks work gracefully with cascading updates. Example usage:
get config() {
return {
// ...
hooks: {
postUpdate: () => localStorage.setItem(`latestFoo`, this.state.foo),
},
};
}
Published by tdumitrescu almost 8 years ago