{"version":3,"sources":["../src/elements/scroll-snap.ts"],"sourcesContent":["import { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { emitEvent } from '../utilities/events';\nimport { stylesScrollSnap } from '../styles/elements/scroll-snap';\nimport KemetScrollSnapSlide from './scroll-snap-slide';\nimport { EnumAxis, EnumDirections, TypeAxis, TypeDirection } from '../utilities/constants';\n\n/**\n * @since 1.0.0\n * @status stable\n *\n * @tagname kemet-scroll-snap\n * @summary A scroll-snap implementation for responsive sliders.\n *\n * @prop {TypeAxis} axis - Determines the direction the component flows. Values include: (horizontal | vertical)\n * @prop {TypeDirection} pagination - Determines where to display the paginator. Values include: (top | right | bottom | left)\n *\n * @slot slides - Place your slides here.\n * @slot pagination - Place the paginator component here if you want one.\n *\n * @csspart slides - The slides container.\n * @csspart pagination - The pagination element.\n *\n * @cssproperty --kemet-scroll-snap-gap - Space between the slides.\n * @cssproperty --kemet-scroll-snap-horizontal-max-width - The horizontal max width of the container.\n * @cssproperty --kemet-scroll-snap-vertical-height - The vertical height of the container.\n * @cssproperty --kemet-scroll-snap-slides-vertical-padding - Padding on the vertical axis.\n *\n * @event kemet-make-slides - Fires when slide data has been created.\n *\n */\n\n@customElement('kemet-scroll-snap')\nexport default class KemetScrollSnap extends LitElement {\n  static styles = [stylesScrollSnap];\n\n  @property({ type: String, reflect: true })\n  axis: TypeAxis = EnumAxis.Horizontal;\n\n  @property({ type: String, reflect: true })\n  pagination: TypeDirection = EnumDirections.Bottom;\n\n  @state()\n  isTouchDevice: boolean;\n\n  @state()\n  slides: KemetScrollSnapSlide[];\n\n  constructor() {\n    super();\n\n    this.addEventListener('kemet-focus', (event: CustomEvent) => {\n      this.focusSlide(event.detail);\n    });\n  }\n\n  firstUpdated() {\n    // standard properties\n    this.isTouchDevice = 'ontouchstart' in document.documentElement;\n    this.slides = [];\n\n    this.setFocusedSlides();\n  }\n\n  updated() {\n    this.setVerticalAttribute();\n  }\n\n  render() {\n    return html`\n      <slot name=\"slides\"></slot>\n      <slot name=\"pagination\"></slot>\n    `;\n  }\n\n  setFocusedSlides() {\n    // reference: https://24ways.org/2019/beautiful-scrolling-experiences-without-libraries/\n    // reference: https://css-tricks.com/an-explanation-of-how-the-intersection-observer-watches/\n    const slides = this.querySelectorAll('kemet-scroll-snap-slide');\n    const container = this.querySelector('[slot=\"slides\"]');\n\n    const options = {\n      root: container,\n      rootMargin: '0px',\n      threshold: 0.5,\n    };\n\n    const callback = (entries: IntersectionObserverEntry[]) => {\n      entries.forEach((entry: IntersectionObserverEntry) => {\n        const target = entry.target as KemetScrollSnapSlide;\n        target.focused = entry.intersectionRatio >= 0.5;\n      });\n\n      this.makeSlides();\n    };\n\n    const observer = new IntersectionObserver(callback, options);\n\n    slides.forEach((slide) => {\n      observer.observe(slide);\n    });\n  }\n\n  makeSlides() {\n    const slides = [];\n\n    this.querySelectorAll('kemet-scroll-snap-slide').forEach((element, index) => {\n      const slide = element as KemetScrollSnapSlide;\n\n      slide.index = index;\n      slides.push({\n        id: index,\n        focused: slide.focused,\n        label: slide.label,\n      });\n    });\n\n    this.slides = slides;\n    emitEvent(this, 'kemet-make-slides', this.slides);\n  }\n\n  focusSlide(index: number) {\n    const activeSlide = this.querySelector(`kemet-scroll-snap-slide[index=\"${index}\"]`);\n    activeSlide.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n  }\n\n  setVerticalAttribute() {\n    if (this.axis === 'vertical') {\n      document.querySelector('html').setAttribute('kemet-scroll-snap-axis', 'vertical');\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'kemet-scroll-snap': KemetScrollSnap\n  }\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,MAAM,kBAAkB;AACjC,SAAS,eAAe,UAAU,aAAa;AAgC/C,IAAqB,kBAArB,cAA6C,WAAW;AAAA,EAetD,cAAc;AACZ,UAAM;AAZR;AAGA;AAWE,SAAK,iBAAiB,eAAe,CAAC,UAAuB;AAC3D,WAAK,WAAW,MAAM,MAAM;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EAEA,eAAe;AAEb,SAAK,gBAAgB,kBAAkB,SAAS;AAChD,SAAK,SAAS,CAAC;AAEf,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,UAAU;AACR,SAAK,qBAAqB;AAAA,EAC5B;AAAA,EAEA,SAAS;AACP,WAAO;AAAA;AAAA;AAAA;AAAA,EAIT;AAAA,EAEA,mBAAmB;AAGjB,UAAM,SAAS,KAAK,iBAAiB,yBAAyB;AAC9D,UAAM,YAAY,KAAK,cAAc,iBAAiB;AAEtD,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,WAAW;AAAA,IACb;AAEA,UAAM,WAAW,CAAC,YAAyC;AACzD,cAAQ,QAAQ,CAAC,UAAqC;AACpD,cAAM,SAAS,MAAM;AACrB,eAAO,UAAU,MAAM,qBAAqB;AAAA,MAC9C,CAAC;AAED,WAAK,WAAW;AAAA,IAClB;AAEA,UAAM,WAAW,IAAI,qBAAqB,UAAU,OAAO;AAE3D,WAAO,QAAQ,CAAC,UAAU;AACxB,eAAS,QAAQ,KAAK;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa;AACX,UAAM,SAAS,CAAC;AAEhB,SAAK,iBAAiB,yBAAyB,EAAE,QAAQ,CAAC,SAAS,UAAU;AAC3E,YAAM,QAAQ;AAEd,YAAM,QAAQ;AACd,aAAO,KAAK;AAAA,QACV,IAAI;AAAA,QACJ,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAED,SAAK,SAAS;AACd,cAAU,MAAM,qBAAqB,KAAK,MAAM;AAAA,EAClD;AAAA,EAEA,WAAW,OAAe;AACxB,UAAM,cAAc,KAAK,cAAc,kCAAkC,KAAK,IAAI;AAClF,gBAAY,eAAe,EAAE,UAAU,UAAU,OAAO,UAAU,CAAC;AAAA,EACrE;AAAA,EAEA,uBAAuB;AACrB,QAAI,KAAK,SAAS,YAAY;AAC5B,eAAS,cAAc,MAAM,EAAE,aAAa,0BAA0B,UAAU;AAAA,IAClF;AAAA,EACF;AACF;AAlGqB,gBACZ,SAAS,CAAC,gBAAgB;AAGjC;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAHtB,gBAInB;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GANtB,gBAOnB;AAGA;AAAA,EADC,MAAM;AAAA,GATY,gBAUnB;AAGA;AAAA,EADC,MAAM;AAAA,GAZY,gBAanB;AAbmB,kBAArB;AAAA,EADC,cAAc,mBAAmB;AAAA,GACb;","names":[]}