@@ -1477,7 +1700,9 @@ smStripSelect.innerHTML = `
customElements.define('sm-strip-select', class extends HTMLElement {
constructor() {
super()
- this.attachShadow({ mode: 'open' }).append(smStripSelect.content.cloneNode(true))
+ this.attachShadow({
+ mode: 'open'
+ }).append(smStripSelect.content.cloneNode(true))
}
static get observedAttributes() {
return ['value']
@@ -1488,7 +1713,7 @@ customElements.define('sm-strip-select', class extends HTMLElement {
set value(val) {
this.setAttribute('value', val)
}
- scrollLeft() {
+ scrollLeft = () => {
this.select.scrollBy({
top: 0,
left: -this.scrollDistance,
@@ -1496,7 +1721,7 @@ customElements.define('sm-strip-select', class extends HTMLElement {
})
}
- scrollRight() {
+ scrollRight = () => {
this.select.scrollBy({
top: 0,
left: this.scrollDistance,
@@ -1518,8 +1743,7 @@ customElements.define('sm-strip-select', class extends HTMLElement {
if (entries[0].isIntersecting) {
this.previousArrow.classList.add('hide')
this.previousGradient.classList.add('hide')
- }
- else {
+ } else {
this.previousArrow.classList.remove('hide')
this.previousGradient.classList.remove('hide')
}
@@ -1531,8 +1755,7 @@ customElements.define('sm-strip-select', class extends HTMLElement {
if (entries[0].isIntersecting) {
this.nextArrow.classList.add('hide')
this.nextGradient.classList.add('hide')
- }
- else {
+ } else {
this.nextArrow.classList.remove('hide')
this.nextGradient.classList.remove('hide')
}
@@ -1553,7 +1776,11 @@ customElements.define('sm-strip-select', class extends HTMLElement {
if (previousOption)
previousOption.classList.remove('active')
e.target.classList.add('active')
- e.target.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' })
+ e.target.scrollIntoView({
+ behavior: 'smooth',
+ inline: 'center',
+ block: 'nearest'
+ })
this.setAttribute('value', e.detail.value)
this.dispatchEvent(new CustomEvent('change', {
bubbles: true,
@@ -1572,13 +1799,13 @@ customElements.define('sm-strip-select', class extends HTMLElement {
previousOption = firstElement;
}
});
- this.nextArrow.addEventListener('click', this.scrollRight.bind(this))
- this.previousArrow.addEventListener('click', this.scrollLeft.bind(this))
+ this.nextArrow.addEventListener('click', this.scrollRight)
+ this.previousArrow.addEventListener('click', this.scrollLeft)
}
disconnectedCallback() {
- this.nextArrow.removeEventListener('click', this.scrollRight.bind(this))
- this.previousArrow.removeEventListener('click', this.scrollLeft.bind(this))
+ this.nextArrow.removeEventListener('click', this.scrollRight)
+ this.previousArrow.removeEventListener('click', this.scrollLeft)
}
})
@@ -1586,36 +1813,41 @@ customElements.define('sm-strip-select', class extends HTMLElement {
const smStripOption = document.createElement('template')
smStripOption.innerHTML = `
@@ -1623,7 +1855,9 @@ smStripOption.innerHTML = `
customElements.define('sm-strip-option', class extends HTMLElement {
constructor() {
super()
- this.attachShadow({ mode: 'open' }).append(smStripOption.content.cloneNode(true))
+ this.attachShadow({
+ mode: 'open'
+ }).append(smStripOption.content.cloneNode(true))
}
sendDetails() {
let optionSelected = new CustomEvent('optionSelected', {
@@ -1660,78 +1894,126 @@ const smPopup = document.createElement('template')
smPopup.innerHTML = `
`;
customElements.define('sm-popup', class extends HTMLElement {
constructor() {
super()
- this.attachShadow({ mode: 'open' }).append(smPopup.content.cloneNode(true))
+ this.attachShadow({
+ mode: 'open'
+ }).append(smPopup.content.cloneNode(true))
+
+ this.allowClosing = false
}
- resumeScrolling() {
+ resumeScrolling = () => {
const scrollY = document.body.style.top;
window.scrollTo(0, parseInt(scrollY || '0') * -1);
setTimeout(() => {
@@ -1777,31 +2054,49 @@ customElements.define('sm-popup', class extends HTMLElement {
}, 300);
}
- show(pinned, popupStack) {
- this.setAttribute('open', '')
- this.pinned = pinned
- this.popupStack = popupStack
- this.popupContainer.classList.remove('hide')
- if (window.innerWidth < 648)
- this.popup.style.transform = 'translateY(0)';
- else
- this.popup.style.transform = 'scale(1)';
+ show = (pinned, popupStack) => {
+ if (popupStack)
+ this.popupStack = popupStack
+ if (this.popupStack && !this.hasAttribute('open')) {
+ this.popupStack.push({
+ popup: this,
+ permission: pinned
+ })
+ if (this.popupStack.items.length > 1) {
+ this.popupStack.items[this.popupStack.items.length - 2].popup.classList.add('stacked')
+ }
+ this.dispatchEvent(
+ new CustomEvent("popupopened", {
+ bubbles: true,
+ detail: {
+ popup: this,
+ popupStack: this.popupStack
+ }
+ })
+ )
+ this.setAttribute('open', '')
+ this.pinned = pinned
+ this.popupContainer.classList.remove('hide')
+ }
+ this.popup.style.transform = 'translateY(0)';
document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`)
+ return this.popupStack
}
- hide() {
- this.removeAttribute('open')
- if (window.innerWidth < 648)
+ hide = () => {
+ if (window.innerWidth < 640)
this.popup.style.transform = 'translateY(100%)';
else
- this.popup.style.transform = 'scale(0.9)';
+ this.popup.style.transform = 'translateY(1rem)';
this.popupContainer.classList.add('hide')
+ this.removeAttribute('open')
if (typeof this.popupStack !== 'undefined') {
this.popupStack.pop()
- if (this.popupStack.items.length === 0) {
+ if (this.popupStack.items.length) {
+ this.popupStack.items[this.popupStack.items.length - 1].popup.classList.remove('stacked')
+ } else {
this.resumeScrolling()
}
- }
- else {
+ } else {
this.resumeScrolling()
}
@@ -1815,15 +2110,24 @@ customElements.define('sm-popup', class extends HTMLElement {
})
}, 300);
}
+ this.dispatchEvent(
+ new CustomEvent("popupclosed", {
+ bubbles: true,
+ detail: {
+ popup: this,
+ popupStack: this.popupStack
+ }
+ })
+ )
}
- handleTouchStart(e) {
+ handleTouchStart = (e) => {
this.touchStartY = e.changedTouches[0].clientY
- this.popup.style.transition = 'initial'
+ this.popup.style.transition = 'transform 0.1s'
this.touchStartTime = e.timeStamp
}
- handleTouchMove(e) {
+ handleTouchMove = (e) => {
e.preventDefault()
if (this.touchStartY < e.changedTouches[0].clientY) {
this.offset = e.changedTouches[0].clientY - this.touchStartY;
@@ -1835,26 +2139,33 @@ customElements.define('sm-popup', class extends HTMLElement {
}*/
}
- handleTouchEnd(e) {
+ handleTouchEnd = (e) => {
this.touchEndTime = e.timeStamp
cancelAnimationFrame(this.touchEndAnimataion)
this.touchEndY = e.changedTouches[0].clientY
this.popup.style.transition = 'transform 0.3s'
if (this.touchEndTime - this.touchStartTime > 200) {
if (this.touchEndY - this.touchStartY > this.threshold) {
- this.hide()
- }
- else {
+ if (this.pinned) {
+ this.show()
+ return
+ } else
+ this.hide()
+ } else {
this.show()
}
- }
- else {
+ } else {
if (this.touchEndY > this.touchStartY)
+ if (this.pinned) {
+ this.show()
+ return
+ }
+ else
this.hide()
}
}
- movePopup() {
+ movePopup = () => {
this.popup.style.transform = `translateY(${this.offset}px)`
}
@@ -1877,12 +2188,16 @@ customElements.define('sm-popup', class extends HTMLElement {
this.show()
this.popupContainer.addEventListener('mousedown', e => {
if (e.target === this.popupContainer && !this.pinned) {
- this.hide()
+ if (this.pinned) {
+ this.show()
+ return
+ } else
+ this.hide()
}
})
this.popupBodySlot.addEventListener('slotchange', () => {
- this.inputFields = this.popupBodySlot.assignedElements().filter(element => element.tagName === 'SM-INPUT' || element.tagName === 'SM-CHECKBOX' || element.tagName === 'TEXTAREA' || element.type === 'radio')
+ this.inputFields = this.querySelectorAll('sm-input', 'sm-checkbox', 'textarea', 'radio')
})
this.popupHeader.addEventListener('touchstart', (e) => {
@@ -1896,9 +2211,9 @@ customElements.define('sm-popup', class extends HTMLElement {
})
}
disconnectedCallback() {
- this.popupHeader.removeEventListener('touchstart', this.handleTouchStart.bind(this))
- this.popupHeader.removeEventListener('touchmove', this.handleTouchMove.bind(this))
- this.popupHeader.removeEventListener('touchend', this.handleTouchEnd.bind(this))
+ this.popupHeader.removeEventListener('touchstart', this.handleTouchStart)
+ this.popupHeader.removeEventListener('touchmove', this.handleTouchMove)
+ this.popupHeader.removeEventListener('touchend', this.handleTouchEnd)
}
})
@@ -1908,82 +2223,114 @@ const smCarousel = document.createElement('template')
smCarousel.innerHTML = `
-
-
-
-
-
-
-
+
+
+
+
+
+
`;
customElements.define('sm-carousel', class extends HTMLElement {
constructor() {
super()
- this.attachShadow({ mode: 'open' }).append(smCarousel.content.cloneNode(true))
+ this.attachShadow({
+ mode: 'open'
+ }).append(smCarousel.content.cloneNode(true))
}
- scrollLeft() {
+ static get observedAttributes() {
+ return ['indicator']
+ }
+
+ scrollLeft = () => {
this.carousel.scrollBy({
top: 0,
left: -this.scrollDistance,
@@ -2047,7 +2399,7 @@ customElements.define('sm-carousel', class extends HTMLElement {
})
}
- scrollRight() {
+ scrollRight = () => {
this.carousel.scrollBy({
top: 0,
left: this.scrollDistance,
@@ -2061,32 +2413,50 @@ customElements.define('sm-carousel', class extends HTMLElement {
this.carouselSlot = this.shadowRoot.querySelector('slot')
this.nextArrow = this.shadowRoot.querySelector('.next-item')
this.previousArrow = this.shadowRoot.querySelector('.previous-item')
- this.nextGradient = this.shadowRoot.querySelector('.right')
- this.previousGradient = this.shadowRoot.querySelector('.left')
+ this.indicatorsContainer = this.shadowRoot.querySelector('.indicators')
this.carouselItems
+ this.indicators
+ this.showIndicator = false
this.scrollDistance = this.carouselContainer.getBoundingClientRect().width / 3
- const firstElementObserver = new IntersectionObserver(entries => {
- if (entries[0].isIntersecting) {
- this.previousArrow.classList.remove('expand')
- this.previousGradient.classList.add('hide')
- }
- else {
- this.previousArrow.classList.add('expand')
- this.previousGradient.classList.remove('hide')
- }
- }, {
- root: this.carouselContainer,
- threshold: 0.9
- })
- const lastElementObserver = new IntersectionObserver(entries => {
- if (entries[0].isIntersecting) {
- this.nextArrow.classList.remove('expand')
- this.nextGradient.classList.add('hide')
- }
- else {
- this.nextArrow.classList.add('expand')
- this.nextGradient.classList.remove('hide')
- }
+ let frag = document.createDocumentFragment();
+ if (this.hasAttribute('indicator'))
+ this.showIndicator = true
+
+
+ let firstVisible = false,
+ lastVisible = false
+ const allElementsObserver = new IntersectionObserver(entries => {
+ entries.forEach(entry => {
+ if (this.showIndicator)
+ if (entry.isIntersecting) {
+ this.indicators[parseInt(entry.target.attributes.rank.textContent)].classList.add('active')
+ }
+ else
+ this.indicators[parseInt(entry.target.attributes.rank.textContent)].classList.remove('active')
+ if (!entry.target.previousElementSibling)
+ if (entry.isIntersecting) {
+ this.previousArrow.classList.remove('expand')
+ firstVisible = true
+ }
+ else {
+ this.previousArrow.classList.add('expand')
+ firstVisible = false
+ }
+ if (!entry.target.nextElementSibling)
+ if (entry.isIntersecting) {
+ this.nextArrow.classList.remove('expand')
+ lastVisible = true
+ }
+ else {
+ this.nextArrow.classList.add('expand')
+
+ lastVisible = false
+ }
+ if (firstVisible && lastVisible)
+ this.indicatorsContainer.classList.add('hide')
+ else
+ this.indicatorsContainer.classList.remove('hide')
+ })
}, {
root: this.carouselContainer,
threshold: 0.9
@@ -2102,8 +2472,18 @@ customElements.define('sm-carousel', class extends HTMLElement {
this.carouselSlot.addEventListener('slotchange', e => {
this.carouselItems = this.carouselSlot.assignedElements()
- firstElementObserver.observe(this.carouselItems[0])
- lastElementObserver.observe(this.carouselItems[this.carouselItems.length - 1])
+ this.carouselItems.forEach(item => allElementsObserver.observe(item))
+ if (this.showIndicator) {
+ this.indicatorsContainer.innerHTML = ``
+ this.carouselItems.forEach((item, index) => {
+ let dot = document.createElement('div')
+ dot.classList.add('dot')
+ frag.append(dot)
+ item.setAttribute('rank', index)
+ })
+ this.indicatorsContainer.append(frag)
+ this.indicators = this.indicatorsContainer.children
+ }
})
this.addEventListener('keyup', e => {
@@ -2113,13 +2493,22 @@ customElements.define('sm-carousel', class extends HTMLElement {
this.scrollRight()
})
- this.nextArrow.addEventListener('click', this.scrollRight.bind(this))
- this.previousArrow.addEventListener('click', this.scrollLeft.bind(this))
+ this.nextArrow.addEventListener('click', this.scrollRight)
+ this.previousArrow.addEventListener('click', this.scrollLeft)
+ }
+
+ attributeChangedCallback(name, oldValue, newValue) {
+ if (name === 'indicator') {
+ if (this.hasAttribute('indicator'))
+ this.showIndicator = true
+ else
+ this.showIndicator = false
+ }
}
disconnectedCallback() {
- this.nextArrow.removeEventListener('click', this.scrollRight.bind(this))
- this.previousArrow.removeEventListener('click', this.scrollLeft.bind(this))
+ this.nextArrow.removeEventListener('click', this.scrollRight)
+ this.previousArrow.removeEventListener('click', this.scrollLeft)
}
})
@@ -2128,130 +2517,153 @@ customElements.define('sm-carousel', class extends HTMLElement {
const smNotifications = document.createElement('template')
smNotifications.innerHTML = `
@@ -2260,29 +2672,30 @@ stroke-width: 6;
customElements.define('sm-notifications', class extends HTMLElement {
constructor() {
super()
- this.shadow = this.attachShadow({ mode: 'open' }).append(smNotifications.content.cloneNode(true))
+ this.shadow = this.attachShadow({
+ mode: 'open'
+ }).append(smNotifications.content.cloneNode(true))
}
- handleTouchStart(e) {
+ handleTouchStart = (e) => {
this.notification = e.target.closest('.notification')
this.touchStartX = e.changedTouches[0].clientX
this.notification.style.transition = 'initial'
this.touchStartTime = e.timeStamp
}
- handleTouchMove(e) {
+ handleTouchMove = (e) => {
e.preventDefault()
if (this.touchStartX < e.changedTouches[0].clientX) {
this.offset = e.changedTouches[0].clientX - this.touchStartX;
this.touchEndAnimataion = requestAnimationFrame(this.movePopup)
- }
- else {
+ } else {
this.offset = -(this.touchStartX - e.changedTouches[0].clientX);
this.touchEndAnimataion = requestAnimationFrame(this.movePopup)
}
}
- handleTouchEnd(e) {
+ handleTouchEnd = (e) => {
this.notification.style.transition = 'transform 0.3s, opacity 0.3s'
this.touchEndTime = e.timeStamp
cancelAnimationFrame(this.touchEndAnimataion)
@@ -2290,19 +2703,15 @@ customElements.define('sm-notifications', class extends HTMLElement {
if (this.touchEndTime - this.touchStartTime > 200) {
if (this.touchEndX - this.touchStartX > this.threshold) {
this.removeNotification(this.notification)
- }
- else if (this.touchStartX - this.touchEndX > this.threshold) {
+ } else if (this.touchStartX - this.touchEndX > this.threshold) {
this.removeNotification(this.notification, true)
- }
- else {
+ } else {
this.resetPosition()
}
- }
- else {
+ } else {
if (this.touchEndX > this.touchStartX) {
this.removeNotification(this.notification)
- }
- else {
+ } else {
this.removeNotification(this.notification, true)
}
}
@@ -2312,11 +2721,11 @@ customElements.define('sm-notifications', class extends HTMLElement {
this.notification.style.transform = `translateX(${this.offset}px)`
}
- resetPosition() {
+ resetPosition = () => {
this.notification.style.transform = `translateX(0)`
}
- push(messageBody, type, pinned) {
+ push = (messageBody, type, pinned) => {
let notification = document.createElement('div'),
composition = ``
notification.classList.add('notification')
@@ -2329,8 +2738,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
`
- }
- else if (type === 'success') {
+ } else if (type === 'success') {
composition += `