Comparing version 2.0.0-beta.5 to 2.0.0
{ | ||
"name": "axentix", | ||
"version": "2.0.0-beta.5", | ||
"description": "Axentix is an open source Framework based on CSS Grid using HTML, CSS and JS. The easy layout control and grid system makes it one of the most easy to learn framework.", | ||
"version": "2.0.0", | ||
"description": "Axentix is a framework mixing fully customizable components & utility-first classes, leaving the design choice to the developer.", | ||
"homepage": "https://useaxentix.com", | ||
@@ -9,7 +9,12 @@ "author": "Axel SIMONET, Vincent LEVEQUE", | ||
"scripts": { | ||
"serve": "vite --host", | ||
"build": "vite build && npm run build:def", | ||
"dev": "vite --host", | ||
"build": "node scripts/build.js && npm run build:def", | ||
"build:main": "node scripts/build.js main", | ||
"build:def": "tsc", | ||
"generate:examples": "node scripts/generate-examples.js" | ||
}, | ||
"funding": { | ||
"type": "buymeacoffee", | ||
"url": "https://www.buymeacoffee.com/axentix" | ||
}, | ||
"keywords": [ | ||
@@ -36,3 +41,3 @@ "axentix", | ||
"module": "./dist/axentix.esm.js", | ||
"typings": "./src/index.d.ts", | ||
"typings": "./dist/index.d.ts", | ||
"files": [ | ||
@@ -47,8 +52,10 @@ "dist", | ||
"devDependencies": { | ||
"autoprefixer": "^10.4.1", | ||
"sass": "^1.45.2", | ||
"typescript": "^4.5.4", | ||
"vite": "^2.7.10", | ||
"autoprefixer": "^10.4.2", | ||
"fast-glob": "^3.2.11", | ||
"rollup-plugin-visualizer": "^5.6.0", | ||
"sass": "^1.49.9", | ||
"typescript": "^4.6.2", | ||
"vite": "^2.8.6", | ||
"vite-plugin-mpa": "^1.1.1" | ||
} | ||
} |
@@ -10,19 +10,15 @@ <p align="center"> | ||
<p align="center"> | ||
<a href="https://useaxentix.com/"><strong>Home</strong></a> | | ||
<a href="https://useaxentix.com/docs/"><strong>Documentation</strong></a> | ||
<a href="https://useaxentix.com/?ref=github"><strong>Home</strong></a> | | ||
<a href="https://useaxentix.com/docs/?ref=github"><strong>Documentation</strong></a> | ||
</p> | ||
<h3 align="center"> | ||
WARNING: This branch corresponds to Axentix v2 which is still under development. | ||
<br/> | ||
Find the LTS version on the <a href="https://github.com/axentix/axentix/tree/v1">v1 branch</a>. | ||
</h3> | ||
<br> | ||
<p align="center"> | ||
<a href="https://badge.fury.io/js/axentix"> | ||
<img src="https://badge.fury.io/js/axentix.svg" alt="npm version" /> | ||
<a href="https://www.npmjs.com/package/axentix"> | ||
<img alt="npm" src="https://img.shields.io/npm/v/axentix"> | ||
</a> | ||
<img src="https://img.shields.io/github/v/release/axentix/axentix" alt="GitHub release (latest by date)" /> | ||
<a href="https://github.com/axentix/axentix/releases"> | ||
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/axentix/axentix"> | ||
</a> | ||
<a href="https://www.jsdelivr.com/package/npm/axentix"> | ||
@@ -50,5 +46,5 @@ <img src="https://data.jsdelivr.com/v1/package/npm/axentix/badge?style=rounded" alt="jsDelivr Hits" /> | ||
Axentix is an open source Framework based on CSS Grid using HTML, CSS and JS. The easy layout control and grid system makes it one of the most easy to learn framework. | ||
Axentix is a framework mixing fully customizable components & utility-first classes, leaving the design choice to the developer. | ||
 | ||
 | ||
@@ -59,3 +55,3 @@ ## Quickstart | ||
``` | ||
npm install axentix@next | ||
npm install axentix | ||
``` | ||
@@ -65,3 +61,3 @@ | ||
``` | ||
yarn add axentix@next | ||
yarn add axentix | ||
``` | ||
@@ -88,3 +84,3 @@ | ||
Find the documentation at <https://useaxentix.com/2.0.x/docs/>. | ||
Find the documentation at [https://useaxentix.com/docs/](https://useaxentix.com/docs/?ref=github). | ||
@@ -91,0 +87,0 @@ ## Changelog |
@@ -69,3 +69,3 @@ import { AxentixComponent, Component } from '../../utils/component'; | ||
constructor(element: string, options?: ICaroulixOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: ICaroulixOptions) { | ||
super(); | ||
@@ -79,3 +79,3 @@ | ||
this.options = getComponentOptions('Caroulix', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Caroulix', options, this.el); | ||
@@ -82,0 +82,0 @@ this.setup(); |
import { AxentixComponent, Component } from '../../utils/component'; | ||
import { instances, registerComponent } from '../../utils/config'; | ||
import { createEvent, getComponentOptions, getInstanceByType } from '../../utils/utilities'; | ||
import { createEvent, getComponentOptions, getInstanceByType, getTriggers } from '../../utils/utilities'; | ||
@@ -28,13 +28,13 @@ interface ICollapsibleOptions { | ||
#collapsibleTriggers: NodeListOf<HTMLElement>; | ||
#isInitialStart = true; | ||
#triggers: Array<HTMLElement>; | ||
#sidenavTriggers: Array<HTMLElement>; | ||
#isInit = true; | ||
#isActive = false; | ||
#isAnimated = false; | ||
#isInSidenav = false; | ||
#childIsActive = false; | ||
#listenerRef: any; | ||
#resizeRef: any; | ||
#sidenavId = ''; | ||
#sidenavId: string; | ||
constructor(element: string, options?: ICollapsibleOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: ICollapsibleOptions) { | ||
super(); | ||
@@ -48,3 +48,3 @@ | ||
this.options = getComponentOptions('Collapsible', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Collapsible', options, this.el); | ||
@@ -60,7 +60,7 @@ this.setup(); | ||
this.#collapsibleTriggers = document.querySelectorAll('.collapsible-trigger'); | ||
this.#isInitialStart = true; | ||
this.#triggers = getTriggers(this.el.id); | ||
this.#isInit = true; | ||
this.#isActive = this.el.classList.contains('active') ? true : false; | ||
this.#isAnimated = false; | ||
this.#isInSidenav = false; | ||
this.#sidenavId = ''; | ||
this.#childIsActive = false; | ||
@@ -72,7 +72,8 @@ | ||
this.#detectSidenav(); | ||
this.#detectChild(); | ||
this.#childIsActive = this.el.querySelector('.active') ? true : false; | ||
if (this.options.sidenav.activeClass) this.#addActiveInSidenav(); | ||
if (this.#isActive) this.open(); | ||
this.#isInitialStart = false; | ||
this.#isInit = false; | ||
} | ||
@@ -82,7 +83,3 @@ | ||
this.#listenerRef = this.#onClickTrigger.bind(this); | ||
this.#collapsibleTriggers.forEach((trigger) => { | ||
if (trigger.dataset.target === this.el.id) { | ||
trigger.addEventListener('click', this.#listenerRef); | ||
} | ||
}); | ||
this.#triggers.forEach((trigger) => trigger.addEventListener('click', this.#listenerRef)); | ||
@@ -94,5 +91,3 @@ this.#resizeRef = this.#handleResize.bind(this); | ||
removeListeners() { | ||
this.#collapsibleTriggers.forEach((trigger) => { | ||
if (trigger.dataset.target === this.el.id) trigger.removeEventListener('click', this.#listenerRef); | ||
}); | ||
this.#triggers.forEach((trigger) => trigger.removeEventListener('click', this.#listenerRef)); | ||
this.#listenerRef = undefined; | ||
@@ -105,3 +100,3 @@ | ||
#handleResize() { | ||
if (this.#isActive && !this.#isInSidenav) this.el.style.maxHeight = this.el.scrollHeight + 'px'; | ||
if (this.#isActive && !this.#sidenavId) this.el.style.maxHeight = this.el.scrollHeight + 'px'; | ||
} | ||
@@ -113,33 +108,24 @@ | ||
if (sidenavElem) { | ||
this.#isInSidenav = true; | ||
this.#sidenavId = sidenavElem.id; | ||
this.#sidenavTriggers = this.#triggers.filter((t) => t.closest('.sidenav')?.id === sidenavElem.id); | ||
} | ||
} | ||
#detectChild() { | ||
this.#childIsActive = this.el.querySelector('.active') ? true : false; | ||
} | ||
#addActiveInSidenav() { | ||
if (this.#childIsActive && this.#isInSidenav) { | ||
const triggers = document.querySelectorAll('.sidenav .collapsible-trigger'); | ||
triggers.forEach((trigger: HTMLElement) => { | ||
if (trigger.dataset.target === this.el.id) trigger.classList.add('active'); | ||
}); | ||
if (!this.#childIsActive || !this.#sidenavId) return; | ||
this.el.classList.add('active'); | ||
this.open(); | ||
this.#isActive = true; | ||
} | ||
this.#sidenavTriggers.forEach((trigger) => trigger.classList.add('active')); | ||
this.el.classList.add('active'); | ||
this.open(); | ||
this.#isActive = true; | ||
} | ||
/** Enable / disable active state to trigger when collapsible is in sidenav */ | ||
#addActiveToTrigger(state: boolean) { | ||
const triggers = document.querySelectorAll('.sidenav .collapsible-trigger'); | ||
#toggleTriggerActive(state: boolean) { | ||
if (!this.#sidenavId) return; | ||
triggers.forEach((trigger: HTMLElement) => { | ||
if (trigger.dataset.target === this.el.id) { | ||
if (state) trigger.classList.add('active'); | ||
else trigger.classList.remove('active'); | ||
} | ||
this.#sidenavTriggers.forEach((trigger) => { | ||
if (state) trigger.classList.add('active'); | ||
else trigger.classList.remove('active'); | ||
}); | ||
@@ -149,9 +135,5 @@ } | ||
#autoClose() { | ||
if (!this.#isInitialStart && this.#isInSidenav) { | ||
if (!this.#isInit && this.#sidenavId) { | ||
getInstanceByType('Collapsible').forEach((collapsible: Collapsible) => { | ||
if ( | ||
collapsible.#isInSidenav && | ||
collapsible.#sidenavId === this.#sidenavId && | ||
collapsible.el.id !== this.el.id | ||
) | ||
if (collapsible.#sidenavId === this.#sidenavId && collapsible.el.id !== this.el.id) | ||
collapsible.close(); | ||
@@ -179,3 +161,3 @@ }); | ||
open() { | ||
if (this.#isActive && !this.#isInitialStart) return; | ||
if (this.#isActive && !this.#isInit) return; | ||
@@ -189,3 +171,3 @@ createEvent(this.el, 'collapsible.open'); | ||
if (this.options.sidenav.activeWhenOpen) this.#addActiveToTrigger(true); | ||
if (this.options.sidenav.activeWhenOpen) this.#toggleTriggerActive(true); | ||
if (this.options.sidenav.autoClose) this.#autoClose(); | ||
@@ -207,3 +189,3 @@ | ||
if (this.options.sidenav.activeWhenOpen) this.#addActiveToTrigger(false); | ||
if (this.options.sidenav.activeWhenOpen) this.#toggleTriggerActive(false); | ||
@@ -210,0 +192,0 @@ setTimeout(() => { |
import { AxentixComponent, Component } from '../../utils/component'; | ||
import { registerComponent, instances } from '../../utils/config'; | ||
import { createEvent, getComponentOptions, getInstanceByType } from '../../utils/utilities'; | ||
import { createEvent, getComponentOptions, getInstanceByType, getTriggers } from '../../utils/utilities'; | ||
@@ -11,2 +11,3 @@ interface IDropdownOptions { | ||
preventViewport?: boolean; | ||
closeOnClick?: boolean; | ||
} | ||
@@ -20,2 +21,3 @@ | ||
preventViewport: false, | ||
closeOnClick: true, | ||
}; | ||
@@ -29,3 +31,3 @@ | ||
#dropdownContent: HTMLElement; | ||
#dropdownTrigger: HTMLElement; | ||
#trigger: HTMLElement; | ||
#isAnimated = false; | ||
@@ -35,4 +37,5 @@ #isActive = false; | ||
#listenerRef: any; | ||
#contentHeightRef: any; | ||
constructor(element: string, options?: IDropdownOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: IDropdownOptions) { | ||
super(); | ||
@@ -46,3 +49,3 @@ | ||
this.options = getComponentOptions('Dropdown', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Dropdown', options, this.el); | ||
@@ -59,3 +62,3 @@ this.setup(); | ||
this.#dropdownContent = this.el.querySelector('.dropdown-content'); | ||
this.#dropdownTrigger = this.el.querySelector('.dropdown-trigger'); | ||
this.#trigger = getTriggers(this.el.id)[0]; | ||
this.#isAnimated = false; | ||
@@ -76,6 +79,9 @@ this.#isActive = this.el.classList.contains('active') ? true : false; | ||
this.#listenerRef = this.#onClickTrigger.bind(this); | ||
this.#dropdownTrigger.addEventListener('click', this.#listenerRef); | ||
this.#trigger.addEventListener('click', this.#listenerRef); | ||
this.#documentClickRef = this.#onDocumentClick.bind(this); | ||
document.addEventListener('click', this.#documentClickRef, true); | ||
this.#contentHeightRef = this.#setContentHeight.bind(this); | ||
if (this.options.preventViewport) window.addEventListener('scroll', this.#contentHeightRef); | ||
} | ||
@@ -86,3 +92,3 @@ | ||
this.#dropdownTrigger.removeEventListener('click', this.#listenerRef); | ||
this.#trigger.removeEventListener('click', this.#listenerRef); | ||
this.#listenerRef = undefined; | ||
@@ -92,2 +98,5 @@ | ||
this.#documentClickRef = undefined; | ||
if (this.options.preventViewport) window.removeEventListener('scroll', this.#contentHeightRef); | ||
this.#contentHeightRef = undefined; | ||
} | ||
@@ -108,3 +117,9 @@ | ||
#onDocumentClick(e: any) { | ||
if (e.target.matches('.dropdown-trigger') || this.#isAnimated || !this.#isActive) return; | ||
if ( | ||
e.target === this.#trigger || | ||
this.#isAnimated || | ||
!this.#isActive || | ||
(!this.options.closeOnClick && e.target.closest('.dropdown-content')) | ||
) | ||
return; | ||
@@ -181,3 +196,2 @@ this.close(); | ||
this.#dropdownContent.style.display = ''; | ||
this.#isAnimated = false; | ||
this.#isActive = false; | ||
@@ -184,0 +198,0 @@ createEvent(this.el, 'dropdown.closed'); |
import { AxentixComponent, Component } from '../../utils/component'; | ||
import { registerComponent, instances } from '../../utils/config'; | ||
import { createEvent, getComponentOptions } from '../../utils/utilities'; | ||
import { createEvent, getComponentOptions, getTriggers } from '../../utils/utilities'; | ||
@@ -37,3 +37,3 @@ interface IFabOptions { | ||
constructor(element: string, options?: IFabOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: IFabOptions) { | ||
super(); | ||
@@ -47,3 +47,3 @@ | ||
this.options = getComponentOptions('Fab', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Fab', options, this.el); | ||
@@ -61,4 +61,4 @@ this.setup(); | ||
this.#isActive = false; | ||
this.#trigger = document.querySelector(`#${this.el.id} .fab-trigger`); | ||
this.#fabMenu = document.querySelector(`#${this.el.id} .fab-menu`); | ||
this.#trigger = getTriggers(this.el.id)[0]; | ||
this.#fabMenu = this.el.querySelector('.fab-menu'); | ||
@@ -65,0 +65,0 @@ this.#verifOptions(); |
@@ -1,3 +0,1 @@ | ||
import { config } from '../../utils/config'; | ||
const checkBrowserValidity = (input: HTMLInputElement): boolean | string => { | ||
@@ -29,3 +27,3 @@ return input.checkValidity() || input.validationMessage; | ||
export const validateInput = (input: HTMLInputElement, eType: string): boolean => { | ||
const advancedMode = input.getAttribute(`${config.prefix}-form-validate`); | ||
const advancedMode = input.getAttribute('data-form-validate'); | ||
let auto = false; | ||
@@ -61,3 +59,3 @@ | ||
export const validateAll = (form: HTMLFormElement, reset?: boolean): boolean => { | ||
const inputs = form.querySelectorAll(`[${config.prefix}-form-validate]`); | ||
const inputs = form.querySelectorAll(`[data-form-validate]`); | ||
if (reset) { | ||
@@ -64,0 +62,0 @@ inputs.forEach((input) => resetInputValidation(input.closest('.form-field'))); |
@@ -1,2 +0,2 @@ | ||
import { getCssVar, config } from '../../utils/config'; | ||
import { getCssVar } from '../../utils/config'; | ||
import { validateInput } from './forms-validation'; | ||
@@ -32,12 +32,15 @@ | ||
const formField = input.closest('.form-field'); | ||
const customSelect = formField.querySelector('.form-custom-select'); | ||
const isActive = formField.classList.contains('active'); | ||
const hasContent = | ||
input.value.length > 0 || | ||
(input.tagName !== 'SELECT' && input.placeholder.length > 0) || | ||
input.tagName === 'SELECT' || | ||
input.matches('[type="date"]') || | ||
input.matches('[type="month"]') || | ||
input.matches('[type="week"]') || | ||
input.matches('[type="time"]'); | ||
const types = ['date', 'month', 'week', 'time']; | ||
let hasContent = customSelect && input.tagName === 'DIV' && input.innerText.length > 0; | ||
if (!customSelect) | ||
hasContent = | ||
input.value.length > 0 || | ||
(input.tagName !== 'SELECT' && input.placeholder.length > 0) || | ||
input.tagName === 'SELECT' || | ||
types.some((type) => input.matches(`[type="${type}"]`)); | ||
const isFocused = document.activeElement === input; | ||
@@ -47,7 +50,7 @@ const isDisabled = input.hasAttribute('disabled') || input.hasAttribute('readonly'); | ||
if (input.firstInit) { | ||
updateInput(input, isActive, hasContent, isFocused, formField); | ||
updateInput(input, isActive, hasContent, isFocused, formField, customSelect); | ||
input.firstInit = false; | ||
input.isInit = true; | ||
} else { | ||
if (!isDisabled) updateInput(input, isActive, hasContent, isFocused, formField); | ||
if (!isDisabled) updateInput(input, isActive, hasContent, isFocused, formField, customSelect); | ||
} | ||
@@ -59,4 +62,12 @@ }; | ||
*/ | ||
const updateInput = (input: any, isActive: boolean, hasContent: boolean, isFocused: boolean, formField) => { | ||
const updateInput = ( | ||
input: any, | ||
isActive: boolean, | ||
hasContent: boolean, | ||
isFocused: boolean, | ||
formField, | ||
customSelect: HTMLDivElement | ||
) => { | ||
const isTextArea = input.type === 'textarea'; | ||
const label = formField.querySelector('label:not(.form-check)'); | ||
@@ -69,6 +80,7 @@ if (!isActive && (hasContent || isFocused)) { | ||
if (!isTextArea) setFormPosition(input, formField); | ||
if (!isTextArea) setFormPosition(input, formField, customSelect, label); | ||
else if (label) label.style.backgroundColor = getLabelColor(label); | ||
if (isFocused && !isTextArea) formField.classList.add('is-focused'); | ||
else formField.classList.remove('is-focused'); | ||
else if (!customSelect) formField.classList.remove('is-focused'); | ||
@@ -82,7 +94,13 @@ if (isFocused && isTextArea) formField.classList.add('is-textarea-focused'); | ||
*/ | ||
const setFormPosition = (input: HTMLElement, formField: HTMLElement) => { | ||
const setFormPosition = ( | ||
input: HTMLElement, | ||
formField: HTMLElement, | ||
customSelect: HTMLDivElement, | ||
label?: HTMLLabelElement | ||
) => { | ||
const inputWidth = input.clientWidth, | ||
inputLeftOffset = input.offsetLeft; | ||
const topOffset = input.clientHeight + input.offsetTop + 'px'; | ||
const topOffset = input.clientHeight + (customSelect ? customSelect.offsetTop : input.offsetTop) + 'px'; | ||
const isBordered = input.closest('.form-material').classList.contains('form-material-bordered'); | ||
@@ -106,8 +124,25 @@ formField.style.setProperty(getCssVar('form-material-position'), topOffset); | ||
const label = formField.querySelector('label'); | ||
if (label) label.style.left = labelLeft + 'px'; | ||
if (label) { | ||
label.style.left = labelLeft + 'px'; | ||
if (isBordered) label.style.backgroundColor = getLabelColor(label); | ||
} | ||
}; | ||
const getLabelColor = (label) => { | ||
let target: HTMLElement = label; | ||
while (target.parentElement) { | ||
let bg = window.getComputedStyle(target).backgroundColor; | ||
if (bg && !['transparent', 'rgba(0, 0, 0, 0)'].includes(bg)) { | ||
return bg; | ||
} | ||
target = target.parentElement; | ||
} | ||
return 'white'; | ||
}; | ||
const validate = (input: HTMLInputElement, e: Event) => { | ||
if (input.hasAttribute(`${config.prefix}-form-validate`)) validateInput(input, e.type); | ||
if (input.hasAttribute(`data-form-validate`)) validateInput(input, e.type); | ||
}; | ||
@@ -195,3 +230,5 @@ | ||
export const updateInputs = ( | ||
inputElements = document.querySelectorAll('.form-material .form-field:not(.form-default) .form-control') | ||
inputElements: NodeListOf<HTMLElement> | Array<HTMLElement> = document.querySelectorAll( | ||
'.form-material .form-field:not(.form-default) .form-control:not(.form-custom-select)' | ||
) | ||
) => { | ||
@@ -198,0 +235,0 @@ const { setupInputs, detectInputs } = Array.from(inputElements).reduce( |
@@ -26,19 +26,20 @@ import { AxentixComponent, Component } from '../../utils/component'; | ||
#openOnClickRef: any; | ||
#closeEventRef: any; | ||
#onClickRef: any; | ||
#transitionEndEventRef: any; | ||
#keyUpRef: any; | ||
#scrollRef: any; | ||
#resizeRef: any; | ||
#overlay: HTMLElement; | ||
#overlayClickEventRef: any; | ||
#overflowParents: Array<HTMLElement>; | ||
#basicWidth = 0; | ||
#basicHeight = 0; | ||
#newTop = 0; | ||
#newLeft = 0; | ||
#baseRect: DOMRect; | ||
#newHeight = 0; | ||
#newWidth = 0; | ||
#isActive = false; | ||
#isAnimated = false; | ||
#isResponsive = false; | ||
#container: HTMLDivElement; | ||
#isClosing = false; | ||
#isOpening = false; | ||
constructor(element: string, options?: ILightboxOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: ILightboxOptions) { | ||
super(); | ||
@@ -52,3 +53,3 @@ | ||
this.options = getComponentOptions('Lightbox', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Lightbox', options, this.el); | ||
@@ -71,23 +72,38 @@ this.setup(); | ||
setupListeners() { | ||
this.#openOnClickRef = this.open.bind(this); | ||
this.el.addEventListener('click', this.#openOnClickRef); | ||
this.#onClickRef = this.#onClickTrigger.bind(this); | ||
this.el.addEventListener('click', this.#onClickRef); | ||
this.#closeEventRef = this.close.bind(this); | ||
window.addEventListener('keyup', this.#closeEventRef); | ||
window.addEventListener('scroll', this.#closeEventRef); | ||
window.addEventListener('resize', this.#closeEventRef); | ||
this.#keyUpRef = this.#handleKeyUp.bind(this); | ||
this.#scrollRef = this.#handleScroll.bind(this); | ||
this.#resizeRef = this.#handleResize.bind(this); | ||
this.#transitionEndEventRef = this.#handleTransition.bind(this); | ||
window.addEventListener('keyup', this.#keyUpRef); | ||
window.addEventListener('scroll', this.#scrollRef); | ||
window.addEventListener('resize', this.#resizeRef); | ||
this.el.addEventListener('transitionend', this.#transitionEndEventRef); | ||
} | ||
removeListeners() { | ||
this.el.removeEventListener('click', this.#openOnClickRef); | ||
this.el.removeEventListener('click', this.#onClickRef); | ||
this.el.removeEventListener('transitionend', this.#transitionEndEventRef); | ||
window.removeEventListener('keyup', this.#closeEventRef); | ||
window.removeEventListener('scroll', this.#closeEventRef); | ||
window.removeEventListener('resize', this.#closeEventRef); | ||
window.removeEventListener('keyup', this.#keyUpRef); | ||
window.removeEventListener('scroll', this.#scrollRef); | ||
window.removeEventListener('resize', this.#resizeRef); | ||
this.#openOnClickRef = undefined; | ||
this.#closeEventRef = undefined; | ||
this.#onClickRef = undefined; | ||
this.#keyUpRef = undefined; | ||
this.#scrollRef = undefined; | ||
this.#resizeRef = undefined; | ||
this.#transitionEndEventRef = undefined; | ||
} | ||
#setOverlay() { | ||
if (this.#overlay) { | ||
return; | ||
} | ||
this.#setOverflowParents(); | ||
this.#overlay = document.createElement('div'); | ||
@@ -110,12 +126,15 @@ this.#overlay.style.transitionDuration = this.options.animationDuration + 'ms'; | ||
#showOverlay() { | ||
this.#overlay.style.opacity = '1'; | ||
setTimeout(() => { | ||
this.#overlay.style.opacity = '1'; | ||
}, 50); | ||
} | ||
#unsetOverlay() { | ||
#hideOverlay() { | ||
this.#overlay.style.opacity = '0'; | ||
} | ||
#unsetOverlay() { | ||
this.#overlay.removeEventListener('click', this.#overlayClickEventRef); | ||
setTimeout(() => { | ||
this.#overlay.remove(); | ||
}, this.options.animationDuration); | ||
this.#overlay.remove(); | ||
this.#overlay = null; | ||
} | ||
@@ -126,8 +145,8 @@ | ||
if (window.innerWidth / window.innerHeight >= this.#basicWidth / this.#basicHeight) { | ||
if (window.innerWidth / window.innerHeight >= this.#baseRect.width / this.#baseRect.height) { | ||
this.#newHeight = window.innerHeight - offset; | ||
this.#newWidth = (this.#newHeight * this.#basicWidth) / this.#basicHeight; | ||
this.#newWidth = (this.#newHeight * this.#baseRect.width) / this.#baseRect.height; | ||
} else { | ||
this.#newWidth = window.innerWidth - offset; | ||
this.#newHeight = (this.#newWidth * this.#basicHeight) / this.#basicWidth; | ||
this.#newHeight = (this.#newWidth * this.#baseRect.height) / this.#baseRect.width; | ||
} | ||
@@ -147,3 +166,3 @@ } | ||
this.#overflowParents.push(elem); | ||
elem.style.setProperty('overflow', 'visible', 'important'); | ||
if (elem !== document.body) elem.style.setProperty('overflow', 'visible', 'important'); | ||
document.body.style.overflowX = 'hidden'; | ||
@@ -159,62 +178,104 @@ } | ||
#handleTransition(e) { | ||
if (!e.propertyName.includes('width') && !e.propertyName.includes('height')) { | ||
return; | ||
} | ||
if (this.#isClosing) { | ||
this.#clearLightbox(); | ||
this.#isClosing = false; | ||
this.#isActive = false; | ||
createEvent(this.el, 'lightbox.closed'); | ||
} else if (this.#isOpening) { | ||
this.#isOpening = false; | ||
createEvent(this.el, 'lightbox.opened'); | ||
} | ||
} | ||
#handleKeyUp(e) { | ||
if (e.key === 'Escape' && (this.#isOpening || this.#isActive)) this.close(); | ||
} | ||
#handleScroll() { | ||
if (this.#isActive || this.#isOpening) this.close(); | ||
} | ||
#handleResize = () => { | ||
if (this.#isActive) this.close(); | ||
}; | ||
#clearLightbox() { | ||
this.el.classList.remove('active'); | ||
this.#unsetOverlay(); | ||
this.#unsetOverflowParents(); | ||
if (this.#isResponsive) this.el.classList.add('responsive-media'); | ||
this.#container.removeAttribute('style'); | ||
this.el.style.position = ''; | ||
this.el.style.left = ''; | ||
this.el.style.top = ''; | ||
this.el.style.width = ''; | ||
this.el.style.height = ''; | ||
this.el.style.transform = ''; | ||
} | ||
#onClickTrigger() { | ||
if (this.#isOpening || this.#isActive) { | ||
this.close(); | ||
return; | ||
} | ||
this.open(); | ||
} | ||
/** Open lightbox */ | ||
open() { | ||
if (this.#isActive) return this.close(); | ||
else if (this.#isAnimated) return; | ||
this.#isOpening = true; | ||
let rect: DOMRect, containerRect: DOMRect; | ||
this.#setOverflowParents(); | ||
if (this.#isClosing) { | ||
rect = containerRect = this.#container.getBoundingClientRect(); | ||
} else { | ||
rect = containerRect = this.el.getBoundingClientRect(); | ||
} | ||
this.#isClosing = false; | ||
this.#setOverlay(); | ||
this.#showOverlay(); | ||
const centerTop = window.innerHeight / 2; | ||
const centerLeft = window.innerWidth / 2; | ||
const rect = this.el.getBoundingClientRect(); | ||
const containerRect = this.el.getBoundingClientRect(); | ||
this.#baseRect = rect; | ||
this.el.style.width = this.#baseRect.width + 'px'; | ||
this.el.style.height = this.#baseRect.height + 'px'; | ||
this.#basicWidth = rect.width; | ||
this.el.style.width = this.#basicWidth + 'px'; | ||
this.#basicHeight = rect.height; | ||
this.el.style.height = this.#basicHeight + 'px'; | ||
this.el.style.top = '0'; | ||
this.el.style.left = '0'; | ||
this.#newTop = centerTop + window.scrollY - (containerRect.top + window.scrollY); | ||
this.#newLeft = centerLeft + window.scrollX - (containerRect.left + window.scrollX); | ||
const newTop = centerTop + window.scrollY - (containerRect.top + window.scrollY); | ||
const newLeft = centerLeft + window.scrollX - (containerRect.left + window.scrollX); | ||
this.#calculateRatio(); | ||
this.#container.style.position = 'relative'; | ||
this.#setOverlay(); | ||
setTimeout(() => { | ||
createEvent(this.el, 'lightbox.open'); | ||
this.#isActive = true; | ||
this.#isAnimated = true; | ||
this.el.classList.add('active'); | ||
if (this.el.classList.contains('responsive-media')) { | ||
this.#isResponsive = true; | ||
this.el.classList.remove('responsive-media'); | ||
this.#isResponsive = true; | ||
} else { | ||
this.#isResponsive = false; | ||
} | ||
this.el.classList.add('active'); | ||
this.#isActive = true; | ||
this.#container.style.width = this.#baseRect.width + 'px'; | ||
this.#container.style.height = this.#baseRect.height + 'px'; | ||
this.#showOverlay(); | ||
this.#container.style.width = this.#basicWidth + 'px'; | ||
this.#container.style.height = this.#basicHeight + 'px'; | ||
this.el.style.width = this.#newWidth + 'px'; | ||
this.el.style.height = this.#newHeight + 'px'; | ||
this.el.style.top = this.#newTop - this.#newHeight / 2 + 'px'; | ||
this.el.style.left = this.#newLeft - this.#newWidth / 2 + 'px'; | ||
this.#isAnimated = false; | ||
this.el.style.top = newTop - this.#newHeight / 2 + 'px'; | ||
this.el.style.left = newLeft - this.#newWidth / 2 + 'px'; | ||
}, 50); | ||
setTimeout(() => { | ||
createEvent(this.el, 'lightbox.opened'); | ||
}, this.options.animationDuration + 50); | ||
} | ||
@@ -224,34 +285,15 @@ | ||
close(e?: any) { | ||
if (!this.#isActive || (e && e.key && e.key !== 'Escape') || this.#isAnimated) return; | ||
if (e?.key && e.key !== 'Escape') return; | ||
this.#isActive = false; | ||
this.#isClosing = true; | ||
this.#isOpening = false; | ||
this.#isAnimated = true; | ||
this.el.style.top = '0'; | ||
this.el.style.left = '0'; | ||
this.el.style.width = this.#basicWidth + 'px'; | ||
this.el.style.height = this.#basicHeight + 'px'; | ||
this.#unsetOverlay(); | ||
createEvent(this.el, 'lightbox.close'); | ||
this.#hideOverlay(); | ||
setTimeout(() => { | ||
this.el.classList.remove('active'); | ||
if (this.#isResponsive) this.el.classList.add('responsive-media'); | ||
this.#container.removeAttribute('style'); | ||
this.el.style.left = ''; | ||
this.el.style.top = ''; | ||
this.el.style.width = ''; | ||
this.el.style.height = ''; | ||
this.el.style.transform = ''; | ||
this.#unsetOverflowParents(); | ||
this.#isActive = false; | ||
this.#isAnimated = false; | ||
createEvent(this.el, 'lightbox.closed'); | ||
}, this.options.animationDuration + 50); | ||
this.el.style.position = 'absolute'; | ||
this.el.style.top = '0px'; | ||
this.el.style.left = '0px'; | ||
this.el.style.width = this.#baseRect.width + 'px'; | ||
this.el.style.height = this.#baseRect.height + 'px'; | ||
} | ||
@@ -258,0 +300,0 @@ } |
import { AxentixComponent, Component } from '../../utils/component'; | ||
import { registerComponent, instances } from '../../utils/config'; | ||
import { createEvent, createOverlay, getComponentOptions, updateOverlay } from '../../utils/utilities'; | ||
import { | ||
createEvent, | ||
createOverlay, | ||
getComponentOptions, | ||
updateOverlay, | ||
getTriggers, | ||
} from '../../utils/utilities'; | ||
@@ -23,3 +29,3 @@ interface IModalOptions { | ||
#modalTriggers: NodeListOf<HTMLElement>; | ||
#triggers: Array<HTMLElement>; | ||
#isActive = false; | ||
@@ -29,3 +35,3 @@ #isAnimated = false; | ||
constructor(element: string, options?: IModalOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: IModalOptions) { | ||
super(); | ||
@@ -39,3 +45,3 @@ | ||
this.options = getComponentOptions('Modal', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Modal', options, this.el); | ||
@@ -50,3 +56,3 @@ this.setup(); | ||
createEvent(this.el, 'modal.setup'); | ||
this.#modalTriggers = document.querySelectorAll('.modal-trigger'); | ||
this.#triggers = getTriggers(this.el.id); | ||
this.#isActive = this.el.classList.contains('active') ? true : false; | ||
@@ -69,15 +75,7 @@ this.#isAnimated = false; | ||
this.#listenerRef = this.#onClickTrigger.bind(this); | ||
this.#modalTriggers.forEach((trigger) => { | ||
if (trigger.dataset.target === this.el.id) { | ||
trigger.addEventListener('click', this.#listenerRef); | ||
} | ||
}); | ||
this.#triggers.forEach((trigger) => trigger.addEventListener('click', this.#listenerRef)); | ||
} | ||
removeListeners() { | ||
this.#modalTriggers.forEach((trigger) => { | ||
if (trigger.dataset.target === this.el.id) { | ||
trigger.removeEventListener('click', this.#listenerRef); | ||
} | ||
}); | ||
this.#triggers.forEach((trigger) => trigger.removeEventListener('click', this.#listenerRef)); | ||
this.#listenerRef = undefined; | ||
@@ -84,0 +82,0 @@ } |
@@ -37,3 +37,3 @@ import { AxentixComponent, Component } from '../../utils/component'; | ||
constructor(element: string, options?: IScrollSpyOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: IScrollSpyOptions) { | ||
super(); | ||
@@ -47,3 +47,3 @@ | ||
this.options = getComponentOptions('ScrollSpy', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('ScrollSpy', options, this.el); | ||
@@ -50,0 +50,0 @@ this.setup(); |
@@ -9,2 +9,3 @@ import { registerComponent, instances } from '../../utils/config'; | ||
updateOverlay, | ||
getTriggers, | ||
} from '../../utils/utilities'; | ||
@@ -29,3 +30,3 @@ | ||
#sidenavTriggers: NodeListOf<HTMLElement>; | ||
#triggers: Array<HTMLElement>; | ||
#isActive = false; | ||
@@ -41,3 +42,3 @@ #isAnimated = false; | ||
constructor(element: string, options?: ISidenavOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: ISidenavOptions) { | ||
super(); | ||
@@ -51,3 +52,3 @@ | ||
this.options = getComponentOptions('Sidenav', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Sidenav', options, this.el); | ||
@@ -62,3 +63,3 @@ this.setup(); | ||
createEvent(this.el, 'sidenav.setup'); | ||
this.#sidenavTriggers = document.querySelectorAll('.sidenav-trigger'); | ||
this.#triggers = getTriggers(this.el.id); | ||
this.#isActive = false; | ||
@@ -93,5 +94,4 @@ this.#isAnimated = false; | ||
this.#listenerRef = this.#onClickTrigger.bind(this); | ||
this.#sidenavTriggers.forEach((trigger) => { | ||
if (trigger.dataset.target === this.el.id) trigger.addEventListener('click', this.#listenerRef); | ||
}); | ||
this.#triggers.forEach((trigger) => trigger.addEventListener('click', this.#listenerRef)); | ||
this.#windowResizeRef = this.#resizeHandler.bind(this); | ||
@@ -102,6 +102,5 @@ window.addEventListener('resize', this.#windowResizeRef); | ||
removeListeners() { | ||
this.#sidenavTriggers.forEach((trigger) => { | ||
if (trigger.dataset.target === this.el.id) trigger.removeEventListener('click', this.#listenerRef); | ||
}); | ||
this.#triggers.forEach((trigger) => trigger.removeEventListener('click', this.#listenerRef)); | ||
this.#listenerRef = undefined; | ||
window.removeEventListener('resize', this.#windowResizeRef); | ||
@@ -108,0 +107,0 @@ this.#windowResizeRef = undefined; |
@@ -49,3 +49,3 @@ import { AxentixComponent, Component } from '../../utils/component'; | ||
constructor(element: string, options?: ITabOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: ITabOptions) { | ||
super(); | ||
@@ -59,3 +59,3 @@ | ||
this.options = getComponentOptions('Tab', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Tab', options, this.el); | ||
@@ -62,0 +62,0 @@ this.setup(); |
import { getCssVar, registerComponent, instances } from '../../utils/config'; | ||
import { createEvent, extend, getComponentOptions, getInstanceByType } from '../../utils/utilities'; | ||
import { createEvent, extend, getInstanceByType } from '../../utils/utilities'; | ||
@@ -59,3 +59,3 @@ interface IToastOptions { | ||
this.#content = content; | ||
this.options = getComponentOptions('Toast', options, '', true); | ||
this.options = extend(Toast.getDefaultOptions(), options); | ||
// @ts-ignore | ||
@@ -62,0 +62,0 @@ this.options.position = this.options.position.toLowerCase(); |
@@ -33,6 +33,7 @@ import { AxentixComponent, Component } from '../../utils/component'; | ||
#listenerResizeRef: any; | ||
#timeoutRef: any; | ||
#elRect: DOMRect; | ||
#tooltipRect: DOMRect; | ||
constructor(element: string, options?: ITooltipOptions, isLoadedWithData?: boolean) { | ||
constructor(element: string, options?: ITooltipOptions) { | ||
super(); | ||
@@ -45,3 +46,3 @@ | ||
this.el = document.querySelector(element); | ||
this.options = getComponentOptions('Tooltip', options, this.el, isLoadedWithData); | ||
this.options = getComponentOptions('Tooltip', options, this.el); | ||
@@ -78,4 +79,5 @@ this.setup(); | ||
this.setupListeners(); | ||
this.updatePosition(); | ||
this.updatePosition(); | ||
this.#tooltip.style.display = 'none'; | ||
} | ||
@@ -112,5 +114,5 @@ | ||
#setBasicPosition() { | ||
const isHorizontalSide = this.options.position == 'top' || this.options.position == 'bottom'; | ||
const isVerticalSide = this.options.position == 'top' || this.options.position == 'bottom'; | ||
if (isHorizontalSide) { | ||
if (isVerticalSide) { | ||
const top = this.options.position === 'top' ? this.#elRect.top : this.#elRect.top + this.#elRect.height; | ||
@@ -171,5 +173,7 @@ this.#tooltip.style.top = top + 'px'; | ||
show() { | ||
this.#tooltip.style.display = 'block'; | ||
this.updatePosition(); | ||
clearTimeout(this.#timeoutRef); | ||
setTimeout(() => { | ||
this.#timeoutRef = setTimeout(() => { | ||
createEvent(this.el, 'tooltip.show'); | ||
@@ -189,5 +193,10 @@ | ||
createEvent(this.el, 'tooltip.hide'); | ||
clearTimeout(this.#timeoutRef); | ||
this.#tooltip.style.transform = 'translate(0)'; | ||
this.#tooltip.style.opacity = '0'; | ||
this.#timeoutRef = setTimeout(() => { | ||
this.#tooltip.style.display = 'none'; | ||
}, this.options.animationDuration); | ||
} | ||
@@ -197,3 +206,3 @@ | ||
change(options?: ITooltipOptions) { | ||
this.options = getComponentOptions('Tooltip', options, this.el, true); | ||
this.options = getComponentOptions('Tooltip', options, this.el); | ||
@@ -200,0 +209,0 @@ if (!this.#positionList.includes(this.options.position)) this.options.position = 'top'; |
import { getPointerType, getUid } from '../../utils/utilities'; | ||
import { config, getCssVar } from '../../utils/config'; | ||
import { getCssVar } from '../../utils/config'; | ||
let pointerType = ''; | ||
const prefix = config.prefix; | ||
const targetMap = {}; | ||
@@ -25,8 +24,8 @@ const itemMap = {}; | ||
target.setAttribute(`${prefix}-waves-id`, id); | ||
container.classList.add(`${prefix}-waves-item-inner`); | ||
container.setAttribute(`${prefix}-waves-id`, id); | ||
target.setAttribute('data-waves-id', id); | ||
container.classList.add('data-waves-item-inner'); | ||
container.setAttribute('data-waves-id', id); | ||
el.classList.add(`${prefix}-waves-box`); | ||
el.setAttribute(`${prefix}-waves-id`, id); | ||
el.classList.add('data-waves-box'); | ||
el.setAttribute('data-waves-id', id); | ||
@@ -53,4 +52,4 @@ el.appendChild(container); | ||
waves.setAttribute(`${prefix}-waves-id`, id); | ||
waves.classList.add(`${prefix}-waves-item`); | ||
waves.setAttribute('data-waves-id', id); | ||
waves.classList.add('data-waves-item'); | ||
waves.setAttribute('style', style); | ||
@@ -65,3 +64,3 @@ | ||
target.removeAttribute(`${prefix}-waves-id`); | ||
target.removeAttribute('data-waves-id'); | ||
delete itemMap[id]; | ||
@@ -83,3 +82,3 @@ delete targetMap[id]; | ||
if (!item) item = createWaveItem(target); | ||
id = item.getAttribute(`${prefix}-waves-id`) || getUid(); | ||
id = item.getAttribute('data-waves-id') || getUid(); | ||
@@ -114,5 +113,5 @@ const container: HTMLElement = item.children[0]; | ||
if (target) return target; | ||
if (el.getAttribute(`${prefix}-waves`) !== null) return el; | ||
if (el.getAttribute('data-waves') !== null) return el; | ||
return el.closest(`[${prefix}-waves]`) || null; | ||
return el.closest('[data-waves]') || null; | ||
}; | ||
@@ -122,7 +121,7 @@ | ||
const el = e.target; | ||
const id = el.getAttribute(`${prefix}-waves-id`) || ''; | ||
const id = el.getAttribute('data-waves-id') || ''; | ||
const target = getTarget(el, id); | ||
if (!target || target.getAttribute('disabled')) return; | ||
const color = target.getAttribute(`${prefix}-waves`); | ||
const color = target.getAttribute('data-waves'); | ||
@@ -129,0 +128,0 @@ let { clientX, clientY } = e; |
@@ -32,2 +32,3 @@ // Core CSS | ||
export { Forms } from './components/forms/index'; | ||
export { Select } from './components/forms/select'; | ||
@@ -34,0 +35,0 @@ // Must be loaded at the end |
@@ -77,5 +77,4 @@ import { getComponentClass, getDataElements } from './config'; | ||
try { | ||
const options = formatOptions(component, el); | ||
const classDef = getComponentClass(component); | ||
new classDef(`#${el.id}`, options, true); | ||
new classDef(`#${el.id}`); | ||
} catch (error) { | ||
@@ -82,0 +81,0 @@ console.error('[Axentix] Data: Unable to load ' + component, error); |
@@ -14,8 +14,4 @@ import { instances, getComponentClass } from './config'; | ||
export const getComponentOptions = (component, options, el, isLoadedWithData) => | ||
extend( | ||
getComponentClass(component).getDefaultOptions(), | ||
isLoadedWithData ? {} : formatOptions(component, el), | ||
options | ||
); | ||
export const getComponentOptions = (component, options, el) => | ||
extend(getComponentClass(component).getDefaultOptions(), formatOptions(component, el), options); | ||
@@ -82,3 +78,3 @@ export const wrap = (target, wrapper = document.createElement('div')) => { | ||
isActive && overlay | ||
? document.querySelector('.ax-overlay[data-target="' + id + '"]') | ||
? document.querySelector(`.ax-overlay[data-target="${id}"]`) | ||
: document.createElement('div'); | ||
@@ -109,1 +105,4 @@ overlayElement.classList.add('ax-overlay'); | ||
}; | ||
export const getTriggers = (id: string, query = '[data-target="{ID}"]'): Array<HTMLElement> => | ||
Array.from(document.querySelectorAll(query.replace('{ID}', id))); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
945300
231
13956
0
7
117