added code to speed up loading
This commit is contained in:
parent
8b892fec20
commit
df751c1287
555
components.js
555
components.js
@ -204,18 +204,19 @@ border: none;
|
|||||||
.input {
|
.input {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
text-align: left;
|
||||||
position: relative;
|
position: relative;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
padding: 0.7em 1em;
|
padding: 0.7em 1em;
|
||||||
border-radius: 0.3em;
|
border-radius: 0.3em;
|
||||||
transition: opacity 0.3s;
|
transition: opacity 0.3s;
|
||||||
background: rgba(var(--text-color), 0.1);
|
background: rgba(var(--text-color), 0.06);
|
||||||
|
box-shadow: 0 0 0 0.1em rgba(var(--text-color), 0.2) inset;
|
||||||
font-family: var(--font-family);
|
font-family: var(--font-family);
|
||||||
width: 100%
|
width: 100%
|
||||||
outline: none;
|
outline: none;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:focus{
|
input:focus{
|
||||||
caret-color: var(--accent-color);
|
caret-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
@ -281,6 +282,9 @@ input{
|
|||||||
border: solid 1px rgba(var(--text-color), 0.2);
|
border: solid 1px rgba(var(--text-color), 0.2);
|
||||||
padding: 0.6em 1em;
|
padding: 0.6em 1em;
|
||||||
}
|
}
|
||||||
|
.helper-text:empty{
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
@media (any-hover: hover){
|
@media (any-hover: hover){
|
||||||
.icon:hover{
|
.icon:hover{
|
||||||
background: rgba(var(--text-color), 0.1);
|
background: rgba(var(--text-color), 0.1);
|
||||||
@ -288,19 +292,19 @@ input{
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="outer-container">
|
<div class="outer-container">
|
||||||
<label part="input" class="input">
|
<label part="input" class="input">
|
||||||
<slot name="icon"></slot>
|
<slot name="icon"></slot>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<input/>
|
<input/>
|
||||||
<div part="placeholder" class="label"></div>
|
<div part="placeholder" class="label"></div>
|
||||||
</div>
|
</div>
|
||||||
<svg class="icon clear hide" viewBox="0 0 64 64">
|
<svg class="icon clear hide" viewBox="0 0 64 64">
|
||||||
<title>clear</title>
|
<title>clear</title>
|
||||||
<line x1="64" y1="0" x2="0" y2="64"/>
|
<line x1="64" y1="0" x2="0" y2="64"/>
|
||||||
<line x1="64" y1="64" x2="0" y2="0"/>
|
<line x1="64" y1="64" x2="0" y2="0"/>
|
||||||
</svg>
|
</svg>
|
||||||
</label>
|
</label>
|
||||||
<div class="helper-text hide"></div>
|
<div class="helper-text hide"></div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
customElements.define('sm-input',
|
customElements.define('sm-input',
|
||||||
@ -339,22 +343,22 @@ customElements.define('sm-input',
|
|||||||
return this.shadowRoot.querySelector('input').checkValidity()
|
return this.shadowRoot.querySelector('input').checkValidity()
|
||||||
}
|
}
|
||||||
|
|
||||||
focusIn() {
|
focusIn = () => {
|
||||||
this.shadowRoot.querySelector('input').focus()
|
this.shadowRoot.querySelector('input').focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
focusOut() {
|
focusOut = () => {
|
||||||
this.shadowRoot.querySelector('input').blur()
|
this.shadowRoot.querySelector('input').blur()
|
||||||
}
|
}
|
||||||
|
|
||||||
preventNonNumericalInput(e) {
|
preventNonNumericalInput = (e) => {
|
||||||
let keyCode = e.keyCode;
|
let keyCode = e.keyCode;
|
||||||
if (!((keyCode > 47 && keyCode < 56) || (keyCode > 36 && keyCode < 39) || (keyCode > 95 && keyCode < 104) || keyCode === 110 || (keyCode > 7 && keyCode < 19))) {
|
if (!((keyCode > 47 && keyCode < 56) || (keyCode > 36 && keyCode < 39) || (keyCode > 95 && keyCode < 106) || keyCode === 110 || (keyCode > 7 && keyCode < 19))) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fireEvent() {
|
fireEvent = () => {
|
||||||
let event = new Event('input', {
|
let event = new Event('input', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
cancelable: true,
|
cancelable: true,
|
||||||
@ -363,7 +367,7 @@ customElements.define('sm-input',
|
|||||||
this.dispatchEvent(event);
|
this.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkInput() {
|
checkInput = (e) => {
|
||||||
if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder') === '')
|
if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder') === '')
|
||||||
return;
|
return;
|
||||||
if (this.input.value !== '') {
|
if (this.input.value !== '') {
|
||||||
@ -392,6 +396,8 @@ customElements.define('sm-input',
|
|||||||
this.helperText = this.shadowRoot.querySelector('.helper-text')
|
this.helperText = this.shadowRoot.querySelector('.helper-text')
|
||||||
this.valueChanged = false;
|
this.valueChanged = false;
|
||||||
this.readonly = false
|
this.readonly = false
|
||||||
|
this.min
|
||||||
|
this.max
|
||||||
this.animate = this.hasAttribute('animate')
|
this.animate = this.hasAttribute('animate')
|
||||||
this.input = this.shadowRoot.querySelector('input')
|
this.input = this.shadowRoot.querySelector('input')
|
||||||
this.shadowRoot.querySelector('.label').textContent = this.getAttribute('placeholder')
|
this.shadowRoot.querySelector('.label').textContent = this.getAttribute('placeholder')
|
||||||
@ -402,6 +408,19 @@ customElements.define('sm-input',
|
|||||||
if (this.hasAttribute('required')) {
|
if (this.hasAttribute('required')) {
|
||||||
this.input.setAttribute('required', '')
|
this.input.setAttribute('required', '')
|
||||||
}
|
}
|
||||||
|
if (this.hasAttribute('min')) {
|
||||||
|
let minValue = this.getAttribute('min')
|
||||||
|
this.input.setAttribute('min', minValue)
|
||||||
|
this.min = parseInt(minValue)
|
||||||
|
}
|
||||||
|
if (this.hasAttribute('max')) {
|
||||||
|
let maxValue = this.getAttribute('max')
|
||||||
|
this.input.setAttribute('max', maxValue)
|
||||||
|
this.max = parseInt(maxValue)
|
||||||
|
}
|
||||||
|
if (this.hasAttribute('pattern')) {
|
||||||
|
this.input.setAttribute('pattern', this.getAttribute('pattern'))
|
||||||
|
}
|
||||||
if (this.hasAttribute('readonly')) {
|
if (this.hasAttribute('readonly')) {
|
||||||
this.input.setAttribute('readonly', '')
|
this.input.setAttribute('readonly', '')
|
||||||
this.readonly = true
|
this.readonly = true
|
||||||
@ -412,6 +431,7 @@ customElements.define('sm-input',
|
|||||||
if (this.hasAttribute('type')) {
|
if (this.hasAttribute('type')) {
|
||||||
if (this.getAttribute('type') === 'number') {
|
if (this.getAttribute('type') === 'number') {
|
||||||
this.input.setAttribute('inputmode', 'numeric')
|
this.input.setAttribute('inputmode', 'numeric')
|
||||||
|
this.input.setAttribute('type', 'number')
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this.input.setAttribute('type', this.getAttribute('type'))
|
this.input.setAttribute('type', this.getAttribute('type'))
|
||||||
@ -434,6 +454,7 @@ customElements.define('sm-input',
|
|||||||
if (oldValue !== newValue) {
|
if (oldValue !== newValue) {
|
||||||
if (name === 'placeholder')
|
if (name === 'placeholder')
|
||||||
this.shadowRoot.querySelector('.label').textContent = newValue;
|
this.shadowRoot.querySelector('.label').textContent = newValue;
|
||||||
|
this.setAttribute('aria-label', newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1488,7 +1509,7 @@ customElements.define('sm-strip-select', class extends HTMLElement {
|
|||||||
set value(val) {
|
set value(val) {
|
||||||
this.setAttribute('value', val)
|
this.setAttribute('value', val)
|
||||||
}
|
}
|
||||||
scrollLeft() {
|
scrollLeft = () => {
|
||||||
this.select.scrollBy({
|
this.select.scrollBy({
|
||||||
top: 0,
|
top: 0,
|
||||||
left: -this.scrollDistance,
|
left: -this.scrollDistance,
|
||||||
@ -1496,7 +1517,7 @@ customElements.define('sm-strip-select', class extends HTMLElement {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollRight() {
|
scrollRight = () => {
|
||||||
this.select.scrollBy({
|
this.select.scrollBy({
|
||||||
top: 0,
|
top: 0,
|
||||||
left: this.scrollDistance,
|
left: this.scrollDistance,
|
||||||
@ -1572,13 +1593,13 @@ customElements.define('sm-strip-select', class extends HTMLElement {
|
|||||||
previousOption = firstElement;
|
previousOption = firstElement;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.nextArrow.addEventListener('click', this.scrollRight.bind(this))
|
this.nextArrow.addEventListener('click', this.scrollRight)
|
||||||
this.previousArrow.addEventListener('click', this.scrollLeft.bind(this))
|
this.previousArrow.addEventListener('click', this.scrollLeft)
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
this.nextArrow.removeEventListener('click', this.scrollRight.bind(this))
|
this.nextArrow.removeEventListener('click', this.scrollRight)
|
||||||
this.previousArrow.removeEventListener('click', this.scrollLeft.bind(this))
|
this.previousArrow.removeEventListener('click', this.scrollLeft)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1660,73 +1681,80 @@ const smPopup = document.createElement('template')
|
|||||||
smPopup.innerHTML = `
|
smPopup.innerHTML = `
|
||||||
<style>
|
<style>
|
||||||
*{
|
*{
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
:host{
|
:host{
|
||||||
display: grid;
|
position: fixed;
|
||||||
|
display: grid;
|
||||||
}
|
}
|
||||||
.popup-container{
|
.popup-container{
|
||||||
display: grid;
|
display: grid;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
background: #00000060;
|
background: rgba(0, 0, 0, 0.6);
|
||||||
z-index: 10;
|
transition: opacity 0.3s ease;
|
||||||
transition: opacity 0.3s ease;
|
z-index: 10;
|
||||||
|
}
|
||||||
|
:host(.stacked) .popup{
|
||||||
|
transform: scale(0.9) translateY(-2rem) !important;
|
||||||
}
|
}
|
||||||
.popup{
|
.popup{
|
||||||
display: flex;
|
margin-bottom: 0.5rem;
|
||||||
flex-direction: column;
|
display: flex;
|
||||||
position: relative;
|
flex-direction: column;
|
||||||
align-self: flex-end;
|
position: relative;
|
||||||
align-items: flex-start;
|
align-self: flex-end;
|
||||||
width: 100%;
|
align-items: flex-start;
|
||||||
border-radius: 0.5rem 0.5rem 0 0;
|
width: calc(100% - 1rem);
|
||||||
transform: translateY(100%);
|
border-radius: 0.8rem;
|
||||||
transition: transform 0.3s;
|
transform: translateY(100%);
|
||||||
background: rgba(var(--foreground-color), 1);
|
transition: transform 0.3s;
|
||||||
box-shadow: 0 -1rem 2rem #00000020;
|
background: rgba(var(--foreground-color), 1);
|
||||||
max-height: 100vh;
|
box-shadow: 0 -1rem 2rem #00000020;
|
||||||
|
max-height: 100vh;
|
||||||
}
|
}
|
||||||
.container-header{
|
.container-header{
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.popup-top{
|
.popup-top{
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.popup-body{
|
.popup-body{
|
||||||
flex: 1;
|
display: flex;
|
||||||
width: 100%;
|
flex-direction: column;
|
||||||
padding: 1.5rem;
|
flex: 1;
|
||||||
overflow-y: auto;
|
width: 100%;
|
||||||
|
padding: 1.5rem;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
.heading{
|
.heading{
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
.heading:first-letter{
|
.heading:first-letter{
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
.hide{
|
.hide{
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 640px){
|
@media screen and (min-width: 640px){
|
||||||
.popup{
|
.popup{
|
||||||
width: max-content;
|
width: max-content;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
border-radius: 0.4rem;
|
border-radius: 0.4rem;
|
||||||
height: auto;
|
height: auto;
|
||||||
transform: translateY(0) scale(0.9);
|
transform: translateY(1rem);
|
||||||
box-shadow: 0 2rem 2rem #00000040;
|
box-shadow: 0 3rem 2rem -0.5rem #00000040;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 640px){
|
@media screen and (max-width: 640px){
|
||||||
.popup-top{
|
.popup-top{
|
||||||
@ -1767,9 +1795,11 @@ customElements.define('sm-popup', class extends HTMLElement {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super()
|
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;
|
const scrollY = document.body.style.top;
|
||||||
window.scrollTo(0, parseInt(scrollY || '0') * -1);
|
window.scrollTo(0, parseInt(scrollY || '0') * -1);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -1777,27 +1807,47 @@ customElements.define('sm-popup', class extends HTMLElement {
|
|||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
show(pinned, 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.setAttribute('open', '')
|
this.setAttribute('open', '')
|
||||||
this.pinned = pinned
|
this.pinned = pinned
|
||||||
this.popupStack = popupStack
|
|
||||||
this.popupContainer.classList.remove('hide')
|
this.popupContainer.classList.remove('hide')
|
||||||
if (window.innerWidth < 648)
|
this.popup.style.transform = 'translateY(0)';
|
||||||
this.popup.style.transform = 'translateY(0)';
|
|
||||||
else
|
|
||||||
this.popup.style.transform = 'scale(1)';
|
|
||||||
document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`)
|
document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`)
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent("popupopened", {
|
||||||
|
bubbles: true,
|
||||||
|
detail: {
|
||||||
|
popup: this,
|
||||||
|
popupStack: this.popupStack
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return this.popupStack
|
||||||
}
|
}
|
||||||
hide() {
|
hide = () => {
|
||||||
this.removeAttribute('open')
|
this.removeAttribute('open')
|
||||||
if (window.innerWidth < 648)
|
if(window.innerWidth < 640)
|
||||||
this.popup.style.transform = 'translateY(100%)';
|
this.popup.style.transform = 'translateY(100%)';
|
||||||
else
|
else
|
||||||
this.popup.style.transform = 'scale(0.9)';
|
this.popup.style.transform = 'translateY(1rem)';
|
||||||
this.popupContainer.classList.add('hide')
|
this.popupContainer.classList.add('hide')
|
||||||
if (typeof this.popupStack !== 'undefined') {
|
if (typeof this.popupStack !== 'undefined') {
|
||||||
this.popupStack.pop()
|
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()
|
this.resumeScrolling()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1815,15 +1865,24 @@ customElements.define('sm-popup', class extends HTMLElement {
|
|||||||
})
|
})
|
||||||
}, 300);
|
}, 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.touchStartY = e.changedTouches[0].clientY
|
||||||
this.popup.style.transition = 'initial'
|
this.popup.style.transition = 'initial'
|
||||||
this.touchStartTime = e.timeStamp
|
this.touchStartTime = e.timeStamp
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchMove(e) {
|
handleTouchMove = (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (this.touchStartY < e.changedTouches[0].clientY) {
|
if (this.touchStartY < e.changedTouches[0].clientY) {
|
||||||
this.offset = e.changedTouches[0].clientY - this.touchStartY;
|
this.offset = e.changedTouches[0].clientY - this.touchStartY;
|
||||||
@ -1834,8 +1893,8 @@ customElements.define('sm-popup', class extends HTMLElement {
|
|||||||
this.popup.style.transform = `translateY(-${this.offset}px)`
|
this.popup.style.transform = `translateY(-${this.offset}px)`
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchEnd(e) {
|
handleTouchEnd = (e) => {
|
||||||
this.touchEndTime = e.timeStamp
|
this.touchEndTime = e.timeStamp
|
||||||
cancelAnimationFrame(this.touchEndAnimataion)
|
cancelAnimationFrame(this.touchEndAnimataion)
|
||||||
this.touchEndY = e.changedTouches[0].clientY
|
this.touchEndY = e.changedTouches[0].clientY
|
||||||
@ -1854,7 +1913,7 @@ customElements.define('sm-popup', class extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
movePopup() {
|
movePopup = () => {
|
||||||
this.popup.style.transform = `translateY(${this.offset}px)`
|
this.popup.style.transform = `translateY(${this.offset}px)`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1882,7 +1941,7 @@ customElements.define('sm-popup', class extends HTMLElement {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.popupBodySlot.addEventListener('slotchange', () => {
|
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) => {
|
this.popupHeader.addEventListener('touchstart', (e) => {
|
||||||
@ -1896,9 +1955,9 @@ customElements.define('sm-popup', class extends HTMLElement {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
this.popupHeader.removeEventListener('touchstart', this.handleTouchStart.bind(this))
|
this.popupHeader.removeEventListener('touchstart', this.handleTouchStart)
|
||||||
this.popupHeader.removeEventListener('touchmove', this.handleTouchMove.bind(this))
|
this.popupHeader.removeEventListener('touchmove', this.handleTouchMove)
|
||||||
this.popupHeader.removeEventListener('touchend', this.handleTouchEnd.bind(this))
|
this.popupHeader.removeEventListener('touchend', this.handleTouchEnd)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1908,82 +1967,89 @@ const smCarousel = document.createElement('template')
|
|||||||
smCarousel.innerHTML = `
|
smCarousel.innerHTML = `
|
||||||
<style>
|
<style>
|
||||||
*{
|
*{
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
:host{
|
:host{
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.icon {
|
.icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
fill: none;
|
fill: none;
|
||||||
height: 2.6rem;
|
height: 2.6rem;
|
||||||
width: 2.6rem;
|
width: 2.6rem;
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
padding: 0.9rem;
|
padding: 0.9rem;
|
||||||
stroke: rgba(var(--foreground-color), 0.8);
|
stroke: rgba(var(--foreground-color), 0.8);
|
||||||
stroke-width: 14;
|
stroke-width: 14;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
stroke-linejoin: round;
|
stroke-linejoin: round;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
background: rgba(var(--text-color), 1);
|
background: rgba(var(--text-color), 1);
|
||||||
box-shadow: 0 0.2rem 0.2rem #00000020,
|
box-shadow: 0 0.2rem 0.2rem #00000020,
|
||||||
0 0.5rem 1rem #00000040;
|
0 0.5rem 1rem #00000040;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
.hide{
|
.hide{
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
.expand{
|
.expand{
|
||||||
transform: scale(1)
|
transform: scale(1)
|
||||||
}
|
}
|
||||||
.previous-item{
|
.previous-item{
|
||||||
left: 1rem;
|
left: 1rem;
|
||||||
}
|
}
|
||||||
.next-item{
|
.next-item{
|
||||||
right: 1rem;
|
right: 1rem;
|
||||||
}
|
|
||||||
.left,.right{
|
|
||||||
position: absolute;
|
|
||||||
width: 3rem;
|
|
||||||
height: 100%;
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.left{
|
|
||||||
background: linear-gradient(to left, transparent, rgba(var(--foreground-color), 0.6))
|
|
||||||
}
|
|
||||||
.right{
|
|
||||||
right: 0;
|
|
||||||
background: linear-gradient(to right, transparent, rgba(var(--foreground-color), 0.6))
|
|
||||||
}
|
}
|
||||||
.carousel-container{
|
.carousel-container{
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.carousel{
|
.carousel{
|
||||||
display: flex;
|
display: flex;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: auto hidden;
|
width: 100%;
|
||||||
scroll-snap-type: x mandatory;
|
overflow: auto hidden;
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
}
|
||||||
|
.indicators{
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1rem;
|
||||||
|
gap: 0.5rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.dot{
|
||||||
|
position: relative;
|
||||||
|
padding: 0.2rem;
|
||||||
|
background: rgba(var(--text-color), 0.3);
|
||||||
|
border-radius: 1rem;
|
||||||
|
transition: 0.2s;
|
||||||
|
}
|
||||||
|
.dot.active{
|
||||||
|
transform: scale(1.5);
|
||||||
|
background: var(--accent-color);
|
||||||
}
|
}
|
||||||
slot::slotted(*){
|
slot::slotted(*){
|
||||||
scroll-snap-align: center;
|
scroll-snap-align: center;
|
||||||
}
|
}
|
||||||
:host([align-items="start"]) slot::slotted(*){
|
:host([align-items="start"]) slot::slotted(*){
|
||||||
scroll-snap-align: start;
|
scroll-snap-align: start;
|
||||||
}
|
}
|
||||||
:host([align-items="center"]) slot::slotted(*){
|
:host([align-items="center"]) slot::slotted(*){
|
||||||
scroll-snap-align: center;
|
scroll-snap-align: center;
|
||||||
}
|
}
|
||||||
:host([align-items="end"]) slot::slotted(*){
|
:host([align-items="end"]) slot::slotted(*){
|
||||||
scroll-snap-align: end;
|
scroll-snap-align: end;
|
||||||
@ -2017,19 +2083,18 @@ scroll-snap-align: end;
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="carousel-container">
|
<div class="carousel-container">
|
||||||
<div class="left"></div>
|
<svg class="icon previous-item" viewBox="4 0 64 64">
|
||||||
<svg class="icon previous-item" viewBox="4 0 64 64">
|
<title>Previous</title>
|
||||||
<title>Previous</title>
|
<polyline points="48.01 0.35 16.35 32 48.01 63.65"/>
|
||||||
<polyline points="48.01 0.35 16.35 32 48.01 63.65"/>
|
</svg>
|
||||||
</svg>
|
<div part="carousel" class="carousel">
|
||||||
<div part="carousel" class="carousel">
|
<slot></slot>
|
||||||
<slot></slot>
|
</div>
|
||||||
</div>
|
<svg class="icon next-item" viewBox="-6 0 64 64">
|
||||||
<svg class="icon next-item" viewBox="-6 0 64 64">
|
<title>Next</title>
|
||||||
<title>Next</title>
|
<polyline points="15.99 0.35 47.65 32 15.99 63.65"/>
|
||||||
<polyline points="15.99 0.35 47.65 32 15.99 63.65"/>
|
</svg>
|
||||||
</svg>
|
<div class="indicators"></div>
|
||||||
<div class="right"></div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -2039,7 +2104,11 @@ customElements.define('sm-carousel', class extends HTMLElement {
|
|||||||
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({
|
this.carousel.scrollBy({
|
||||||
top: 0,
|
top: 0,
|
||||||
left: -this.scrollDistance,
|
left: -this.scrollDistance,
|
||||||
@ -2047,7 +2116,7 @@ customElements.define('sm-carousel', class extends HTMLElement {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollRight() {
|
scrollRight = () => {
|
||||||
this.carousel.scrollBy({
|
this.carousel.scrollBy({
|
||||||
top: 0,
|
top: 0,
|
||||||
left: this.scrollDistance,
|
left: this.scrollDistance,
|
||||||
@ -2061,32 +2130,50 @@ customElements.define('sm-carousel', class extends HTMLElement {
|
|||||||
this.carouselSlot = this.shadowRoot.querySelector('slot')
|
this.carouselSlot = this.shadowRoot.querySelector('slot')
|
||||||
this.nextArrow = this.shadowRoot.querySelector('.next-item')
|
this.nextArrow = this.shadowRoot.querySelector('.next-item')
|
||||||
this.previousArrow = this.shadowRoot.querySelector('.previous-item')
|
this.previousArrow = this.shadowRoot.querySelector('.previous-item')
|
||||||
this.nextGradient = this.shadowRoot.querySelector('.right')
|
this.indicatorsContainer = this.shadowRoot.querySelector('.indicators')
|
||||||
this.previousGradient = this.shadowRoot.querySelector('.left')
|
|
||||||
this.carouselItems
|
this.carouselItems
|
||||||
|
this.indicators
|
||||||
|
this.showIndicator = false
|
||||||
this.scrollDistance = this.carouselContainer.getBoundingClientRect().width / 3
|
this.scrollDistance = this.carouselContainer.getBoundingClientRect().width / 3
|
||||||
const firstElementObserver = new IntersectionObserver(entries => {
|
let frag = document.createDocumentFragment();
|
||||||
if (entries[0].isIntersecting) {
|
if (this.hasAttribute('indicator'))
|
||||||
this.previousArrow.classList.remove('expand')
|
this.showIndicator = true
|
||||||
this.previousGradient.classList.add('hide')
|
|
||||||
}
|
|
||||||
else {
|
let firstVisible = false,
|
||||||
this.previousArrow.classList.add('expand')
|
lastVisible = false
|
||||||
this.previousGradient.classList.remove('hide')
|
const allElementsObserver = new IntersectionObserver(entries => {
|
||||||
}
|
entries.forEach(entry => {
|
||||||
}, {
|
if(this.showIndicator)
|
||||||
root: this.carouselContainer,
|
if (entry.isIntersecting) {
|
||||||
threshold: 0.9
|
this.indicators[parseInt(entry.target.attributes.rank.textContent)].classList.add('active')
|
||||||
})
|
}
|
||||||
const lastElementObserver = new IntersectionObserver(entries => {
|
else
|
||||||
if (entries[0].isIntersecting) {
|
this.indicators[parseInt(entry.target.attributes.rank.textContent)].classList.remove('active')
|
||||||
this.nextArrow.classList.remove('expand')
|
if (!entry.target.previousElementSibling)
|
||||||
this.nextGradient.classList.add('hide')
|
if(entry.isIntersecting) {
|
||||||
}
|
this.previousArrow.classList.remove('expand')
|
||||||
else {
|
firstVisible = true
|
||||||
this.nextArrow.classList.add('expand')
|
}
|
||||||
this.nextGradient.classList.remove('hide')
|
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,
|
root: this.carouselContainer,
|
||||||
threshold: 0.9
|
threshold: 0.9
|
||||||
@ -2102,8 +2189,18 @@ customElements.define('sm-carousel', class extends HTMLElement {
|
|||||||
|
|
||||||
this.carouselSlot.addEventListener('slotchange', e => {
|
this.carouselSlot.addEventListener('slotchange', e => {
|
||||||
this.carouselItems = this.carouselSlot.assignedElements()
|
this.carouselItems = this.carouselSlot.assignedElements()
|
||||||
firstElementObserver.observe(this.carouselItems[0])
|
this.carouselItems.forEach(item => allElementsObserver.observe(item))
|
||||||
lastElementObserver.observe(this.carouselItems[this.carouselItems.length - 1])
|
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 => {
|
this.addEventListener('keyup', e => {
|
||||||
@ -2113,13 +2210,22 @@ customElements.define('sm-carousel', class extends HTMLElement {
|
|||||||
this.scrollRight()
|
this.scrollRight()
|
||||||
})
|
})
|
||||||
|
|
||||||
this.nextArrow.addEventListener('click', this.scrollRight.bind(this))
|
this.nextArrow.addEventListener('click', this.scrollRight)
|
||||||
this.previousArrow.addEventListener('click', this.scrollLeft.bind(this))
|
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() {
|
disconnectedCallback() {
|
||||||
this.nextArrow.removeEventListener('click', this.scrollRight.bind(this))
|
this.nextArrow.removeEventListener('click', this.scrollRight)
|
||||||
this.previousArrow.removeEventListener('click', this.scrollLeft.bind(this))
|
this.previousArrow.removeEventListener('click', this.scrollLeft)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -2156,27 +2262,28 @@ transform: none;
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.notification{
|
.notification{
|
||||||
display: flex;
|
display: flex;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
transform: translateY(-1rem);
|
margin-bottom: 0.5rem;
|
||||||
position: relative;
|
transform: translateY(-1rem);
|
||||||
border-radius: 0.3rem;
|
position: relative;
|
||||||
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1),
|
border-radius: 0.3rem;
|
||||||
0.5rem 1rem 2rem rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1),
|
||||||
background: rgba(var(--foreground-color), 1);
|
0.5rem 1rem 2rem rgba(0, 0, 0, 0.1);
|
||||||
transition: height 0.3s, transform 0.3s, opacity 0.3s;
|
background: rgba(var(--foreground-color), 1);
|
||||||
overflow: hidden;
|
transition: height 0.3s, transform 0.3s, opacity 0.3s;
|
||||||
overflow-wrap: break-word;
|
overflow: hidden;
|
||||||
word-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
-ms-word-break: break-all;
|
word-wrap: break-word;
|
||||||
word-break: break-all;
|
-ms-word-break: break-all;
|
||||||
word-break: break-word;
|
word-break: break-all;
|
||||||
-ms-hyphens: auto;
|
word-break: break-word;
|
||||||
-moz-hyphens: auto;
|
-ms-hyphens: auto;
|
||||||
-webkit-hyphens: auto;
|
-moz-hyphens: auto;
|
||||||
hyphens: auto;
|
-webkit-hyphens: auto;
|
||||||
max-width: 100%;
|
hyphens: auto;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
h4:first-letter,
|
h4:first-letter,
|
||||||
p:first-letter{
|
p:first-letter{
|
||||||
@ -2247,7 +2354,7 @@ stroke-width: 6;
|
|||||||
transform: translateX(1rem);
|
transform: translateX(1rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 640px){
|
@media screen and (any-hover: none){
|
||||||
.close{
|
.close{
|
||||||
display: none
|
display: none
|
||||||
}
|
}
|
||||||
@ -2263,14 +2370,14 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
|||||||
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.notification = e.target.closest('.notification')
|
||||||
this.touchStartX = e.changedTouches[0].clientX
|
this.touchStartX = e.changedTouches[0].clientX
|
||||||
this.notification.style.transition = 'initial'
|
this.notification.style.transition = 'initial'
|
||||||
this.touchStartTime = e.timeStamp
|
this.touchStartTime = e.timeStamp
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchMove(e) {
|
handleTouchMove = (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (this.touchStartX < e.changedTouches[0].clientX) {
|
if (this.touchStartX < e.changedTouches[0].clientX) {
|
||||||
this.offset = e.changedTouches[0].clientX - this.touchStartX;
|
this.offset = e.changedTouches[0].clientX - this.touchStartX;
|
||||||
@ -2282,7 +2389,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchEnd(e) {
|
handleTouchEnd = (e) => {
|
||||||
this.notification.style.transition = 'transform 0.3s, opacity 0.3s'
|
this.notification.style.transition = 'transform 0.3s, opacity 0.3s'
|
||||||
this.touchEndTime = e.timeStamp
|
this.touchEndTime = e.timeStamp
|
||||||
cancelAnimationFrame(this.touchEndAnimataion)
|
cancelAnimationFrame(this.touchEndAnimataion)
|
||||||
@ -2312,11 +2419,11 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
|||||||
this.notification.style.transform = `translateX(${this.offset}px)`
|
this.notification.style.transform = `translateX(${this.offset}px)`
|
||||||
}
|
}
|
||||||
|
|
||||||
resetPosition() {
|
resetPosition = () => {
|
||||||
this.notification.style.transform = `translateX(0)`
|
this.notification.style.transform = `translateX(0)`
|
||||||
}
|
}
|
||||||
|
|
||||||
push(messageBody, type, pinned) {
|
push = (messageBody, type, pinned) => {
|
||||||
let notification = document.createElement('div'),
|
let notification = document.createElement('div'),
|
||||||
composition = ``
|
composition = ``
|
||||||
notification.classList.add('notification')
|
notification.classList.add('notification')
|
||||||
@ -2362,12 +2469,12 @@ customElements.define('sm-notifications', class extends HTMLElement {
|
|||||||
else {
|
else {
|
||||||
notification.setAttribute('style', `transform: translateY(0); opacity: 1`)
|
notification.setAttribute('style', `transform: translateY(0); opacity: 1`)
|
||||||
}
|
}
|
||||||
notification.addEventListener('touchstart', this.handleTouchStart.bind(this))
|
notification.addEventListener('touchstart', this.handleTouchStart)
|
||||||
notification.addEventListener('touchmove', this.handleTouchMove.bind(this))
|
notification.addEventListener('touchmove', this.handleTouchMove)
|
||||||
notification.addEventListener('touchend', this.handleTouchEnd.bind(this))
|
notification.addEventListener('touchend', this.handleTouchEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
removeNotification(notification, toLeft) {
|
removeNotification = (notification, toLeft) => {
|
||||||
if (!this.offset)
|
if (!this.offset)
|
||||||
this.offset = 0;
|
this.offset = 0;
|
||||||
|
|
||||||
|
|||||||
2200
index.html
2200
index.html
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user