@@ -1476,7 +1605,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']
@@ -1487,7 +1618,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,
@@ -1495,7 +1626,7 @@ customElements.define('sm-strip-select', class extends HTMLElement {
})
}
- scrollRight() {
+ scrollRight = () => {
this.select.scrollBy({
top: 0,
left: this.scrollDistance,
@@ -1517,8 +1648,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')
}
@@ -1530,8 +1660,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')
}
@@ -1552,7 +1681,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,
@@ -1571,13 +1704,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)
}
})
@@ -1585,36 +1718,42 @@ customElements.define('sm-strip-select', class extends HTMLElement {
const smStripOption = document.createElement('template')
smStripOption.innerHTML = `
@@ -1622,7 +1761,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', {
@@ -1659,116 +1800,150 @@ 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(() => {
@@ -1776,31 +1951,49 @@ customElements.define('sm-popup', class extends HTMLElement {
}, 300);
}
- show(pinned, popupStack) {
- this.setAttribute('open', '')
- this.pinned = pinned
- this.popupStack = popupStack
+ 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')
- if (window.innerWidth < 648)
- this.popup.style.transform = 'translateY(0)';
- else
- this.popup.style.transform = 'scale(1)';
+ this.popup.style.transform = 'none';
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(3rem)';
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()
}
@@ -1814,15 +2007,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;
@@ -1834,26 +2036,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)`
}
@@ -1869,19 +2078,26 @@ customElements.define('sm-popup', class extends HTMLElement {
this.touchEndY = 0
this.touchStartTime = 0
this.touchEndTime = 0
- this.threshold = this.popup.getBoundingClientRect().height * 0.3
this.touchEndAnimataion;
+ this.threshold
if (this.hasAttribute('open'))
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')
+ setTimeout(() => {
+ this.threshold = this.popup.getBoundingClientRect().height * 0.3
+ }, 200);
+ this.inputFields = this.querySelectorAll('sm-input', 'sm-checkbox', 'textarea', 'sm-textarea', 'radio')
})
this.popupHeader.addEventListener('touchstart', (e) => {
@@ -1895,9 +2111,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)
}
})
@@ -1907,80 +2123,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,
@@ -2044,7 +2299,7 @@ customElements.define('sm-carousel', class extends HTMLElement {
})
}
- scrollRight() {
+ scrollRight = () => {
this.carousel.scrollBy({
top: 0,
left: this.scrollDistance,
@@ -2058,32 +2313,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
@@ -2099,8 +2372,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 => {
@@ -2110,13 +2393,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)
}
})
@@ -2125,111 +2417,154 @@ customElements.define('sm-carousel', class extends HTMLElement {
const smNotifications = document.createElement('template')
smNotifications.innerHTML = `
@@ -2238,29 +2573,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)
@@ -2268,19 +2604,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)
}
}
@@ -2290,11 +2622,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')
@@ -2307,13 +2639,11 @@ customElements.define('sm-notifications', class extends HTMLElement {
`
- }
- else if (type === 'success') {
+ } else if (type === 'success') {
composition += `
- `
+ `
}
composition += `
${messageBody}
@@ -2325,8 +2655,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
notification.innerHTML = composition
this.notificationPanel.prepend(notification)
if (window.innerWidth > 640) {
- notification.animate([
- {
+ notification.animate([{
transform: `translateX(1rem)`,
opacity: '0'
},
@@ -2337,22 +2666,20 @@ customElements.define('sm-notifications', class extends HTMLElement {
], this.animationOptions).onfinish = () => {
notification.setAttribute('style', `transform: none;`);
}
- }
- else {
+ } else {
notification.setAttribute('style', `transform: translateY(0); opacity: 1`)
}
- notification.addEventListener('touchstart', this.handleTouchStart.bind(this))
- notification.addEventListener('touchmove', this.handleTouchMove.bind(this))
- notification.addEventListener('touchend', this.handleTouchEnd.bind(this))
+ notification.addEventListener('touchstart', this.handleTouchStart)
+ notification.addEventListener('touchmove', this.handleTouchMove)
+ notification.addEventListener('touchend', this.handleTouchEnd)
}
- removeNotification(notification, toLeft) {
+ removeNotification = (notification, toLeft) => {
if (!this.offset)
this.offset = 0;
if (toLeft)
- notification.animate([
- {
+ notification.animate([{
transform: `translateX(${this.offset}px)`,
opacity: '1'
},
@@ -2364,8 +2691,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
notification.remove()
}
else {
- notification.animate([
- {
+ notification.animate([{
transform: `translateX(${this.offset}px)`,
opacity: '1'
},
@@ -2403,7 +2729,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
this.touchEndAnimataion;
this.notificationPanel.addEventListener('click', e => {
- if (e.target.closest('.close')) (
+ if (e.target.closest('.close'))(
this.removeNotification(e.target.closest('.notification'))
)
})
@@ -2420,8 +2746,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
this.notificationPanel.style.padding = '1.5rem 0 3rem 1.5rem';
else
this.notificationPanel.style.padding = '1rem 1rem 2rem 1rem';
- }
- else if (mutation.removedNodes.length && !this.notificationPanel.children.length) {
+ } else if (mutation.removedNodes.length && !this.notificationPanel.children.length) {
this.notificationPanel.style.padding = 0;
}
}
@@ -2440,92 +2765,121 @@ customElements.define('sm-notifications', class extends HTMLElement {
const smMenu = document.createElement('template')
smMenu.innerHTML = `