license import { MDCComponent } from '@material/base/component' ; import { CustomEventListener } from '@material/base/types' ; import { MDCSegmentedButtonSegment , MDCSegmentedButtonSegmentFactory } from '../segment/component' ; import { MDCSegmentedButtonEvent , SegmentDetail } from '../types' ; import { MDCSegmentedButtonAdapter } from './adapter' ; import { events , selectors } from './constants' ; import { MDCSegmentedButtonFoundation } from './foundation' ; export class MDCSegmentedButton extends MDCComponent < MDCSegmentedButtonFoundation > { static override attachTo ( root ) { return new MDCSegmentedButton ( root ) ; } get segments ( ) : ReadonlyArray < MDCSegmentedButtonSegment > { return this . segmentsList . slice ( ) ; } private segmentsList ! : MDCSegmentedButtonSegment [ ] ; private segmentFactory ! : ( el : Element ) => MDCSegmentedButtonSegment ; private handleSelected ! : CustomEventListener < MDCSegmentedButtonEvent > ; override initialize ( segmentFactory = ( el ) => new MDCSegmentedButtonSegment ( el ) ) { this . segmentFactory = segmentFactory ; this . segmentsList = this . instantiateSegments ( this . segmentFactory ) ; } param segmentFactory return private instantiateSegments ( segmentFactory ) { const segmentElements = [ ] . slice . call ( this . root . querySelectorAll ( selectors . SEGMENT ) ) ; return segmentElements . map ( ( el ) => segmentFactory ( el ) ) ; } override initialSyncWithDOM ( ) { this . handleSelected = ( event ) => { this . foundation . handleSelected ( event . detail ) ; } ; this . listen ( events . SELECTED , this . handleSelected ) ; const isSingleSelect = this . foundation . isSingleSelect ( ) ; for ( let i = 0 ; i < this . segmentsList . length ; i ++ ) { const segment = this . segmentsList [ i ] ; segment . setIndex ( i ) ; segment . setIsSingleSelect ( isSingleSelect ) ; } const selectedSegments = this . segmentsList . filter ( ( segment ) => segment . isSelected ( ) ) ; if ( isSingleSelect && selectedSegments . length === 0 && this . segmentsList . length > 0 ) { throw new Error ( 'No segment selected in singleSelect mdc-segmented-button' ) ; } else if ( isSingleSelect && selectedSegments . length > 1 ) { throw new Error ( 'Multiple segments selected in singleSelect mdc-segmented-button' ) ; } } override destroy ( ) { for ( const segment of this . segmentsList ) { segment . destroy ( ) ; } this . unlisten ( events . SELECTED , this . handleSelected ) ; super . destroy ( ) ; } override getDefaultFoundation ( ) { const adapter = { hasClass : ( className ) => { return this . root . classList . contains ( className ) ; } , getSegments : ( ) => { return this . mappedSegments ( ) ; } , selectSegment : ( indexOrSegmentId ) => { const segmentDetail = this . mappedSegments ( ) . find ( ( detail ) => detail . index === indexOrSegmentId || detail . segmentId === indexOrSegmentId ) ; if ( segmentDetail ) { this . segmentsList [ segmentDetail . index ] . setSelected ( ) ; } } , unselectSegment : ( indexOrSegmentId ) => { const segmentDetail = this . mappedSegments ( ) . find ( ( detail ) => detail . index === indexOrSegmentId || detail . segmentId === indexOrSegmentId ) ; if ( segmentDetail ) { this . segmentsList [ segmentDetail . index ] . setUnselected ( ) ; } } , notifySelectedChange : ( detail ) => { this . emit < SegmentDetail > ( events . CHANGE , detail , true ) ; } } ; return new MDCSegmentedButtonFoundation ( adapter ) ; } return getSelectedSegments ( ) { return this . foundation . getSelectedSegments ( ) ; } param indexOrSegmentId selectSegment ( indexOrSegmentId ) { this . foundation . selectSegment ( indexOrSegmentId ) ; } param indexOrSegmentId unselectSegment ( indexOrSegmentId ) { this . foundation . unselectSegment ( indexOrSegmentId ) ; } param indexOrSegmentId return isSegmentSelected ( indexOrSegmentId ) { return this . foundation . isSegmentSelected ( indexOrSegmentId ) ; } return private mappedSegments ( ) { return this . segmentsList . map ( ( segment , index ) => { return { index , selected : segment . isSelected ( ) , segmentId : segment . getSegmentId ( ) } ; } ) ; } }