11import type { View } from '@ember/-internals/glimmer/lib/renderer' ;
2- import { get , nativeDescDecorator , PROPERTY_DID_CHANGE } from '@ember/-internals/metal' ;
2+ import {
3+ descriptorForProperty ,
4+ get ,
5+ nativeDescDecorator ,
6+ PROPERTY_DID_CHANGE ,
7+ } from '@ember/-internals/metal' ;
38import type { PropertyDidChange } from '@ember/-internals/metal/lib/property_events' ;
49import { getOwner } from '@ember/-internals/owner' ;
510import { TargetActionSupport } from '@ember/-internals/runtime' ;
611import {
712 ActionSupport ,
813 addChildView ,
9- ClassNamesSupport ,
1014 CoreView ,
1115 EventDispatcher ,
1216 getChildViews ,
@@ -34,6 +38,8 @@ import {
3438// Keep track of which component classes have already been processed for lazy event setup.
3539let lazyEventsProcessed = new WeakMap < EventDispatcher , WeakSet < object > > ( ) ;
3640
41+ const EMPTY_ARRAY = Object . freeze ( [ ] ) ;
42+
3743/**
3844@module @ember /component
3945*/
@@ -767,7 +773,6 @@ declare const SIGNATURE: unique symbol;
767773 @class Component
768774 @extends Ember.CoreView
769775 @uses Ember.TargetActionSupport
770- @uses Ember.ClassNamesSupport
771776 @uses Ember.ActionSupport
772777 @uses Ember.ViewMixin
773778 @uses Ember.ViewStateSupport
@@ -778,7 +783,6 @@ declare const SIGNATURE: unique symbol;
778783interface Component < S = unknown >
779784 extends CoreView ,
780785 ViewStateSupport ,
781- ClassNamesSupport ,
782786 TargetActionSupport ,
783787 ActionSupport ,
784788 ViewMixin ,
@@ -787,7 +791,6 @@ interface Component<S = unknown>
787791class Component < S = unknown >
788792 extends CoreView . extend (
789793 ViewStateSupport ,
790- ClassNamesSupport ,
791794 TargetActionSupport ,
792795 ActionSupport ,
793796 ViewMixin ,
@@ -800,7 +803,12 @@ class Component<S = unknown>
800803 didUpdateAttrs ( ) { } ,
801804 willRender ( ) { } ,
802805 willUpdate ( ) { } ,
803- } as ComponentMethods
806+ } as ComponentMethods ,
807+ {
808+ concatenatedProperties : [ 'classNames' , 'classNameBindings' ] ,
809+ classNames : EMPTY_ARRAY ,
810+ classNameBindings : EMPTY_ARRAY ,
811+ }
804812 )
805813 implements PropertyDidChange
806814{
@@ -816,6 +824,77 @@ class Component<S = unknown>
816824 declare [ IS_DISPATCHING_ATTRS ] : boolean ;
817825 declare [ DIRTY_TAG ] : DirtyableTag ;
818826
827+ /**
828+ Standard CSS class names to apply to the view's outer element. This
829+ property automatically inherits any class names defined by the view's
830+ superclasses as well.
831+
832+ @property classNames
833+ @type Array
834+ @default ['ember-view']
835+ @public
836+ */
837+ declare classNames : string [ ] ;
838+
839+ /**
840+ A list of properties of the view to apply as class names. If the property
841+ is a string value, the value of that string will be applied as a class
842+ name.
843+
844+ ```javascript
845+ // Applies the 'high' class to the view element
846+ import Component from '@ember/component';
847+ Component.extend({
848+ classNameBindings: ['priority'],
849+ priority: 'high'
850+ });
851+ ```
852+
853+ If the value of the property is a Boolean, the name of that property is
854+ added as a dasherized class name.
855+
856+ ```javascript
857+ // Applies the 'is-urgent' class to the view element
858+ import Component from '@ember/component';
859+ Component.extend({
860+ classNameBindings: ['isUrgent'],
861+ isUrgent: true
862+ });
863+ ```
864+
865+ If you would prefer to use a custom value instead of the dasherized
866+ property name, you can pass a binding like this:
867+
868+ ```javascript
869+ // Applies the 'urgent' class to the view element
870+ import Component from '@ember/component';
871+ Component.extend({
872+ classNameBindings: ['isUrgent:urgent'],
873+ isUrgent: true
874+ });
875+ ```
876+
877+ If you would like to specify a class that should only be added when the
878+ property is false, you can declare a binding like this:
879+
880+ ```javascript
881+ // Applies the 'disabled' class to the view element
882+ import Component from '@ember/component';
883+ Component.extend({
884+ classNameBindings: ['isEnabled::disabled'],
885+ isEnabled: false
886+ });
887+ ```
888+
889+ This list of properties is inherited from the component's superclasses as well.
890+
891+ @property classNameBindings
892+ @type Array
893+ @default []
894+ @public
895+ */
896+ declare classNameBindings : string [ ] ;
897+
819898 init ( properties ?: object | undefined ) {
820899 super . init ( properties ) ;
821900
@@ -869,6 +948,16 @@ class Component<S = unknown>
869948 ! eventNames . length
870949 ) ;
871950 }
951+
952+ assert (
953+ `Only arrays are allowed for 'classNameBindings'` ,
954+ descriptorForProperty ( this , 'classNameBindings' ) === undefined &&
955+ Array . isArray ( this . classNameBindings )
956+ ) ;
957+ assert (
958+ `Only arrays of static class strings are allowed for 'classNames'. For dynamic classes, use 'classNameBindings'.` ,
959+ descriptorForProperty ( this , 'classNames' ) === undefined && Array . isArray ( this . classNames )
960+ ) ;
872961 }
873962
874963 __dispatcher ?: EventDispatcher | null ;
0 commit comments