{"version":3,"sources":["webpack:///../../../src/components/VSlideGroup/VSlideGroup.ts"],"names":["BaseSlideGroup","name","directives","Resize","Touch","props","activeClass","type","default","centerActive","nextIcon","prevIcon","showArrows","Boolean","validator","v","data","internalItemsLength","isOverflowing","resizeTimeout","startX","scrollOffset","widths","content","wrapper","computed","__cachedNext","this","genTransition","__cachedPrev","classes","hasAffixes","isMobile","hasNext","Math","hasPrev","watch","internalValue","beforeUpdate","$children","updated","methods","genNext","slot","$scopedSlots","next","$slots","$createElement","staticClass","class","on","click","key","genContent","ref","genData","value","onResize","genIcon","icon","$vuetify","rtl","location","upperLocation","hasAffix","disabled","genPrev","prev","genWrapper","start","e","move","end","calculateNewOffset","sign","newAbosluteOffset","direction","onAffixClick","onTouchStart","onTouchMove","onTouchEnd","maxScrollOffset","overflowCheck","fn","scrollIntoView","selectedIndex","calculateCenteredOffset","selectedItem","calculateUpdatedOffset","clientWidth","selectedElement","offsetLeft","currentScrollOffset","totalWidth","itemOffset","additionalOffset","offsetCentered","scrollTo","$refs","setWidths","window","render","h","provide","slideGroup"],"mappings":"2TAyCaA,EAAiB,eAAM,OAAN,eAWrB,CACPC,KADO,mBAGPC,WAAY,CACVC,OAAA,OACAC,MAAA,QAGFC,MAAO,CACLC,YAAa,CACXC,KADW,OAEXC,QAAS,wBAEXC,aALK,QAMLC,SAAU,CACRH,KADQ,OAERC,QAAS,SAEXG,SAAU,CACRJ,KADQ,OAERC,QAAS,SAEXI,WAAY,CACVL,KAAM,CAACM,QADG,QAEVC,UAAW,SAAAC,GAAC,MACG,mBAANA,GAAmB,CAAC,SAAD,mCAShCC,KAAM,iBAAO,CACXC,oBADW,EAEXC,eAFW,EAGXC,cAHW,EAIXC,OAJW,EAKXC,aALW,EAMXC,OAAQ,CACNC,QADM,EAENC,QAAS,KAIbC,SAAU,CACRC,aADQ,WAEN,OAAOC,KAAKC,cAAZ,SAEFC,aAJQ,WAKN,OAAOF,KAAKC,cAAZ,SAEFE,QAPQ,WAQN,wCACK,qCADE,OAAP,IAEE,iBAFK,EAGL,6BAA8BH,KAHzB,WAIL,gCAAiCA,KAAKT,iBAG1Ca,WAfQ,WAgBN,OAAQJ,KAAR,YAEE,aAAe,SAGf,cAAgB,OAAQA,KAAR,SAIhB,OAAW,OAAOA,KAAP,cAGX,aAAe,OACbA,KAAKK,UACLL,KAFa,cAQf,QAAS,OACNA,KAAD,UACAA,KAFO,gBAMbM,QA1CQ,WA2CN,IAAKN,KAAL,WAAsB,OAAO,EADxB,MAGwBA,KAHxB,OAGC,EAHD,EAGC,QAAWH,EAHZ,EAGYA,QAGjB,OAAOD,EAAUW,KAAA,IAASP,KAAT,cAAjB,GAEFQ,QAlDQ,WAmDN,OAAOR,KAAKI,YAAZ,IAA0BJ,KAAKN,eAInCe,MAAO,CACLC,cADK,YAKLnB,cALK,YAMLG,aANK,SAMO,GACVM,KAAA,+DAIJW,aAhHO,WAiHLX,KAAA,qBAA4BA,KAAKY,WAAN,IAA3B,QAGFC,QApHO,WAqHDb,KAAKV,uBAAyBU,KAAKY,WAAN,IAAjC,QACAZ,KAAA,aAGFc,QAAS,CAEPC,QAFO,WAEA,WACCC,EAAOhB,KAAKiB,aAAaC,KAC3BlB,KAAKiB,aAAaC,KADT,IAETlB,KAAKmB,OAAOD,MAAQlB,KAFxB,aAIA,OAAOA,KAAKoB,eAAe,MAAO,CAChCC,YADgC,sBAEhCC,MAAO,CACL,iCAAkCtB,KAAKM,SAEzCiB,GAAI,CACFC,MAAO,kBAAM,yBAEfC,IAAK,QACJ,CATH,KAWFC,WAlBO,WAmBL,OAAO1B,KAAKoB,eAAe,MAAO,CAChCC,YADgC,yBAEhCM,IAAK,WACJ3B,KAAKmB,OAHR,UAKFS,QAxBO,WAyBL,MAAO,CACLN,MAAOtB,KADF,QAELzB,WAAY,CAAC,CACXD,KADW,SAEXuD,MAAO7B,KAAK8B,aAIlBC,QAjCO,SAiCA,GACL,IAAIC,EAAJ,EAEIhC,KAAKiC,SAASC,KAAlB,SAAyBC,EACvBH,EAAA,OACShC,KAAKiC,SAASC,KAAlB,SAAyBC,IAC9BH,EAAA,QAGF,IAAMI,EAAgB,GAAH,OAAMD,EAAA,kBAAN,OAAkCA,EAAA,MAArD,IACME,EAAYrC,KAAA,aAAlB,IAEA,OACGA,KAAD,YADF,EAKOA,KAAKoB,eAAe,EAApB,KAA2B,CAChC1C,MAAO,CACL4D,UAAWD,IAEXrC,KAAA,UAJJ,EAII,UANK,MASXuC,QAzDO,WAyDA,WACCvB,EAAOhB,KAAKiB,aAAauB,KAC3BxC,KAAKiB,aAAauB,KADT,IAETxC,KAAKmB,OAAOqB,MAAQxC,KAFxB,aAIA,OAAOA,KAAKoB,eAAe,MAAO,CAChCC,YADgC,sBAEhCC,MAAO,CACL,iCAAkCtB,KAAKQ,SAEzCe,GAAI,CACFC,MAAO,kBAAM,yBAEfC,IAAK,QACJ,CATH,KAWFxB,cAzEO,SAyEM,GACX,OAAOD,KAAKoB,eAAe,EAApB,KAAqC,CAACpB,KAAK+B,QAAlD,MAEFU,WA5EO,WA4EG,WACR,OAAOzC,KAAKoB,eAAe,MAAO,CAChCC,YADgC,yBAEhC9C,WAAY,CAAC,CACXD,KADW,QAEXuD,MAAO,CACLa,MAAQ,SAAAC,GAAD,OAAmB,kBAAsB,EAD3C,eAELC,KAAO,SAAAD,GAAD,OAAmB,kBAAsB,EAF1C,cAGLE,IAAM,SAAAF,GAAD,OAAmB,kBAAsB,EAAtB,gBAG5BhB,IAAK,WACJ,CAAC3B,KAXJ,gBAaF8C,mBA1FO,SA0FW,SAChB,IAAMC,EAAOb,GAAG,EAAhB,EACMc,EAAoBD,EAAA,GACvB,SAAAE,GAAA,EAAD,GAAkCtD,EADpC,QAGA,OAAOoD,EAAOxC,KAAA,IAASA,KAAA,MAA4BZ,EAAA,QAAiBA,EAAtD,SAAd,IAEFuD,aAjGO,SAiGK,GACVlD,KAAA,0BACAA,KAAA,aAEF8B,SArGO,WAuGD9B,KAAJ,cAEAA,KAAA,aAEFmD,aA3GO,SA2GK,GAAe,IACjBvD,EAAYI,KAApB,MAAQJ,QAERI,KAAA,OAAcA,KAAKN,aAAeiD,EAAlC,YAEA/C,EAAA,uCACAA,EAAA,6CAEFwD,YAnHO,SAmHI,GACTpD,KAAA,aAAoBA,KAAKP,OAASkD,EAAlC,YAEFU,WAtHO,WAsHG,MACqBrD,KAA7B,MAAM,EADE,EACF,QAAWH,EADT,EACSA,QACXyD,EAAkB1D,EAAA,YAAsBC,EAA9C,YAEAD,EAAA,qCACAA,EAAA,qCAEII,KAAKiC,SAAT,IAEMjC,KAAKN,aAAe,IAAMM,KAA9B,cACEA,KAAA,eACSA,KAAKN,eAAT,IACLM,KAAA,iBAIEA,KAAKN,aAAe,IAAMM,KAA9B,cACEA,KAAA,eACSA,KAAKN,cAAT,IACLM,KAAA,iBAINuD,cA7IO,SA6IM,KACXZ,EAAA,kBACA3C,KAAA,eAAsBwD,EAAtB,IAEFC,eAjJO,WAkJAzD,KAAL,eAKyB,IAAvBA,KAAK0D,gBACH1D,KAAD,eAAuBA,KAF1B,cAIEA,KAAA,eACSA,KAAJ,aACLA,KAAA,aAAoBA,KAAK2D,wBACvB3D,KAAK4D,aADa,IAElB5D,KAFkB,OAGlBA,KAAKiC,SAHP,KAKSjC,KAAJ,gBACLA,KAAA,aAAoBA,KAAK6D,uBACvB7D,KAAK4D,aADa,IAElB5D,KAFkB,OAGlBA,KAAKiC,SAHa,IAIlBjC,KAJF,iBAQJ6D,uBA1KO,SA0Ke,SACpB,IAAMC,EAAcC,EAApB,YACMC,EAAa9B,EACdvC,EAAA,QAAiBoE,EAAjB,WADiB,EAElBA,EAFJ,WAIA,IACEE,MAGF,IAAMC,EAAavE,EAAA,QAAnB,EACMwE,EAAaL,EAAnB,EACMM,EAAN,GAAyBN,EAQzB,OANIE,EAAJ,EACEC,EAAsB1D,KAAA,IAASyD,EAAT,EAAtB,GACSE,EAAJ,IACLD,EAAsB1D,KAAA,IAAS0D,GAAuBC,EAAA,EAAhC,GAA6EvE,EAAA,QAAiBA,EAApH,UAGKuC,GAAG,EAAV,GAEFyB,wBAhMO,SAgMgB,OAA4D,IAC3E,EAAN,EAAM,WAAcG,EAApB,EAAoBA,YAEpB,KAAS,CACP,IAAMO,EAAiB1E,EAAA,UAA8BmE,EAA9B,EAAgDnE,EAAA,QAAvE,EACA,OAAQY,KAAA,IAASZ,EAAA,QAAiBA,EAA1B,QAA0CY,KAAA,MAAlD,IAEA,IAAM,EAAiByD,EAAaF,EAAb,EAA+BnE,EAAA,QAAtD,EACA,OAAOY,KAAA,IAASZ,EAAA,QAAiBA,EAA1B,QAA0CY,KAAA,MAAjD,KAGJ+D,SA3MO,SA2MC,GACNtE,KAAA,aAAoBA,KAAK8C,mBAAmBX,EAAU,CAEpDvC,QAASI,KAAKuE,MAAM3E,QAAUI,KAAKuE,MAAM3E,QAAhC,YAF2C,EAGpDC,QAASG,KAAKuE,MAAM1E,QAAUG,KAAKuE,MAAM1E,QAAhC,YAAsD,GAC9DG,KAAKiC,SAJY,IAIEjC,KAJtB,eAMFwE,UAlNO,WAkN6B,WAClCC,OAAA,uBAA6B,WAAK,MACH,EAA7B,MAAM,EAD0B,EAC1B,QAAW5E,EADe,EACfA,QAEjB,SAAc,CACZD,QAASA,EAAUA,EAAH,YADJ,EAEZC,QAASA,EAAUA,EAAH,YAAyB,GAG3C,gBAAqB,iBAAsB,SAA3C,QAEA,wBAKN6E,OA3VO,SA2VD,GACJ,OAAOC,EAAE,MAAO3E,KAAR,UAAwB,CAC9BA,KAD8B,UAE9BA,KAF8B,aAG9BA,KAHF,eAQW,OAAA3B,EAAA,OAAsB,CACnCC,KADmC,gBAGnCsG,QAHmC,WAIjC,MAAO,CACLC,WAAY7E","file":"js/chunk-5ada8f46.07bb4a8b.js","sourcesContent":["// Styles\nimport './VSlideGroup.sass'\n\n// Components\nimport VIcon from '../VIcon'\nimport { VFadeTransition } from '../transitions'\n\n// Extensions\nimport { BaseItemGroup } from '../VItemGroup/VItemGroup'\n\n// Mixins\nimport Mobile from '../../mixins/mobile'\n\n// Directives\nimport Resize from '../../directives/resize'\nimport Touch from '../../directives/touch'\n\n// Utilities\nimport mixins, { ExtractVue } from '../../util/mixins'\n\n// Types\nimport Vue, { VNode } from 'vue'\n\ninterface TouchEvent {\n touchstartX: number\n touchmoveX: number\n stopPropagation: Function\n}\n\ninterface Widths {\n content: number\n wrapper: number\n}\n\ninterface options extends Vue {\n $refs: {\n content: HTMLElement\n wrapper: HTMLElement\n }\n}\n\nexport const BaseSlideGroup = mixins\n/* eslint-enable indent */\n>(\n BaseItemGroup,\n Mobile,\n /* @vue/component */\n).extend({\n name: 'base-slide-group',\n\n directives: {\n Resize,\n Touch,\n },\n\n props: {\n activeClass: {\n type: String,\n default: 'v-slide-item--active',\n },\n centerActive: Boolean,\n nextIcon: {\n type: String,\n default: '$next',\n },\n prevIcon: {\n type: String,\n default: '$prev',\n },\n showArrows: {\n type: [Boolean, String],\n validator: v => (\n typeof v === 'boolean' || [\n 'always',\n 'desktop',\n 'mobile',\n ].includes(v)\n ),\n },\n },\n\n data: () => ({\n internalItemsLength: 0,\n isOverflowing: false,\n resizeTimeout: 0,\n startX: 0,\n scrollOffset: 0,\n widths: {\n content: 0,\n wrapper: 0,\n },\n }),\n\n computed: {\n __cachedNext (): VNode {\n return this.genTransition('next')\n },\n __cachedPrev (): VNode {\n return this.genTransition('prev')\n },\n classes (): object {\n return {\n ...BaseItemGroup.options.computed.classes.call(this),\n 'v-slide-group': true,\n 'v-slide-group--has-affixes': this.hasAffixes,\n 'v-slide-group--is-overflowing': this.isOverflowing,\n }\n },\n hasAffixes (): Boolean {\n switch (this.showArrows) {\n // Always show arrows on desktop & mobile\n case 'always': return true\n\n // Always show arrows on desktop\n case 'desktop': return !this.isMobile\n\n // Show arrows on mobile when overflowing.\n // This matches the default 2.2 behavior\n case true: return this.isOverflowing\n\n // Always show on mobile\n case 'mobile': return (\n this.isMobile ||\n this.isOverflowing\n )\n\n // https://material.io/components/tabs#scrollable-tabs\n // Always show arrows when\n // overflowed on desktop\n default: return (\n !this.isMobile &&\n this.isOverflowing\n )\n }\n },\n hasNext (): boolean {\n if (!this.hasAffixes) return false\n\n const { content, wrapper } = this.widths\n\n // Check one scroll ahead to know the width of right-most item\n return content > Math.abs(this.scrollOffset) + wrapper\n },\n hasPrev (): boolean {\n return this.hasAffixes && this.scrollOffset !== 0\n },\n },\n\n watch: {\n internalValue: 'setWidths',\n // When overflow changes, the arrows alter\n // the widths of the content and wrapper\n // and need to be recalculated\n isOverflowing: 'setWidths',\n scrollOffset (val) {\n this.$refs.content.style.transform = `translateX(${-val}px)`\n },\n },\n\n beforeUpdate () {\n this.internalItemsLength = (this.$children || []).length\n },\n\n updated () {\n if (this.internalItemsLength === (this.$children || []).length) return\n this.setWidths()\n },\n\n methods: {\n // Always generate next for scrollable hint\n genNext (): VNode | null {\n const slot = this.$scopedSlots.next\n ? this.$scopedSlots.next({})\n : this.$slots.next || this.__cachedNext\n\n return this.$createElement('div', {\n staticClass: 'v-slide-group__next',\n class: {\n 'v-slide-group__next--disabled': !this.hasNext,\n },\n on: {\n click: () => this.onAffixClick('next'),\n },\n key: 'next',\n }, [slot])\n },\n genContent (): VNode {\n return this.$createElement('div', {\n staticClass: 'v-slide-group__content',\n ref: 'content',\n }, this.$slots.default)\n },\n genData (): object {\n return {\n class: this.classes,\n directives: [{\n name: 'resize',\n value: this.onResize,\n }],\n }\n },\n genIcon (location: 'prev' | 'next'): VNode | null {\n let icon = location\n\n if (this.$vuetify.rtl && location === 'prev') {\n icon = 'next'\n } else if (this.$vuetify.rtl && location === 'next') {\n icon = 'prev'\n }\n\n const upperLocation = `${location[0].toUpperCase()}${location.slice(1)}`\n const hasAffix = (this as any)[`has${upperLocation}`]\n\n if (\n !this.showArrows &&\n !hasAffix\n ) return null\n\n return this.$createElement(VIcon, {\n props: {\n disabled: !hasAffix,\n },\n }, (this as any)[`${icon}Icon`])\n },\n // Always generate prev for scrollable hint\n genPrev (): VNode | null {\n const slot = this.$scopedSlots.prev\n ? this.$scopedSlots.prev({})\n : this.$slots.prev || this.__cachedPrev\n\n return this.$createElement('div', {\n staticClass: 'v-slide-group__prev',\n class: {\n 'v-slide-group__prev--disabled': !this.hasPrev,\n },\n on: {\n click: () => this.onAffixClick('prev'),\n },\n key: 'prev',\n }, [slot])\n },\n genTransition (location: 'prev' | 'next') {\n return this.$createElement(VFadeTransition, [this.genIcon(location)])\n },\n genWrapper (): VNode {\n return this.$createElement('div', {\n staticClass: 'v-slide-group__wrapper',\n directives: [{\n name: 'touch',\n value: {\n start: (e: TouchEvent) => this.overflowCheck(e, this.onTouchStart),\n move: (e: TouchEvent) => this.overflowCheck(e, this.onTouchMove),\n end: (e: TouchEvent) => this.overflowCheck(e, this.onTouchEnd),\n },\n }],\n ref: 'wrapper',\n }, [this.genContent()])\n },\n calculateNewOffset (direction: 'prev' | 'next', widths: Widths, rtl: boolean, currentScrollOffset: number) {\n const sign = rtl ? -1 : 1\n const newAbosluteOffset = sign * currentScrollOffset +\n (direction === 'prev' ? -1 : 1) * widths.wrapper\n\n return sign * Math.max(Math.min(newAbosluteOffset, widths.content - widths.wrapper), 0)\n },\n onAffixClick (location: 'prev' | 'next') {\n this.$emit(`click:${location}`)\n this.scrollTo(location)\n },\n onResize () {\n /* istanbul ignore next */\n if (this._isDestroyed) return\n\n this.setWidths()\n },\n onTouchStart (e: TouchEvent) {\n const { content } = this.$refs\n\n this.startX = this.scrollOffset + e.touchstartX as number\n\n content.style.setProperty('transition', 'none')\n content.style.setProperty('willChange', 'transform')\n },\n onTouchMove (e: TouchEvent) {\n this.scrollOffset = this.startX - e.touchmoveX\n },\n onTouchEnd () {\n const { content, wrapper } = this.$refs\n const maxScrollOffset = content.clientWidth - wrapper.clientWidth\n\n content.style.setProperty('transition', null)\n content.style.setProperty('willChange', null)\n\n if (this.$vuetify.rtl) {\n /* istanbul ignore else */\n if (this.scrollOffset > 0 || !this.isOverflowing) {\n this.scrollOffset = 0\n } else if (this.scrollOffset <= -maxScrollOffset) {\n this.scrollOffset = -maxScrollOffset\n }\n } else {\n /* istanbul ignore else */\n if (this.scrollOffset < 0 || !this.isOverflowing) {\n this.scrollOffset = 0\n } else if (this.scrollOffset >= maxScrollOffset) {\n this.scrollOffset = maxScrollOffset\n }\n }\n },\n overflowCheck (e: TouchEvent, fn: (e: TouchEvent) => void) {\n e.stopPropagation()\n this.isOverflowing && fn(e)\n },\n scrollIntoView /* istanbul ignore next */ () {\n if (!this.selectedItem) {\n return\n }\n\n if (\n this.selectedIndex === 0 ||\n (!this.centerActive && !this.isOverflowing)\n ) {\n this.scrollOffset = 0\n } else if (this.centerActive) {\n this.scrollOffset = this.calculateCenteredOffset(\n this.selectedItem.$el as HTMLElement,\n this.widths,\n this.$vuetify.rtl\n )\n } else if (this.isOverflowing) {\n this.scrollOffset = this.calculateUpdatedOffset(\n this.selectedItem.$el as HTMLElement,\n this.widths,\n this.$vuetify.rtl,\n this.scrollOffset\n )\n }\n },\n calculateUpdatedOffset (selectedElement: HTMLElement, widths: Widths, rtl: boolean, currentScrollOffset: number): number {\n const clientWidth = selectedElement.clientWidth\n const offsetLeft = rtl\n ? (widths.content - selectedElement.offsetLeft - clientWidth)\n : selectedElement.offsetLeft\n\n if (rtl) {\n currentScrollOffset = -currentScrollOffset\n }\n\n const totalWidth = widths.wrapper + currentScrollOffset\n const itemOffset = clientWidth + offsetLeft\n const additionalOffset = clientWidth * 0.4\n\n if (offsetLeft < currentScrollOffset) {\n currentScrollOffset = Math.max(offsetLeft - additionalOffset, 0)\n } else if (totalWidth < itemOffset) {\n currentScrollOffset = Math.min(currentScrollOffset - (totalWidth - itemOffset - additionalOffset), widths.content - widths.wrapper)\n }\n\n return rtl ? -currentScrollOffset : currentScrollOffset\n },\n calculateCenteredOffset (selectedElement: HTMLElement, widths: Widths, rtl: boolean): number {\n const { offsetLeft, clientWidth } = selectedElement\n\n if (rtl) {\n const offsetCentered = widths.content - offsetLeft - clientWidth / 2 - widths.wrapper / 2\n return -Math.min(widths.content - widths.wrapper, Math.max(0, offsetCentered))\n } else {\n const offsetCentered = offsetLeft + clientWidth / 2 - widths.wrapper / 2\n return Math.min(widths.content - widths.wrapper, Math.max(0, offsetCentered))\n }\n },\n scrollTo /* istanbul ignore next */ (location: 'prev' | 'next') {\n this.scrollOffset = this.calculateNewOffset(location, {\n // Force reflow\n content: this.$refs.content ? this.$refs.content.clientWidth : 0,\n wrapper: this.$refs.wrapper ? this.$refs.wrapper.clientWidth : 0,\n }, this.$vuetify.rtl, this.scrollOffset)\n },\n setWidths /* istanbul ignore next */ () {\n window.requestAnimationFrame(() => {\n const { content, wrapper } = this.$refs\n\n this.widths = {\n content: content ? content.clientWidth : 0,\n wrapper: wrapper ? wrapper.clientWidth : 0,\n }\n\n this.isOverflowing = this.widths.wrapper < this.widths.content\n\n this.scrollIntoView()\n })\n },\n },\n\n render (h): VNode {\n return h('div', this.genData(), [\n this.genPrev(),\n this.genWrapper(),\n this.genNext(),\n ])\n },\n})\n\nexport default BaseSlideGroup.extend({\n name: 'v-slide-group',\n\n provide (): object {\n return {\n slideGroup: this,\n }\n },\n})\n"],"sourceRoot":""}