@@ -15,7 +15,10 @@ import {
1515 TemplateRef ,
1616 Type ,
1717} from '@angular/core' ;
18+ import classnames from 'classnames' ;
1819import toStyle from 'css-to-style' ;
20+ import stylenames , { StyleObject } from 'stylenames' ;
21+ import { Many } from '../declarations/many' ;
1922import { ReactContentProps } from '../renderer/react-content' ;
2023import { isReactNode } from '../renderer/react-node' ;
2124import { isReactRendererData } from '../renderer/renderer' ;
@@ -42,52 +45,57 @@ export type InputRendererOptions<TContext extends object> =
4245
4346export type JsxRenderFunc < TContext > = ( context : TContext ) => JSX . Element ;
4447
48+ export type ContentClassValue = string [ ] | Set < string > | { [ klass : string ] : any } ;
49+ export type ContentStyleValue = string | StyleObject ;
50+
4551/**
4652 * Base class for Angular @Components wrapping React Components.
47- * Simplifies some of the handling around passing down props and setting CSS on the host component.
53+ * Simplifies some of the handling around passing down props and CSS styling on the host component.
4854 */
4955// NOTE: TProps is not used at the moment, but a preparation for a potential future change.
5056export abstract class ReactWrapperComponent < TProps extends { } > implements AfterViewInit , OnChanges {
51- private _contentClass : string ;
52- private _contentStyle : string ;
57+ private _contentClass : Many < ContentClassValue > ;
58+ private _contentStyle : ContentStyleValue ;
5359
5460 protected abstract reactNodeRef : ElementRef < HTMLElement > ;
5561
5662 /**
57- * Alternative to `class` using the same syntax.
63+ * Alternative to `class` and `[ngClass]` using the same syntax.
5864 *
59- * @description Since this is a wrapper component, sticking to the virtual DOM concept, this should have any styling of its own.
60- * Any value passes to `contentClass` will be passed to the root component's class.
65+ * @description Since this is a wrapper component, sticking to the virtual DOM concept, its DOM element shouldn't have any styling of its own.
66+ * Instead, any value passes to `contentClass` will be passed to the root component's class as `className` .
6167 */
6268 @Input ( )
63- set contentClass ( value : string ) {
69+ set contentClass ( value : Many < ContentClassValue > ) {
6470 this . _contentClass = value ;
6571 if ( isReactNode ( this . reactNodeRef . nativeElement ) ) {
66- this . reactNodeRef . nativeElement . setProperty ( 'className' , value ) ;
72+ this . reactNodeRef . nativeElement . setProperty ( 'className' , classnames ( value ) ) ;
6773 this . changeDetectorRef . detectChanges ( ) ;
6874 }
6975 }
7076
71- get contentClass ( ) : string {
77+ get contentClass ( ) : Many < ContentClassValue > {
7278 return this . _contentClass ;
7379 }
7480
7581 /**
76- * Alternative to `style` using the same syntax.
82+ * Alternative to `style` and `[ngStyle]` using (almost) the same syntax.
83+ * All syntax supports by `ngStyle` is supported, with the exception of specifying units in the key (`{ 'width.px': 12 }`).
7784 *
7885 * @description Since this is a wrapper component, sticking to the virtual DOM concept, this should have any styling of its own.
7986 * Any value passes to `contentStyle` will be passed to the root component's style.
8087 */
8188 @Input ( )
82- set contentStyle ( value : string ) {
89+ set contentStyle ( value : ContentStyleValue ) {
8390 this . _contentStyle = value ;
8491 if ( isReactNode ( this . reactNodeRef . nativeElement ) ) {
85- this . reactNodeRef . nativeElement . setProperty ( 'style' , toStyle ( value ) ) ;
92+ const stringValue = typeof value === 'string' ? value : stylenames ( value ) ;
93+ this . reactNodeRef . nativeElement . setProperty ( 'style' , toStyle ( stringValue ) ) ;
8694 this . changeDetectorRef . detectChanges ( ) ;
8795 }
8896 }
8997
90- get contentStyle ( ) : string {
98+ get contentStyle ( ) : ContentStyleValue {
9199 return this . _contentStyle ;
92100 }
93101
0 commit comments