-
Couldn't load subscription status.
- Fork 71
Wrapper libraries: ReactWrapperComponent
An abstract class which provides a lot of help in regards to authoring wrapper libraries' components.
The full API documentation is in the code (wrapper-component.ts), but essentially, all wrapper components should extend it. Here are some of the more important stuff it handles for you as a wrapper component author:
- Pass down all attributes to the underlying React components
- Note that this does not cover
Inputs, since those are not plain strings and cannot be attached to the DOM [as-is]
- Note that this does not cover
- Allow automatically setting the
displayof the wrapper component, based on the root node of the wrapper React element (e.g. if you render an<Expander>which then renders a<div>, thedisplayof your wrapper component would be set toblockat runtime) - seeWrapperComponentOptions - Allow passing in arbitrary events that React can handle automatically
- [Much] Easier creation and handling of render props - see
createRenderPropHandlerandcreateInputJsxRenderer- Automatic change detection for render props containing templates (by passing in an
NgZoneinWrapperComponentOptions)
- Automatic change detection for render props containing templates (by passing in an
Render props as a concept does not translate directly to Angular. The closest concept to it is an <ng-template> (the main difference between the two being that the later also has change detection via the implicit context its defined and use in - i.e. the template closure or component).
To still allow Angular apps to use the concepts they know inside React components, we created the InputRendererOptions type:
export type InputRendererOptions<TContext extends object> =
| TemplateRef<TContext>
| ((context: TContext) => HTMLElement)
| ComponentRef<TContext>
| RenderComponentOptions<TContext>;
export interface RenderComponentOptions<TContext extends object> {
readonly componentType: Type<TContext>;
readonly factoryResolver: ComponentFactoryResolver;
readonly injector: Injector;
}This allows passing any number of types as what will be then translated over to render props.
For more info on how these are then used see the inline code documentation, as well as the "Helper components" pages (ReactContent, ReactTemplate, Disguise).
When extend-ing from this component, there are a few restrictions being added, to make the lives of everyone easier and enforcing the message that these are just wrapper components, and shouldn't have their own styling, take their own space in the DOM etc.
- Passing in the
classattribute is forbidden. UsecontentClassinstead, which leveragesclassnamesto allow both the familiarclasssyntax as well as one that's more likeNgClass' one. - Passing in the
styleattribute is forbidden. UsecontentStyleinstead, which allows using both the familiarstylestring-based syntax, as well as one that's more likeNgStyle(leveragingstylenames).
As mentioned above, wrapper components should not have styling of their own. Ideally, they'd all be set with display: contents on themselves, removing them from the document flow. However, browser support for this is partial, and to not break Edge and IE we don't use it at the moment. See #102 for more info and follow up on that.