import { CSSResultArray , html , PropertyValues , SpectrumElement , TemplateResult , } from '@spectrum-web-components/base' ; import { property , query , } from '@spectrum-web-components/base/src/decorators.js' ; import { ifDefined } from '@spectrum-web-components/base/src/directives.js' ; import '@spectrum-web-components/divider/sp-divider.js' ; import '@spectrum-web-components/action-button/sp-action-button.js' ; import '@spectrum-web-components/button-group/sp-button-group.js' ; import crossStyles from '@spectrum-web-components/icon/src/spectrum-icon-cross.css.js' ; import '@spectrum-web-components/icons-ui/icons/sp-icon-cross500.js' ; import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js' ; import { FocusVisiblePolyfillMixin , ObserveSlotPresence , } from '@spectrum-web-components/shared' ; import { firstFocusableIn } from '@spectrum-web-components/shared/src/first-focusable-in.js' ; import styles from './dialog.css.js' ; element slot slot slot slot slot fires export class Dialog extends FocusVisiblePolyfillMixin ( ObserveSlotPresence ( SpectrumElement , [ '[slot="hero"]' , '[slot="footer"]' , '[slot="button"]' , ] ) ) { public static get styles ( ) : CSSResultArray { return [ styles , crossStyles ] ; } @ query ( '.content' ) private contentElement ! : HTMLDivElement ; @ property ( { type : Boolean , reflect : true } ) public error = false ; @ property ( { type : Boolean , reflect : true } ) public dismissable = false ; protected get hasFooter ( ) : boolean { return this . getSlotContentPresence ( '[slot="footer"]' ) ; } protected get hasButtons ( ) : boolean { return this . getSlotContentPresence ( '[slot="button"]' ) ; } protected get hasHero ( ) : boolean { return this . getSlotContentPresence ( '[slot="hero"]' ) ; } @ property ( { type : Boolean , reflect : true , attribute : 'no-divider' } ) public noDivider = false ; @ property ( { type : String , reflect : true } ) public mode ? : 'fullscreen' | 'fullscreenTakeover' ; @ property ( { type : String , reflect : true } ) public size ? : 's' | 'm' | 'l' ; public focus ( ) { if ( this . shadowRoot ) { const firstFocusable = firstFocusableIn ( this . shadowRoot ) ; if ( firstFocusable ) { if ( firstFocusable . updateComplete ) { firstFocusable . updateComplete . then ( ( ) => firstFocusable . focus ( ) ) ; } else { firstFocusable . focus ( ) ; } this . removeAttribute ( 'tabindex' ) ; } } else { super . focus ( ) ; } } public close ( ) { this . dispatchEvent ( new Event ( 'close' , { bubbles : true , } ) ) ; } protected render ( ) { return html `
            <div class="grid">
                <slot name="hero"></slot>
                <slot
                    name="heading"
                    class=${ ifDefined ( this . hasHero ? this . hasHero : undefined ) }
                ></slot>
                ${ this . error ? html `
                          <sp-icon-alert class="type-icon"></sp-icon-alert>
                      ` : html `` }
                ${ this . noDivider ? html `` : html `
                          <sp-divider size="m" class="divider"></sp-divider>
                      ` }
                <div class="content">
                    <slot @slotchange=${ this . onContentSlotChange }></slot>
                </div>
                ${ this . hasFooter ? html `
                          <div class="footer">
                              <slot name="footer"></slot>
                          </div>
                      ` : html `` }
                ${ this . hasButtons ? html `
                          <sp-button-group
                              class="button-group ${ this . hasFooter ? '' : 'button-group--noFooter' }"
                          >
                              <slot name="button"></slot>
                          </sp-button-group>
                      ` : html `` }
                ${ this . dismissable ? html `
                          <sp-action-button
                              class="close-button"
                              label="Close"
                              quiet
                              size="m"
                              @click=${ this . close }
                          >
                              <sp-icon-cross500
                                  class="spectrum-UIIcon-Cross500"
                                  slot="icon"
                              ></sp-icon-cross500>
                          </sp-action-button>
                      ` : html `` }
            </div>
        ` ; } public shouldManageTabOrderForScrolling = ( ) : void => { const { offsetHeight , scrollHeight } = this . contentElement ; if ( offsetHeight < scrollHeight ) { this . contentElement . tabIndex = 0 ; } else { this . contentElement . removeAttribute ( 'tabindex' ) ; } } ; protected shouldUpdate ( changes ) { if ( changes . has ( 'mode' ) && ! ! this . mode ) { this . dismissable = false ; } if ( changes . has ( 'dismissable' ) && this . dismissable ) { this . dismissable = ! this . mode ; } return super . shouldUpdate ( changes ) ; } protected onContentSlotChange ( ) { this . shouldManageTabOrderForScrolling ( ) ; } public connectedCallback ( ) { super . connectedCallback ( ) ; window . addEventListener ( 'resize' , this . shouldManageTabOrderForScrolling ) ; } public disconnectedCallback ( ) { window . removeEventListener ( 'resize' , this . shouldManageTabOrderForScrolling ) ; super . disconnectedCallback ( ) ; } }