Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ribajs/bs4

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ribajs/bs4 - npm Package Compare versions

Comparing version 1.9.0-alpha.0 to 1.9.0-alpha.1

src/binders/bs4-show-toast-on.binder.ts

58

package.json
{
"name": "@ribajs/bs4",
"description": "Bootstrap 4 module for Riba.js",
"version": "1.9.0-alpha.0",
"version": "1.9.0-alpha.1",
"author": "Pascal Garber <pascal@artandcode.studio>",

@@ -45,33 +45,41 @@ "contributors": [],

"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-object-rest-spread": "^7.9.5",
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/plugin-syntax-export-default-from": "^7.8.3",
"@babel/preset-env": "^7.9.5",
"@babel/preset-typescript": "^7.9.0",
"@babel/runtime-corejs3": "^7.9.2",
"@ribajs/tsconfig": "1.9.0-alpha.0",
"@babel/cli": "^7.10.4",
"@babel/core": "^7.10.4",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-proposal-object-rest-spread": "^7.10.4",
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
"@babel/plugin-syntax-export-default-from": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"@babel/preset-typescript": "^7.10.4",
"@babel/runtime": "^7.10.4",
"@babel/runtime-corejs3": "^7.10.4",
"@ribajs/eslint-config": "1.9.0-alpha.1",
"@ribajs/tsconfig": "1.9.0-alpha.1",
"@ribajs/types": "1.8.3",
"@types/jest": "^25.2.1",
"@typescript-eslint/eslint-plugin": "^2.29.0",
"@typescript-eslint/parser": "^2.29.0",
"@types/jest": "^26.0.4",
"@typescript-eslint/eslint-plugin": "^3.6.0",
"@typescript-eslint/parser": "^3.6.0",
"@yarnpkg/pnpify": "^2.1.0",
"babel-jest": "^26.1.0",
"babel-loader": "^8.1.0",
"babel-plugin-array-includes": "^2.0.3",
"core-js": "^3.6.5",
"eslint": "^6.8.0",
"jest": "^25.4.0",
"eslint": "^7.4.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.1.0",
"jest-extended": "^0.11.5",
"ts-jest": "^25.4.0",
"typescript": "^3.8.3",
"webpack": "^5.0.0-beta.15",
"webpack-cli": "^3.3.11"
"prettier": "^2.0.5",
"ts-jest": "^26.1.1",
"typescript": "^3.9.6",
"webpack": "^5.0.0-beta.22",
"webpack-cli": "^3.3.12"
},
"dependencies": {
"@ribajs/cache": "1.9.0-alpha.0",
"@ribajs/core": "1.9.0-alpha.0",
"@ribajs/extras": "1.9.0-alpha.0",
"@ribajs/utils": "1.9.0-alpha.0",
"bootstrap": "^4.4.1",
"@ribajs/cache": "1.9.0-alpha.1",
"@ribajs/core": "1.9.0-alpha.1",
"@ribajs/extras": "1.9.0-alpha.1",
"@ribajs/utils": "1.9.0-alpha.1",
"bootstrap": "^4.5.0",
"popper.js": "^1.16.1"

@@ -78,0 +86,0 @@ },

@@ -1,4 +0,4 @@

import { Binder, EventDispatcher } from '@ribajs/core';
import { CollapseService } from '../services/collapse.service';
import { onRoute } from '@ribajs/utils/src/url';
import { Binder, EventDispatcher } from "@ribajs/core";
import { CollapseService } from "../services/collapse.service";
import { onRoute } from "@ribajs/utils/src/url";

