import { Attr , Attribute as AttributeUNS , AttributeNS , attrValues , } from "@opticss/element-analysis" ; import { assertNever , assertNeverCalled } from "@opticss/util" ; import { ATTR_PRESENT , CLASS_NAME_IDENT } from "../BlockSyntax" ; import { OutputMode , ResolvedConfiguration } from "../configuration" ; import { Attribute } from "./Attribute" ; import { Block } from "./Block" ; import { BlockClass } from "./BlockClass" ; import { RulesetContainer } from "./RulesetContainer" ; import { Style } from "./Style" ; const isIdent = ( ident ? ) : boolean => ! ident || CLASS_NAME_IDENT . test ( ident ) ; /**
 * AttrValue represents the value of an Attribute in a particular Block.
 * An Attribute can have many AttrValue children that are considered to
 * be mutually exclusive. Attributes can be designated as "global";
 */ export class AttrValue extends Style < AttrValue , Block , Attribute , never > { isGlobal = false ; private _sourceAttributes : Attr [ ] | undefined ; public readonly rulesets : RulesetContainer < AttrValue > ; param name param parent constructor ( name , parent ) { super ( name , parent ) ; this . rulesets = new RulesetContainer ( this ) ; } protected get ChildConstructor ( ) : never { return assertNeverCalled ( ) ; } newChild ( ) { return assertNeverCalled ( ) ; } returns get value ( ) : string { return this . uid ; } returns get isPresenceRule ( ) : boolean { return this . value === ATTR_PRESENT ; } returns get attribute ( ) : Attribute { return this . parent ; } returns get blockClass ( ) : BlockClass { return this . parent . blockClass ; } asSourceAttributes ( ) { if ( ! this . _sourceAttributes ) { let blockClass = this . blockClass ; let rootIsOptional = true ; this . _sourceAttributes = blockClass . asSourceAttributes ( rootIsOptional ) ; let value = this . isPresenceRule ? attrValues . absent ( ) : attrValues . constant ( this . value ) ; if ( this . parent . namespace ) { this . _sourceAttributes . push ( new AttributeNS ( this . parent . namespace , this . parent . name , value ) ) ; } else { this . _sourceAttributes . push ( new AttributeUNS ( this . parent . name , value ) ) ; } } return this . _sourceAttributes . slice ( ) ; } returns name ( ) { let namespace = this . attribute . namespace ? `${ this . attribute . namespace }|` : "" ; let value = ( this . value && this . value !== ATTR_PRESENT ) ? isIdent ( this . value ) ? `=${ this . value }` : `="${ this . value }"` : "" ; return `[${ namespace }${ this . parent . name }${ value }]` ; } param scope returns asSource ( scope ? ) { return this . attribute . blockClass . asSource ( scope ) + this . name ( ) ; } public cssClass ( config , reservedClassNames ) { if ( this . presetCssClass ) { return this . presetCssClass ; } switch ( config . outputMode ) { case OutputMode . BEM : return `${ this . parent . cssClass ( config , reservedClassNames ) }${ this . isPresenceRule ? "" : `-${ this . value }` }` ; case OutputMode . BEM_UNIQUE : return `${ this . parent . cssClass ( config , reservedClassNames ) }${ this . isPresenceRule ? "" : `-${ this . value }` }` ; default : return assertNever ( config . outputMode ) ; } } returns all ( ) { return [ this ] ; } } export function isAttrValue ( o ) { return o instanceof AttrValue ; }