@@ -11,6 +11,6 @@ /**

export const collapseOnUrlBinder: Binder<string> = {
name: 'bs4-collapse-on-url',
name: "bs4-collapse-on-url",
routine(el: HTMLElement, url: string) {
const collapseService = new CollapseService(this.el, [], {toggle: false});
const dispatcher = new EventDispatcher('main');
const collapseService = new CollapseService(this.el, [], { toggle: false });
const dispatcher = new EventDispatcher("main");

@@ -26,4 +26,4 @@ const checkURL = (urlToCheck?: string) => {

dispatcher.on('newPageReady', () => checkURL(url));
dispatcher.on("newPageReady", () => checkURL(url));
},
};

@@ -1,4 +0,4 @@

import { Binder } from '@ribajs/core';
import { Binder } from "@ribajs/core";
// import { CollapseService } from '../services/collapse.service';
import { CollapseService } from '../services/collapse.service';
import { CollapseService } from "../services/collapse.service";

@@ -9,8 +9,9 @@ /**

export const collapseBinder: Binder<string> = {
name: 'bs4-collapse',
name: "bs4-collapse",
bind() {
console.warn('bs4-collapse is deprecated, use bs4-toggle-collapse-on-click instead.');
console.warn(
"bs4-collapse is deprecated, use bs4-toggle-collapse-on-click instead."
);
},
routine(el: HTMLElement, targetSelector: string) {
const targets = document.querySelectorAll<HTMLElement>(targetSelector);

@@ -21,6 +22,8 @@

targets.forEach((target) => {
collapseServices.push(new CollapseService(target, [el], {toggle: false }));
collapseServices.push(
new CollapseService(target, [el], { toggle: false })
);
});
el.addEventListener('click', (event) => {
el.addEventListener("click", (event) => {
event.preventDefault();

@@ -27,0 +30,0 @@ collapseServices.forEach((collapseService) => {

@@ -1,3 +0,3 @@

import { Binder } from '@ribajs/core';
import { DropdownService } from '../services/dropdown.service';
import { Binder } from "@ribajs/core";
import { DropdownService } from "../services/dropdown.service";

@@ -9,9 +9,9 @@ /**

export const dropdownBinder: Binder<string> = {
name: 'bs4-dropdown',
name: "bs4-dropdown",
routine(el: HTMLElement, option: any = {}) {
let toggler: HTMLButtonElement;
if (el.classList.contains('dropdown-toggle')) {
if (el.classList.contains("dropdown-toggle")) {
toggler = el as HTMLButtonElement;
} else {
toggler = el.querySelector('.dropdown-toggle') as HTMLButtonElement;
toggler = el.querySelector(".dropdown-toggle") as HTMLButtonElement;
}

@@ -25,3 +25,3 @@

toggler.addEventListener('click', () => {
toggler.addEventListener("click", () => {
dropdownService.toggle();

@@ -28,0 +28,0 @@ });

@@ -1,4 +0,4 @@

import { Binder, EventDispatcher } from '@ribajs/core';
import { CollapseService } from '../services/collapse.service';
import { onRoute } from '@ribajs/utils/src/url';
import { Binder, EventDispatcher } from "@ribajs/core";
import { CollapseService } from "../services/collapse.service";
import { onRoute } from "@ribajs/utils/src/url";

@@ -11,6 +11,6 @@ /**

export const expanOnUrlBinder: Binder<string> = {
name: 'bs4-expan-on-url',
name: "bs4-expan-on-url",
routine(el: HTMLElement, url: string) {
const collapseService = new CollapseService(el, [], {toggle: false});
const dispatcher = new EventDispatcher('main');
const collapseService = new CollapseService(el, [], { toggle: false });
const dispatcher = new EventDispatcher("main");

@@ -26,3 +26,3 @@ const checkURL = (urlToCheck?: string) => {

dispatcher.on('newPageReady', () => checkURL(url));
dispatcher.on("newPageReady", () => checkURL(url));

@@ -29,0 +29,0 @@ checkURL(url);

@@ -1,3 +0,3 @@

import { Binder } from '@ribajs/core';
import { debounce } from '@ribajs/utils/src/control';
import { Binder } from "@ribajs/core";
import { debounce } from "@ribajs/utils/src/control";

@@ -9,3 +9,3 @@ /**

export const scrollspyClassBinder: Binder<string> = {
name: 'bs4-scrollspy-*',
name: "bs4-scrollspy-*",
bind(el: HTMLElement) {

@@ -18,3 +18,3 @@ this.customData = {};

*/
this.customData.isInViewport = (elem: Element ): boolean => {
this.customData.isInViewport = (elem: Element): boolean => {
if (!elem) {

@@ -27,3 +27,4 @@ return false;

return (
distance.top + distance.height >= this.customData.offsetBottom && distance.bottom - distance.height <= this.customData.offsetTop
distance.top + distance.height >= this.customData.offsetBottom &&
distance.bottom - distance.height <= this.customData.offsetTop
);

@@ -50,3 +51,3 @@ };

el.classList.add(className);
if ((el as HTMLInputElement).type === 'radio') {
if ((el as HTMLInputElement).type === "radio") {
(el as HTMLInputElement).checked = true;

@@ -56,3 +57,3 @@ }

el.classList.remove(className);
if ((el as HTMLInputElement).type === 'radio') {
if ((el as HTMLInputElement).type === "radio") {
(el as HTMLInputElement).checked = false;

@@ -62,7 +63,11 @@ }

};
window.addEventListener('scroll', debounce(this.customData.onScroll.bind(this)), { passive: true });
window.addEventListener(
"scroll",
debounce(this.customData.onScroll.bind(this)),
{ passive: true }
);
this.customData.onScroll();
},
routine(el: HTMLElement, targetSelector: string) {
const nativeIDTargetSelector = targetSelector.replace('#', '');
const nativeIDTargetSelector = targetSelector.replace("#", "");
this.customData.target = document.getElementById(nativeIDTargetSelector);

@@ -72,4 +77,7 @@ this.customData.className = this.args[0] as string;

unbind() {
window.removeEventListener('scroll', debounce(this.customData.onScroll.bind(this)));
window.removeEventListener(
"scroll",
debounce(this.customData.onScroll.bind(this))
);
},
};

@@ -1,6 +0,5 @@

import { Binder } from '@ribajs/core';
import { Binder } from "@ribajs/core";
// import { CollapseService } from '../services/collapse.service';
import { CollapseService } from '../services/collapse.service';
import { CollapseService } from "../services/collapse.service";
export interface Bs4CollapseOnEventBinder extends Binder<boolean> {

@@ -13,6 +12,6 @@ onEvent: (event: Event) => void;

/**
*
*
*/
export const toggleCollapseOnEventBinder: Binder<string> = {
name: 'bs4-toggle-collapse-on-*',
name: "bs4-toggle-collapse-on-*",
collapseServices: [] as CollapseService[],

@@ -37,3 +36,2 @@ targets: null,

routine(el: HTMLElement, targetSelector: string) {
if (this.args === null) {

@@ -48,7 +46,11 @@ throw new Error("args is null");

if (self.targets.length <= 0) {
console.warn(`[toggleCollapseOnEventBinder] No element with selector "${targetSelector}" found.`);
console.warn(
`[toggleCollapseOnEventBinder] No element with selector "${targetSelector}" found.`
);
}
self.targets.forEach((target) => {
self.collapseServices.push(new CollapseService(target, [el], {toggle: false }));
self.collapseServices.push(
new CollapseService(target, [el], { toggle: false })
);
});

@@ -55,0 +57,0 @@

@@ -1,2 +0,2 @@

import Popper from 'popper.js'; // /dist/umd/popper
import Popper from "popper.js"; // /dist/umd/popper

@@ -8,14 +8,14 @@ /**

*/
import { Binder } from '@ribajs/core';
import { Binder } from "@ribajs/core";
const template = document.createElement('div');
template.classList.add('tooltip');
template.setAttribute('role', 'tooltip');
const template = document.createElement("div");
template.classList.add("tooltip");
template.setAttribute("role", "tooltip");
const arrow = document.createElement('div');
arrow.classList.add('arrow');
const arrow = document.createElement("div");
arrow.classList.add("arrow");
template.appendChild(arrow);
const inner = document.createElement('div');
inner.classList.add('tooltip-inner');
const inner = document.createElement("div");
inner.classList.add("tooltip-inner");
template.appendChild(inner);

@@ -27,3 +27,3 @@

export const tooltipBinder: Binder<string> = {
name: 'bs4-tooltip',
name: "bs4-tooltip",
block: false,

@@ -34,3 +34,8 @@ bind(el: HTMLUnknownElement) {

this.customData.show = () => {
const placement = (this.el.dataset.placement || 'top') as 'auto' | 'top' | 'right' | 'bottom' | 'left';
const placement = (this.el.dataset.placement || "top") as
| "auto"
| "top"
| "right"
| "bottom"
| "left";
const offset = 0;

@@ -44,9 +49,9 @@ this.customData.popper = new Popper(el, this.customData.tip, {

flip: {
behavior: 'flip',
behavior: "flip",
},
arrow: {
element: '.arrow',
element: ".arrow",
},
preventOverflow: {
boundariesElement: 'scrollParent',
boundariesElement: "scrollParent",
},

@@ -56,7 +61,7 @@ },

document.body.appendChild(this.customData.tip);
this.customData.tip.classList.add('show');
this.customData.tip.classList.add('bs-tooltip-' + placement);
this.customData.tip.classList.add("show");
this.customData.tip.classList.add("bs-tooltip-" + placement);
};
this.customData.hide = () => {
this.customData.tip.classList.remove('show');
this.customData.tip.classList.remove("show");
if (this.customData.popper) {

@@ -66,8 +71,10 @@ this.customData.popper.destroy();

};
el.addEventListener('mouseenter', this.customData.show);
el.addEventListener('mouseleave', this.customData.hide);
el.addEventListener("mouseenter", this.customData.show);
el.addEventListener("mouseleave", this.customData.hide);
},
routine(el: HTMLElement, text: string) {
const innerEl = this.customData.tip.querySelector('.tooltip-inner') as HTMLDivElement;
const innerEl = this.customData.tip.querySelector(
".tooltip-inner"
) as HTMLDivElement;
innerEl.innerHTML = text;

@@ -78,5 +85,5 @@ },

this.customData.hide();
this.el.removeEventListener('mouseenter', this.customData.show);
this.el.removeEventListener('mouseleave', this.customData.hide);
this.el.removeEventListener("mouseenter", this.customData.show);
this.el.removeEventListener("mouseleave", this.customData.hide);
},
};

@@ -1,10 +0,11 @@

export { collapseOnUrlBinder } from './bs4-collapse-on-url.binder';
export { collapseBinder } from './bs4-collapse.binder';
export { toggleCollapseOnEventBinder } from './bs4-toggle-collapse-on-event.binder';
export { dropdownBinder } from './bs4-dropdown.binder';
export { expanOnUrlBinder } from './bs4-expan-on-url.binder';
export { scrollspyClassBinder } from './bs4-scrollspy-class.binder';
export { tooltipBinder } from './bs4-tooltip.binder';
export { scrollToOnEventBinder } from './scroll-to-on-event.binder';
export { toggleAttributeBinder } from './toggle-attribute.binder';
export { toggleClassBinder } from './toggle-class.binder';
export { collapseOnUrlBinder } from "./bs4-collapse-on-url.binder";
export { collapseBinder } from "./bs4-collapse.binder";
export { toggleCollapseOnEventBinder } from "./bs4-toggle-collapse-on-event.binder";
export { dropdownBinder } from "./bs4-dropdown.binder";
export { expanOnUrlBinder } from "./bs4-expan-on-url.binder";
export { showToastOnEventBinder } from "./bs4-show-toast-on.binder";
export { scrollspyClassBinder } from "./bs4-scrollspy-class.binder";
export { tooltipBinder } from "./bs4-tooltip.binder";
export { scrollToOnEventBinder } from "./scroll-to-on-event.binder";
export { toggleAttributeBinder } from "./toggle-attribute.binder";
export { toggleClassBinder } from "./toggle-class.binder";

@@ -1,6 +0,6 @@

import { Binder } from '@ribajs/core';
import { scrollTo } from '@ribajs/utils/src/dom';
import { Binder } from "@ribajs/core";
import { scrollTo } from "@ribajs/utils/src/dom";
export const scrollToOnEventBinder: Binder<string> = {
name: 'scroll-to-on-*',
name: "scroll-to-on-*",
bind(el: HTMLUnknownElement) {

@@ -10,3 +10,5 @@ this.customData = {};

const offset = Number(el.dataset.offset || 0);
const scrollElement = el.dataset.scrollElement ? document.querySelector(el.dataset.scrollElement) : window;
const scrollElement = el.dataset.scrollElement
? document.querySelector(el.dataset.scrollElement)
: window;
scrollTo(this.customData.target, offset, scrollElement);

@@ -20,3 +22,3 @@ event.preventDefault();

if (this.args === null) {
throw new Error('args is null');
throw new Error("args is null");
}

@@ -23,0 +25,0 @@ const eventName = this.args[0] as string;

@@ -1,6 +0,6 @@

import { Binder, EventDispatcher } from '@ribajs/core';
import { Binder, EventDispatcher } from "@ribajs/core";
export interface Bs4ToggleAttribute extends Binder<boolean> {
toggleButtonEvents: EventDispatcher | null;
state: 'removed' | 'added';
state: "removed" | "added";
triggerState: () => void;

@@ -13,9 +13,7 @@ onToggle: () => void;

import {
TOGGLE_BUTTON, TOGGLE_ATTRIBUTE,
} from '../constants';
import { TOGGLE_BUTTON, TOGGLE_ATTRIBUTE } from "../constants";
/**
* Adds / removes the attribute on click on the bs4-toggle-button with the same id
* E.g. with this binder you can toggle a hidden attribute to show / hide the element
* E.g. with this binder you can toggle a hidden attribute to show / hide the element
* Events

@@ -26,8 +24,11 @@ * * `off`

export const toggleAttributeBinder: Binder<string> = {
name: 'bs4-toggle-attribute-*',
name: "bs4-toggle-attribute-*",
toggleButtonEvents: null,
state: 'off',
state: "off",
triggerState() {
const self = (this.binder || this) as Bs4ToggleAttribute;
self.toggleButtonEvents?.trigger(TOGGLE_BUTTON.eventNames.state, self.state);
self.toggleButtonEvents?.trigger(
TOGGLE_BUTTON.eventNames.state,
self.state
);
},

@@ -41,3 +42,3 @@ onToggle() {

const self = (this.binder || this) as Bs4ToggleAttribute;
if (self.state === 'removed') {
if (self.state === "removed") {
self.add.bind(this)(el);

@@ -52,4 +53,8 @@ } else {

el.removeAttribute(attributeName);
self.state = 'removed'
el.dispatchEvent(new CustomEvent(TOGGLE_ATTRIBUTE.elEventNames.removed, {detail: {attributeName}}));
self.state = "removed";
el.dispatchEvent(
new CustomEvent(TOGGLE_ATTRIBUTE.elEventNames.removed, {
detail: { attributeName },
})
);
self.triggerState();

@@ -60,6 +65,10 @@ },

const attributeName = this.args[0] as string;
el.setAttribute(attributeName, attributeName);
self.state = 'added';
el.dispatchEvent(new CustomEvent(TOGGLE_ATTRIBUTE.elEventNames.added, {detail: {attributeName}}));
self.state = "added";
el.dispatchEvent(
new CustomEvent(TOGGLE_ATTRIBUTE.elEventNames.added, {
detail: { attributeName },
})
);
self.triggerState();

@@ -70,3 +79,3 @@ },

const attributeName = this.args[0] as string;
self.state = el.hasAttribute(attributeName) ? 'added' : 'removed'
self.state = el.hasAttribute(attributeName) ? "added" : "removed";
},

@@ -76,4 +85,10 @@

const self = (this.binder || this) as Bs4ToggleAttribute;
self.toggleButtonEvents?.off(TOGGLE_BUTTON.eventNames.toggle, self.onToggle.bind(this));
self.toggleButtonEvents?.off(TOGGLE_BUTTON.eventNames.init, self.triggerState.bind(this));
self.toggleButtonEvents?.off(
TOGGLE_BUTTON.eventNames.toggle,
self.onToggle.bind(this)
);
self.toggleButtonEvents?.off(
TOGGLE_BUTTON.eventNames.init,
self.triggerState.bind(this)
);
},

@@ -86,14 +101,27 @@

if (oldId && toggleButton) {
toggleButton.off(TOGGLE_BUTTON.eventNames.toggle, self.onToggle.bind(this));
toggleButton.off(TOGGLE_BUTTON.eventNames.init, self.triggerState.bind(this));
toggleButton.off(
TOGGLE_BUTTON.eventNames.toggle,
self.onToggle.bind(this)
);
toggleButton.off(
TOGGLE_BUTTON.eventNames.init,
self.triggerState.bind(this)
);
}
if(!self.toggleButtonEvents) {
self.toggleButtonEvents = new EventDispatcher(TOGGLE_BUTTON.nsPrefix + newId);
if (!self.toggleButtonEvents) {
self.toggleButtonEvents = new EventDispatcher(
TOGGLE_BUTTON.nsPrefix + newId
);
toggleButton = self.toggleButtonEvents as EventDispatcher;
toggleButton.on(TOGGLE_BUTTON.eventNames.toggle, self.onToggle.bind(this));
toggleButton.on(TOGGLE_BUTTON.eventNames.init, self.triggerState.bind(this));
toggleButton.on(
TOGGLE_BUTTON.eventNames.toggle,
self.onToggle.bind(this)
);
toggleButton.on(
TOGGLE_BUTTON.eventNames.init,
self.triggerState.bind(this)
);
}
},
};

@@ -1,6 +0,6 @@

import { Binder, EventDispatcher } from '@ribajs/core';
import { Binder, EventDispatcher } from "@ribajs/core";
export interface Bs4ToggleClass extends Binder<boolean> {
toggleButtonEvents: EventDispatcher | null;
state: 'removed' | 'added';
state: "removed" | "added";
triggerState: () => void;

@@ -13,5 +13,3 @@ onToggle: () => void;

import {
TOGGLE_BUTTON, TOGGLE_CLASS,
} from '../constants';
import { TOGGLE_BUTTON, TOGGLE_CLASS } from "../constants";

@@ -26,8 +24,11 @@ /**

export const toggleClassBinder: Binder<string> = {
name: 'bs4-toggle-class-*',
name: "bs4-toggle-class-*",
toggleButtonEvents: null,
state: 'off',
state: "off",
triggerState() {
const self = (this.binder || this) as Bs4ToggleClass;
self.toggleButtonEvents?.trigger(TOGGLE_BUTTON.eventNames.state, self.state);
self.toggleButtonEvents?.trigger(
TOGGLE_BUTTON.eventNames.state,
self.state
);
},

@@ -41,3 +42,3 @@ onToggle() {

const self = (this.binder || this) as Bs4ToggleClass;
if (self.state === 'removed') {
if (self.state === "removed") {
self.add.bind(this)(el);

@@ -52,4 +53,8 @@ } else {

el.classList.remove(className);
self.state = 'removed'
el.dispatchEvent(new CustomEvent(TOGGLE_CLASS.elEventNames.removed, {detail: {className}}));
self.state = "removed";
el.dispatchEvent(
new CustomEvent(TOGGLE_CLASS.elEventNames.removed, {
detail: { className },
})
);
self.triggerState();

@@ -60,6 +65,10 @@ },

const className = this.args[0] as string;
el.classList.add(className, className);
self.state = 'added';
el.dispatchEvent(new CustomEvent(TOGGLE_CLASS.elEventNames.added, {detail: {className}}));
self.state = "added";
el.dispatchEvent(
new CustomEvent(TOGGLE_CLASS.elEventNames.added, {
detail: { className },
})
);
self.triggerState();

@@ -70,3 +79,3 @@ },

const className = this.args[0] as string;
self.state = el.classList.contains(className) ? 'added' : 'removed'
self.state = el.classList.contains(className) ? "added" : "removed";
},

@@ -76,4 +85,10 @@

const self = (this.binder || this) as Bs4ToggleClass;
self.toggleButtonEvents?.off(TOGGLE_BUTTON.eventNames.toggle, self.onToggle.bind(this));
self.toggleButtonEvents?.off(TOGGLE_BUTTON.eventNames.init, self.triggerState.bind(this));
self.toggleButtonEvents?.off(
TOGGLE_BUTTON.eventNames.toggle,
self.onToggle.bind(this)
);
self.toggleButtonEvents?.off(
TOGGLE_BUTTON.eventNames.init,
self.triggerState.bind(this)
);
},

@@ -86,14 +101,27 @@

if (oldId && toggleButton) {
toggleButton.off(TOGGLE_BUTTON.eventNames.toggle, self.onToggle.bind(this));
toggleButton.off(TOGGLE_BUTTON.eventNames.init, self.triggerState.bind(this));
toggleButton.off(
TOGGLE_BUTTON.eventNames.toggle,
self.onToggle.bind(this)
);
toggleButton.off(
TOGGLE_BUTTON.eventNames.init,
self.triggerState.bind(this)
);
}
if(!self.toggleButtonEvents) {
self.toggleButtonEvents = new EventDispatcher(TOGGLE_BUTTON.nsPrefix + newId);
if (!self.toggleButtonEvents) {
self.toggleButtonEvents = new EventDispatcher(
TOGGLE_BUTTON.nsPrefix + newId
);
toggleButton = self.toggleButtonEvents as EventDispatcher;
toggleButton.on(TOGGLE_BUTTON.eventNames.toggle, self.onToggle.bind(this));
toggleButton.on(TOGGLE_BUTTON.eventNames.init, self.triggerState.bind(this));
toggleButton.on(
TOGGLE_BUTTON.eventNames.toggle,
self.onToggle.bind(this)
);
toggleButton.on(
TOGGLE_BUTTON.eventNames.init,
self.triggerState.bind(this)
);
}
},
};

@@ -0,8 +1,7 @@

import { RibaModule } from "@ribajs/core";
import { RibaModule } from '@ribajs/core';
import * as binders from './binders';
import * as components from './components';
import * as binders from "./binders";
import * as components from "./components";
// import * as formatters from './formatters/bs4.formatters';
import * as services from './services';
import * as services from "./services";
export const bs4Module: RibaModule = {

@@ -9,0 +8,0 @@ binders,

@@ -0,9 +1,11 @@

import { handleizeFormatter } from "@ribajs/core";
import {
handleizeFormatter,
} from '@ribajs/core';
import { CollapseService, EVENT_HIDE, EVENT_SHOW } from '../../services/collapse.service';
CollapseService,
EVENT_HIDE,
EVENT_SHOW,
} from "../../services/collapse.service";
import { TemplatesComponent } from '../templates/templates.component';
import { TemplatesComponent } from "../templates/templates.component";
import template from './bs4-accordion.component.html';
import template from "./bs4-accordion.component.html";

@@ -14,3 +16,11 @@ interface AccordionItem {

show: boolean;
iconDirection: 'left' | 'left-up' | 'up' | 'up-right' | 'right' | 'right-down' | 'down' | 'down-left';
iconDirection:
| "left"
| "left-up"
| "up"
| "up-right"
| "right"
| "right-down"
| "down"
| "down-left";
}

@@ -20,13 +30,13 @@

items: AccordionItem[];
toggle: Bs4AccordionComponent['toggle'];
show: Bs4AccordionComponent['show'];
hide: Bs4AccordionComponent['hide'];
toggle: Bs4AccordionComponent["toggle"];
show: Bs4AccordionComponent["show"];
hide: Bs4AccordionComponent["hide"];
collapseIconSrc?: string;
collapseIconSize: number;
showOnlyOne: boolean;
}
export class Bs4AccordionComponent extends TemplatesComponent {
public static tagName = "bs4-accordion";
public static tagName = 'bs4-accordion';
protected autobind = true;

@@ -36,11 +46,11 @@

{
name: 'title',
name: "title",
required: true,
},
{
name: 'show',
name: "show",
required: false,
},
{
name: 'icon-direction',
name: "icon-direction",
required: false,

@@ -53,3 +63,3 @@ },

static get observedAttributes() {
return ['collapse-icon-src', 'collapse-icon-size'];
return ["collapse-icon-src", "collapse-icon-size", "show-only-one"];
}

@@ -63,2 +73,3 @@

collapseIconSize: 16,
showOnlyOne: true,
};

@@ -71,6 +82,8 @@

public hide(item: AccordionItem, index: number) {
const target = this.el.querySelector<HTMLElement>(`[data-index="${index}"]`);
const target = this.el.querySelector<HTMLElement>(
`[data-index="${index}"]`
);
if (target) {
this.initItemEventListeners(item, target);
new CollapseService(target, [this.el], {toggle: false}).hide();
new CollapseService(target, [this.el], { toggle: false }).hide();
}

@@ -80,7 +93,13 @@ }

public show(item: AccordionItem, index: number) {
const target = this.el.querySelector<HTMLElement>(`[data-index="${index}"]`);
const others = Array.from(this.el.querySelectorAll<HTMLElement>(`[data-index]:not([data-index="${index}"])`));
if (others) {
const target = this.el.querySelector<HTMLElement>(
`[data-index="${index}"]`
);
const others = Array.from(
this.el.querySelectorAll<HTMLElement>(
`[data-index]:not([data-index="${index}"])`
)
);
if (others && this.scope.showOnlyOne) {
for (const other of others) {
new CollapseService(other, [], {toggle: false}).hide();
new CollapseService(other, [], { toggle: false }).hide();
}

@@ -90,3 +109,3 @@ }

this.initItemEventListeners(item, target);
new CollapseService(target, [], {toggle: false}).show();
new CollapseService(target, [], { toggle: false }).show();
}

@@ -96,7 +115,13 @@ }

public toggle(item: AccordionItem, index: number) {
const target = this.el.querySelector<HTMLElement>(`[data-index="${index}"]`);
const others = Array.from(this.el.querySelectorAll<HTMLElement>(`[data-index]:not([data-index="${index}"])`));
if (others) {
const target = this.el.querySelector<HTMLElement>(
`[data-index="${index}"]`
);
const others = Array.from(
this.el.querySelectorAll<HTMLElement>(
`[data-index]:not([data-index="${index}"])`
)
);
if (others && this.scope.showOnlyOne) {
for (const other of others) {
new CollapseService(other, [], {toggle: false}).hide();
new CollapseService(other, [], { toggle: false }).hide();
}

@@ -106,3 +131,3 @@ }

this.initItemEventListeners(item, target);
new CollapseService(target, [], {toggle: false}).toggle();
new CollapseService(target, [], { toggle: false }).toggle();
}

@@ -112,6 +137,20 @@ }

protected initItemEventListeners(item: AccordionItem, element: HTMLElement) {
element.removeEventListener(EVENT_HIDE, this.onHide.bind(this, element, item));
element.removeEventListener(EVENT_SHOW, this.onShow.bind(this, element, item));
element.addEventListener(EVENT_HIDE, this.onHide.bind(this, element, item), { once: true });
element.addEventListener(EVENT_SHOW, this.onShow.bind(this, element, item), { once: true });
element.removeEventListener(
EVENT_HIDE,
this.onHide.bind(this, element, item)
);
element.removeEventListener(
EVENT_SHOW,
this.onShow.bind(this, element, item)
);
element.addEventListener(
EVENT_HIDE,
this.onHide.bind(this, element, item),
{ once: true }
);
element.addEventListener(
EVENT_SHOW,
this.onShow.bind(this, element, item),
{ once: true }
);
}

@@ -125,3 +164,3 @@

item.show = true;
item.iconDirection = 'up';
item.iconDirection = "up";
const firstContentChild = this.getContentChildByIndex();

@@ -135,3 +174,3 @@ if (firstContentChild) {

item.show = false;
item.iconDirection = 'down';
item.iconDirection = "down";
const firstContentChild = this.getContentChildByIndex();

@@ -144,5 +183,7 @@ if (firstContentChild) {

protected transformTemplateAttributes(attributes: any) {
attributes.handle = attributes.handle || handleizeFormatter.read(attributes.title);
attributes.handle =
attributes.handle || handleizeFormatter.read(attributes.title);
attributes.show = !!attributes.show;
attributes.iconDirection = attributes.iconDirection || attributes.show ? 'up' : 'down';
attributes.iconDirection =
attributes.iconDirection || attributes.show ? "up" : "down";

@@ -155,9 +196,14 @@ return attributes;

* Se also bsf-tabs
* @param element
* @param visibile
* @param element
* @param visibile
*/
protected triggerVisibilityChangedForElement(element: Element, visibile: boolean) {
protected triggerVisibilityChangedForElement(
element: Element,
visibile: boolean
) {
setTimeout(() => {
// Use this event to update any custom element when it becomes visibile
element.dispatchEvent(new CustomEvent('visibility-changed', {detail: {visibile}}));
element.dispatchEvent(
new CustomEvent("visibility-changed", { detail: { visibile } })
);
}, 200);

@@ -172,4 +218,3 @@ }

protected async init(observedAttributes: string[]) {
return super.init(observedAttributes)
.then((view) => {
return super.init(observedAttributes).then((view) => {
return view;

@@ -191,4 +236,14 @@ });

protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
protected parsedAttributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.parsedAttributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
}

@@ -195,0 +250,0 @@

@@ -1,22 +0,19 @@

import {
Component,
} from '@ribajs/core';
import { Component } from "@ribajs/core";
interface Scope {
animationClass: string;
onClick: Bs4ButtonComponent['onClick'];
onClick: Bs4ButtonComponent["onClick"];
}
export class Bs4ButtonComponent extends Component {
public static tagName = "bs4-button";
public static tagName = 'bs4-button';
protected autobind = true;
static get observedAttributes() {
return ['animation-class'];
return ["animation-class"];
}
protected scope: Scope = {
animationClass: 'btn-animation-start',
animationClass: "btn-animation-start",
onClick: this.onClick,

@@ -58,9 +55,17 @@ };

protected async init(observedAttributes: string[]) {
return super.init(observedAttributes)
.then((view) => {
this.el.addEventListener('webkitAnimationStart' as 'animationstart', this.onStartAnimation.bind(this));
this.el.addEventListener('animationstart', this.onStartAnimation.bind(this));
this.el.addEventListener('webkitAnimationEnd' as 'animationend', this.onEndAnimation.bind(this));
this.el.addEventListener('animationend', this.onEndAnimation.bind(this));
this.el.addEventListener('click', this.onClick.bind(this));
return super.init(observedAttributes).then((view) => {
this.el.addEventListener(
"webkitAnimationStart" as "animationstart",
this.onStartAnimation.bind(this)
);
this.el.addEventListener(
"animationstart",
this.onStartAnimation.bind(this)
);
this.el.addEventListener(
"webkitAnimationEnd" as "animationend",
this.onEndAnimation.bind(this)
);
this.el.addEventListener("animationend", this.onEndAnimation.bind(this));
this.el.addEventListener("click", this.onClick.bind(this));
return view;

@@ -84,4 +89,14 @@ });

protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
protected parsedAttributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.parsedAttributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
}

@@ -92,7 +107,16 @@

super.disconnectedCallback();
this.el.removeEventListener('webkitAnimationStart' as 'animationstart', this.onStartAnimation.bind(this));
this.el.removeEventListener('animationstart', this.onStartAnimation.bind(this));
this.el.removeEventListener('webkitAnimationEnd' as 'animationend', this.onEndAnimation.bind(this));
this.el.removeEventListener('animationend', this.onEndAnimation.bind(this));
this.el.removeEventListener('click', this.onClick.bind(this));
this.el.removeEventListener(
"webkitAnimationStart" as "animationstart",
this.onStartAnimation.bind(this)
);
this.el.removeEventListener(
"animationstart",
this.onStartAnimation.bind(this)
);
this.el.removeEventListener(
"webkitAnimationEnd" as "animationend",
this.onEndAnimation.bind(this)
);
this.el.removeEventListener("animationend", this.onEndAnimation.bind(this));
this.el.removeEventListener("click", this.onClick.bind(this));
}

@@ -99,0 +123,0 @@

@@ -1,31 +0,39 @@

import { Component } from '@ribajs/core';
import CarouselService from '../../services/carousel.service';
import { CarouselOption } from '../../interfaces'
import { Component } from "@ribajs/core";
import CarouselService from "../../services/carousel.service";
import { CarouselOption } from "../../interfaces";
export interface Scope {
// Properties
interval: CarouselOption['interval'];
keyboard: CarouselOption['keyboard'];
slide: CarouselOption['slide'];
pauseOn: CarouselOption['pause'];
wrap: CarouselOption['wrap'];
touch: CarouselOption['touch'];
ride: CarouselOption['ride']; // TODO
interval: CarouselOption["interval"];
keyboard: CarouselOption["keyboard"];
slide: CarouselOption["slide"];
pauseOn: CarouselOption["pause"];
wrap: CarouselOption["wrap"];
touch: CarouselOption["touch"];
ride: CarouselOption["ride"]; // TODO
fade: boolean;
// Methods
next: Bs4CarouselComponent['next'];
nextWhenVisible: Bs4CarouselComponent['nextWhenVisible'];
prev: Bs4CarouselComponent['prev'];
pause: Bs4CarouselComponent['pause'];
cycle: Bs4CarouselComponent['cycle'];
to: Bs4CarouselComponent['to'];
dispose: Bs4CarouselComponent['dispose'];
next: Bs4CarouselComponent["next"];
nextWhenVisible: Bs4CarouselComponent["nextWhenVisible"];
prev: Bs4CarouselComponent["prev"];
pause: Bs4CarouselComponent["pause"];
cycle: Bs4CarouselComponent["cycle"];
to: Bs4CarouselComponent["to"];
dispose: Bs4CarouselComponent["dispose"];
}
export class Bs4CarouselComponent extends Component {
public static tagName = "bs4-carousel";
public static tagName = 'bs4-carousel';
static get observedAttributes() {
return ['interval', 'keyboard', 'slide', 'pauseOn', 'wrap', 'touch', 'ride', 'fade'];
return [
"interval",
"keyboard",
"slide",
"pauseOn",
"wrap",
"touch",
"ride",
"fade",
];
}

@@ -67,3 +75,3 @@

await super.beforeBind();
this.el.classList.add('carousel', 'slide');
this.el.classList.add("carousel", "slide");
}

@@ -79,6 +87,6 @@

wrap: this.scope.wrap,
touch: this.scope.touch,
touch: this.scope.touch,
});
if (this.scope.fade) {
this.el.classList.add('carousel-fade');
this.el.classList.add("carousel-fade");
}

@@ -131,3 +139,8 @@ // TODO make this configurateable?

public attributeChangedCallback(name: string, oldValue: any, newValue: any, namespace: string | null) {
public attributeChangedCallback(
name: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.attributeChangedCallback(name, oldValue, newValue, namespace);

@@ -134,0 +147,0 @@ }

@@ -1,4 +0,4 @@

import { Component } from '@ribajs/core';
import { Component } from "@ribajs/core";
import template from './bs4-contents.component.html';
import template from "./bs4-contents.component.html";

@@ -44,5 +44,4 @@ export interface Anchor {

export class Bs4ContentsComponent extends Component {
public static tagName = "bs4-contents";
public static tagName = 'bs4-contents';
protected autobind = true;

@@ -53,3 +52,10 @@

static get observedAttributes() {
return ['headers-start', 'headers-depth', 'find-header-id-depth', 'header-parent-selector', 'scroll-offset', 'scroll-element'];
return [
"headers-start",
"headers-depth",
"find-header-id-depth",
"header-parent-selector",
"scroll-offset",
"scroll-element",
];
}

@@ -75,3 +81,6 @@

protected getIdFromElementOrParent(element: HTMLElement, depth = 1): string | null {
protected getIdFromElementOrParent(
element: HTMLElement,
depth = 1
): string | null {
if (element.id) {

@@ -88,4 +97,11 @@ return element.id;

protected pushHeaders(wrapperElement: Element, headersStart: number, headersDepth: number, pushTo: Anchor[]) {
const headerElements = wrapperElement.querySelectorAll('h' + headersStart) as NodeListOf<HTMLHeadingElement>;
protected pushHeaders(
wrapperElement: Element,
headersStart: number,
headersDepth: number,
pushTo: Anchor[]
) {
const headerElements = wrapperElement.querySelectorAll(
"h" + headersStart
) as NodeListOf<HTMLHeadingElement>;
headerElements.forEach((headerElement) => {

@@ -98,3 +114,3 @@ const id = this.getIdFromElementOrParent(headerElement);

element: headerElement,
href: '#' + id,
href: "#" + id,
title: headerElement.innerHTML,

@@ -104,3 +120,8 @@ childs: [],

if (headerElement.parentElement && headersDepth >= headersStart + 1) {
this.pushHeaders(headerElement.parentElement, headersStart + 1, headersDepth, pushTo[pushTo.length - 1].childs);
this.pushHeaders(
headerElement.parentElement,
headersStart + 1,
headersDepth,
pushTo[pushTo.length - 1].childs
);
}

@@ -116,10 +137,20 @@ });

await super.afterBind();
if (this.scope.headerParentSelector && this.scope.headersStart && this.scope.headersDepth) {
this.wrapperElement = document.querySelector(this.scope.headerParentSelector) || undefined;
if (
this.scope.headerParentSelector &&
this.scope.headersStart &&
this.scope.headersDepth
) {
this.wrapperElement =
document.querySelector(this.scope.headerParentSelector) || undefined;
this.scope.anchors = [];
if (!this.wrapperElement) {
console.error('No wrapper element found!');
console.error("No wrapper element found!");
return;
}
this.pushHeaders(this.wrapperElement, this.scope.headersStart, this.scope.headersDepth, this.scope.anchors);
this.pushHeaders(
this.wrapperElement,
this.scope.headersStart,
this.scope.headersDepth,
this.scope.anchors
);
}

@@ -129,7 +160,17 @@ }

protected requiredAttributes() {
return ['headersStart', 'headersDepth', 'headerParentSelector'];
return ["headersStart", "headersDepth", "headerParentSelector"];
}
protected attributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.attributeChangedCallback(attributeName, oldValue, newValue, namespace);
protected attributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.attributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
}

@@ -136,0 +177,0 @@

@@ -1,8 +0,7 @@

import { Component } from '@ribajs/core';
import { DropdownService } from '../../services/dropdown.service';
import { Component } from "@ribajs/core";
import { DropdownService } from "../../services/dropdown.service";
export class Bs4DropdownComponent extends Component {
public static tagName = "bs4-dropdown";
public static tagName = 'bs4-dropdown';
protected scope: any = {

@@ -26,3 +25,3 @@ toggle: this.toggle,

if (!this.dropdownService) {
throw new Error('DropdownService not ready!');
throw new Error("DropdownService not ready!");
}

@@ -34,3 +33,7 @@ return this.dropdownService.toggle();

super.connectedCallback();
this.dropdownService = new DropdownService(this.el.querySelector('.dropdown-toggle') as HTMLButtonElement | HTMLAnchorElement);
this.dropdownService = new DropdownService(
this.el.querySelector(".dropdown-toggle") as
| HTMLButtonElement
| HTMLAnchorElement
);
this.init(Bs4DropdownComponent.observedAttributes);

@@ -37,0 +40,0 @@ }

@@ -1,9 +0,8 @@

import { Component } from '@ribajs/core';
import { Component } from "@ribajs/core";
export class Bs4IconComponent extends Component {
public static tagName = "bs4-icon";
public static tagName = 'bs4-icon';
static get observedAttributes() {
return ['size', 'width', 'height', 'src', 'color', 'direction'];
return ["size", "width", "height", "src", "color", "direction"];
}

@@ -19,44 +18,67 @@

public attributeChangedCallback(name: string, oldValue: any, newValue: any, namespace: string | null) {
public attributeChangedCallback(
name: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
// injects the changed attributes to scope
super.attributeChangedCallback(name, oldValue, newValue, namespace);
if (name === 'src') {
if (name === "src") {
if (!newValue) {
console.warn('The src attribute must have a value!');
return '';
console.warn("The src attribute must have a value!", this.scope);
return "";
}
if (fetch) {
fetch(newValue)
.then((response) => {
// console.debug('response.headers.get("content-type")', response.headers.get('content-type'));
if (response.status !== 200) {
console.error(response.statusText);
return '';
}
if (response.headers.get('content-type')?.indexOf('image/svg+xml') !== -1) {
return response.text();
} else {
console.error('[bs4-icon] Only svg\'s are supported! But content-type is ' + response.headers.get('content-type'));
}
return '';
})
.then((response) => {
this.el.innerHTML = response;
})
.catch((error) => {
console.error(error);
});
.then((response) => {
// console.debug('response.headers.get("content-type")', response.headers.get('content-type'));
if (response.status !== 200) {
console.error(response.statusText);
return "";
}
if (
response.headers.get("content-type")?.indexOf("image/svg+xml") !==
-1
) {
return response.text();
} else {
console.error(
"[bs4-icon] Only svg's are supported! But content-type is " +
response.headers.get("content-type")
);
}
return "";
})
.then((response) => {
this.el.innerHTML = response;
})
.catch((error) => {
console.error(error);
});
}
}
if (name === "title") {
const title = document.createElementNS(
"http://www.w3.org/2000/svg",
"title"
);
title.textContent = newValue;
const svg = this.el.firstElementChild;
if (svg) {
svg.appendChild(title);
}
}
if (name === 'color') {
if (newValue.indexOf(',') !== -1) {
newValue = newValue.split(',');
if (name === "color") {
if (newValue.indexOf(",") !== -1) {
newValue = newValue.split(",");
if (newValue.length > 0) {
this.el.className = this.el.className.replace(/(^|\s)color-\S+/g, '');
this.el.className = this.el.className.replace(/(^|\s)color-\S+/g, "");
for (let i = 0; i < newValue.length; i++) {
const newColor: string = newValue[i];
if (newColor.startsWith('#') || newColor.startsWith('rgb')) {
if (newColor.startsWith("#") || newColor.startsWith("rgb")) {
this.el.style.color = newColor;

@@ -69,3 +91,3 @@ }

this.el.style.color = newValue;
this.el.className = this.el.className.replace(/(^|\s)color-\S+/g, '');
this.el.className = this.el.className.replace(/(^|\s)color-\S+/g, "");
this.el.classList.add(`color-${newValue}`);

@@ -75,48 +97,68 @@ }

if (name === 'size') {
if (name === "size") {
const size = newValue;
this.el.style.height = size + 'px';
this.el.style.width = size + 'px';
this.el.className = this.el.className.replace(/(^|\s)size-\S+/g, '');
this.el.style.height = size + "px";
this.el.style.width = size + "px";
this.el.className = this.el.className.replace(/(^|\s)size-\S+/g, "");
this.el.classList.add(`size-${size}`);
}
if (name === 'width') {
if (name === "width") {
const width = newValue;
this.el.style.width = width + 'px';
this.el.className = this.el.className.replace(/(^|\s)width-\S+/g, '');
this.el.style.width = width + "px";
this.el.className = this.el.className.replace(/(^|\s)width-\S+/g, "");
this.el.classList.add(`width-${width}`);
}
if (name === 'height') {
if (name === "height") {
const height = newValue;
this.el.style.height = height + 'px';
this.el.className = this.el.className.replace(/(^|\s)height-\S+/g, '');
this.el.style.height = height + "px";
this.el.className = this.el.className.replace(/(^|\s)height-\S+/g, "");
this.el.classList.add(`height-${height}`);
}
if (name === 'direction') {
if (name === "direction") {
const direction = newValue;
let classString = `direction-${direction}`;
if (direction === 'left' ) {
classString += ' rotate-270';
} else if ( direction === 'left-top' || direction === 'left-up' || direction === 'top-left' || direction === 'up-left' ) {
classString += ' rotate-315' ;
} else if ( direction === 'top' || direction === 'up' ) {
classString += ' rotate-0';
} else if ( direction === 'top-right' || direction === 'up-right' || direction === 'right-top' || direction === 'right-up') {
classString += ' rotate-45';
} else if ( direction === 'right' ) {
classString += ' rotate-90';
} else if ( direction === 'right-bottom' || direction === 'right-down' || direction === 'bottom-right' || direction === 'down-right' ) {
classString += ' rotate-135';
} else if ( direction === 'bottom' || direction === 'down' ) {
classString += ' rotate-180';
} else if ( direction === 'left-bottom' || direction === 'left-down' || direction === 'bottom-left' || direction === 'down-left' ) {
classString += ' rotate-225';
if (direction === "left") {
classString += " rotate-270";
} else if (
direction === "left-top" ||
direction === "left-up" ||
direction === "top-left" ||
direction === "up-left"
) {
classString += " rotate-315";
} else if (direction === "top" || direction === "up") {
classString += " rotate-0";
} else if (
direction === "top-right" ||
direction === "up-right" ||
direction === "right-top" ||
direction === "right-up"
) {
classString += " rotate-45";
} else if (direction === "right") {
classString += " rotate-90";
} else if (
direction === "right-bottom" ||
direction === "right-down" ||
direction === "bottom-right" ||
direction === "down-right"
) {
classString += " rotate-135";
} else if (direction === "bottom" || direction === "down") {
classString += " rotate-180";
} else if (
direction === "left-bottom" ||
direction === "left-down" ||
direction === "bottom-left" ||
direction === "down-left"
) {
classString += " rotate-225";
}
this.el.className = this.el.className.replace(/(^|\s)direction-\S+/g, '');
this.el.className = this.el.className.replace(/(^|\s)rotate-\S+/g, '');
this.el.className += ' ' + classString;
this.el.className = this.el.className.replace(/(^|\s)direction-\S+/g, "");
this.el.className = this.el.className.replace(/(^|\s)rotate-\S+/g, "");
this.el.className += " " + classString;
}

@@ -127,10 +169,15 @@ }

super.connectedCallback();
this.el.setAttribute('aria-hidden', 'true');
this.el.setAttribute('role', 'img');
this.el.classList.add('iconset');
this.el.setAttribute("aria-hidden", "true");
this.el.setAttribute("role", "img");
this.el.classList.add("iconset");
this.init(Bs4IconComponent.observedAttributes);
// set default values
if (!this.scope.direction) {
this.scope.direction = 'up';
this.attributeChangedCallback('direction', null, this.scope.direction, null);
this.scope.direction = "up";
this.attributeChangedCallback(
"direction",
null,
this.scope.direction,
null
);
}

@@ -137,0 +184,0 @@ }

@@ -1,8 +0,12 @@

import { Component, EventDispatcher } from '@ribajs/core';
import { CollapseService, EVENT_SHOWN, EVENT_HIDDEN, CLASS_NAME_COLLAPSED } from '../../services/collapse.service';
import { Component, EventDispatcher } from "@ribajs/core";
import {
CollapseService,
EVENT_SHOWN,
EVENT_HIDDEN,
CLASS_NAME_COLLAPSED,
} from "../../services/collapse.service";
export class Bs4NavbarComponent extends Component {
public static tagName = "bs4-navbar";
public static tagName = 'bs4-navbar';
protected scope: any = {

@@ -13,3 +17,3 @@ toggle: this.toggle,

isCollapsed: true,
collapseSelector: '.navbar-collapse'
collapseSelector: ".navbar-collapse",
};

@@ -19,6 +23,6 @@

protected collapseServices: CollapseService[] = [];
protected router?: EventDispatcher;
protected routerEvents?: EventDispatcher;
static get observedAttributes() {
return ['collapse-selector'];
return ["collapse-selector"];
}

@@ -35,9 +39,7 @@

public toggle(event?: Event) {
for (const collapseService of this.collapseServices) {
collapseService.toggle();
}
if (event) {

@@ -71,4 +73,4 @@ event.preventDefault();

super.connectedCallback();
this.router = new EventDispatcher('main');
this.router.on('newPageReady', this.onNewPageReady.bind(this));
this.routerEvents = new EventDispatcher("main");
this.routerEvents.on("newPageReady", this.onNewPageReady.bind(this));

@@ -86,3 +88,4 @@ this.setCollapseElement();

this.collapseElements = this.el.querySelectorAll<HTMLElement>(this.scope.collapseSelector) || [];
this.collapseElements =
this.el.querySelectorAll<HTMLElement>(this.scope.collapseSelector) || [];

@@ -94,3 +97,5 @@ // Add new event listeners

for (const collapseElement of Array.from(this.collapseElements)) {
this.collapseServices.push(new CollapseService(collapseElement, [this.el], {toggle: false}));
this.collapseServices.push(
new CollapseService(collapseElement, [this.el], { toggle: false })
);
}

@@ -100,3 +105,2 @@ }

this.hide();
}

@@ -107,4 +111,10 @@

this.collapseElements.forEach((collapseElement: HTMLElement) => {
collapseElement.addEventListener(EVENT_SHOWN, this.onStateChange.bind(this));
collapseElement.addEventListener(EVENT_HIDDEN, this.onStateChange.bind(this));
collapseElement.addEventListener(
EVENT_SHOWN,
this.onStateChange.bind(this)
);
collapseElement.addEventListener(
EVENT_HIDDEN,
this.onStateChange.bind(this)
);
});

@@ -117,4 +127,10 @@ }

this.collapseElements.forEach((collapseElement: HTMLElement) => {
collapseElement.removeEventListener(EVENT_SHOWN, this.onStateChange.bind(this));
collapseElement.removeEventListener(EVENT_HIDDEN, this.onStateChange.bind(this));
collapseElement.removeEventListener(
EVENT_SHOWN,
this.onStateChange.bind(this)
);
collapseElement.removeEventListener(
EVENT_HIDDEN,
this.onStateChange.bind(this)
);
});

@@ -127,4 +143,4 @@ }

this.removeCollapseEventListeners();
if (this.router) {
this.router.off('newPageReady', this.onNewPageReady);
if (this.routerEvents) {
this.routerEvents.off("newPageReady", this.onNewPageReady);
}

@@ -134,3 +150,2 @@ }

protected onStateChange() {
this.scope.isCollapsed = !!this.collapseServices[0]?.isCollapsed();

@@ -140,6 +155,6 @@

this.el.classList.add(CLASS_NAME_COLLAPSED);
this.el.setAttribute('aria-expanded', 'false');
this.el.setAttribute("aria-expanded", "false");
} else {
this.el.classList.remove(CLASS_NAME_COLLAPSED);
this.el.setAttribute('aria-expanded', 'true');
this.el.setAttribute("aria-expanded", "true");
}

@@ -152,5 +167,15 @@ }

protected parsedAttributeChangedCallback(attributeName: string | string[], oldValue: any, newValue: any, namespace: string | null) {
super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
if (attributeName === 'collapseSelector') {
protected parsedAttributeChangedCallback(
attributeName: string | string[],
oldValue: any,
newValue: any,
namespace: string | null
) {
super.parsedAttributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
if (attributeName === "collapseSelector") {
this.setCollapseElement();

@@ -157,0 +182,0 @@ }

@@ -1,4 +0,7 @@

import { Bs4ContentsComponent, Scope as Bs4ContentsComponentScope } from '../bs4-contents/bs4-contents.component';
import {
Bs4ContentsComponent,
Scope as Bs4ContentsComponentScope,
} from "../bs4-contents/bs4-contents.component";
import template from './bs4-scrollspy.component.html';
import template from "./bs4-scrollspy.component.html";

@@ -24,5 +27,4 @@ export interface Anchor {

export class Bs4ScrollspyComponent extends Bs4ContentsComponent {
public static tagName = "bs4-scrollspy";
public static tagName = 'bs4-scrollspy';
protected autobind = true;

@@ -33,3 +35,11 @@

static get observedAttributes() {
return ['headers-start', 'headers-depth', 'find-header-id-depth', 'header-parent-selector', 'offset', 'offset-bottom', 'scroll-offset'];
return [
"headers-start",
"headers-depth",
"find-header-id-depth",
"header-parent-selector",
"offset",
"offset-bottom",
"scroll-offset",
];
}

@@ -58,3 +68,3 @@

protected requiredAttributes() {
return ['headersStart', 'headersDepth', 'headerParentSelector'];
return ["headersStart", "headersDepth", "headerParentSelector"];
}

@@ -61,0 +71,0 @@

import { Component } from "@ribajs/core";
import { getUrl } from '@ribajs/utils/src/url';
import { getUrl } from "@ribajs/utils/src/url";
import template from "./bs4-share.component.html";

@@ -16,3 +16,3 @@ import labelTemplate from "./bs4-share.label.html";

labelTemplate: string;
/** true if the browser runs on Android */

@@ -27,3 +27,3 @@ isAndroid: boolean;

dropdownId: string;
/**
/**
* Object with share urls like whatsapp, telegram, instagram etc used if the native share is noit available

@@ -34,2 +34,4 @@ * Only used if the browser has not an native share support like on android and iOS

dropdownDirection: "up" | "down" | "right" | "left";
// Methods

@@ -49,3 +51,3 @@ shareOnService: Bs4ShareComponent["shareOnService"];

interface Navigator {
share: (data: NavigatorShareParam) => Promise<any>;
share: (data?: ShareData) => Promise<void>;
}

@@ -67,4 +69,14 @@ }

public _debug = false;
static get observedAttributes() {
return ["type", "title", "text", "url", "media-url", "label"];
return [
"type",
"title",
"text",
"url",
"media-url",
"label",
"dropdown-direction",
];
}

@@ -82,8 +94,3 @@

this.scope = this.getScopeDefaults();
// this._debug = true;
this.debug('constructor', this.scope);
this.init(Bs4ShareComponent.observedAttributes);
this.addEventListeners();
this.debug("constructor", this.scope);
Bs4ShareComponent.count++;

@@ -100,6 +107,7 @@ }

urlTemplate: "https://www.facebook.com/sharer/sharer.php?u={{url}}",
mediaUrlTemplate: "https://www.facebook.com/sharer/sharer.php?u={{media_url}}",
type: 'popup',
mediaUrlTemplate:
"https://www.facebook.com/sharer/sharer.php?u={{media_url}}",
type: "popup",
url: "",
availableFor: ['page', 'image', 'video'],
availableFor: ["page", "image", "video"],
},

@@ -113,3 +121,3 @@ {

url: "",
availableFor: ['page', 'image', 'video'],
availableFor: ["page", "image", "video"],
},

@@ -122,6 +130,6 @@ {

"?url={{url}}&media={{media_url}}&description={{text}}",
type: 'popup',
type: "popup",
url: "",
availableFor: ['image', 'video'],
availableFor: ["image", "video"],
},

@@ -133,5 +141,5 @@ {

mediaUrlTemplate: `https://api.whatsapp.com/send?text={{text}}${newLine}${newLine}{{media_url}}${newLine}({{url}})`,
type: 'popup',
type: "popup",
url: "",
availableFor: ['page', 'image', 'video'],
availableFor: ["page", "image", "video"],
},

@@ -143,5 +151,5 @@ {

mediaUrlTemplate: `https://telegram.me/share/url?url={{media_url}}&text={{text}}${newLine}({{url}})`,
type: 'popup',
type: "popup",
url: "",
availableFor: ['page', 'image', 'video'],
availableFor: ["page", "image", "video"],
},

@@ -153,5 +161,5 @@ {

mediaUrlTemplate: `mailto:?subject={{title}}&body={{text}}${newLine}${newLine}{{media_url}}${newLine}({{url}})`,
type: 'href',
type: "href",
url: "",
availableFor: ['page', 'image', 'video'],
availableFor: ["page", "image", "video"],
},

@@ -171,5 +179,5 @@ // {

urlTemplate: "{{raw_media_url}}",
type: 'download',
type: "download",
url: "",
availableFor: ['image', 'video'],
availableFor: ["image", "video"],
},

@@ -194,3 +202,3 @@ ];

const scope: Scope = {
type: 'page',
type: "page",
title: document.title,

@@ -207,9 +215,10 @@ text: "Look at this! 👀🤩",

shareItems: this.getDefaultShareServices(),
dropdownDirection: "down",
// Methods
share: this.share,
shareOnService: this.shareOnService,
}
};
// on those two support "mobile deep links", so HTTP based fallback for all others.
scope.isDesktop = !scope.isIos && !scope.isAndroid;
scope.isDesktop = !scope.isIos && !scope.isAndroid;

@@ -227,2 +236,8 @@ return scope;

protected connectedCallback() {
super.connectedCallback();
this.init(Bs4ShareComponent.observedAttributes);
this.addEventListeners();
}
protected disconnectedCallback() {

@@ -234,13 +249,13 @@ super.disconnectedCallback();

protected addEventListeners() {
this.el.addEventListener('open', this.onExternalOpenEvent.bind(this));
this.el.addEventListener('close', this.onExternalCloseEvent.bind(this));
this.el.addEventListener("open", this.onExternalOpenEvent.bind(this));
this.el.addEventListener("close", this.onExternalCloseEvent.bind(this));
}
protected removeEventListeners() {
this.el.removeEventListener('open', this.onExternalOpenEvent.bind(this));
this.el.removeEventListener('close', this.onExternalOpenEvent.bind(this));
this.el.removeEventListener("open", this.onExternalOpenEvent.bind(this));
this.el.removeEventListener("close", this.onExternalOpenEvent.bind(this));
}
protected getURLForShare() {
if (this.scope.type === 'page' && this.scope.url) {
if (this.scope.type === "page" && this.scope.url) {
return getUrl(this.scope.url);

@@ -252,3 +267,3 @@ }

protected getMediaUrlForShare() {
if (this.scope.type !== 'page' && this.scope.url) {
if (this.scope.type !== "page" && this.scope.url) {
return getUrl(this.scope.url);

@@ -265,3 +280,3 @@ }

* Currently only used for email
* @param appendUrl
* @param appendUrl
*/

@@ -279,4 +294,4 @@ protected getTitleForShare() {

let urlTemplate = shareItem.urlTemplate;
if (this.scope.type !== 'page' && shareItem.mediaUrlTemplate) {
if (this.scope.type !== "page" && shareItem.mediaUrlTemplate) {
urlTemplate = shareItem.mediaUrlTemplate;

@@ -286,4 +301,4 @@ }

const shareURL = urlTemplate
.replace("{{url}}", encodeURIComponent(url))
.replace("{{url}}", encodeURIComponent(url))
.replace("{{url}}", encodeURIComponent(url))
.replace("{{media_url}}", encodeURIComponent(mediaUrl))

@@ -297,3 +312,2 @@ .replace("{{raw_media_url}}", mediaUrl)

}
}

@@ -306,3 +320,6 @@

if (!dropDownButtonElement) {
console.warn('Element with selector ".dropdown-toggle-share" not found!', this.el);
console.warn(
'Element with selector ".dropdown-toggle-share" not found!',
this.el
);
return;

@@ -315,13 +332,9 @@ }

* New browser popup with the external site (e.g. Facebook) on you want to share your url
* @param binding
* @param event
* @param controller
* @param el
* @param binding
* @param event
* @param controller
* @param el
*/
public shareOnService(
event: Event,
controller: any,
el: HTMLAnchorElement
) {
console.debug('Open popup');
public shareOnService(event: Event, controller: any, el: HTMLAnchorElement) {
this.debug("Open popup");

@@ -336,3 +349,6 @@ this.dropdown?.close();

// We use the default browser anchor href logic for download and href
if (el.hasAttribute("type") && el.getAttribute("type") === "download" || el.getAttribute("type") === "href") {
if (
(el.hasAttribute("type") && el.getAttribute("type") === "download") ||
el.getAttribute("type") === "href"
) {
return true;

@@ -344,3 +360,3 @@ }

// console.debug('Open popup');
// this.debug('Open popup');

@@ -359,3 +375,3 @@ window.open(

public async share(event: Event): Promise<any> {
console.debug('share', this.scope);
this.debug("share", this.scope);
event.preventDefault();

@@ -373,3 +389,3 @@ event.stopPropagation();

// TODO show flash message
// console.debug(error.message);
// this.debug(error.message);
return;

@@ -387,3 +403,3 @@ }

await super.beforeBind();
// console.debug('beforeBind');
// this.debug('beforeBind');
}

@@ -394,3 +410,3 @@

this.initDropdown();
// console.debug('afterBind', this.scope);
// this.debug('afterBind', this.scope);
}

@@ -403,6 +419,7 @@

protected template() {
this.debug("template", this.el, this.el.hasChildNodes());
if (this.el && this.el.hasChildNodes()) {
// If a child is set, this is a custom label template
this.scope.labelTemplate = this.el.innerHTML;
// console.debug('Custom label template: ', this.el.innerHTML);
this.debug("Custom label template: ", this.scope.labelTemplate);
}

@@ -409,0 +426,0 @@ return template;

@@ -1,8 +0,10 @@

import {
Component,
EventDispatcher,
} from '@ribajs/core';
import { getViewportDimensions } from '@ribajs/utils/src/dom';
import { Component, EventDispatcher } from "@ribajs/core";
import { getViewportDimensions } from "@ribajs/utils/src/dom";
type State = 'overlay-left' | 'overlay-right' | 'side-left' | 'side-right' | 'hidden';
type State =
| "overlay-left"
| "overlay-right"
| "side-left"
| "side-right"
| "hidden";

@@ -31,3 +33,3 @@ interface Scope {

*/
position: 'left' | 'right';
position: "left" | "right";
/**

@@ -62,17 +64,16 @@ * Auto show the sidebar if the viewport width is wider than this value

*/
hide: Bs4SidebarComponent['hide'];
hide: Bs4SidebarComponent["hide"];
/**
* Shows / opens the sidebar
*/
show: Bs4SidebarComponent['show'];
show: Bs4SidebarComponent["show"];
/**
* Toggles (closes or opens) the sidebar
*/
toggle: Bs4SidebarComponent['toggle'];
toggle: Bs4SidebarComponent["toggle"];
}
export class Bs4SidebarComponent extends Component {
public static tagName = "bs4-sidebar";
public static tagName = 'bs4-sidebar';
protected style?: CSSStyleDeclaration;

@@ -84,12 +85,12 @@

return [
'id',
'container-selector',
'position',
'width',
'auto-show-on-wider-than',
'auto-hide-on-slimmer-than',
'force-hide-on-location-pathnames',
'force-show-on-location-pathnames',
'overlay-on-slimmer-than',
'watch-new-page-ready-event',
"id",
"container-selector",
"position",
"width",
"auto-show-on-wider-than",
"auto-hide-on-slimmer-than",
"force-hide-on-location-pathnames",
"force-show-on-location-pathnames",
"overlay-on-slimmer-than",
"watch-new-page-ready-event",
];

@@ -100,14 +101,13 @@ }

protected routerEvents = new EventDispatcher('main');
protected routerEvents = new EventDispatcher("main");
protected scope: Scope = {
// template properties
containerSelector: undefined,
state: 'hidden',
state: "hidden",
id: undefined,
width: '250px',
width: "250px",
// Options
position: 'left',
position: "left",
autoShowOnWiderThan: 1199,

@@ -139,3 +139,3 @@ autoHideOnSlimmerThan: 1200,

public hide() {
this.scope.state = 'hidden';
this.scope.state = "hidden";
this.onStateChange();

@@ -147,5 +147,5 @@ }

if (vw < this.scope.overlayOnSlimmerThan) {
this.scope.state = 'overlay-' + this.scope.position as State;
this.scope.state = ("overlay-" + this.scope.position) as State;
} else {
this.scope.state = 'side-' + this.scope.position as State;
this.scope.state = ("side-" + this.scope.position) as State;
}

@@ -156,3 +156,3 @@ this.onStateChange();

public toggle() {
if (this.scope.state === 'hidden') {
if (this.scope.state === "hidden") {
this.show();

@@ -168,3 +168,7 @@ } else {

this.style = window.getComputedStyle(this.el);
window.addEventListener('resize', this.onEnviromentChanges.bind(this), false);
window.addEventListener(
"resize",
this.onEnviromentChanges.bind(this),
false
);
// inital

@@ -180,8 +184,10 @@ this.onEnviromentChanges();

if (this.toggleButtonEvents) {
this.toggleButtonEvents.off('toggle', this.onToggle.bind(this));
this.toggleButtonEvents.off('init', this.triggerState.bind(this));
this.toggleButtonEvents.off("toggle", this.onToggle.bind(this));
this.toggleButtonEvents.off("init", this.triggerState.bind(this));
}
this.toggleButtonEvents = new EventDispatcher('bs4-toggle-button:' + this.scope.id);
this.toggleButtonEvents.on('toggle', this.onToggle.bind(this));
this.toggleButtonEvents.on('init', this.triggerState.bind(this));
this.toggleButtonEvents = new EventDispatcher(
"bs4-toggle-button:" + this.scope.id
);
this.toggleButtonEvents.on("toggle", this.onToggle.bind(this));
this.toggleButtonEvents.on("init", this.triggerState.bind(this));
}

@@ -191,3 +197,3 @@

if (this.scope.watchNewPageReadyEvent) {
this.routerEvents.on('newPageReady', this.onEnviromentChanges.bind(this));
this.routerEvents.on("newPageReady", this.onEnviromentChanges.bind(this));
}

@@ -198,18 +204,27 @@ }

this.setContainersStyle();
const translateX = this.scope.position === 'left' ? '-100%' : '100%';
this.el.setAttribute('style', `transform:translateX(${translateX});width:${this.scope.width};`);
const translateX = this.scope.position === "left" ? "-100%" : "100%";
this.el.setAttribute(
"style",
`transform:translateX(${translateX});width:${this.scope.width};`
);
}
protected onSide(directon: State) {
this.setContainersStyle(undefined, '', directon);
this.el.setAttribute('style', `transform:translateX(0);width:${this.scope.width};`);
this.setContainersStyle(undefined, "", directon);
this.el.setAttribute(
"style",
`transform:translateX(0);width:${this.scope.width};`
);
}
protected onOverlay(directon: State) {
this.setContainersStyle(undefined, '', directon);
this.el.setAttribute('style', `transform:translateX(0);width:${this.scope.width};`);
this.setContainersStyle(undefined, "", directon);
this.el.setAttribute(
"style",
`transform:translateX(0);width:${this.scope.width};`
);
}
protected triggerState() {
this.toggleButtonEvents?.trigger('state', this.scope.state);
this.toggleButtonEvents?.trigger("state", this.scope.state);
}

@@ -219,10 +234,10 @@

switch (this.scope.state) {
case 'side-left':
case 'side-right':
case "side-left":
case "side-right":
this.onSide(this.scope.state);
break;
case 'overlay-left':
case 'overlay-right':
this.onOverlay(this.scope.state);
break;
case "overlay-left":
case "overlay-right":
this.onOverlay(this.scope.state);
break;
default:

@@ -233,3 +248,3 @@ this.onHidden();

if (this.toggleButtonEvents) {
this.toggleButtonEvents.trigger('toggled', this.scope.state);
this.toggleButtonEvents.trigger("toggled", this.scope.state);
}

@@ -239,17 +254,27 @@ }

protected get width() {
return this.el.offsetWidth ? this.el.offsetWidth + 'px' : this.scope.width;
return this.el.offsetWidth ? this.el.offsetWidth + "px" : this.scope.width;
}
protected setStateByEnviroment() {
if (this.scope.forceHideOnLocationPathnames.includes(window.location.pathname)) {
if (
this.scope.forceHideOnLocationPathnames.includes(window.location.pathname)
) {
return this.hide();
}
if (this.scope.forceShowOnLocationPathnames.includes(window.location.pathname)) {
if (
this.scope.forceShowOnLocationPathnames.includes(window.location.pathname)
) {
return this.show();
}
const vw = getViewportDimensions().w;
if (this.scope.autoHideOnSlimmerThan > -1 && vw < this.scope.autoHideOnSlimmerThan) {
if (
this.scope.autoHideOnSlimmerThan > -1 &&
vw < this.scope.autoHideOnSlimmerThan
) {
return this.hide();
}
if (this.scope.autoShowOnWiderThan > -1 && vw > this.scope.autoShowOnWiderThan) {
if (
this.scope.autoShowOnWiderThan > -1 &&
vw > this.scope.autoShowOnWiderThan
) {
return this.show();

@@ -267,3 +292,7 @@ }

protected getContainers() {
return this.scope.containerSelector ? document.querySelectorAll<HTMLUnknownElement>(this.scope.containerSelector) : undefined;
return this.scope.containerSelector
? document.querySelectorAll<HTMLUnknownElement>(
this.scope.containerSelector
)
: undefined;
}

@@ -276,3 +305,7 @@

protected setContainersStyle(containers?: NodeListOf<HTMLUnknownElement>, style?: string, move?: State) {
protected setContainersStyle(
containers?: NodeListOf<HTMLUnknownElement>,
style?: string,
move?: State
) {
if (!containers) {

@@ -295,3 +328,7 @@ containers = this.getContainers();

*/
protected setContainerStyle(container: HTMLUnknownElement, style = '', move?: State) {
protected setContainerStyle(
container: HTMLUnknownElement,
style = "",
move?: State
) {
if (move) {

@@ -301,19 +338,19 @@ const width = this.width;

switch (move) {
case 'side-left':
case "side-left":
switch (conStyle.position) {
case 'fixed':
style += 'left:' + width;
case "fixed":
style += "left:" + width;
break;
default:
style += 'margin-left:' + width;
style += "margin-left:" + width;
break;
}
break;
case 'side-right':
case "side-right":
switch (conStyle.position) {
case 'fixed':
style += 'right:' + width;
case "fixed":
style += "right:" + width;
break;
default:
style += 'margin-right:' + width;
style += "margin-right:" + width;
break;

@@ -326,3 +363,6 @@ }

}
return container.setAttribute('style', `transition:${this.style ? this.style.transition : ''};${style}`);
return container.setAttribute(
"style",
`transition:${this.style ? this.style.transition : ""};${style}`
);
}

@@ -342,11 +382,21 @@

protected requiredAttributes() {
return ['id'];
return ["id"];
}
protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
if (attributeName === 'containerSelector') {
protected parsedAttributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.parsedAttributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
if (attributeName === "containerSelector") {
this.initContainers();
}
if (attributeName === 'id') {
if (attributeName === "id") {
this.initToggleButtonEventDispatcher();

@@ -359,7 +409,11 @@ }

super.disconnectedCallback();
this.toggleButtonEvents?.off('init', this.triggerState.bind(this));
this.toggleButtonEvents?.off('toggle', this.onToggle.bind(this));
this.toggleButtonEvents?.off('init', this.triggerState.bind(this));
this.routerEvents.off('newPageReady', this.onEnviromentChanges.bind(this));
window.removeEventListener('resize', this.onEnviromentChanges.bind(this), false);
this.toggleButtonEvents?.off("init", this.triggerState.bind(this));
this.toggleButtonEvents?.off("toggle", this.onToggle.bind(this));
this.toggleButtonEvents?.off("init", this.triggerState.bind(this));
this.routerEvents.off("newPageReady", this.onEnviromentChanges.bind(this));
window.removeEventListener(
"resize",
this.onEnviromentChanges.bind(this),
false
);
}

@@ -369,3 +423,5 @@

if (!this.el.hasChildNodes()) {
console.warn('No child elements found, this component as no template so you need to define your own as child of this component.');
console.warn(
"No child elements found, this component as no template so you need to define your own as child of this component."
);
}

@@ -372,0 +428,0 @@ return null;

@@ -1,22 +0,45 @@

import { TemplatesComponent } from '../templates/templates.component';
import { TemplatesComponent } from "../templates/templates.component";
import { EventDispatcher } from "@ribajs/core";
import { clone, camelCase } from '@ribajs/utils/src/type';
import { clone, camelCase } from "@ribajs/utils/src/type";
import { Dragscroll, DragscrollOptions, Autoscroll, AutoscrollOptions, Utils as ExtraUtils, ScrollPosition, ScrollEventsService } from '@ribajs/extras';
import {
Dragscroll,
DragscrollOptions,
Autoscroll,
AutoscrollOptions,
Utils as ExtraUtils,
ScrollPosition,
ScrollEventsService,
} from "@ribajs/extras";
import templateSlides from './bs4-slideshow-slides.component.html';
import templateSlides from "./bs4-slideshow-slides.component.html";
import templateControls from './bs4-slideshow-controls.component.html';
import templateControls from "./bs4-slideshow-controls.component.html";
import templateIndicators from './bs4-slideshow-indicators.component.html';
import templateIndicators from "./bs4-slideshow-indicators.component.html";
const SLIDESHOW_INNER_SELECTOR = '.slideshow-inner';
const SLIDESHOW_INNER_SELECTOR = ".slideshow-inner";
const SLIDES_SELECTOR = `${SLIDESHOW_INNER_SELECTOR} > .slide`;
export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
export type Breakpoint = "xs" | "sm" | "md" | "lg" | "xl";
export type ControlsPosition = 'insite-middle' | 'insite-bottom' | 'insite-top' | 'outsite-middle' | 'outsite-bottom' | 'outsite-top';
export type ControlsPosition =
| "insite-middle"
| "insite-bottom"
| "insite-top"
| "outsite-middle"
| "outsite-bottom"
| "outsite-top";
export type IndicatorsPosition = 'insite-bottom' | 'insite-top' | 'insite-right' | 'insite-left' | 'outsite-bottom' | 'outsite-top' | 'outsite-right' | 'outsite-left';
export type IndicatorsPosition =
| "insite-bottom"
| "insite-top"
| "insite-right"
| "insite-left"
| "outsite-bottom"
| "outsite-top"
| "outsite-right"
| "outsite-left";

@@ -44,3 +67,3 @@ export interface Position extends DOMRect {

export interface Options {
/** Show controls */
/** Show controls */
controls: boolean;

@@ -76,3 +99,3 @@ /** Position of the controls */

/** Slide angle, can be vertical or horizontal */
angle: 'vertical' | 'horizontal';
angle: "vertical" | "horizontal";
/** Pause on autoplay (with interval) */

@@ -90,5 +113,5 @@ pause: boolean;

export interface Scope extends Options {
next: Bs4SlideshowComponent['next'];
prev: Bs4SlideshowComponent['prev'];
goTo: Bs4SlideshowComponent['goTo'];
next: Bs4SlideshowComponent["next"];
prev: Bs4SlideshowComponent["prev"];
goTo: Bs4SlideshowComponent["goTo"];
controlsPositionClass: string;

@@ -100,3 +123,2 @@ indicatorsPositionClass: string;

export class Bs4SlideshowComponent extends TemplatesComponent {
protected get slideshowInner() {

@@ -107,3 +129,5 @@ if (!this._slideshowInner) {

if (!this._slideshowInner) {
throw new Error(`Child element with selecto ${SLIDESHOW_INNER_SELECTOR} not found!`);
throw new Error(
`Child element with selecto ${SLIDESHOW_INNER_SELECTOR} not found!`
);
}

@@ -118,3 +142,5 @@ return this._slideshowInner;

if (!this._slideElements) {
throw new Error(`Child element with selecto ${SLIDES_SELECTOR} not found!`);
throw new Error(
`Child element with selecto ${SLIDES_SELECTOR} not found!`
);
}

@@ -126,3 +152,5 @@ return this._slideElements;

if (!this._controlsElements) {
this._controlsElements = this.el.querySelectorAll('.slideshow-control-prev, .slideshow-control-next');
this._controlsElements = this.el.querySelectorAll(
".slideshow-control-prev, .slideshow-control-next"
);
}

@@ -134,3 +162,3 @@ return this._controlsElements;

if (!this._indicatorsElement) {
this._indicatorsElement = this.el.querySelector('.slideshow-indicators');
this._indicatorsElement = this.el.querySelector(".slideshow-indicators");
}

@@ -142,132 +170,132 @@ return this._indicatorsElement;

return [
'min-width',
'slides-to-show',
'slides-to-scroll',
'controls',
'controls-position',
'draggable',
'autoplay',
'autoplay-interval',
'autoplay-velocity',
'control-prev-icon-src',
'control-next-icon-src',
'indicator-inactive-icon-src',
'indicator-active-icon-src',
'angle',
'set-active-slide',
'pause-on-hover',
'sticky',
'indicators',
'indicators-position',
'pause',
"min-width",
"slides-to-show",
"slides-to-scroll",
"controls",
"controls-position",
"draggable",
"autoplay",
"autoplay-interval",
"autoplay-velocity",
"control-prev-icon-src",
"control-next-icon-src",
"indicator-inactive-icon-src",
"indicator-active-icon-src",
"angle",
"set-active-slide",
"pause-on-hover",
"sticky",
"indicators",
"indicators-position",
"pause",
'sm-min-width',
'sm-slides-to-show',
'sm-slides-to-scroll',
'sm-controls',
'sm-controls-position',
'sm-draggable',
'sm-autoplay',
'sm-autoplay-interval',
'sm-autoplay-velocity',
'sm-control-prev-icon-src',
'sm-control-next-icon-src',
'sm-indicator-inactive-icon-src',
'sm-indicator-active-icon-src',
'sm-angle',
'sm-set-active-slide',
'sm-pause-on-hover',
'sm-sticky',
'sm-indicators',
'sm-indicators-position',
'sm-pause',
"sm-min-width",
"sm-slides-to-show",
"sm-slides-to-scroll",
"sm-controls",
"sm-controls-position",
"sm-draggable",
"sm-autoplay",
"sm-autoplay-interval",
"sm-autoplay-velocity",
"sm-control-prev-icon-src",
"sm-control-next-icon-src",
"sm-indicator-inactive-icon-src",
"sm-indicator-active-icon-src",
"sm-angle",
"sm-set-active-slide",
"sm-pause-on-hover",
"sm-sticky",
"sm-indicators",
"sm-indicators-position",
"sm-pause",
'md-min-width',
'md-slides-to-show',
'md-slides-to-scroll',
'md-controls',
'md-controls-position',
'md-draggable',
'md-autoplay',
'md-autoplay-interval',
'md-autoplay-velocity',
'md-control-prev-icon-src',
'md-control-next-icon-src',
'md-indicator-inactive-icon-src',
'md-indicator-active-icon-src',
'md-angle',
'md-set-active-slide',
'md-pause-on-hover',
'md-sticky',
'md-indicators',
'sm-indicators-position',
'md-pause',
"md-min-width",
"md-slides-to-show",
"md-slides-to-scroll",
"md-controls",
"md-controls-position",
"md-draggable",
"md-autoplay",
"md-autoplay-interval",
"md-autoplay-velocity",
"md-control-prev-icon-src",
"md-control-next-icon-src",
"md-indicator-inactive-icon-src",
"md-indicator-active-icon-src",
"md-angle",
"md-set-active-slide",
"md-pause-on-hover",
"md-sticky",
"md-indicators",
"sm-indicators-position",
"md-pause",
'lg-min-width',
'lg-slides-to-show',
'lg-slides-to-scroll',
'lg-controls',
'lg-controls-position',
'lg-draggable',
'lg-autoplay',
'lg-autoplay-interval',
'lg-autoplay-velocity',
'lg-control-prev-icon-src',
'lg-control-next-icon-src',
'lg-indicator-inactive-icon-src',
'lg-indicator-active-icon-src',
'lg-angle',
'lg-set-active-slide',
'lg-pause-on-hover',
'lg-sticky',
'lg-indicators',
'lg-indicators-position',
'lg-pause',
"lg-min-width",
"lg-slides-to-show",
"lg-slides-to-scroll",
"lg-controls",
"lg-controls-position",
"lg-draggable",
"lg-autoplay",
"lg-autoplay-interval",
"lg-autoplay-velocity",
"lg-control-prev-icon-src",
"lg-control-next-icon-src",
"lg-indicator-inactive-icon-src",
"lg-indicator-active-icon-src",
"lg-angle",
"lg-set-active-slide",
"lg-pause-on-hover",
"lg-sticky",
"lg-indicators",
"lg-indicators-position",
"lg-pause",
'xl-min-width',
'xl-slides-to-show',
'xl-slides-to-scroll',
'xl-controls',
'xl-controls-position',
'xl-draggable',
'xl-autoplay',
'xl-autoplay-interval',
'xl-autoplay-velocity',
'xl-control-prev-icon-src',
'xl-control-next-icon-src',
'xl-indicator-inactive-icon-src',
'xl-indicator-active-icon-src',
'xl-angle',
'xl-set-active-slide',
'xl-pause-on-hover',
'xl-sticky',
'xl-indicators',
'xl-indicators-position',
'xl-pause',
"xl-min-width",
"xl-slides-to-show",
"xl-slides-to-scroll",
"xl-controls",
"xl-controls-position",
"xl-draggable",
"xl-autoplay",
"xl-autoplay-interval",
"xl-autoplay-velocity",
"xl-control-prev-icon-src",
"xl-control-next-icon-src",
"xl-indicator-inactive-icon-src",
"xl-indicator-active-icon-src",
"xl-angle",
"xl-set-active-slide",
"xl-pause-on-hover",
"xl-sticky",
"xl-indicators",
"xl-indicators-position",
"xl-pause",
];
}
public static tagName = 'bs4-slideshow';
public static tagName = "bs4-slideshow";
protected templateAttributes = [
{
name: 'class',
name: "class",
required: false,
},
{
name: 'handle',
name: "handle",
required: false,
},
{
name: 'type',
name: "type",
required: true,
},
{
name: 'active',
type: 'boolean',
name: "active",
type: "boolean",
required: false,
},
{
name: 'index',
type: 'number',
name: "index",
type: "number",
required: false,

@@ -302,7 +330,9 @@ },

protected resumeTimer: number | null = null;
protected routerEvents?: EventDispatcher;
/**
* Current breakpoint
*/
protected breakpoint: Breakpoint = 'xs';
protected breakpoint: Breakpoint = "xs";

@@ -319,7 +349,7 @@ protected scope: Scope = {

controls: true,
controlsPosition: 'insite-middle',
controlsPosition: "insite-middle",
pauseOnHover: true,
sticky: false,
indicators: true,
indicatorsPosition: 'insite-bottom',
indicatorsPosition: "insite-bottom",
pause: false,

@@ -330,7 +360,7 @@ draggable: true,

autoplayVelocity: 0.8,
controlPrevIconSrc: '',
controlNextIconSrc: '',
indicatorActiveIconSrc: '',
indicatorInactiveIconSrc: '',
angle: 'horizontal',
controlPrevIconSrc: "",
controlNextIconSrc: "",
indicatorActiveIconSrc: "",
indicatorInactiveIconSrc: "",
angle: "horizontal",

@@ -355,4 +385,4 @@ // Responsive options

// Classes
controlsPositionClass: '',
indicatorsPositionClass: '',
controlsPositionClass: "",
indicatorsPositionClass: "",
};

@@ -380,3 +410,3 @@

* Go to slide by index
* @param index
* @param index
*/

@@ -389,7 +419,10 @@ public goTo(index: number) {

if (!this.scope.items[index]) {
console.error(`Slide with index "${index}" not found!`, this.scope.items[index]);
console.error(
`Slide with index "${index}" not found!`,
this.scope.items[index]
);
return;
}
if (this.scope.angle === 'vertical') {
if (this.scope.angle === "vertical") {
// Check if we do not need to slide

@@ -400,3 +433,5 @@ if (this.scope.items[index].position.centerY === 0) {

}
top = this.slideshowInner.scrollTop + this.scope.items[index].position.centerY;
top =
this.slideshowInner.scrollTop +
this.scope.items[index].position.centerY;
} else {

@@ -408,3 +443,5 @@ // Check if we do not need to slide

}
left = this.slideshowInner.scrollLeft + this.scope.items[index].position.centerX;
left =
this.slideshowInner.scrollLeft +
this.scope.items[index].position.centerX;
}

@@ -415,5 +452,5 @@

// if is is window to scroll
if (typeof(this.slideshowInner.scroll) === 'function') {
if (typeof this.slideshowInner.scroll === "function") {
this.slideshowInner.scroll({
behavior: 'smooth',
behavior: "smooth",
left,

@@ -423,3 +460,3 @@ top,

} else {
if (this.scope.angle === 'vertical') {
if (this.scope.angle === "vertical") {
this.slideshowInner.scrollTop = top;

@@ -433,40 +470,134 @@ } else {

protected setOptions(dest: ResponsiveOptions | Options, source: ResponsiveOptions | Options) {
dest.slidesToScroll = typeof(source.slidesToScroll) !== 'undefined' ? clone(false, source.slidesToScroll) : dest.slidesToScroll;
dest.controls = typeof(source.controls) !== 'undefined' ? clone(false, source.controls) : dest.controls;
dest.controlsPosition = typeof(source.controlsPosition) !== 'undefined' ? clone(false, source.controlsPosition) : dest.controlsPosition;
dest.draggable = typeof(source.draggable) !== 'undefined' ? clone(false, source.draggable) : dest.draggable;
dest.autoplay = typeof(source.autoplay) !== 'undefined' ? clone(false, source.autoplay) : dest.autoplay;
dest.autoplayInterval = typeof(source.autoplayInterval) !== 'undefined' ? clone(false, source.autoplayInterval) : dest.autoplayInterval;
dest.autoplayVelocity = typeof(source.autoplayVelocity) !== 'undefined' ? clone(false, source.autoplayVelocity) : dest.autoplayVelocity;
dest.controlPrevIconSrc = typeof(source.controlPrevIconSrc) !== 'undefined' ? clone(false, source.controlPrevIconSrc) : dest.controlPrevIconSrc;
dest.controlNextIconSrc = typeof(source.controlNextIconSrc) !== 'undefined' ? clone(false, source.controlNextIconSrc) : dest.controlNextIconSrc;
dest.indicatorActiveIconSrc = typeof(source.indicatorActiveIconSrc) !== 'undefined' ? clone(false, source.indicatorActiveIconSrc) : dest.indicatorActiveIconSrc;
dest.indicatorInactiveIconSrc = typeof(source.indicatorInactiveIconSrc) !== 'undefined' ? clone(false, source.indicatorInactiveIconSrc) : dest.indicatorInactiveIconSrc;
dest.angle = typeof(source.angle) !== 'undefined' ? clone(false, source.angle) : dest.angle;
dest.pauseOnHover = typeof(source.pauseOnHover) !== 'undefined' ? clone(false, source.pauseOnHover) : dest.pauseOnHover;
dest.sticky = typeof(source.sticky) !== 'undefined' ? clone(false, source.sticky) : dest.sticky;
dest.indicators = typeof(source.indicators) !== 'undefined' ? clone(false, source.indicators) : dest.indicators;
dest.indicatorsPosition = typeof(source.indicatorsPosition) !== 'undefined' ? clone(false, source.indicatorsPosition) : dest.indicatorsPosition;
dest.pause = typeof(source.pause) !== 'undefined' ? clone(false, source.pause) : dest.pause;
protected setOptions(
dest: ResponsiveOptions | Options,
source: ResponsiveOptions | Options
) {
dest.slidesToScroll =
typeof source.slidesToScroll !== "undefined"
? clone(false, source.slidesToScroll)
: dest.slidesToScroll;
dest.controls =
typeof source.controls !== "undefined"
? clone(false, source.controls)
: dest.controls;
dest.controlsPosition =
typeof source.controlsPosition !== "undefined"
? clone(false, source.controlsPosition)
: dest.controlsPosition;
dest.draggable =
typeof source.draggable !== "undefined"
? clone(false, source.draggable)
: dest.draggable;
dest.autoplay =
typeof source.autoplay !== "undefined"
? clone(false, source.autoplay)
: dest.autoplay;
dest.autoplayInterval =
typeof source.autoplayInterval !== "undefined"
? clone(false, source.autoplayInterval)
: dest.autoplayInterval;
dest.autoplayVelocity =
typeof source.autoplayVelocity !== "undefined"
? clone(false, source.autoplayVelocity)
: dest.autoplayVelocity;
dest.controlPrevIconSrc =
typeof source.controlPrevIconSrc !== "undefined"
? clone(false, source.controlPrevIconSrc)
: dest.controlPrevIconSrc;
dest.controlNextIconSrc =
typeof source.controlNextIconSrc !== "undefined"
? clone(false, source.controlNextIconSrc)
: dest.controlNextIconSrc;
dest.indicatorActiveIconSrc =
typeof source.indicatorActiveIconSrc !== "undefined"
? clone(false, source.indicatorActiveIconSrc)
: dest.indicatorActiveIconSrc;
dest.indicatorInactiveIconSrc =
typeof source.indicatorInactiveIconSrc !== "undefined"
? clone(false, source.indicatorInactiveIconSrc)
: dest.indicatorInactiveIconSrc;
dest.angle =
typeof source.angle !== "undefined"
? clone(false, source.angle)
: dest.angle;
dest.pauseOnHover =
typeof source.pauseOnHover !== "undefined"
? clone(false, source.pauseOnHover)
: dest.pauseOnHover;
dest.sticky =
typeof source.sticky !== "undefined"
? clone(false, source.sticky)
: dest.sticky;
dest.indicators =
typeof source.indicators !== "undefined"
? clone(false, source.indicators)
: dest.indicators;
dest.indicatorsPosition =
typeof source.indicatorsPosition !== "undefined"
? clone(false, source.indicatorsPosition)
: dest.indicatorsPosition;
dest.pause =
typeof source.pause !== "undefined"
? clone(false, source.pause)
: dest.pause;
}
protected setOptionsIfUndefined(dest: ResponsiveOptions | Options, source: ResponsiveOptions | Options) {
dest.slidesToScroll = typeof(dest.slidesToScroll) === 'undefined' ? source.slidesToScroll : dest.slidesToScroll;
dest.controls = typeof(dest.controls) === 'undefined' ? source.controls : dest.controls;
dest.controlsPosition = typeof(dest.controlsPosition) === 'undefined' ? source.controlsPosition : dest.controlsPosition;
dest.draggable = typeof(dest.draggable) === 'undefined' ? source.draggable : dest.draggable;
dest.autoplay = typeof(dest.autoplay) === 'undefined' ? source.autoplay : dest.autoplay;
dest.autoplayInterval = typeof(dest.autoplayInterval) === 'undefined' ? source.autoplayInterval : dest.autoplayInterval;
dest.autoplayVelocity = typeof(dest.autoplayVelocity) === 'undefined' ? source.autoplayVelocity : dest.autoplayVelocity;
dest.controlPrevIconSrc = typeof(dest.controlPrevIconSrc) === 'undefined' ? source.controlPrevIconSrc : dest.controlPrevIconSrc;
dest.controlNextIconSrc = typeof(dest.controlNextIconSrc) === 'undefined' ? source.controlNextIconSrc : dest.controlNextIconSrc;
dest.indicatorActiveIconSrc = typeof(dest.indicatorActiveIconSrc) === 'undefined' ? source.indicatorActiveIconSrc : dest.indicatorActiveIconSrc;
dest.indicatorInactiveIconSrc = typeof(dest.indicatorInactiveIconSrc) === 'undefined' ? source.indicatorInactiveIconSrc : dest.indicatorInactiveIconSrc;
dest.angle = typeof(dest.angle) === 'undefined' ? source.angle : dest.angle;
dest.pauseOnHover = typeof(dest.pauseOnHover) === 'undefined' ? source.pauseOnHover : dest.pauseOnHover;
dest.sticky = typeof(dest.sticky) === 'undefined' ? source.sticky : dest.sticky;
dest.indicators = typeof(dest.indicators) === 'undefined' ? source.indicators : dest.indicators;
dest.indicatorsPosition = typeof(dest.indicatorsPosition) === 'undefined' ? source.indicatorsPosition : dest.indicatorsPosition;
dest.pause = typeof(dest.pause) === 'undefined' ? source.pause : dest.pause;
protected setOptionsIfUndefined(
dest: ResponsiveOptions | Options,
source: ResponsiveOptions | Options
) {
dest.slidesToScroll =
typeof dest.slidesToScroll === "undefined"
? source.slidesToScroll
: dest.slidesToScroll;
dest.controls =
typeof dest.controls === "undefined" ? source.controls : dest.controls;
dest.controlsPosition =
typeof dest.controlsPosition === "undefined"
? source.controlsPosition
: dest.controlsPosition;
dest.draggable =
typeof dest.draggable === "undefined" ? source.draggable : dest.draggable;
dest.autoplay =
typeof dest.autoplay === "undefined" ? source.autoplay : dest.autoplay;
dest.autoplayInterval =
typeof dest.autoplayInterval === "undefined"
? source.autoplayInterval
: dest.autoplayInterval;
dest.autoplayVelocity =
typeof dest.autoplayVelocity === "undefined"
? source.autoplayVelocity
: dest.autoplayVelocity;
dest.controlPrevIconSrc =
typeof dest.controlPrevIconSrc === "undefined"
? source.controlPrevIconSrc
: dest.controlPrevIconSrc;
dest.controlNextIconSrc =
typeof dest.controlNextIconSrc === "undefined"
? source.controlNextIconSrc
: dest.controlNextIconSrc;
dest.indicatorActiveIconSrc =
typeof dest.indicatorActiveIconSrc === "undefined"
? source.indicatorActiveIconSrc
: dest.indicatorActiveIconSrc;
dest.indicatorInactiveIconSrc =
typeof dest.indicatorInactiveIconSrc === "undefined"
? source.indicatorInactiveIconSrc
: dest.indicatorInactiveIconSrc;
dest.angle = typeof dest.angle === "undefined" ? source.angle : dest.angle;
dest.pauseOnHover =
typeof dest.pauseOnHover === "undefined"
? source.pauseOnHover
: dest.pauseOnHover;
dest.sticky =
typeof dest.sticky === "undefined" ? source.sticky : dest.sticky;
dest.indicators =
typeof dest.indicators === "undefined"
? source.indicators
: dest.indicators;
dest.indicatorsPosition =
typeof dest.indicatorsPosition === "undefined"
? source.indicatorsPosition
: dest.indicatorsPosition;
dest.pause = typeof dest.pause === "undefined" ? source.pause : dest.pause;
}

@@ -485,9 +616,18 @@

protected setControlsOptions() {
const xsControlsPosition = this.scope.xs.controlsPosition?.split(
"-"
) as ControlsPosition[];
const smControlsPosition = this.scope.sm.controlsPosition?.split(
"-"
) as ControlsPosition[];
const mdControlsPosition = this.scope.md.controlsPosition?.split(
"-"
) as ControlsPosition[];
const lgControlsPosition = this.scope.lg.controlsPosition?.split(
"-"
) as ControlsPosition[];
const xlControlsPosition = this.scope.xl.controlsPosition?.split(
"-"
) as ControlsPosition[];
const xsControlsPosition = this.scope.xs.controlsPosition?.split('-') as ControlsPosition[];
const smControlsPosition = this.scope.sm.controlsPosition?.split('-') as ControlsPosition[];
const mdControlsPosition = this.scope.md.controlsPosition?.split('-') as ControlsPosition[];
const lgControlsPosition = this.scope.lg.controlsPosition?.split('-') as ControlsPosition[];
const xlControlsPosition = this.scope.xl.controlsPosition?.split('-') as ControlsPosition[];
this.scope.controlsPositionClass = `control-${xsControlsPosition[0]} control-${xsControlsPosition[1]} control-sm-${smControlsPosition[0]} control-sm-${smControlsPosition[1]} control-md-${mdControlsPosition[0]} control-md-${mdControlsPosition[1]} control-lg-${lgControlsPosition[0]} control-lg-${lgControlsPosition[1]} control-xl-${xlControlsPosition[0]} control-xl-${xlControlsPosition[1]}`;

@@ -497,9 +637,18 @@ }

protected setIndicatorsOptions() {
const xsIndicatorsPosition = this.scope.xs.indicatorsPosition?.split(
"-"
) as IndicatorsPosition[];
const smIndicatorsPosition = this.scope.sm.indicatorsPosition?.split(
"-"
) as IndicatorsPosition[];
const mdIndicatorsPosition = this.scope.md.indicatorsPosition?.split(
"-"
) as IndicatorsPosition[];
const lgIndicatorsPosition = this.scope.lg.indicatorsPosition?.split(
"-"
) as IndicatorsPosition[];
const xlIndicatorsPosition = this.scope.xl.indicatorsPosition?.split(
"-"
) as IndicatorsPosition[];
const xsIndicatorsPosition = this.scope.xs.indicatorsPosition?.split('-') as IndicatorsPosition[];
const smIndicatorsPosition = this.scope.sm.indicatorsPosition?.split('-') as IndicatorsPosition[];
const mdIndicatorsPosition = this.scope.md.indicatorsPosition?.split('-') as IndicatorsPosition[];
const lgIndicatorsPosition = this.scope.lg.indicatorsPosition?.split('-') as IndicatorsPosition[];
const xlIndicatorsPosition = this.scope.xl.indicatorsPosition?.split('-') as IndicatorsPosition[];
this.scope.indicatorsPositionClass = `indicators-${xsIndicatorsPosition[0]} indicators-${xsIndicatorsPosition[1]} indicators-sm-${smIndicatorsPosition[0]} indicators-sm-${smIndicatorsPosition[1]} indicators-md-${mdIndicatorsPosition[0]} indicators-md-${mdIndicatorsPosition[1]} indicators-lg-${lgIndicatorsPosition[0]} indicators-lg-${lgIndicatorsPosition[1]} indicators-xl-${xlIndicatorsPosition[0]} indicators-xl-${xlIndicatorsPosition[1]}`;

@@ -513,18 +662,18 @@ }

if (size >= this.scope.xs.minWidth && size < this.scope.sm.minWidth) {
return 'xs';
return "xs";
}
// SM
if (size >= this.scope.sm.minWidth && size < this.scope.md.minWidth) {
return 'sm';
return "sm";
}
// MD
if (size >= this.scope.md.minWidth && size < this.scope.lg.minWidth) {
return 'md';
return "md";
}
// LG
if (size >= this.scope.lg.minWidth && size < this.scope.xl.minWidth) {
return 'lg';
return "lg";
}
// XL
return 'xl';
return "xl";
}

@@ -552,3 +701,3 @@

protected onResize() {
protected onViewChanges() {
const newBreakpoint = this.getBreakpoint();

@@ -625,28 +774,69 @@ if (newBreakpoint !== this.breakpoint) {

protected addEventListeners() {
window.addEventListener('resize', this.onResize.bind(this), {passive: true});
if (!this.routerEvents) {
this.routerEvents = new EventDispatcher("main");
}
this.routerEvents.on("newPageReady", this.onBreakpointChanges.bind(this));
window.addEventListener("resize", this.onViewChanges.bind(this), {
passive: true,
});
// Custom event triggered by some parent components when this component changes his visibility, e.g. triggered in the bs4-tabs component
this.el.addEventListener('visibility-changed' as any, this.onVisibilityChanged.bind(this));
this.el.addEventListener(
"visibility-changed" as any,
this.onVisibilityChanged.bind(this)
);
this.slideshowInner.addEventListener('scroll', this.onScroll.bind(this), { passive: true});
this.slideshowInner.addEventListener('scrollended', this.onScrollend.bind(this), {passive: true});
this.slideshowInner.addEventListener("scroll", this.onScroll.bind(this), {
passive: true,
});
this.slideshowInner.addEventListener(
"scrollended",
this.onScrollend.bind(this),
{ passive: true }
);
this.el.addEventListener('mouseenter', this.onMouseIn.bind(this), {passive: true});
this.el.addEventListener('mouseover', this.onMouseIn.bind(this), {passive: true});
this.el.addEventListener('focusin', this.onMouseIn.bind(this), {passive: true});
this.el.addEventListener('touchstart', this.onMouseIn.bind(this), {passive: true});
this.el.addEventListener("mouseenter", this.onMouseIn.bind(this), {
passive: true,
});
this.el.addEventListener("mouseover", this.onMouseIn.bind(this), {
passive: true,
});
this.el.addEventListener("focusin", this.onMouseIn.bind(this), {
passive: true,
});
this.el.addEventListener("touchstart", this.onMouseIn.bind(this), {
passive: true,
});
this.el.addEventListener('mouseout', this.onMouseOut.bind(this), {passive: true});
this.el.addEventListener('mouseleave', this.onMouseOut.bind(this), {passive: true});
this.el.addEventListener('focusout', this.onMouseOut.bind(this), {passive: true});
this.el.addEventListener("mouseout", this.onMouseOut.bind(this), {
passive: true,
});
this.el.addEventListener("mouseleave", this.onMouseOut.bind(this), {
passive: true,
});
this.el.addEventListener("focusout", this.onMouseOut.bind(this), {
passive: true,
});
this.el.addEventListener('mouseup', this.onMouseUp.bind(this), {passive: true});
this.el.addEventListener('touchend', this.onMouseUp.bind(this), {passive: true});
this.el.addEventListener('scroll', this.onMouseUp.bind(this), {passive: true});
this.el.addEventListener('scrollend', this.onMouseUp.bind(this), {passive: true});
this.el.addEventListener("mouseup", this.onMouseUp.bind(this), {
passive: true,
});
this.el.addEventListener("touchend", this.onMouseUp.bind(this), {
passive: true,
});
this.el.addEventListener("scroll", this.onMouseUp.bind(this), {
passive: true,
});
this.el.addEventListener("scrollend", this.onMouseUp.bind(this), {
passive: true,
});
// See ScrollEventsService for this event
this.el.addEventListener('scrollended', this.onMouseUp.bind(this), {passive: true});
this.el.addEventListener("scrollended", this.onMouseUp.bind(this), {
passive: true,
});
// inital
this.onResize();
this.onViewChanges();
// this.onScroll();

@@ -657,17 +847,23 @@ this.onScrollend();

protected removeEventListeners() {
window.removeEventListener('resize', this.onResize.bind(this));
window.removeEventListener("resize", this.onViewChanges.bind(this));
this.el.removeEventListener('visibility-changed' as any, this.onVisibilityChanged.bind(this));
this.el.removeEventListener(
"visibility-changed" as any,
this.onVisibilityChanged.bind(this)
);
this.slideshowInner.removeEventListener('scroll', this.onScroll.bind(this));
this.slideshowInner.removeEventListener('scrollended', this.onScrollend.bind(this));
this.slideshowInner.removeEventListener("scroll", this.onScroll.bind(this));
this.slideshowInner.removeEventListener(
"scrollended",
this.onScrollend.bind(this)
);
this.el.removeEventListener('mouseenter', this.onMouseIn.bind(this));
this.el.removeEventListener('mouseover', this.onMouseIn.bind(this));
this.el.removeEventListener('focusin', this.onMouseIn.bind(this));
this.el.removeEventListener('touchstart', this.onMouseIn.bind(this));
this.el.removeEventListener("mouseenter", this.onMouseIn.bind(this));
this.el.removeEventListener("mouseover", this.onMouseIn.bind(this));
this.el.removeEventListener("focusin", this.onMouseIn.bind(this));
this.el.removeEventListener("touchstart", this.onMouseIn.bind(this));
this.el.removeEventListener('mouseout', this.onMouseOut.bind(this));
this.el.removeEventListener('mouseleave', this.onMouseOut.bind(this));
this.el.removeEventListener('focusout', this.onMouseOut.bind(this));
this.el.removeEventListener("mouseout", this.onMouseOut.bind(this));
this.el.removeEventListener("mouseleave", this.onMouseOut.bind(this));
this.el.removeEventListener("focusout", this.onMouseOut.bind(this));
}

@@ -683,3 +879,3 @@

this.initResponsiveOptions();
this.removeEventListeners();
// this.removeEventListeners();
this.addEventListeners();

@@ -689,7 +885,5 @@ }

protected initSlideshowInner() {
this.initSlideshowInnerSlides();
this.scrollEventsService = new ScrollEventsService(this.slideshowInner);
}

@@ -699,4 +893,7 @@

if (!this.dragscrollService) {
const dragscrollOptions: DragscrollOptions = {detectGlobalMove: true};
this.dragscrollService = new Dragscroll(this.slideshowInner, dragscrollOptions);
const dragscrollOptions: DragscrollOptions = { detectGlobalMove: true };
this.dragscrollService = new Dragscroll(
this.slideshowInner,
dragscrollOptions
);
}

@@ -706,3 +903,3 @@ }

protected disableDesktopDragscroll() {
if (this.dragscrollService ) {
if (this.dragscrollService) {
this.dragscrollService.destroy();

@@ -720,3 +917,6 @@ this.dragscrollService = undefined;

};
this.continuousAutoplayService = new Autoscroll(this.slideshowInner, autoscrollOptions);
this.continuousAutoplayService = new Autoscroll(
this.slideshowInner,
autoscrollOptions
);
}

@@ -728,3 +928,6 @@ // on continuous autoplay the scrollended event is never triggered, so call this method all `intervalsTimeMs` milliseconds as a WORKAROUND

// console.debug('intervalsTimeMs', intervalsTimeMs);
this.continuousAutoplayIntervalIndex = window.setInterval(this.onScrollend.bind(this), intervalsTimeMs);
this.continuousAutoplayIntervalIndex = window.setInterval(
this.onScrollend.bind(this),
intervalsTimeMs
);
}

@@ -761,3 +964,2 @@ }

protected disableAutoplay() {

@@ -779,3 +981,3 @@ this.disableIntervalAutoplay();

if (!this.slideElements) {
throw new Error('No slides found!');
throw new Error("No slides found!");
}

@@ -787,3 +989,2 @@

}
}

@@ -795,4 +996,4 @@

attributes.index = index;
attributes.class = attributes.class || '';
attributes.class += ' slide';
attributes.class = attributes.class || "";
attributes.class += " slide";
return attributes;

@@ -809,9 +1010,9 @@ }

if (attributes.type) {
if (attributes.type === 'slide') {
this.scope.items.push({...attributes, content});
if (attributes.type === "slide") {
this.scope.items.push({ ...attributes, content });
}
if (attributes.type === 'controls') {
if (attributes.type === "controls") {
this.templateControls = content;
}
if (attributes.type === 'indicators') {
if (attributes.type === "indicators") {
this.templateIndicators = content;

@@ -831,4 +1032,7 @@ }

this.slideElements.forEach((slideElement, index) => {
const handle = slideElement.getAttribute('handle') || slideElement.getAttribute('id') || index.toString();
slideElement.setAttribute('index', index.toString());
const handle =
slideElement.getAttribute("handle") ||
slideElement.getAttribute("id") ||
index.toString();
slideElement.setAttribute("index", index.toString());
const attributes = {

@@ -839,3 +1043,7 @@ handle,

index,
position: {...slideElement.getBoundingClientRect(), centerY: 0, centerX: 0},
position: {
...slideElement.getBoundingClientRect(),
centerY: 0,
centerX: 0,
},
};

@@ -866,7 +1074,15 @@ this.scope.items.push(attributes);

}
let nearZero = Math.abs(this.scope.angle === 'vertical' ? this.scope.items[0].position.centerY : this.scope.items[0].position.centerX);
let nearZero = Math.abs(
this.scope.angle === "vertical"
? this.scope.items[0].position.centerY
: this.scope.items[0].position.centerX
);
let minIndex = 0;
for (let i = 1; i < this.scope.items.length; i++) {
const position = Math.abs(this.scope.angle === 'vertical' ? this.scope.items[i].position.centerY : this.scope.items[i].position.centerX);
const position = Math.abs(
this.scope.angle === "vertical"
? this.scope.items[i].position.centerY
: this.scope.items[i].position.centerX
);
nearZero = this.getCurrentClosestNumber(0, position, nearZero);

@@ -889,4 +1105,7 @@ if (nearZero === position) {

}
if (this.slideElements[index] && this.slideElements[index].classList.remove) {
this.slideElements[index].classList.remove('active');
if (
this.slideElements[index] &&
this.slideElements[index].classList.remove
) {
this.slideElements[index].classList.remove("active");
}

@@ -905,3 +1124,3 @@ }

if (this.slideElements && this.slideElements[index].classList.add) {
this.slideElements[index].classList.add('active');
this.slideElements[index].classList.add("active");
}

@@ -915,4 +1134,12 @@ return index;

}
const maxScrollTo = this.scope.angle === 'vertical' ? this.getScrollPosition().maxY : this.getScrollPosition().maxX;
const scrollTo = this.scope.angle === 'vertical' ? this.slideshowInner.scrollTop + this.scope.items[index].position.centerY : this.slideshowInner.scrollLeft + this.scope.items[index].position.centerX;
const maxScrollTo =
this.scope.angle === "vertical"
? this.getScrollPosition().maxY
: this.getScrollPosition().maxX;
const scrollTo =
this.scope.angle === "vertical"
? this.slideshowInner.scrollTop +
this.scope.items[index].position.centerY
: this.slideshowInner.scrollLeft +
this.scope.items[index].position.centerX;
return scrollTo <= maxScrollTo && scrollTo >= 0;

@@ -947,3 +1174,3 @@ }

if (prevIndex < 0) {
prevIndex = (this.slideElements.length - 1) + (prevIndex + 1);
prevIndex = this.slideElements.length - 1 + (prevIndex + 1);
}

@@ -962,3 +1189,5 @@

if (this.scope.items.length !== this.slideElements?.length) {
console.warn(`The slide objects must be the same size as the slide elements! ${this.scope.items.length} !== ${this.slideElements?.length}`);
console.warn(
`The slide objects must be the same size as the slide elements! ${this.scope.items.length} !== ${this.slideElements?.length}`
);
return;

@@ -986,5 +1215,5 @@ }

// 0 if element is in the middle / center
centerY: (rect.y + (rect.height / 2)) - mainBoundingClient.height / 2,
centerY: rect.y + rect.height / 2 - mainBoundingClient.height / 2,
// 0 if element is in the middle / center
centerX: (rect.x + (rect.width / 2)) - mainBoundingClient.width / 2,
centerX: rect.x + rect.width / 2 - mainBoundingClient.width / 2,
};

@@ -1006,9 +1235,16 @@ }

*/
protected attributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
protected attributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
let optionForSize: Breakpoint = "xs";
let optionForSize: Breakpoint = 'xs';
let responsiveScope: ResponsiveOptions | Options = this.scope;
if (this.observedAttributesToCheck && this.observedAttributesToCheck[attributeName]) {
if (
this.observedAttributesToCheck &&
this.observedAttributesToCheck[attributeName]
) {
this.observedAttributesToCheck[attributeName].initialized = true;

@@ -1019,16 +1255,16 @@ }

if (attributeName.startsWith('sm-')) {
optionForSize = 'sm';
if (attributeName.startsWith("sm-")) {
optionForSize = "sm";
responsiveScope = this.scope.sm;
attributeName = attributeName.slice(3);
} else if (attributeName.startsWith('md-')) {
optionForSize = 'md';
} else if (attributeName.startsWith("md-")) {
optionForSize = "md";
responsiveScope = this.scope.md;
attributeName = attributeName.slice(3);
} else if (attributeName.startsWith('lg-')) {
optionForSize = 'lg';
} else if (attributeName.startsWith("lg-")) {
optionForSize = "lg";
responsiveScope = this.scope.lg;
attributeName = attributeName.slice(3);
} else if (attributeName.startsWith('xl-')) {
optionForSize = 'xl';
} else if (attributeName.startsWith("xl-")) {
optionForSize = "xl";
responsiveScope = this.scope.xl;

@@ -1038,6 +1274,4 @@ attributeName = attributeName.slice(3);

const parsedAttributeName = camelCase(attributeName);
if (responsiveScope && (responsiveScope as any)[parsedAttributeName]) {

@@ -1051,3 +1285,8 @@ oldValue = (responsiveScope as any)[parsedAttributeName];

// call custom attribute changed callback with parsed values
this.parsedAttributeChangedCallback(optionForSize + parsedAttributeName, oldValue, newValue, namespace);
this.parsedAttributeChangedCallback(
optionForSize + parsedAttributeName,
oldValue,
newValue,
namespace
);

@@ -1064,4 +1303,14 @@ this.bindIfReady();

*/
protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
return super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
protected parsedAttributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
return super.parsedAttributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
}

@@ -1068,0 +1317,0 @@

@@ -1,6 +0,6 @@

import { handleizeFormatter } from '@ribajs/core';
import templateHorizontal from './bs4-tabs-horizontal.component.html';
import templateVertical from './bs4-tabs-vertical.component.html';
import { handleizeFormatter } from "@ribajs/core";
import templateHorizontal from "./bs4-tabs-horizontal.component.html";
import templateVertical from "./bs4-tabs-vertical.component.html";
import { TemplatesComponent } from '../templates/templates.component';
import { TemplatesComponent } from "../templates/templates.component";

@@ -18,32 +18,31 @@ export interface Tab {

items: Tab[];
activate: Bs4TabsComponent['activate'];
deactivate: Bs4TabsComponent['activate'];
deactivateAll: Bs4TabsComponent['deactivateAll'];
activate: Bs4TabsComponent["activate"];
deactivate: Bs4TabsComponent["activate"];
deactivateAll: Bs4TabsComponent["deactivateAll"];
optionTabsAutoHeight: boolean;
optionTabsAngle: 'vertical' | 'horizontal';
optionTabsAngle: "vertical" | "horizontal";
}
export class Bs4TabsComponent extends TemplatesComponent {
public static tagName = "bs4-tabs";
public static tagName = 'bs4-tabs';
protected templateAttributes = [
{
name: 'title',
name: "title",
required: true,
},
{
name: 'handle',
name: "handle",
required: false,
},
{
name: 'type',
name: "type",
required: false,
},
{
name: 'active',
name: "active",
required: false,
},
{
name: 'index',
name: "index",
required: false,

@@ -57,5 +56,5 @@ },

deactivate: this.deactivate,
deactivateAll:this.deactivateAll,
deactivateAll: this.deactivateAll,
optionTabsAutoHeight: false,
optionTabsAngle: 'horizontal',
optionTabsAngle: "horizontal",
};

@@ -69,24 +68,64 @@

return [
'option-tabs-auto-height',
'option-tabs-angle',
'tab-0-title', 'tab-0-content', 'tab-0-handle',
'tab-1-title', 'tab-1-content', 'tab-1-handle',
'tab-2-title', 'tab-2-content', 'tab-2-handle',
'tab-3-title', 'tab-3-content', 'tab-3-handle',
'tab-4-title', 'tab-4-content', 'tab-4-handle',
'tab-5-title', 'tab-5-content', 'tab-5-handle',
'tab-6-title', 'tab-6-content', 'tab-6-handle',
'tab-7-title', 'tab-7-content', 'tab-7-handle',
'tab-8-title', 'tab-8-content', 'tab-8-handle',
'tab-9-title', 'tab-9-content', 'tab-9-handle',
'tab-10-title', 'tab-10-content', 'tab-10-handle',
'tab-11-title', 'tab-11-content', 'tab-11-handle',
'tab-12-title', 'tab-12-content', 'tab-12-handle',
'tab-13-title', 'tab-13-content', 'tab-13-handle',
'tab-14-title', 'tab-14-content', 'tab-14-handle',
'tab-15-title', 'tab-15-content', 'tab-15-handle',
'tab-16-title', 'tab-16-content', 'tab-16-handle',
'tab-17-title', 'tab-17-content', 'tab-17-handle',
'tab-18-title', 'tab-18-content', 'tab-18-handle',
'tab-19-title', 'tab-19-content', 'tab-19-handle',
"option-tabs-auto-height",
"option-tabs-angle",
"tab-0-title",
"tab-0-content",
"tab-0-handle",
"tab-1-title",
"tab-1-content",
"tab-1-handle",
"tab-2-title",
"tab-2-content",
"tab-2-handle",
"tab-3-title",
"tab-3-content",
"tab-3-handle",
"tab-4-title",
"tab-4-content",
"tab-4-handle",
"tab-5-title",
"tab-5-content",
"tab-5-handle",
"tab-6-title",
"tab-6-content",
"tab-6-handle",
"tab-7-title",
"tab-7-content",
"tab-7-handle",
"tab-8-title",
"tab-8-content",
"tab-8-handle",
"tab-9-title",
"tab-9-content",
"tab-9-handle",
"tab-10-title",
"tab-10-content",
"tab-10-handle",
"tab-11-title",
"tab-11-content",
"tab-11-handle",
"tab-12-title",
"tab-12-content",
"tab-12-handle",
"tab-13-title",
"tab-13-content",
"tab-13-handle",
"tab-14-title",
"tab-14-content",
"tab-14-handle",
"tab-15-title",
"tab-15-content",
"tab-15-handle",
"tab-16-title",
"tab-16-content",
"tab-16-handle",
"tab-17-title",
"tab-17-content",
"tab-17-handle",
"tab-18-title",
"tab-18-content",
"tab-18-handle",
"tab-19-title",
"tab-19-content",
"tab-19-handle",
];

@@ -114,8 +153,8 @@ }

this.tabPanes.forEach((tabPane) => {
if (!(tabPane as unknown as HTMLElement).style) {
if (!((tabPane as unknown) as HTMLElement).style) {
return;
}
(tabPane as unknown as HTMLElement).style.height = 'auto';
(tabPane as unknown as HTMLElement).style.display = 'block';
const height = (tabPane as unknown as HTMLElement).offsetHeight || 0;
((tabPane as unknown) as HTMLElement).style.height = "auto";
((tabPane as unknown) as HTMLElement).style.display = "block";
const height = ((tabPane as unknown) as HTMLElement).offsetHeight || 0;
if (height > heigest) {

@@ -126,9 +165,9 @@ heigest = height;

this.tabPanes.forEach((tabPane) => {
if (!(tabPane as unknown as HTMLElement).style) {
if (!((tabPane as unknown) as HTMLElement).style) {
return;
}
// Reset display style property
(tabPane as unknown as HTMLElement).style.display = '';
((tabPane as unknown) as HTMLElement).style.display = "";
if (heigest > 0) {
(tabPane as unknown as HTMLElement).style.height = heigest + 'px';
((tabPane as unknown) as HTMLElement).style.height = heigest + "px";
}

@@ -160,3 +199,6 @@ });

if (firstTabContentChild) {
this.triggerVisibilityChangedForElement(firstTabContentChild as Element, tab.active);
this.triggerVisibilityChangedForElement(
firstTabContentChild as Element,
tab.active
);
}

@@ -176,3 +218,7 @@

protected getTabContentChildByIndex(index: number) {
return this.el.querySelector(`.tab-content .tab-pane:nth-child(${index + 1}) > *`) || undefined;
return (
this.el.querySelector(
`.tab-content .tab-pane:nth-child(${index + 1}) > *`
) || undefined
);
}

@@ -183,9 +229,14 @@

* E.g. this event is used the bs4-slideshow component
* @param element
* @param visibile
* @param element
* @param visibile
*/
protected triggerVisibilityChangedForElement(element: Element, visibile: boolean) {
protected triggerVisibilityChangedForElement(
element: Element,
visibile: boolean
) {
setTimeout(() => {
// Use this event to update any custom element when it becomes visibile
element.dispatchEvent(new CustomEvent('visibility-changed', {detail: {visibile}}));
element.dispatchEvent(
new CustomEvent("visibility-changed", { detail: { visibile } })
);
}, 200);

@@ -204,3 +255,3 @@ }

this.tabPanes = this.el.querySelectorAll('[role="tabpanel"]');
this.scrollable = this.el.querySelector('[scrollable]');
this.scrollable = this.el.querySelector("[scrollable]");
}

@@ -210,3 +261,9 @@

while (newSize > this.scope.items.length) {
this.scope.items.push({handle: '', title: '', content: '', active: false, index: this.scope.items.length - 1});
this.scope.items.push({
handle: "",
title: "",
content: "",
active: false,
index: this.scope.items.length - 1,
});
}

@@ -222,3 +279,4 @@ }

const tabScrollPosition = curTab.getBoundingClientRect();
const scrollLeftTo = this.scrollable.scrollLeft || 0 + tabScrollPosition.left;
const scrollLeftTo =
this.scrollable.scrollLeft || 0 + tabScrollPosition.left;
// TODO animate

@@ -239,11 +297,14 @@ // this.scrollable.animate({ scrollLeft: scrollLeftTo}, 'slow');

if (this.tabs) {
this.tabs.forEach(((tab) => {
tab.removeEventListener('shown.bs.tab', this.onTabShownEventHandler);
tab.addEventListener('shown.bs.tab', this.onTabShownEventHandler);
}));
this.tabs.forEach((tab) => {
tab.removeEventListener("shown.bs.tab", this.onTabShownEventHandler);
tab.addEventListener("shown.bs.tab", this.onTabShownEventHandler);
});
}
if (this.scope.optionTabsAutoHeight) {
window.removeEventListener('resize', this.onResizeEventHandler.bind(this));
window.addEventListener('resize', this.onResizeEventHandler.bind(this));
window.removeEventListener(
"resize",
this.onResizeEventHandler.bind(this)
);
window.addEventListener("resize", this.onResizeEventHandler.bind(this));
this.setHeight();

@@ -254,3 +315,3 @@ }

protected addTabByAttribute(attributeName: string, newValue: string) {
const index = Number(attributeName.replace(/[^0-9]/g, ''));
const index = Number(attributeName.replace(/[^0-9]/g, ""));
if (index >= this.scope.items.length) {

@@ -260,10 +321,12 @@ this.resizeTabsArray(index + 1);

this.scope.items[index].index = index;
if (attributeName.endsWith('Content')) {
if (attributeName.endsWith("Content")) {
this.scope.items[index].content = newValue;
}
if (attributeName.endsWith('Title')) {
if (attributeName.endsWith("Title")) {
this.scope.items[index].title = newValue;
this.scope.items[index].handle = this.scope.items[index].handle || handleizeFormatter.read(this.scope.items[index].title);
this.scope.items[index].handle =
this.scope.items[index].handle ||
handleizeFormatter.read(this.scope.items[index].title);
}
if (attributeName.endsWith('Handle')) {
if (attributeName.endsWith("Handle")) {
this.scope.items[index].handle = newValue;

@@ -293,5 +356,15 @@ }

protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
if (attributeName.startsWith('tab')) {
protected parsedAttributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.parsedAttributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
if (attributeName.startsWith("tab")) {
this.addTabByAttribute(attributeName, newValue);

@@ -314,3 +387,3 @@ this.initTabs();

if (!this.el.hasChildNodes() || this.hasOnlyTemplateChilds()) {
if (this.scope.optionTabsAngle === 'horizontal') {
if (this.scope.optionTabsAngle === "horizontal") {
return templateHorizontal;

@@ -317,0 +390,0 @@ } else {

@@ -10,16 +10,19 @@ /**

import {
Component,
EventDispatcher,
} from '@ribajs/core';
import { Component, EventDispatcher } from "@ribajs/core";
import {
TOGGLE_BUTTON,
} from '../../constants';
import { TOGGLE_BUTTON } from "../../constants";
type State = 'undefined' | 'overlay-left' | 'overlay-right' | 'side-left' | 'side-right' | 'hidden' | 'added' | 'removed';
type State =
| "undefined"
| "overlay-left"
| "overlay-right"
| "side-left"
| "side-right"
| "hidden"
| "added"
| "removed";
interface Scope {
targetId?: string;
toggle: Bs4ToggleButtonComponent['toggle'];
toggle: Bs4ToggleButtonComponent["toggle"];
state: State;

@@ -33,12 +36,11 @@ isActive: boolean;

export class Bs4ToggleButtonComponent extends Component {
static get observedAttributes() {
return ['target-id'];
return ["target-id"];
}
protected requiredAttributes() {
return ['targetId'];
return ["targetId"];
}
public static tagName = 'bs4-toggle-button';
public static tagName = "bs4-toggle-button";

@@ -52,3 +54,3 @@ protected autobind = true;

toggle: this.toggle,
state: 'undefined',
state: "undefined",
isActive: true,

@@ -65,3 +67,6 @@ isClosed: false,

if (this.eventDispatcher) {
this.eventDispatcher.trigger(TOGGLE_BUTTON.eventNames.toggle, this.scope.targetId);
this.eventDispatcher.trigger(
TOGGLE_BUTTON.eventNames.toggle,
this.scope.targetId
);
}

@@ -73,3 +78,6 @@ }

// Trigger init to trigger there current state of all the components that are connected to this component
return this.eventDispatcher?.trigger(TOGGLE_BUTTON.eventNames.init, this.scope.targetId);
return this.eventDispatcher?.trigger(
TOGGLE_BUTTON.eventNames.init,
this.scope.targetId
);
}

@@ -84,3 +92,3 @@

this.scope.state = state;
this.scope.isActive = state !== 'hidden' && state !== 'removed';
this.scope.isActive = state !== "hidden" && state !== "removed";
this.scope.isClosed = !this.scope.isActive;

@@ -91,17 +99,46 @@ }

if (this.eventDispatcher) {
this.eventDispatcher.off(TOGGLE_BUTTON.eventNames.toggled, this.onToggledEvent);
this.eventDispatcher.off(
TOGGLE_BUTTON.eventNames.toggled,
this.onToggledEvent
);
}
this.eventDispatcher = new EventDispatcher(TOGGLE_BUTTON.nsPrefix + id);
this.eventDispatcher.on(TOGGLE_BUTTON.eventNames.toggled, this.onToggledEvent.bind(this));
this.eventDispatcher.on(
TOGGLE_BUTTON.eventNames.toggled,
this.onToggledEvent.bind(this)
);
// Triggered state triggered by `..trigger('init', ...`
this.eventDispatcher.on(TOGGLE_BUTTON.eventNames.state, this.onToggledEvent.bind(this));
this.eventDispatcher.on(
TOGGLE_BUTTON.eventNames.state,
this.onToggledEvent.bind(this)
);
}
protected attributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.attributeChangedCallback(attributeName, oldValue, newValue, namespace);
protected attributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.attributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
}
protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
if (attributeName === 'targetId' && newValue) {
protected parsedAttributeChangedCallback(
attributeName: string,
oldValue: any,
newValue: any,
namespace: string | null
) {
super.parsedAttributeChangedCallback(
attributeName,
oldValue,
newValue,
namespace
);
if (attributeName === "targetId" && newValue) {
this.initEventDispatcher(newValue);

@@ -115,3 +152,6 @@ }

if (this.eventDispatcher) {
this.eventDispatcher.off(TOGGLE_BUTTON.eventNames.toggled, this.onToggledEvent);
this.eventDispatcher.off(
TOGGLE_BUTTON.eventNames.toggled,
this.onToggledEvent
);
}

@@ -122,3 +162,5 @@ }

if (!this.el.hasChildNodes()) {
console.warn('No child elements found, this component as no template so you need to define your own as child of this component.');
console.warn(
"No child elements found, this component as no template so you need to define your own as child of this component."
);
}

@@ -125,0 +167,0 @@ return null;

@@ -1,15 +0,16 @@

export { Bs4DropdownComponent } from './bs4-dropdown/bs4-dropdown.component';
export { Bs4AccordionComponent } from './bs4-accordion/bs4-accordion.component';
export { Bs4ButtonComponent } from './bs4-button/bs4-button.component';
export { Bs4CarouselComponent } from './bs4-carousel/bs4-carousel.component';
export { Bs4ContentsComponent } from './bs4-contents/bs4-contents.component';
export { Bs4IconComponent } from './bs4-icon/bs4-icon.component';
export { Bs4ScrollspyComponent } from './bs4-scrollspy/bs4-scrollspy.component';
export { Bs4ShareComponent } from './bs4-share/bs4-share.component';
export { Bs4SidebarComponent } from './bs4-sidebar/bs4-sidebar.component';
export { Bs4SlideshowComponent } from './bs4-slideshow/bs4-slideshow.component';
export { Bs4ToggleButtonComponent } from './bs4-toggle-button/bs4-toggle-button.component';
export { Bs4NavbarComponent } from './bs4-navbar/bs4-navbar.component';
export { Bs4TabsComponent } from './bs4-tabs/bs4-tabs.component';
export { Bs4DropdownComponent } from "./bs4-dropdown/bs4-dropdown.component";
export { Bs4AccordionComponent } from "./bs4-accordion/bs4-accordion.component";
export { Bs4ButtonComponent } from "./bs4-button/bs4-button.component";
export { Bs4CarouselComponent } from "./bs4-carousel/bs4-carousel.component";
export { Bs4ContentsComponent } from "./bs4-contents/bs4-contents.component";
export { Bs4IconComponent } from "./bs4-icon/bs4-icon.component";
export { Bs4ScrollspyComponent } from "./bs4-scrollspy/bs4-scrollspy.component";
export { Bs4ShareComponent } from "./bs4-share/bs4-share.component";
export { Bs4SidebarComponent } from "./bs4-sidebar/bs4-sidebar.component";
export { Bs4SlideshowComponent } from "./bs4-slideshow/bs4-slideshow.component";
export { Bs4ToggleButtonComponent } from "./bs4-toggle-button/bs4-toggle-button.component";
export { Bs4NavbarComponent } from "./bs4-navbar/bs4-navbar.component";
export { Bs4TabsComponent } from "./bs4-tabs/bs4-tabs.component";
export { Bs4FormComponent } from "./bs4-form/bs4-form.component";
export { Bs4ToastContainerComponent } from "./bs4-toast-container/bs4-toast-container.component";
export { Bs4ToastItemComponent } from "./bs4-toast-item/bs4-toast-item.component";

@@ -1,9 +0,4 @@

import {
Component,
} from '@ribajs/core';
import {
camelCase,
} from '@ribajs/utils/src/type';
import { Component } from "@ribajs/core";
import { camelCase } from "@ribajs/utils/src/type";
export type AttributeType = string; // 'string' | 'number' | 'boolean';

@@ -24,3 +19,2 @@

export abstract class TemplatesComponent extends Component {
protected templateAttributes: TemplateAttributes = [];

@@ -48,11 +42,15 @@

*/
protected transformTemplateAttribute(name: string, value: any, type?: AttributeType) {
protected transformTemplateAttribute(
name: string,
value: any,
type?: AttributeType
) {
switch (type) {
case 'number':
case "number":
value = Number(value);
break;
case 'boolean':
value = value === 'true';
case "boolean":
value = value === "true";
break;
case 'string':
case "string":
default:

@@ -77,5 +75,10 @@ break;

for (const attribute of this.templateAttributes) {
const attrValue = this.transformTemplateAttribute(attribute.name, tpl.getAttribute(attribute.name));
const attrValue = this.transformTemplateAttribute(
attribute.name,
tpl.getAttribute(attribute.name)
);
if (attribute.required && !attrValue) {
console.error(new Error(`template "${attribute.name}" attribute is required!`));
console.error(
new Error(`template "${attribute.name}" attribute is required!`)
);
return;

@@ -91,10 +94,10 @@ }

const content = tpl.innerHTML;
this.scope.items.push({...attributes, content});
this.scope.items.push({ ...attributes, content });
}
protected addItemsByTemplate() {
const templates = this.el.querySelectorAll<HTMLTemplateElement>('template');
const templates = this.el.querySelectorAll<HTMLTemplateElement>("template");
for (let index = 0; index < templates.length; index++) {
const tpl = templates[index];
this.addItemByTemplate(tpl, index);

@@ -106,3 +109,3 @@ }

protected removeTemplates() {
const templates = this.el.querySelectorAll<HTMLTemplateElement>('template');
const templates = this.el.querySelectorAll<HTMLTemplateElement>("template");
for (let index = 0; index < templates.length; index++) {

@@ -118,3 +121,5 @@ const tpl = templates[index];

const child = this.el.childNodes[index];
allAreTemplates = allAreTemplates && (child.nodeName === 'TEMPLATE' || child.nodeName === '#text');
allAreTemplates =
allAreTemplates &&
(child.nodeName === "TEMPLATE" || child.nodeName === "#text");
}

@@ -121,0 +126,0 @@ return allAreTemplates;

// EventDispatcher events
export const TOGGLE_BUTTON = {
nsPrefix: 'bs4-toggle-button:',
nsPrefix: "bs4-toggle-button:",
eventNames: {
toggle: 'toggle',
toggled: 'toggled',
init: 'init',
state: 'state',
}
toggle: "toggle",
toggled: "toggled",
init: "init",
state: "state",
},
};

@@ -14,12 +14,12 @@

elEventNames: {
removed: 'removed',
added: 'added',
}
}
removed: "removed",
added: "added",
},
};
export const TOGGLE_CLASS= {
export const TOGGLE_CLASS = {
elEventNames: {
removed: 'removed',
added: 'added',
}
}
removed: "removed",
added: "added",
},
};

@@ -1,8 +0,8 @@

export * from './services';
export * from './binders';
export * from './components';
export * from "./services";
export * from "./binders";
export * from "./components";
// export * as formatters from './formatters/bs4.formatters';
export * from './services';
export * from "./services";
// export * from './interfaces/interfaces';
export * from './constants';
export * from './bs4.module';
export * from "./constants";
export * from "./bs4.module";

@@ -1,2 +0,10 @@

export type CarouselClassName = 'carousel' | 'active' | 'slide' | 'carousel-item-right' | 'carousel-item-left' | 'carousel-item-next' | 'carousel-item-prev' | 'carousel-item' | 'pointer-event';
export type CarouselClassName =
| "carousel"
| "active"
| "slide"
| "carousel-item-right"
| "carousel-item-left"
| "carousel-item-next"
| "carousel-item-prev"
| "carousel-item"
| "pointer-event";

@@ -1,1 +0,1 @@

export type CarouselDirection = 'next' | 'prev' | 'left' | 'right';
export type CarouselDirection = "next" | "prev" | "left" | "right";

@@ -0,59 +1,59 @@

/**
* Copy from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/bootstrap/index.d.ts
*/
export interface CarouselOption {
/**
* Copy from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/bootstrap/index.d.ts
* The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.
*
* @default 5000
*/
export interface CarouselOption {
/**
* The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.
*
* @default 5000
*/
interval?: false | number;
defaultInterval?: false | number;
interval?: false | number;
defaultInterval?: false | number;
/**
* Whether the carousel should react to keyboard events.
*
* @default true
*/
keyboard?: boolean;
/**
* Whether the carousel should react to keyboard events.
*
* @default true
*/
keyboard?: boolean;
/**
* Use to easily control the position of the carousel. It accepts the keywords prev or next, which alters the slide position
* relative to its current position. Alternatively, use `data-slide-to` to pass a raw slide index to the carousel.
*
* @default false
*/
slide?: "next" | "prev" | false;
/**
* Use to easily control the position of the carousel. It accepts the keywords prev or next, which alters the slide position
* relative to its current position. Alternatively, use `data-slide-to` to pass a raw slide index to the carousel.
*
* @default false
*/
slide?: "next" | "prev" | false;
/**
* If set to "hover", pauses the cycling of the carousel on `mouseenter` and resumes the cycling of the carousel on `mouseleave`.
* If set to false, hovering over the carousel won't pause it.
*
* On touch-enabled devices, when set to "hover", cycling will pause on `touchend` (once the user finished interacting with the carousel)
* for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.
*
* @default "hover"
*/
pause?: "hover" | false;
/**
* If set to "hover", pauses the cycling of the carousel on `mouseenter` and resumes the cycling of the carousel on `mouseleave`.
* If set to false, hovering over the carousel won't pause it.
*
* On touch-enabled devices, when set to "hover", cycling will pause on `touchend` (once the user finished interacting with the carousel)
* for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.
*
* @default "hover"
*/
pause?: "hover" | false;
/**
* Whether the carousel should cycle continuously or have hard stops.
*
* @default true
*/
wrap?: boolean;
/**
* Whether the carousel should cycle continuously or have hard stops.
*
* @default true
*/
wrap?: boolean;
/**
* Whether the carousel should support left/right swipe interactions on touchscreen devices.
*
* @default true
*/
touch?: boolean;
/**
* Whether the carousel should support left/right swipe interactions on touchscreen devices.
*
* @default true
*/
touch?: boolean;
/**
* Autoplays the carousel after the user manually cycles the first item. If "carousel", autoplays the carousel on load.
*
* @default false
*/
ride?: boolean;
}
/**
* Autoplays the carousel after the user manually cycles the first item. If "carousel", autoplays the carousel on load.
*
* @default false
*/
ride?: boolean;
}

@@ -1,4 +0,5 @@

export * from './carousel-class-name';
export * from './carousel-direction';
export * from './carousel-option';
export * from './share-item';
export * from "./carousel-class-name";
export * from "./carousel-direction";
export * from "./carousel-option";
export * from "./share-item";
export * from "./toast";

@@ -1,42 +0,42 @@

export type ShareUrlType = 'page' | 'image' | 'video';
export type ShareUrlType = "page" | "image" | "video";
export interface ShareItem {
/**
* An id for this share button entry. The share element associated with this entry will be classed with
* 'pswp__share--' + id
*/
id: string;
/**
* The user-visible text to display for this entry.
*/
label: string;
/**
* The full sharing endpoint URL for this social media site (e.g. Facebook's is facebook.com/sharer/sharer.php), with URL parameters.
* PhotoSwipUI_Default treats the URL specially. In the url string, any of the following text is treated specially:
* '{{url}}', '{{image_url}}, '{{raw_image_url}}, '{{text}}'. PhotoSwipeUI_Default will replace each of them with the following value:
*
* {{url}} becomes the (URIEncoded) url to the current "Page" (as returned by getPageURLForShare).
* {{image_url}} becomes the (URIEncoded) url of the selected image (as returned by getURLToShare).
* {{raw_image_url}} becomes the raw url of the selected image (as returned by getURLToShare).
* {{text}} becomes the (URIEncoded) share text of the selected image (as returned by getTextForShare).
*/
url: string;
/**
* Url string with placeholders to generate the url string above
*/
urlTemplate: string;
/**
* An id for this share button entry. The share element associated with this entry will be classed with
* 'pswp__share--' + id
*/
id: string;
mediaUrlTemplate?: string;
/**
* Whether this link is a direct download button or not.
*/
type?: 'download' | 'popup' | 'href';
/**
* The user-visible text to display for this entry.
*/
label: string;
availableFor: ShareUrlType[];
/**
* The full sharing endpoint URL for this social media site (e.g. Facebook's is facebook.com/sharer/sharer.php), with URL parameters.
* PhotoSwipUI_Default treats the URL specially. In the url string, any of the following text is treated specially:
* '{{url}}', '{{image_url}}, '{{raw_image_url}}, '{{text}}'. PhotoSwipeUI_Default will replace each of them with the following value:
*
* {{url}} becomes the (URIEncoded) url to the current "Page" (as returned by getPageURLForShare).
* {{image_url}} becomes the (URIEncoded) url of the selected image (as returned by getURLToShare).
* {{raw_image_url}} becomes the raw url of the selected image (as returned by getURLToShare).
* {{text}} becomes the (URIEncoded) share text of the selected image (as returned by getTextForShare).
*/
url: string;
available?: boolean;
}
/**
* Url string with placeholders to generate the url string above
*/
urlTemplate: string;
mediaUrlTemplate?: string;
/**
* Whether this link is a direct download button or not.
*/
type?: "download" | "popup" | "href";
availableFor: ShareUrlType[];
available?: boolean;
}

@@ -1,4 +0,4 @@

import { CarouselOption } from '../interfaces/carousel-option'
import { CarouselDirection } from '../interfaces/carousel-direction'
import { CarouselClassName } from '../interfaces/carousel-class-name'
import { CarouselOption } from "../interfaces/carousel-option";
import { CarouselDirection } from "../interfaces/carousel-direction";
import { CarouselClassName } from "../interfaces/carousel-class-name";

@@ -12,8 +12,5 @@ /**

import {
TRANSITION_END,
Utils,
} from './utils.service'
import EventHandler from './dom/event-handler'
import SelectorEngine from './dom/selector-engine'
import { TRANSITION_END, Utils } from "./utils.service";
import EventHandler from "./dom/event-handler";
import SelectorEngine from "./dom/selector-engine";

@@ -26,10 +23,10 @@ /**

const NAME = 'carousel'
const DATA_KEY = 'bs.carousel'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
const SWIPE_THRESHOLD = 40
const NAME = "carousel";
const DATA_KEY = "bs.carousel";
const EVENT_KEY = `.${DATA_KEY}`;
const DATA_API_KEY = ".data-api";
const ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
const ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
const SWIPE_THRESHOLD = 40;

@@ -40,22 +37,22 @@ const Default: CarouselOption = {

slide: false,
pause: 'hover',
pause: "hover",
wrap: true,
touch: true
}
touch: true,
};
const DefaultType = {
interval: '(number|boolean)',
keyboard: 'boolean',
slide: '(boolean|string)',
pause: '(string|boolean)',
wrap: 'boolean',
touch: 'boolean'
}
interval: "(number|boolean)",
keyboard: "boolean",
slide: "(boolean|string)",
pause: "(string|boolean)",
wrap: "boolean",
touch: "boolean",
};
const Direction = {
NEXT: 'next' as CarouselDirection,
PREV: 'prev' as CarouselDirection,
LEFT: 'left' as CarouselDirection,
RIGHT: 'right' as CarouselDirection,
}
NEXT: "next" as CarouselDirection,
PREV: "prev" as CarouselDirection,
LEFT: "left" as CarouselDirection,
RIGHT: "right" as CarouselDirection,
};

@@ -75,30 +72,30 @@ const Event = {

LOAD_DATA_API: `load${EVENT_KEY}${DATA_API_KEY}`,
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`
}
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`,
};
const ClassName = {
CAROUSEL: 'carousel' as CarouselClassName,
ACTIVE: 'active' as CarouselClassName,
SLIDE: 'slide' as CarouselClassName,
RIGHT: 'carousel-item-right' as CarouselClassName,
LEFT: 'carousel-item-left' as CarouselClassName,
NEXT: 'carousel-item-next' as CarouselClassName,
PREV: 'carousel-item-prev' as CarouselClassName,
ITEM: 'carousel-item' as CarouselClassName,
POINTER_EVENT: 'pointer-event' as CarouselClassName,
}
CAROUSEL: "carousel" as CarouselClassName,
ACTIVE: "active" as CarouselClassName,
SLIDE: "slide" as CarouselClassName,
RIGHT: "carousel-item-right" as CarouselClassName,
LEFT: "carousel-item-left" as CarouselClassName,
NEXT: "carousel-item-next" as CarouselClassName,
PREV: "carousel-item-prev" as CarouselClassName,
ITEM: "carousel-item" as CarouselClassName,
POINTER_EVENT: "pointer-event" as CarouselClassName,
};
const Selector = {
ACTIVE: '.active',
ACTIVE_ITEM: '.active.carousel-item',
ITEM: '.carousel-item',
ITEM_IMG: '.carousel-item img',
NEXT_PREV: '.carousel-item-next, .carousel-item-prev',
INDICATORS: '.carousel-indicators'
}
ACTIVE: ".active",
ACTIVE_ITEM: ".active.carousel-item",
ITEM: ".carousel-item",
ITEM_IMG: ".carousel-item img",
NEXT_PREV: ".carousel-item-next, .carousel-item-prev",
INDICATORS: ".carousel-indicators",
};
const PointerType = {
TOUCH: 'touch',
PEN: 'pen'
}
TOUCH: "touch",
PEN: "pen",
};

@@ -111,3 +108,2 @@ /**

class CarouselService {
private _items: HTMLElement[] | null = null;

@@ -120,3 +116,3 @@ private _interval: number | null = null;

private _config: CarouselOption;
private _element: HTMLElement
private _element: HTMLElement;
private _indicatorsElement: HTMLElement | null;

@@ -126,25 +122,31 @@ private _touchSupported: boolean;

public touchTimeout: number | null = null
public touchStartX = 0
public touchDeltaX = 0
public touchTimeout: number | null = null;
public touchStartX = 0;
public touchDeltaX = 0;
constructor(element: HTMLElement, config: CarouselOption) {
this._items = null
this._interval = null
this._activeElement = null
this._isPaused = false
this._isSliding = false
this.touchTimeout = null
this.touchStartX = 0
this.touchDeltaX = 0
this._items = null;
this._interval = null;
this._activeElement = null;
this._isPaused = false;
this._isSliding = false;
this.touchTimeout = null;
this.touchStartX = 0;
this.touchDeltaX = 0;
this._config = this._getConfig(config)
this._element = element
this._indicatorsElement = SelectorEngine.findOne(Selector.INDICATORS, this._element) as HTMLElement || null;
this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)
this._config = this._getConfig(config);
this._element = element;
this._indicatorsElement =
(SelectorEngine.findOne(
Selector.INDICATORS,
this._element
) as HTMLElement) || null;
this._touchSupported =
"ontouchstart" in document.documentElement ||
navigator.maxTouchPoints > 0;
this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);
console.debug('CarouselService', this);
console.debug("CarouselService", this);
this._addEventListeners()
this._addEventListeners();
}

@@ -155,3 +157,3 @@

static get Default() {
return Default
return Default;
}

@@ -163,3 +165,3 @@

if (!this._isSliding) {
this._slide(Direction.NEXT)
this._slide(Direction.NEXT);
}

@@ -172,3 +174,3 @@ }

if (!document.hidden && Utils.isVisible(this._element)) {
this.next()
this.next();
}

@@ -179,28 +181,28 @@ }

if (!this._isSliding) {
this._slide(Direction.PREV)
this._slide(Direction.PREV);
}
}
pause(event?: TouchEvent & MouseEvent & PointerEvent | boolean) {
pause(event?: (TouchEvent & MouseEvent & PointerEvent) | boolean) {
if (!event) {
this._isPaused = true
this._isPaused = true;
}
if (SelectorEngine.findOne(Selector.NEXT_PREV, this._element)) {
Utils.triggerTransitionEnd(this._element)
this.cycle(true)
Utils.triggerTransitionEnd(this._element);
this.cycle(true);
}
clearInterval(this._interval || undefined)
this._interval = null
clearInterval(this._interval || undefined);
this._interval = null;
}
cycle(event?: Event | TouchEvent & MouseEvent & PointerEvent | boolean) {
cycle(event?: Event | (TouchEvent & MouseEvent & PointerEvent) | boolean) {
if (!event) {
this._isPaused = false
this._isPaused = false;
}
if (this._interval) {
clearInterval(this._interval)
this._interval = null
clearInterval(this._interval);
this._interval = null;
}

@@ -210,5 +212,7 @@

this._interval = setInterval(
(document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
(document.visibilityState ? this.nextWhenVisible : this.next).bind(
this
),
this._config.interval
)
);
}

@@ -219,30 +223,33 @@ }

if (this._items === null) {
throw new Error('No items found!');
throw new Error("No items found!");
}
this._activeElement = SelectorEngine.findOne(Selector.ACTIVE_ITEM, this._element) as HTMLElement || null;
this._activeElement =
(SelectorEngine.findOne(
Selector.ACTIVE_ITEM,
this._element
) as HTMLElement) || null;
if (this._activeElement === null) {
throw new Error('Active element not found!');
throw new Error("Active element not found!");
}
const activeIndex = this._getItemIndex(this._activeElement)
const activeIndex = this._getItemIndex(this._activeElement);
if (index > this._items.length - 1 || index < 0) {
return
return;
}
if (this._isSliding) {
EventHandler.one(this._element, Event.SLID, () => this.to(index))
return
EventHandler.one(this._element, Event.SLID, () => this.to(index));
return;
}
if (activeIndex === index) {
this.pause()
this.cycle()
return
this.pause();
this.cycle();
return;
}
const direction: CarouselDirection = index > activeIndex ?
Direction.NEXT :
Direction.PREV;
const direction: CarouselDirection =
index > activeIndex ? Direction.NEXT : Direction.PREV;
this._slide(direction, this._items[index])
this._slide(direction, this._items[index]);
}

@@ -252,3 +259,2 @@

// EventHandler.off(this._element, EVENT_KEY)
// this._items = null

@@ -269,22 +275,22 @@ // this._config = null

...Default,
...config
} as CarouselOption
Utils.typeCheckConfig(NAME, config, DefaultType)
return config
...config,
} as CarouselOption;
Utils.typeCheckConfig(NAME, config, DefaultType);
return config;
}
_handleSwipe() {
const absDeltax = Math.abs(this.touchDeltaX)
const absDeltax = Math.abs(this.touchDeltaX);
if (absDeltax <= SWIPE_THRESHOLD) {
return
return;
}
const direction = absDeltax / this.touchDeltaX
const direction = absDeltax / this.touchDeltaX;
this.touchDeltaX = 0
this.touchDeltaX = 0;
// swipe left
if (direction > 0) {
this.prev()
this.prev();
}

@@ -294,3 +300,3 @@

if (direction < 0) {
this.next()
this.next();
}

@@ -301,15 +307,22 @@ }

if (this._config.keyboard) {
EventHandler
.on<KeyboardEvent>(this._element, Event.KEYDOWN, (event) => this._keydown(event))
EventHandler.on<KeyboardEvent>(this._element, Event.KEYDOWN, (event) =>
this._keydown(event)
);
}
if (this._config.pause === 'hover') {
EventHandler
.on(this._element, Event.MOUSEENTER, (event: TouchEvent & MouseEvent & PointerEvent) => this.pause(event))
EventHandler
.on(this._element, Event.MOUSELEAVE, (event: TouchEvent & MouseEvent & PointerEvent) => this.cycle(event))
if (this._config.pause === "hover") {
EventHandler.on(
this._element,
Event.MOUSEENTER,
(event: TouchEvent & MouseEvent & PointerEvent) => this.pause(event)
);
EventHandler.on(
this._element,
Event.MOUSELEAVE,
(event: TouchEvent & MouseEvent & PointerEvent) => this.cycle(event)
);
}
if (this._config.touch && this._touchSupported) {
this._addTouchEventListeners()
this._addTouchEventListeners();
}

@@ -320,8 +333,11 @@ }

const start = (event: TouchEvent & MouseEvent & PointerEvent) => {
if (this._pointerEvent && PointerType[event.pointerType.toUpperCase() as 'TOUCH' | 'PEN' ]) {
this.touchStartX = event.clientX
if (
this._pointerEvent &&
PointerType[event.pointerType.toUpperCase() as "TOUCH" | "PEN"]
) {
this.touchStartX = event.clientX;
} else if (!this._pointerEvent) {
this.touchStartX = event.touches[0].clientX
this.touchStartX = event.touches[0].clientX;
}
}
};

@@ -331,15 +347,18 @@ const move = (event: TouchEvent & MouseEvent & PointerEvent) => {

if (event.touches && event.touches.length > 1) {
this.touchDeltaX = 0
this.touchDeltaX = 0;
} else {
this.touchDeltaX = event.touches[0].clientX - this.touchStartX
this.touchDeltaX = event.touches[0].clientX - this.touchStartX;
}
}
};
const end = (event: TouchEvent & MouseEvent & PointerEvent) => {
if (this._pointerEvent && PointerType[event.pointerType.toUpperCase() as 'TOUCH' | 'PEN']) {
this.touchDeltaX = event.clientX - this.touchStartX
if (
this._pointerEvent &&
PointerType[event.pointerType.toUpperCase() as "TOUCH" | "PEN"]
) {
this.touchDeltaX = event.clientX - this.touchStartX;
}
this._handleSwipe()
if (this._config.pause === 'hover') {
this._handleSwipe();
if (this._config.pause === "hover") {
// If it's a touch-enabled device, mouseenter/leave are fired as

@@ -353,24 +372,54 @@ // part of the mouse compatibility events on first tap - the carousel

this.pause()
this.pause();
if (this.touchTimeout) {
clearTimeout(this.touchTimeout)
clearTimeout(this.touchTimeout);
}
this.touchTimeout = setTimeout((event: TouchEvent & MouseEvent & PointerEvent) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + (this._config.interval || 0))
this.touchTimeout = setTimeout(
(event: TouchEvent & MouseEvent & PointerEvent) => this.cycle(event),
TOUCHEVENT_COMPAT_WAIT + (this._config.interval || 0)
);
}
}
};
Utils.makeArray(SelectorEngine.find(Selector.ITEM_IMG, this._element)).forEach(itemImg => {
EventHandler.on(itemImg, Event.DRAG_START, (event: TouchEvent & MouseEvent & PointerEvent) => event.preventDefault())
})
Utils.makeArray(
SelectorEngine.find(Selector.ITEM_IMG, this._element)
).forEach((itemImg) => {
EventHandler.on(
itemImg,
Event.DRAG_START,
(event: TouchEvent & MouseEvent & PointerEvent) =>
event.preventDefault()
);
});
if (this._pointerEvent) {
EventHandler.on(this._element, Event.POINTERDOWN, (event: TouchEvent & MouseEvent & PointerEvent) => start(event))
EventHandler.on(this._element, Event.POINTERUP, (event: TouchEvent & MouseEvent & PointerEvent) => end(event))
EventHandler.on(
this._element,
Event.POINTERDOWN,
(event: TouchEvent & MouseEvent & PointerEvent) => start(event)
);
EventHandler.on(
this._element,
Event.POINTERUP,
(event: TouchEvent & MouseEvent & PointerEvent) => end(event)
);
this._element.classList.add(ClassName.POINTER_EVENT)
this._element.classList.add(ClassName.POINTER_EVENT);
} else {
EventHandler.on(this._element, Event.TOUCHSTART, (event: TouchEvent & MouseEvent & PointerEvent) => start(event))
EventHandler.on(this._element, Event.TOUCHMOVE, (event: TouchEvent & MouseEvent & PointerEvent) => move(event))
EventHandler.on(this._element, Event.TOUCHEND, (event: TouchEvent & MouseEvent & PointerEvent) => end(event))
EventHandler.on(
this._element,
Event.TOUCHSTART,
(event: TouchEvent & MouseEvent & PointerEvent) => start(event)
);
EventHandler.on(
this._element,
Event.TOUCHMOVE,
(event: TouchEvent & MouseEvent & PointerEvent) => move(event)
);
EventHandler.on(
this._element,
Event.TOUCHEND,
(event: TouchEvent & MouseEvent & PointerEvent) => end(event)
);
}

@@ -380,4 +429,7 @@ }

_keydown(event: KeyboardEvent) {
if ((event.target as any)?.tagName && /input|textarea/i.test((event.target as any).tagName)) {
return
if (
(event.target as any)?.tagName &&
/input|textarea/i.test((event.target as any).tagName)
) {
return;
}

@@ -387,9 +439,9 @@

case ARROW_LEFT_KEYCODE:
event.preventDefault()
this.prev()
break
event.preventDefault();
this.prev();
break;
case ARROW_RIGHT_KEYCODE:
event.preventDefault()
this.next()
break
event.preventDefault();
this.next();
break;
default:

@@ -403,35 +455,53 @@ }

}
this._items = element && element.parentNode ?
Utils.makeArray(SelectorEngine.find(Selector.ITEM, element.parentNode as HTMLElement)) :
[]
this._items =
element && element.parentNode
? Utils.makeArray(
SelectorEngine.find(
Selector.ITEM,
element.parentNode as HTMLElement
)
)
: [];
return this._items.indexOf(element)
return this._items.indexOf(element);
}
_getItemByDirection(direction: CarouselDirection, activeElement: HTMLElement) {
_getItemByDirection(
direction: CarouselDirection,
activeElement: HTMLElement
) {
if (this._items === null) {
throw new Error('No items found!');
throw new Error("No items found!");
}
const isNextDirection = direction === Direction.NEXT
const isPrevDirection = direction === Direction.PREV
const activeIndex = this._getItemIndex(activeElement)
const lastItemIndex = this._items.length - 1
const isGoingToWrap = (isPrevDirection && activeIndex === 0) ||
(isNextDirection && activeIndex === lastItemIndex)
const isNextDirection = direction === Direction.NEXT;
const isPrevDirection = direction === Direction.PREV;
const activeIndex = this._getItemIndex(activeElement);
const lastItemIndex = this._items.length - 1;
const isGoingToWrap =
(isPrevDirection && activeIndex === 0) ||
(isNextDirection && activeIndex === lastItemIndex);
if (isGoingToWrap && !this._config.wrap) {
return activeElement
return activeElement;
}
const delta = direction === Direction.PREV ? -1 : 1
const itemIndex = (activeIndex + delta) % this._items.length
const delta = direction === Direction.PREV ? -1 : 1;
const itemIndex = (activeIndex + delta) % this._items.length;
return itemIndex === -1 ?
this._items[this._items.length - 1] :
this._items[itemIndex]
return itemIndex === -1
? this._items[this._items.length - 1]
: this._items[itemIndex];
}
_triggerSlideEvent(relatedTarget: HTMLElement, eventDirectionName: CarouselDirection) {
const targetIndex = this._getItemIndex(relatedTarget)
const fromIndex = this._getItemIndex(SelectorEngine.findOne(Selector.ACTIVE_ITEM, this._element) as HTMLElement || null)
_triggerSlideEvent(
relatedTarget: HTMLElement,
eventDirectionName: CarouselDirection
) {
const targetIndex = this._getItemIndex(relatedTarget);
const fromIndex = this._getItemIndex(
(SelectorEngine.findOne(
Selector.ACTIVE_ITEM,
this._element
) as HTMLElement) || null
);

@@ -442,4 +512,4 @@ return EventHandler.trigger(this._element, Event.SLIDE, {

from: fromIndex,
to: targetIndex
})
to: targetIndex,
});
}

@@ -449,5 +519,8 @@

if (this._indicatorsElement) {
const indicators = SelectorEngine.find(Selector.ACTIVE, this._indicatorsElement)
const indicators = SelectorEngine.find(
Selector.ACTIVE,
this._indicatorsElement
);
for (let i = 0; i < indicators.length; i++) {
indicators[i].classList.remove(ClassName.ACTIVE)
indicators[i].classList.remove(ClassName.ACTIVE);
}

@@ -457,6 +530,6 @@

this._getItemIndex(element)
]
];
if (nextIndicator) {
nextIndicator.classList.add(ClassName.ACTIVE)
nextIndicator.classList.add(ClassName.ACTIVE);
}

@@ -467,13 +540,17 @@ }

_slide(direction: CarouselDirection, element?: HTMLElement) {
const activeElement = SelectorEngine.findOne(Selector.ACTIVE_ITEM, this._element) as HTMLElement | undefined
const activeElementIndex = this._getItemIndex(activeElement)
const nextElement = element || (activeElement &&
this._getItemByDirection(direction, activeElement))
const activeElement = SelectorEngine.findOne(
Selector.ACTIVE_ITEM,
this._element
) as HTMLElement | undefined;
const activeElementIndex = this._getItemIndex(activeElement);
const nextElement =
element ||
(activeElement && this._getItemByDirection(direction, activeElement));
if (!nextElement) {
throw new Error('Next element not found!');
throw new Error("Next element not found!");
}
const nextElementIndex = this._getItemIndex(nextElement)
const isCycling = Boolean(this._interval)
const nextElementIndex = this._getItemIndex(nextElement);
const isCycling = Boolean(this._interval);

@@ -485,19 +562,19 @@ let directionalClassName: CarouselClassName;

if (direction === Direction.NEXT) {
directionalClassName = ClassName.LEFT
orderClassName = ClassName.NEXT
eventDirectionName = Direction.LEFT
directionalClassName = ClassName.LEFT;
orderClassName = ClassName.NEXT;
eventDirectionName = Direction.LEFT;
} else {
directionalClassName = ClassName.RIGHT
orderClassName = ClassName.PREV
eventDirectionName = Direction.RIGHT
directionalClassName = ClassName.RIGHT;
orderClassName = ClassName.PREV;
eventDirectionName = Direction.RIGHT;
}
if (nextElement && nextElement.classList.contains(ClassName.ACTIVE)) {
this._isSliding = false
return
this._isSliding = false;
return;
}
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
if (slideEvent.defaultPrevented) {
return
return;
}

@@ -507,59 +584,65 @@

// Some weirdness is happening, so we bail
return
return;
}
this._isSliding = true
this._isSliding = true;
if (isCycling) {
this.pause()
this.pause();
}
this._setActiveIndicatorElement(nextElement)
this._setActiveIndicatorElement(nextElement);
if (this._element.classList.contains(ClassName.SLIDE)) {
nextElement.classList.add(orderClassName)
nextElement.classList.add(orderClassName);
Utils.reflow(nextElement)
Utils.reflow(nextElement);
activeElement.classList.add(directionalClassName)
nextElement.classList.add(directionalClassName)
activeElement.classList.add(directionalClassName);
nextElement.classList.add(directionalClassName);
const nextElementInterval = parseInt(nextElement.getAttribute('data-interval') || '0', 10)
const nextElementInterval = parseInt(
nextElement.getAttribute("data-interval") || "0",
10
);
if (nextElementInterval) {
this._config.defaultInterval = this._config.defaultInterval || this._config.interval
this._config.interval = nextElementInterval
this._config.defaultInterval =
this._config.defaultInterval || this._config.interval;
this._config.interval = nextElementInterval;
} else {
this._config.interval = this._config.defaultInterval || this._config.interval
this._config.interval =
this._config.defaultInterval || this._config.interval;
}
const transitionDuration = Utils.getTransitionDurationFromElement(activeElement)
const transitionDuration = Utils.getTransitionDurationFromElement(
activeElement
);
EventHandler
.one(activeElement, TRANSITION_END, () => {
nextElement.classList.remove(directionalClassName)
nextElement.classList.remove(orderClassName)
nextElement.classList.add(ClassName.ACTIVE)
EventHandler.one(activeElement, TRANSITION_END, () => {
nextElement.classList.remove(directionalClassName);
nextElement.classList.remove(orderClassName);
nextElement.classList.add(ClassName.ACTIVE);
activeElement.classList.remove(ClassName.ACTIVE)
activeElement.classList.remove(orderClassName)
activeElement.classList.remove(directionalClassName)
activeElement.classList.remove(ClassName.ACTIVE);
activeElement.classList.remove(orderClassName);
activeElement.classList.remove(directionalClassName);
this._isSliding = false
this._isSliding = false;
setTimeout(() => {
EventHandler.trigger(this._element, Event.SLID, {
relatedTarget: nextElement,
direction: eventDirectionName,
from: activeElementIndex,
to: nextElementIndex
})
}, 0)
})
setTimeout(() => {
EventHandler.trigger(this._element, Event.SLID, {
relatedTarget: nextElement,
direction: eventDirectionName,
from: activeElementIndex,
to: nextElementIndex,
});
}, 0);
});
Utils.emulateTransitionEnd(activeElement, transitionDuration)
Utils.emulateTransitionEnd(activeElement, transitionDuration);
} else {
activeElement.classList.remove(ClassName.ACTIVE)
nextElement.classList.add(ClassName.ACTIVE)
activeElement.classList.remove(ClassName.ACTIVE);
nextElement.classList.add(ClassName.ACTIVE);
this._isSliding = false
this._isSliding = false;
EventHandler.trigger(this._element, Event.SLID, {

@@ -569,8 +652,8 @@ relatedTarget: nextElement,

from: activeElementIndex,
to: nextElementIndex
})
to: nextElementIndex,
});
}
if (isCycling) {
this.cycle()
this.cycle();
}

@@ -580,2 +663,2 @@ }

export default CarouselService
export default CarouselService;

@@ -8,9 +8,6 @@ /**

import {
TRANSITION_END,
Utils,
} from './utils.service'
import EventHandler from './dom/event-handler'
import SelectorEngine from './dom/selector-engine'
import Data from './dom/data'
import { TRANSITION_END, Utils } from "./utils.service";
import EventHandler from "./dom/event-handler";
import SelectorEngine from "./dom/selector-engine";
import Data from "./dom/data";

@@ -28,31 +25,31 @@ export interface Config {

export const NAME = 'collapse'
export const VERSION = '4.3.1'
export const DATA_KEY = 'bs.collapse'
export const EVENT_KEY = `.${DATA_KEY}`
export const NAME = "collapse";
export const VERSION = "4.3.1";
export const DATA_KEY = "bs.collapse";
export const EVENT_KEY = `.${DATA_KEY}`;
export const Default = {
toggle: true,
parent: ''
}
parent: "",
};
export const DefaultType = {
toggle: 'boolean',
parent: '(string|element)'
}
toggle: "boolean",
parent: "(string|element)",
};
export const EVENT_SHOW = `show${EVENT_KEY}`
export const EVENT_SHOWN = `shown${EVENT_KEY}`
export const EVENT_HIDE = `hide${EVENT_KEY}`
export const EVENT_HIDDEN = `hidden${EVENT_KEY}`
export const EVENT_SHOW = `show${EVENT_KEY}`;
export const EVENT_SHOWN = `shown${EVENT_KEY}`;
export const EVENT_HIDE = `hide${EVENT_KEY}`;
export const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
export const CLASS_NAME_SHOW = 'show'
export const CLASS_NAME_COLLAPSE = 'collapse'
export const CLASS_NAME_COLLAPSING = 'collapsing'
export const CLASS_NAME_COLLAPSED = 'collapsed'
export const CLASS_NAME_SHOW = "show";
export const CLASS_NAME_COLLAPSE = "collapse";
export const CLASS_NAME_COLLAPSING = "collapsing";
export const CLASS_NAME_COLLAPSED = "collapsed";
export const WIDTH = 'width'
export const HEIGHT = 'height'
export const WIDTH = "width";
export const HEIGHT = "height";
export const SELECTOR_ACTIVES = '.show, .collapsing'
export const SELECTOR_ACTIVES = ".show, .collapsing";
// export const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]'

@@ -74,6 +71,10 @@

constructor(element: HTMLElement, triggerList: NodeListOf<HTMLElement> | HTMLElement[], config: Partial<Config> = {}) {
this._isTransitioning = false
this._element = element
this._config = this._getConfig(config)
constructor(
element: HTMLElement,
triggerList: NodeListOf<HTMLElement> | HTMLElement[],
config: Partial<Config> = {}
) {
this._isTransitioning = false;
this._element = element;
this._config = this._getConfig(config);
this._triggerArray = Array.from(triggerList);

@@ -99,6 +100,6 @@ // this._triggerArray = Array.from(SelectorEngine.find(

this._parent = this._config.parent ? this._getParent() : null
this._parent = this._config.parent ? this._getParent() : null;
if (!this._config.parent) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray)
this._addAriaAndCollapsedClass(this._element, this._triggerArray);
// this._addAriaAndCollapsedClass(this._element, [])

@@ -108,6 +109,6 @@ }

if (this._config.toggle) {
this.toggle()
this.toggle();
}
Data.setData(element, DATA_KEY, this)
Data.setData(element, DATA_KEY, this);
}

@@ -118,7 +119,7 @@

static get VERSION() {
return VERSION
return VERSION;
}
static get Default() {
return Default
return Default;
}

@@ -138,5 +139,5 @@

if (this.isExpanded()) {
this.hide()
this.hide();
} else {
this.show()
this.show();
}

@@ -146,11 +147,12 @@ }

show() {
if (!this._element) {
console.warn('this._element not set!');
console.warn("this._element not set!");
return;
}
if (this._isTransitioning ||
this._element.classList.contains(CLASS_NAME_SHOW)) {
return
if (
this._isTransitioning ||
this._element.classList.contains(CLASS_NAME_SHOW)
) {
return;
}

@@ -162,127 +164,138 @@

if (this._parent) {
actives = Array.from(SelectorEngine.find(SELECTOR_ACTIVES, this._parent))
.filter(elem => {
if (typeof this._config.parent === 'string') {
return elem.getAttribute('data-parent') === this._config.parent
}
actives = Array.from(
SelectorEngine.find(SELECTOR_ACTIVES, this._parent)
).filter((elem) => {
if (typeof this._config.parent === "string") {
return elem.getAttribute("data-parent") === this._config.parent;
}
return elem.classList.contains(CLASS_NAME_COLLAPSE)
}) as HTMLElement[];
return elem.classList.contains(CLASS_NAME_COLLAPSE);
}) as HTMLElement[];
if (actives.length === 0) {
actives = null
actives = null;
}
}
const container = this._selector ? SelectorEngine.findOne(this._selector) : null;
const container = this._selector
? SelectorEngine.findOne(this._selector)
: null;
if (actives) {
const tempActiveData = actives.filter(elem => container !== elem)
activesData = tempActiveData[0] ? Data.getData(tempActiveData[0], DATA_KEY) : null
const tempActiveData = actives.filter((elem) => container !== elem);
activesData = tempActiveData[0]
? Data.getData(tempActiveData[0], DATA_KEY)
: null;
if (activesData && activesData._isTransitioning) {
return
return;
}
}
const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)
const startEvent = EventHandler.trigger(this._element, EVENT_SHOW);
if (startEvent.defaultPrevented) {
return
return;
}
if (actives) {
actives.forEach(elemActive => {
actives.forEach((elemActive) => {
if (container !== elemActive) {
CollapseService.collapseInterface(elemActive, 'hide')
CollapseService.collapseInterface(elemActive, "hide");
}
if (!activesData) {
Data.setData(elemActive, DATA_KEY, null)
Data.setData(elemActive, DATA_KEY, null);
}
})
});
}
const dimension = this._getDimension()
const dimension = this._getDimension();
this._element.classList.remove(CLASS_NAME_COLLAPSE)
this._element.classList.add(CLASS_NAME_COLLAPSING)
this._element.classList.remove(CLASS_NAME_COLLAPSE);
this._element.classList.add(CLASS_NAME_COLLAPSING);
this._element.style[dimension] = '0'
this._element.style[dimension] = "0";
if (this._triggerArray?.length) {
this._triggerArray.forEach(element => {
element.classList.remove(CLASS_NAME_COLLAPSED)
element.setAttribute('aria-expanded', 'true')
})
this._triggerArray.forEach((element) => {
element.classList.remove(CLASS_NAME_COLLAPSED);
element.setAttribute("aria-expanded", "true");
});
}
this.setTransitioning(true)
this.setTransitioning(true);
const complete = () => {
if (!this._element) {
console.warn('this._element not set!');
console.warn("this._element not set!");
return;
}
this._element.classList.remove(CLASS_NAME_COLLAPSING)
this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)
this._element.classList.remove(CLASS_NAME_COLLAPSING);
this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
this._element.style[dimension] = ''
this._element.style[dimension] = "";
this.setTransitioning(false)
this.setTransitioning(false);
EventHandler.trigger(this._element, EVENT_SHOWN)
}
EventHandler.trigger(this._element, EVENT_SHOWN);
};
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
const scrollSize = `scroll${capitalizedDimension}` as 'scrollWidth' | 'scrollHeight';
const transitionDuration = Utils.getTransitionDurationFromElement(this._element)
const capitalizedDimension =
dimension[0].toUpperCase() + dimension.slice(1);
const scrollSize = `scroll${capitalizedDimension}` as
| "scrollWidth"
| "scrollHeight";
const transitionDuration = Utils.getTransitionDurationFromElement(
this._element
);
EventHandler.one(this._element, TRANSITION_END, complete)
EventHandler.one(this._element, TRANSITION_END, complete);
Utils.emulateTransitionEnd(this._element, transitionDuration)
this._element.style[dimension] = `${this._element[scrollSize]}px`
Utils.emulateTransitionEnd(this._element, transitionDuration);
this._element.style[dimension] = `${this._element[scrollSize]}px`;
if (!this._config.parent && this._triggerArray) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray, true)
this._addAriaAndCollapsedClass(this._element, this._triggerArray, true);
// this._addAriaAndCollapsedClass(this._element, [])
}
}
hide() {
if (!this._element) {
console.warn('this._element not set!');
console.warn("this._element not set!");
return;
}
if (this._isTransitioning ||
!this._element.classList.contains(CLASS_NAME_SHOW)) {
return
if (
this._isTransitioning ||
!this._element.classList.contains(CLASS_NAME_SHOW)
) {
return;
}
const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)
const startEvent = EventHandler.trigger(this._element, EVENT_HIDE);
if (startEvent.defaultPrevented) {
return
return;
}
const dimension = this._getDimension()
const dimension = this._getDimension();
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`
this._element.style[dimension] = `${
this._element.getBoundingClientRect()[dimension]
}px`;
Utils.reflow(this._element)
Utils.reflow(this._element);
this._element.classList.add(CLASS_NAME_COLLAPSING)
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)
this._element.classList.add(CLASS_NAME_COLLAPSING);
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
const triggerArrayLength = this._triggerArray?.length
const triggerArrayLength = this._triggerArray?.length;
if (triggerArrayLength && this._triggerArray && triggerArrayLength > 0) {
for (let i = 0; i < triggerArrayLength; i++) {
const trigger = this._triggerArray[i]
const elem = Utils.getElementFromSelector(trigger)
const trigger = this._triggerArray[i];
const elem = Utils.getElementFromSelector(trigger);
if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) {
trigger.classList.add(CLASS_NAME_COLLAPSED)
trigger.setAttribute('aria-expanded', 'false')
trigger.classList.add(CLASS_NAME_COLLAPSED);
trigger.setAttribute("aria-expanded", "false");
}

@@ -292,3 +305,3 @@ }

this.setTransitioning(true)
this.setTransitioning(true);

@@ -298,18 +311,20 @@ const complete = () => {

if (!this._element) {
console.warn('this._element not set!');
console.warn("this._element not set!");
return;
}
this._element.classList.remove(CLASS_NAME_COLLAPSING)
this._element.classList.add(CLASS_NAME_COLLAPSE)
EventHandler.trigger(this._element, EVENT_HIDDEN)
}
this._element.classList.remove(CLASS_NAME_COLLAPSING);
this._element.classList.add(CLASS_NAME_COLLAPSE);
EventHandler.trigger(this._element, EVENT_HIDDEN);
};
this._element.style[dimension] = ''
const transitionDuration = Utils.getTransitionDurationFromElement(this._element)
this._element.style[dimension] = "";
const transitionDuration = Utils.getTransitionDurationFromElement(
this._element
);
EventHandler.one(this._element, TRANSITION_END, complete)
EventHandler.one(this._element, TRANSITION_END, complete);
Utils.emulateTransitionEnd(this._element, transitionDuration);
if (!this._config.parent && this._triggerArray) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray, false)
this._addAriaAndCollapsedClass(this._element, this._triggerArray, false);
// this._addAriaAndCollapsedClass(this._element, [])

@@ -320,3 +335,3 @@ }

setTransitioning(isTransitioning: boolean) {
this._isTransitioning = isTransitioning
this._isTransitioning = isTransitioning;
}

@@ -329,7 +344,7 @@

this._config = null
this._parent = null
this._element = null
this._config = null;
this._parent = null;
this._element = null;
// this._triggerArray = null
this._isTransitioning = false
this._isTransitioning = false;
}

@@ -342,63 +357,68 @@

...Default,
...config
}
config.toggle = Boolean(config.toggle) // Coerce string values
Utils.typeCheckConfig(NAME, config, DefaultType)
return config as Config
...config,
};
config.toggle = Boolean(config.toggle); // Coerce string values
Utils.typeCheckConfig(NAME, config, DefaultType);
return config as Config;
}
_getDimension() {
const hasWidth = this._element ? this._element.classList.contains(WIDTH) : false;
return hasWidth ? WIDTH : HEIGHT
const hasWidth = this._element
? this._element.classList.contains(WIDTH)
: false;
return hasWidth ? WIDTH : HEIGHT;
}
_getParent() {
let { parent } = this._config
let { parent } = this._config;
if (Utils.isElement(parent)) {
// it's a jQuery object
if (typeof parent.jquery !== 'undefined' || typeof parent[0] !== 'undefined') {
parent = parent[0]
if (
typeof parent.jquery !== "undefined" ||
typeof parent[0] !== "undefined"
) {
parent = parent[0];
}
} else {
parent = SelectorEngine.findOne(parent)
parent = SelectorEngine.findOne(parent);
}
// const selector = `${SELECTOR_DATA_TOGGLE}[data-parent="${parent}"]`
const selector = `[data-parent="${parent}"]`
const selector = `[data-parent="${parent}"]`;
SelectorEngine.find(selector, parent)
.forEach(element => {
const selected = Utils.getElementFromSelector(element)
SelectorEngine.find(selector, parent).forEach((element) => {
const selected = Utils.getElementFromSelector(element);
if (selected) {
this._addAriaAndCollapsedClass(
selected,
[element]
)
} else {
console.warn();
}
})
if (selected) {
this._addAriaAndCollapsedClass(selected, [element]);
} else {
console.warn();
}
});
return parent
return parent;
}
_addAriaAndCollapsedClass(element: HTMLElement, triggerArray: HTMLElement[], isOpen?: boolean) {
_addAriaAndCollapsedClass(
element: HTMLElement,
triggerArray: HTMLElement[],
isOpen?: boolean
) {
// console.debug('_addAriaAndCollapsedClass', element, triggerArray);
if (element) {
if (typeof isOpen !== 'boolean') {
isOpen = element.classList.contains(CLASS_NAME_SHOW)
if (typeof isOpen !== "boolean") {
isOpen = element.classList.contains(CLASS_NAME_SHOW);
}
if (triggerArray.length) {
triggerArray.forEach(elem => {
triggerArray.forEach((elem) => {
if (isOpen) {
elem.classList.remove(CLASS_NAME_COLLAPSED)
elem.classList.remove(CLASS_NAME_COLLAPSED);
} else {
elem.classList.add(CLASS_NAME_COLLAPSED)
elem.classList.add(CLASS_NAME_COLLAPSED);
}
elem.setAttribute('aria-expanded', (!!isOpen).toString())
})
elem.setAttribute("aria-expanded", (!!isOpen).toString());
});
}

@@ -411,30 +431,29 @@ }

static collapseInterface(element: HTMLElement, config: string) {
let data = Data.getData(element, DATA_KEY)
let data = Data.getData(element, DATA_KEY);
const _config: Config = {
...Default,
...element.dataset,
...typeof config === 'object' && config ? config : {}
}
...(typeof config === "object" && config ? config : {}),
};
if (!data && _config.toggle && /show|hide/.test(config)) {
_config.toggle = false
_config.toggle = false;
}
if (!data) {
data = new CollapseService(element, [], _config)
data = new CollapseService(element, [], _config);
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`)
if (typeof config === "string") {
if (typeof data[config] === "undefined") {
throw new TypeError(`No method named "${config}"`);
}
data[config]()
data[config]();
}
}
static getInstance(element: HTMLElement) {
return Data.getData(element, DATA_KEY)
return Data.getData(element, DATA_KEY);
}
}

@@ -15,19 +15,18 @@ /**

const mapData = (() => {
const storeData: { [id: string]: any} = {};
let id = 1
const storeData: { [id: string]: any } = {};
let id = 1;
return {
set(element: HTMLElement, key: string, data: any) {
if (typeof element.dataset.key === 'undefined') {
if (typeof element.dataset.key === "undefined") {
element.dataset.key = key;
element.dataset.id = id.toString();
id++
id++;
}
if (element.dataset.id) {
storeData[element.dataset.id] = data
storeData[element.dataset.id] = data;
}
},
get(element: HTMLElement, key: string) {
if (!element || typeof element.dataset.key === 'undefined') {
return null
if (!element || typeof element.dataset.key === "undefined") {
return null;
}

@@ -38,12 +37,15 @@

id: element.dataset.id,
};
if (
keyProperties.key === key &&
typeof keyProperties.id !== "undefined"
) {
return storeData[keyProperties.id];
}
if (keyProperties.key === key && typeof(keyProperties.id) !== 'undefined') {
return storeData[keyProperties.id]
}
return null
return null;
},
delete(element: HTMLElement, key: string) {
if (typeof element.dataset.key === 'undefined') {
return
if (typeof element.dataset.key === "undefined") {
return;
}

@@ -54,23 +56,26 @@

id: element.dataset.id,
};
if (
keyProperties.key === key &&
typeof keyProperties.id !== "undefined"
) {
delete storeData[keyProperties.id];
delete element.dataset.key;
}
if (keyProperties.key === key && typeof(keyProperties.id) !== 'undefined') {
delete storeData[keyProperties.id]
delete element.dataset.key
}
}
}
})()
},
};
})();
class Data {
public static setData(instance: HTMLElement, key: string, data: any) {
mapData.set(instance, key, data)
mapData.set(instance, key, data);
}
public static getData(instance: HTMLElement, key: string) {
return mapData.get(instance, key)
return mapData.get(instance, key);
}
public static removeData(instance: HTMLElement, key: string) {
mapData.delete(instance, key)
mapData.delete(instance, key);
}
}
export default Data
export default Data;

@@ -5,15 +5,31 @@ /**

class EventHandler {
public static on<T>(element: HTMLElement, eventName: string, handler: (e: T) => void) {
public static on<T>(
element: HTMLElement,
eventName: string,
handler: (e: T) => void
) {
return element.addEventListener(eventName as any, handler, {});
}
public static one<T>(element: HTMLElement, eventName: string, handler: (e: T) => void) {
return element.addEventListener(eventName as any, handler, {once: true});
public static one<T>(
element: HTMLElement,
eventName: string,
handler: (e: T) => void
) {
return element.addEventListener(eventName as any, handler, { once: true });
}
public static off<T>(element: HTMLElement, originalTypeEvent: string, handler: (e: T) => void) {
public static off<T>(
element: HTMLElement,
originalTypeEvent: string,
handler: (e: T) => void
) {
return element.removeEventListener(originalTypeEvent as any, handler);
}
public static trigger<T = any>(element: HTMLElement, eventName: string, extraParameters: any = {}) {
public static trigger<T = any>(
element: HTMLElement,
eventName: string,
extraParameters: any = {}
) {
const event = new CustomEvent<T>(eventName, {

@@ -27,2 +43,2 @@ detail: extraParameters,

export default EventHandler
export default EventHandler;

@@ -1,3 +0,3 @@

export * from './data';
export * from './event-handler';
export * from './selector-engine';
export * from "./data";
export * from "./event-handler";
export * from "./selector-engine";

@@ -9,3 +9,3 @@ /**

import { Utils } from '../utils.service'
import { Utils } from "../utils.service";

@@ -18,59 +18,76 @@ /**

const NODE_TEXT = 3
const NODE_TEXT = 3;
class SelectorEngine {
public static matches(element: HTMLElement | Node & ParentNode, selector: string) {
return Element.prototype.matches.call(element, selector)
public static matches(
element: HTMLElement | (Node & ParentNode),
selector: string
) {
return Element.prototype.matches.call(element, selector);
}
public static find(selector: string, element = document.documentElement) {
return Element.prototype.querySelectorAll.call(element, selector) as NodeListOf<HTMLElement>
return Element.prototype.querySelectorAll.call(
element,
selector
) as NodeListOf<HTMLElement>;
}
public static findOne(selector: string, element = document.documentElement) {
return Element.prototype.querySelector.call(element, selector) as HTMLElement | null;
return Element.prototype.querySelector.call(
element,
selector
) as HTMLElement | null;
}
public static children(element: HTMLElement, selector: string) {
const children = Utils.makeArray(element.children)
return children.filter(child => this.matches(child, selector))
const children = Utils.makeArray(element.children);
return children.filter((child) => this.matches(child, selector));
}
public static parents(element: HTMLElement, selector: string) {
const parents = []
const parents = [];
let ancestor = element.parentNode
let ancestor = element.parentNode;
while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
while (
ancestor &&
ancestor.nodeType === Node.ELEMENT_NODE &&
ancestor.nodeType !== NODE_TEXT
) {
if (this.matches(ancestor, selector)) {
parents.push(ancestor)
parents.push(ancestor);
}
ancestor = ancestor.parentNode
ancestor = ancestor.parentNode;
}
return parents
return parents;
}
public static closest(element: HTMLElement, selector: string) {
return Element.prototype.closest.call(element, selector)
return Element.prototype.closest.call(element, selector);
}
public static prev(element: HTMLElement, selector: string) {
const siblings = []
const siblings = [];
let previous = element.previousSibling
let previous = element.previousSibling;
while (previous && previous.nodeType === Node.ELEMENT_NODE && previous.nodeType !== NODE_TEXT) {
while (
previous &&
previous.nodeType === Node.ELEMENT_NODE &&
previous.nodeType !== NODE_TEXT
) {
if (this.matches(previous as HTMLElement, selector)) {
siblings.push(previous)
siblings.push(previous);
}
previous = previous.previousSibling
previous = previous.previousSibling;
}
return siblings
return siblings;
}
}
export default SelectorEngine
export default SelectorEngine;

@@ -1,3 +0,3 @@

import Popper from 'popper.js'; // /dist/umd/popper
import { Utils } from './utils.service';
import Popper from "popper.js"; // /dist/umd/popper
import { Utils } from "./utils.service";
/**

@@ -17,70 +17,72 @@ * --------------------------------------------------------------------------

export const NAME = 'dropdown';
export const VERSION = '4.1.3';
export const DATA_KEY = 'bs.dropdown';
export const EVENT_KEY = `.${DATA_KEY}`;
export const DATA_API_KEY = '.data-api';
export const ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
export const SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
export const TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
export const ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
export const ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
export const NAME = "dropdown";
export const VERSION = "4.1.3";
export const DATA_KEY = "bs.dropdown";
export const EVENT_KEY = `.${DATA_KEY}`;
export const DATA_API_KEY = ".data-api";
export const ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
export const SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
export const TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
export const ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
export const ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
export const RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
export const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`);
export const REGEXP_KEYDOWN = new RegExp(
`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`
);
export const EVENT = {
HIDE : `hide${EVENT_KEY}`,
HIDDEN : `hidden${EVENT_KEY}`,
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
CLICK : `click${EVENT_KEY}`,
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
KEYDOWN_DATA_API : `keydown${EVENT_KEY}${DATA_API_KEY}`,
KEYUP_DATA_API : `keyup${EVENT_KEY}${DATA_API_KEY}`,
HIDE: `hide${EVENT_KEY}`,
HIDDEN: `hidden${EVENT_KEY}`,
SHOW: `show${EVENT_KEY}`,
SHOWN: `shown${EVENT_KEY}`,
CLICK: `click${EVENT_KEY}`,
CLICK_DATA_API: `click${EVENT_KEY}${DATA_API_KEY}`,
KEYDOWN_DATA_API: `keydown${EVENT_KEY}${DATA_API_KEY}`,
KEYUP_DATA_API: `keyup${EVENT_KEY}${DATA_API_KEY}`,
};
export const CLASSNAME = {
DISABLED : 'disabled',
SHOW : 'show',
DROPUP : 'dropup',
DROPRIGHT : 'dropright',
DROPLEFT : 'dropleft',
MENURIGHT : 'dropdown-menu-right',
MENULEFT : 'dropdown-menu-left',
POSITION_STATIC : 'position-static',
DISABLED: "disabled",
SHOW: "show",
DROPUP: "dropup",
DROPRIGHT: "dropright",
DROPLEFT: "dropleft",
MENURIGHT: "dropdown-menu-right",
MENULEFT: "dropdown-menu-left",
POSITION_STATIC: "position-static",
};
export const SELECTOR = {
DATA_TOGGLE : 'bs4-dropdown .dropdown-toggle',
FORM_CHILD : '.dropdown form',
MENU : '.dropdown-menu',
NAVBAR_NAV : '.navbar-nav',
VISIBLE_ITEMS : '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)',
DATA_TOGGLE: "bs4-dropdown .dropdown-toggle",
FORM_CHILD: ".dropdown form",
MENU: ".dropdown-menu",
NAVBAR_NAV: ".navbar-nav",
VISIBLE_ITEMS: ".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",
};
export const ATTACHMENTMAP = {
TOP : 'top-start',
TOPEND : 'top-end',
BOTTOM : 'bottom-start',
BOTTOMEND : 'bottom-end',
RIGHT : 'right-start',
RIGHTEND : 'right-end',
LEFT : 'left-start',
LEFTEND : 'left-end',
TOP: "top-start",
TOPEND: "top-end",
BOTTOM: "bottom-start",
BOTTOMEND: "bottom-end",
RIGHT: "right-start",
RIGHTEND: "right-end",
LEFT: "left-start",
LEFTEND: "left-end",
};
export const DEFAULT = {
offset : 0,
flip : true,
boundary : 'scrollParent',
reference : 'toggle',
display : 'dynamic',
offset: 0,
flip: true,
boundary: "scrollParent",
reference: "toggle",
display: "dynamic",
};
export const DEFAULTTYPE = {
offset : '(number|string|function)',
flip : 'boolean',
boundary : '(string|element)',
reference : '(string|element)',
display : 'string',
offset: "(number|string|function)",
flip: "boolean",
boundary: "(string|element)",
reference: "(string|element)",
display: "string",
};

@@ -94,3 +96,2 @@

export class DropdownService {
// Getters

@@ -116,3 +117,6 @@

if (button.parentElement) {
const menu = button.parentElement.querySelector(SELECTOR.MENU + '.' + CLASSNAME.SHOW) || undefined;
const menu =
button.parentElement.querySelector(
SELECTOR.MENU + "." + CLASSNAME.SHOW
) || undefined;
if (menu) {

@@ -126,3 +130,7 @@ return this.close(button, menu, button);

public static close(triggerCloseElement: Element, menu: Element, dropdown?: Element) {
public static close(
triggerCloseElement: Element,
menu: Element,
dropdown?: Element
) {
const relatedTarget = {

@@ -138,3 +146,5 @@ relatedTarget: triggerCloseElement,

dropdown.classList.remove(CLASSNAME.SHOW);
dropdown.dispatchEvent(new CustomEvent(EVENT.HIDDEN, { detail: relatedTarget}));
dropdown.dispatchEvent(
new CustomEvent(EVENT.HIDDEN, { detail: relatedTarget })
);
}

@@ -146,3 +156,5 @@

parent.classList.remove(CLASSNAME.SHOW);
parent.dispatchEvent(new CustomEvent(EVENT.HIDDEN, { detail: relatedTarget}));
parent.dispatchEvent(
new CustomEvent(EVENT.HIDDEN, { detail: relatedTarget })
);
}

@@ -157,3 +169,3 @@ }

if (!element.parentElement) {
throw new Error('Parent element not found!');
throw new Error("Parent element not found!");
}

@@ -164,3 +176,3 @@ return element.parentElement;

private _element: HTMLButtonElement | HTMLAnchorElement;
private _popper: any /* Popper */ | null; // TODO Popper namcespace error
private _popper: any | /* Popper */ null; // TODO Popper namcespace error
private _config: any; // TODO

@@ -171,8 +183,10 @@ private _menu: Element;

constructor(elements: HTMLButtonElement | HTMLAnchorElement, config?: any) {
this._element = elements;
this._popper = null;
this._config = this._getConfig(config);
this._menu = this._getMenuElement();
this._element = elements;
this._popper = null;
this._config = this._getConfig(config);
this._menu = this._getMenuElement();
this._inNavbar = this._detectNavbar();
this.clouseOnClickOutsite(DropdownService._getParentFromElement(this._element));
this.clouseOnClickOutsite(
DropdownService._getParentFromElement(this._element)
);
}

@@ -199,3 +213,5 @@

parent.classList.add(CLASSNAME.SHOW);
parent.dispatchEvent(new CustomEvent(EVENT.SHOWN, {detail: relatedTarget}));
parent.dispatchEvent(
new CustomEvent(EVENT.SHOWN, { detail: relatedTarget })
);
}

@@ -205,7 +221,10 @@ }

public toggle() {
if ((this._element as HTMLButtonElement).disabled || this._element.classList.contains(CLASSNAME.DISABLED)) {
if (
(this._element as HTMLButtonElement).disabled ||
this._element.classList.contains(CLASSNAME.DISABLED)
) {
return;
}
const parent = DropdownService._getParentFromElement(this._element);
const parent = DropdownService._getParentFromElement(this._element);
const isActive = this._menu.classList.contains(CLASSNAME.SHOW);

@@ -223,3 +242,3 @@

};
const showEvent = new CustomEvent(EVENT.SHOW, {detail: relatedTarget});
const showEvent = new CustomEvent(EVENT.SHOW, { detail: relatedTarget });

@@ -233,3 +252,5 @@ if (parent) {

this.clouseOnClickOutsite(DropdownService._getParentFromElement(this._element));
this.clouseOnClickOutsite(
DropdownService._getParentFromElement(this._element)
);

@@ -242,4 +263,6 @@ // Disable totally Popper.js for Dropdown in Navbar

*/
if (typeof Popper === 'undefined') {
throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)');
if (typeof Popper === "undefined") {
throw new TypeError(
"Bootstrap dropdown require Popper.js (https://popper.js.org)"
);
}

@@ -249,3 +272,3 @@

if (this._config.reference === 'parent') {
if (this._config.reference === "parent") {
referenceElement = parent as HTMLElement;

@@ -256,3 +279,3 @@ } else if (Utils.isElement(this._config.reference)) {

// Check if it's jQuery element
if (typeof this._config.reference.jquery !== 'undefined') {
if (typeof this._config.reference.jquery !== "undefined") {
referenceElement = this._config.reference[0];

@@ -265,12 +288,18 @@ }

// https://github.com/twbs/bootstrap/issues/24251
if (parent && this._config.boundary !== 'scrollParent') {
if (parent && this._config.boundary !== "scrollParent") {
parent.classList.add(CLASSNAME.POSITION_STATIC);
}
this._popper = new Popper(referenceElement, this._menu as HTMLElement, this._getPopperConfig());
this._popper = new Popper(
referenceElement,
this._menu as HTMLElement,
this._getPopperConfig()
);
}
this.clouseOnClickOutsite(DropdownService._getParentFromElement(this._element));
this.clouseOnClickOutsite(
DropdownService._getParentFromElement(this._element)
);
this._element.focus();
this._element.setAttribute('aria-expanded', 'true');
this._element.setAttribute("aria-expanded", "true");

@@ -282,7 +311,9 @@ if (this._menu.classList.contains(CLASSNAME.SHOW)) {

}
this._menu.dispatchEvent(new CustomEvent(EVENT.SHOWN, {detail: relatedTarget}));
this._menu.dispatchEvent(
new CustomEvent(EVENT.SHOWN, { detail: relatedTarget })
);
}
public dispose() {
this._element.removeAttribute('data-' + DATA_KEY);
this._element.removeAttribute("data-" + DATA_KEY);
delete this._element;

@@ -309,3 +340,6 @@ delete this._menu;

this.close();
document.removeEventListener('click', this.outsideClickListener.bind(this, element));
document.removeEventListener(
"click",
this.outsideClickListener.bind(this, element)
);
}

@@ -319,3 +353,6 @@ }

private clouseOnClickOutsite(element: Element) {
document.addEventListener('click', this.outsideClickListener.bind(this, element));
document.addEventListener(
"click",
this.outsideClickListener.bind(this, element)
);
}

@@ -330,7 +367,3 @@

Utils.typeCheckConfig(
NAME,
config,
DropdownService.DefaultType,
);
Utils.typeCheckConfig(NAME, config, DropdownService.DefaultType);

@@ -346,3 +379,3 @@ return config;

if (!menu) {
throw new Error('Menu not found!');
throw new Error("Menu not found!");
}

@@ -360,3 +393,3 @@ this._menu = menu;

if (!parentDropdown) {
throw new Error('Parent of element not found!');
throw new Error("Parent of element not found!");
}

@@ -381,3 +414,3 @@

private _detectNavbar() {
return this._element.closest && this._element.closest('.navbar') !== null;
return this._element.closest && this._element.closest(".navbar") !== null;
}

@@ -387,7 +420,7 @@

const offsetConf: any = {};
if (typeof this._config.offset === 'function') {
if (typeof this._config.offset === "function") {
offsetConf.fn = (data: any) => {
data.offsets = {
...data.offsets,
...this._config.offset(data.offsets) || {},
...(this._config.offset(data.offsets) || {}),
};

@@ -414,3 +447,3 @@ return data;

// Disable Popper.js if we have a static display
if (this._config.display === 'static') {
if (this._config.display === "static") {
popperConfig.modifiers.applyStyle = {

@@ -422,3 +455,2 @@ enabled: false,

}
}

@@ -1,5 +0,6 @@

export * from './dom';
export * from './carousel.service';
export { CollapseService } from './collapse.service';
export { DropdownService } from './dropdown.service';
export * from './utils.service';
export * from "./dom";
export * from "./carousel.service";
export { CollapseService } from "./collapse.service";
export { DropdownService } from "./dropdown.service";
export { ToastService } from "./toast.service";
export * from "./utils.service";

@@ -1,8 +0,5 @@

import {
Utils as RibaUtils,
} from '@ribajs/core';
import { Utils as RibaUtils } from "@ribajs/core";
export const MAX_UID = 1000000
export const MILLISECONDS_MULTIPLIER = 1000
export const TRANSITION_END = 'transitionend'
export const MILLISECONDS_MULTIPLIER = 1000;
export const TRANSITION_END = "transitionend";

@@ -14,3 +11,2 @@ /**

export class Utils extends RibaUtils {
/**

@@ -21,95 +17,94 @@ * Shoutout AngusCroll (https://goo.gl/pxwQGp)

public static toType(obj: any) {
const matches = {}.toString.call(obj).match(/\s([a-z]+)/i);
const matches = {}.toString.call(obj).match(/\s([a-z]+)/i);
return matches ? matches[1].toLowerCase() : null;
}
public static getUID(prefix: string) {
do {
prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
} while (document.getElementById(prefix))
return prefix
}
public static getSelector(element: HTMLElement) {
let selector = element.getAttribute('data-target')
if (!selector || selector === '#') {
const hrefAttr = element.getAttribute('href')
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null
public static getSelector(element: HTMLElement) {
let selector = element.getAttribute("data-target");
if (!selector || selector === "#") {
const hrefAttr = element.getAttribute("href");
selector = hrefAttr && hrefAttr !== "#" ? hrefAttr.trim() : null;
}
return selector
return selector;
}
public static getSelectorFromElement(element: HTMLElement) {
const selector = Utils.getSelector(element)
const selector = Utils.getSelector(element);
if (selector) {
return document.querySelector(selector) ? selector : null
return document.querySelector(selector) ? selector : null;
}
return null
return null;
}
public static getElementFromSelector(element: HTMLElement) {
const selector = Utils.getSelector(element)
return (selector ? document.querySelector(selector) : null) as HTMLElement | null;
const selector = Utils.getSelector(element);
return (selector
? document.querySelector(selector)
: null) as HTMLElement | null;
}
public static getTransitionDurationFromElement(element: HTMLElement) {
if (!element) {
return 0
return 0;
}
// Get transition-duration of the element
let {
transitionDuration,
transitionDelay
} = window.getComputedStyle(element)
const floatTransitionDuration = parseFloat(transitionDuration)
const floatTransitionDelay = parseFloat(transitionDelay)
let { transitionDuration, transitionDelay } = window.getComputedStyle(
element
);
const floatTransitionDuration = parseFloat(transitionDuration);
const floatTransitionDelay = parseFloat(transitionDelay);
// Return 0 if element or transition duration is not found
if (!floatTransitionDuration && !floatTransitionDelay) {
return 0
return 0;
}
// If multiple durations are defined, take the first
transitionDuration = transitionDuration.split(',')[0]
transitionDelay = transitionDelay.split(',')[0]
return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER
transitionDuration = transitionDuration.split(",")[0];
transitionDelay = transitionDelay.split(",")[0];
return (
(parseFloat(transitionDuration) + parseFloat(transitionDelay)) *
MILLISECONDS_MULTIPLIER
);
}
public static triggerTransitionEnd(element: HTMLElement) {
const evt = document.createEvent('HTMLEvents')
evt.initEvent(TRANSITION_END, true, true)
element.dispatchEvent(evt)
const evt = document.createEvent("HTMLEvents");
evt.initEvent(TRANSITION_END, true, true);
element.dispatchEvent(evt);
}
public static isElement(obj: Element | Element[]) {
return ((obj as Element[])[0] || obj as Element).nodeType;
return ((obj as Element[])[0] || (obj as Element)).nodeType;
}
public static emulateTransitionEnd = (element: HTMLElement, duration: number) => {
let called = false
const durationPadding = 5
const emulatedDuration = duration + durationPadding
public static emulateTransitionEnd = (
element: HTMLElement,
duration: number
) => {
let called = false;
const durationPadding = 5;
const emulatedDuration = duration + durationPadding;
function listener() {
called = true
element.removeEventListener(TRANSITION_END, listener)
called = true;
element.removeEventListener(TRANSITION_END, listener);
}
element.addEventListener(TRANSITION_END, listener)
element.addEventListener(TRANSITION_END, listener);
setTimeout(() => {
if (!called) {
Utils.triggerTransitionEnd(element)
Utils.triggerTransitionEnd(element);
}
}, emulatedDuration)
}
}, emulatedDuration);
};

@@ -122,8 +117,13 @@ /**

*/
public static typeCheckConfig(componentName: string, config: any, configTypes: any) {
public static typeCheckConfig(
componentName: string,
config: any,
configTypes: any
) {
for (const property in configTypes) {
if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
const expectedTypes = configTypes[property];
const value = config[property];
const valueType = value && Utils.isElement(value) ? 'element' : Utils.toType(value);
const value = config[property];
const valueType =
value && Utils.isElement(value) ? "element" : Utils.toType(value);

@@ -133,4 +133,5 @@ if (!valueType || !new RegExp(expectedTypes).test(valueType)) {

`${componentName.toUpperCase()}: ` +
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`);
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
);
}

@@ -143,66 +144,77 @@ }

if (!nodeList) {
return []
return [];
}
return [].slice.call(nodeList)
return [].slice.call(nodeList);
}
public static isVisible(element: HTMLElement) {
if (!element) {
return false
return false;
}
if (element.style && element.parentNode && (element.parentNode as HTMLElement).style) {
const elementStyle = getComputedStyle(element)
const parentNodeStyle = getComputedStyle(element.parentNode as HTMLElement)
return elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
if (
element.style &&
element.parentNode &&
(element.parentNode as HTMLElement).style
) {
const elementStyle = getComputedStyle(element);
const parentNodeStyle = getComputedStyle(
element.parentNode as HTMLElement
);
return (
elementStyle.display !== "none" &&
parentNodeStyle.display !== "none" &&
elementStyle.visibility !== "hidden"
);
}
return false
return false;
}
public static findShadowRoot(element: HTMLElement | Node & ParentNode): HTMLElement | Node & ParentNode | null {
public static findShadowRoot(
element: HTMLElement | (Node & ParentNode)
): HTMLElement | (Node & ParentNode) | null {
if (!document.documentElement.attachShadow) {
return null
return null;
}
// Can find the shadow root otherwise it'll return the document
if (typeof element.getRootNode === 'function') {
const root = element.getRootNode()
return root instanceof ShadowRoot ? root : null
if (typeof element.getRootNode === "function") {
const root = element.getRootNode();
return root instanceof ShadowRoot ? root : null;
}
if (element instanceof ShadowRoot) {
return element
return element;
}
// when we don't find a shadow root
if (!element.parentNode) {
return null
return null;
}
return Utils.findShadowRoot(element.parentNode)
return Utils.findShadowRoot(element.parentNode);
}
public static noop(){
return function () {/** nothing */};
}
public static reflow(element: HTMLElement){
public static noop() {
return function () {
/** nothing */
};
}
public static reflow(element: HTMLElement) {
return element.offsetHeight;
}
}
public static getjQuery = () => {
const { jQuery } = (window as any)
if (jQuery && !document.body.hasAttribute('data-no-jquery')) {
return jQuery
const { jQuery } = window as any;
if (jQuery && !document.body.hasAttribute("data-no-jquery")) {
return jQuery;
}
return null
}
return null;
};
}

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc