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.7.0 to 1.8.0

.browserslistrc

22

babel.config.js

@@ -1,14 +0,12 @@

// iMPORTANT do not use .babelrc: https://github.com/babel/babel/issues/8711#issuecomment-421918023
module.exports = {
"presets": [
"@babel/typescript",
[
"@babel/typescript", {
"allExtensions": true
}
],
[
"@babel/preset-env", {
"targets": {
"ie": "11",
"safari": "10",
"chrome": "52",
"edge": "16",
"firefox": "59"
}
corejs: 3,
useBuiltIns: "entry", // or "usage"
}

@@ -20,9 +18,11 @@ ]

"@babel/plugin-transform-runtime", {
"corejs": 2
"corejs": 3
}
],
"@babel/plugin-syntax-export-default-from",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-proposal-optional-chaining",
"array-includes"
]
};
};
module.exports = {
"testEnvironment": "jsdom",
"moduleFileExtensions": [
testEnvironment: "jsdom",
moduleFileExtensions: [
"ts",

@@ -9,7 +9,7 @@ "tsx",

],
"transform": {
transform: {
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": "/src/.*\\.(test|spec).(ts|tsx)$",
"collectCoverageFrom": [
testRegex: "/src/.*\\.(test|spec).(ts|tsx)$",
collectCoverageFrom: [
"src/**/*.{tsx,ts}",

@@ -19,6 +19,12 @@ "!**/node_modules/**",

],
"coverageReporters": [
coverageReporters: [
"json",
"lcov"
],
],
setupFilesAfterEnv: ["jest-extended"],
globals: {
'ts-jest': {
babelConfig: true
}
}
};
{
"name": "@ribajs/bs4",
"description": "Bootstrap 4 module for Riba.js",
"version": "1.7.0",
"version": "1.8.0",
"author": "Pascal Garber <pascal@artandcode.studio>",

@@ -37,28 +37,38 @@ "contributors": [],

"scripts": {
"test": "npm run type-check && jest --config=jest.config.js",
"type-check": "tslint -c tslint.json 'src/**/*.ts' && tsc --noEmit",
"build": "npm run build:module",
"build:module": "tsc"
"test": "npm run clean && npm run type-check && jest --config=jest.config.js",
"type-check": "eslint src --ext .js,.jsx,.ts,.tsx --fix && tsc --noEmit",
"build": "npm run type-check && npm run build:module",
"build:module": "tsc",
"clean": "rm -rf ./dist ./lib",
"packages:link": "npm link @ribajs/core @ribajs/extras"
},
"devDependencies": {
"@babel/cli": "^7.7.4",
"@babel/core": "^7.7.4",
"@babel/cli": "^7.7.7",
"@babel/core": "^7.7.7",
"@babel/plugin-proposal-class-properties": "^7.7.4",
"@babel/plugin-proposal-object-rest-spread": "^7.7.4",
"@babel/plugin-transform-runtime": "^7.7.4",
"@babel/preset-env": "^7.7.4",
"@babel/preset-typescript": "^7.7.4",
"@types/jest": "^24.0.23",
"@babel/plugin-proposal-object-rest-spread": "^7.7.7",
"@babel/plugin-proposal-optional-chaining": "^7.7.5",
"@babel/plugin-syntax-export-default-from": "^7.7.4",
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.7",
"@babel/preset-typescript": "^7.7.7",
"@babel/runtime-corejs3": "^7.7.7",
"@types/jest": "^24.0.25",
"@typescript-eslint/eslint-plugin": "^2.15.0",
"@typescript-eslint/parser": "^2.15.0",
"babel-loader": "^8.0.6",
"babel-plugin-array-includes": "^2.0.3",
"core-js": "^3.6.2",
"eslint": "^6.8.0",
"jest": "^24.9.0",
"ts-jest": "^24.2.0",
"tslint": "^5.20.1",
"typescript": "^3.7.2",
"webpack": "^4.41.2",
"jest-extended": "^0.11.2",
"ts-jest": "^24.3.0",
"typescript": "^3.7.4",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
},
"dependencies": {
"@ribajs/core": "^1.7.0",
"bootstrap": "^4.3.1",
"@ribajs/core": "^1.8.0",
"@ribajs/extras": "^1.8.0",
"bootstrap": "^4.4.1",
"popper.js": "^1.16.0"

@@ -65,0 +75,0 @@ },

@@ -12,3 +12,3 @@ import { Binder } from '@ribajs/core';

const targets = el.querySelectorAll(targetSelector);
const targets = el.querySelectorAll<HTMLElement>(targetSelector);

@@ -15,0 +15,0 @@ const collapseService = new CollapseService(targets);

@@ -10,3 +10,3 @@ import { Binder } from '@ribajs/core';

name: 'bs4-dropdown',
routine(el: HTMLElement, option: string) {
routine(el: HTMLElement, option: any = {}) {
let toggler: HTMLButtonElement;

@@ -23,5 +23,5 @@ if (el.classList.contains('dropdown-toggle')) {

const dropdownService = new DropdownService(toggler);
const dropdownService = new DropdownService(toggler, option);
toggler.addEventListener('click', (event) => {
toggler.addEventListener('click', () => {
dropdownService.toggle();

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

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

import { Binder } from '@ribajs/core';
import { Binder, Utils } from '@ribajs/core';

@@ -56,3 +56,3 @@ /**

};
window.addEventListener('scroll', this.customData.onScroll);
window.addEventListener('scroll', Utils.debounce(this.customData.onScroll.bind(this)), { passive: true });
this.customData.onScroll();

@@ -66,4 +66,4 @@ },

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

@@ -6,3 +6,3 @@ import { Component, Binder } from '@ribajs/core';

public static tagName: string = 'bs4-dropdown';
public static tagName = 'bs4-dropdown';

@@ -13,3 +13,3 @@ protected scope: any = {

protected dropdownService: DropdownService;
protected dropdownService?: DropdownService;

@@ -22,4 +22,2 @@ static get observedAttributes() {

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

@@ -30,5 +28,14 @@

event.stopPropagation();
if (!this.dropdownService) {
throw new Error('DropdownService not ready!');
}
return this.dropdownService.toggle();
}
protected connectedCallback() {
super.connectedCallback();
this.dropdownService = new DropdownService(this.el.querySelector('.dropdown-toggle') as HTMLButtonElement | HTMLAnchorElement);
this.init(Bs4DropdownComponent.observedAttributes);
}
protected template() {

@@ -35,0 +42,0 @@ return null;

@@ -45,3 +45,3 @@ import { Component } from '@ribajs/core';

public static tagName: string = 'bs4-contents';
public static tagName = 'bs4-contents';

@@ -67,2 +67,6 @@ protected autobind = true;

super(element);
}
protected connectedCallback() {
super.connectedCallback();
this.init(Bs4ContentsComponent.observedAttributes);

@@ -103,2 +107,7 @@ }

protected async beforeBind() {
await super.beforeBind();
}
protected async afterBind() {
await super.afterBind();
if (this.scope.headerParentSelector && this.scope.headersStart && this.scope.headersDepth) {

@@ -115,6 +124,2 @@ this.wrapperElement = document.querySelector(this.scope.headerParentSelector) || undefined;

protected async afterBind() {
super.afterBind();
}
protected requiredAttributes() {

@@ -131,2 +136,3 @@ return ['headersStart', 'headersDepth', 'headerParentSelector'];

super.disconnectedCallback();
this.scope.anchors = [];
}

@@ -133,0 +139,0 @@

@@ -5,3 +5,3 @@ import { Component } from '@ribajs/core';

public static tagName: string = 'bs4-icon';
public static tagName = 'bs4-icon';

@@ -18,11 +18,2 @@ static get observedAttributes() {

super(element);
this.el.setAttribute('aria-hidden', 'true');
this.el.setAttribute('role', 'img');
this.el.classList.add('iconset');
// set default values
// this.attributeChangedCallback('size', null, 32, null);
this.attributeChangedCallback('direction', null, 'top', null);
this.init(Bs4IconComponent.observedAttributes);
}

@@ -35,9 +26,20 @@

if (name === 'src') {
if (!newValue) {
console.warn('The src attribute must have a value!');
return '';
}
if (fetch) {
fetch(newValue)
.then((response) => {
// console.debug('response.headers.get("content-type")', response.headers.get('content-type'));
if (response.status !== 200) {
throw new Error(response.statusText);
console.error(response.statusText);
return '';
}
return response.text();
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 '';
})

@@ -58,3 +60,3 @@ .then((response) => {

if (newValue.length > 0) {
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++) {

@@ -70,3 +72,3 @@ const newColor: string = newValue[i];

this.el.style.color = newValue;
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}`);

@@ -80,3 +82,3 @@ }

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

@@ -88,3 +90,3 @@ }

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

@@ -96,3 +98,3 @@ }

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

@@ -122,4 +124,4 @@ }

this.el.className.replace(/(^|\s)direction-\S+/g, '');
this.el.className.replace(/(^|\s)rotate-\S+/g, '');
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;

@@ -129,2 +131,15 @@ }

protected connectedCallback() {
super.connectedCallback();
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);
}
}
protected template() {

@@ -131,0 +146,0 @@ return null;

@@ -6,3 +6,3 @@ import { Component, EventDispatcher, Binder } from '@ribajs/core';

public static tagName: string = 'bs4-navbar';
public static tagName = 'bs4-navbar';

@@ -15,5 +15,6 @@ protected scope: any = {

collapseSelector: '.navbar-collapse',
animated: true,
};
protected collapse?: NodeListOf<Element>;
protected collapse?: NodeListOf<HTMLElement>;
protected collapseService?: CollapseService;

@@ -23,3 +24,3 @@ protected router?: EventDispatcher;

static get observedAttributes() {
return ['collapse-selector'];
return ['collapse-selector', 'animated'];
}

@@ -33,3 +34,3 @@

if (this.collapseService) {
this.collapseService.toggle();
this.collapseService.toggle(this.scope.animated);
}

@@ -44,3 +45,3 @@ if (event) {

if (this.collapseService) {
this.collapseService.show();
this.collapseService.show(this.scope.animated);
}

@@ -55,3 +56,3 @@ if (event) {

if (this.collapseService) {
this.collapseService.hide();
this.collapseService.hide(this.scope.animated);
}

@@ -133,3 +134,3 @@ if (event) {

if (this.collapseService) {
this.collapseService.hide();
this.collapseService.hide(this.scope.animated);
}

@@ -136,0 +137,0 @@ }

@@ -25,3 +25,3 @@ import { Bs4ContentsComponent, Scope as Bs4ContentsComponentScope } from '../bs4-contents/bs4-contents.component';

public static tagName: string = 'bs4-scrollspy';
public static tagName = 'bs4-scrollspy';

@@ -49,2 +49,6 @@ protected autobind = true;

super(element);
}
protected connectedCallback() {
super.connectedCallback();
this.init(Bs4ScrollspyComponent.observedAttributes);

@@ -51,0 +55,0 @@ }

@@ -23,5 +23,5 @@ import {

/**
* The width of the sidebar
* The width of the sidebar with unit
*/
width: number;
width: string;

@@ -42,2 +42,6 @@ // Options

/**
* Watch the routers `newPageReady` event to update the sidebar state, e.g. hide on slime than after route changes
*/
watchNewPageReadyEvent: boolean;
/**
* You can force to hide the sidebar on corresponding URL pathames e.g. you can hide the sidebar on home with `['/']`.

@@ -72,5 +76,5 @@ */

public static tagName: string = 'bs4-sidebar';
public static tagName = 'bs4-sidebar';
protected style: CSSStyleDeclaration;
protected style?: CSSStyleDeclaration;

@@ -80,3 +84,14 @@ protected autobind = true;

static get observedAttributes() {
return ['id', 'container-selector', 'position', 'width', 'auto-show-in-wider-than', 'auto-hide-on-slimmer-than', 'force-hide-on-location-pathnames', 'force-show-on-location-pathnames', 'overlay-on-slimmer-than'];
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',
];
}

@@ -94,3 +109,3 @@

id: undefined,
width: 250,
width: '250px',

@@ -101,2 +116,3 @@ // Options

autoHideOnSlimmerThan: 1200,
watchNewPageReadyEvent: true,
forceHideOnLocationPathnames: [],

@@ -114,5 +130,2 @@ forceShowOnLocationPathnames: [],

super(element);
this.init(Bs4SidebarComponent.observedAttributes);
this.style = window.getComputedStyle(this.el);
window.addEventListener('resize', this.onEnviromentChanges.bind(this), false);
}

@@ -151,3 +164,12 @@

protected onToggle(targetId: string) {
protected connectedCallback() {
super.connectedCallback();
this.init(Bs4SidebarComponent.observedAttributes);
this.style = window.getComputedStyle(this.el);
window.addEventListener('resize', this.onEnviromentChanges.bind(this), false);
// inital
this.onEnviromentChanges();
}
protected onToggle() {
this.toggle();

@@ -158,10 +180,14 @@ }

if (this.toggleButtonEvents) {
this.toggleButtonEvents.off('toggle', this.onToggle);
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));
}
protected initRouterEventDispatcher() {
this.routerEvents.on('newPageReady', this.onEnviromentChanges.bind(this));
if (this.scope.watchNewPageReadyEvent) {
this.routerEvents.on('newPageReady', this.onEnviromentChanges.bind(this));
}
}

@@ -172,3 +198,3 @@

const translateX = this.scope.position === 'left' ? '-100%' : '100%';
this.el.setAttribute('style', `transform:translateX(${translateX});width:${this.scope.width}px;`);
this.el.setAttribute('style', `transform:translateX(${translateX});width:${this.scope.width};`);
}

@@ -178,3 +204,3 @@

this.setContainersStyle(undefined, '', directon);
this.el.setAttribute('style', `transform:translateX(0);width:${this.scope.width}px;`);
this.el.setAttribute('style', `transform:translateX(0);width:${this.scope.width};`);
}

@@ -184,5 +210,9 @@

this.setContainersStyle(undefined, '', directon);
this.el.setAttribute('style', `transform:translateX(0);width:${this.scope.width}px;`);
this.el.setAttribute('style', `transform:translateX(0);width:${this.scope.width};`);
}
protected triggerState() {
this.toggleButtonEvents?.trigger('state', this.scope.state);
}
protected onStateChange() {

@@ -208,3 +238,3 @@ switch (this.scope.state) {

protected get width() {
return this.el.offsetWidth || this.scope.width;
return this.el.offsetWidth ? this.el.offsetWidth + 'px' : this.scope.width;
}

@@ -220,9 +250,6 @@

const vw = Utils.getViewportDimensions().w;
if (vw < this.scope.autoHideOnSlimmerThan) {
if (this.scope.autoHideOnSlimmerThan > -1 && vw < this.scope.autoHideOnSlimmerThan) {
return this.hide();
}
if (vw < this.scope.autoHideOnSlimmerThan) {
return this.hide();
}
if (vw > this.scope.autoShowOnWiderThan) {
if (this.scope.autoShowOnWiderThan > -1 && vw > this.scope.autoShowOnWiderThan) {
return this.show();

@@ -266,3 +293,3 @@ }

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

@@ -275,6 +302,6 @@ const width = this.width;

case 'fixed':
style += 'left:' + width + 'px';
style += 'left:' + width;
break;
default:
style += 'margin-left:' + width + 'px';
style += 'margin-left:' + width;
break;

@@ -286,6 +313,6 @@ }

case 'fixed':
style += 'right:' + width + 'px';
style += 'right:' + width;
break;
default:
style += 'margin-right:' + width + 'px';
style += 'margin-right:' + width;
break;

@@ -298,12 +325,14 @@ }

}
return container.setAttribute('style', `transition:${this.style.transition};${style}`);
return container.setAttribute('style', `transition:${this.style ? this.style.transition : ''};${style}`);
}
protected async beforeBind() {
await super.beforeBind();
this.initRouterEventDispatcher();
this.onEnviromentChanges();
return this.onEnviromentChanges();
}
protected async afterBind() {
this.onEnviromentChanges();
await super.afterBind();
return this.onEnviromentChanges();
}

@@ -328,2 +357,7 @@

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);
}

@@ -330,0 +364,0 @@

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

import { Component, Binding, handleizeFormatter } from '@ribajs/core';
import template from './bs4-tabs.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';
export interface Tab {

@@ -10,18 +13,48 @@ title: string;

type?: string;
index: number;
}
export interface Scope {
tabs: Tab[];
items: Tab[];
activate: Bs4TabsComponent['activate'];
deactivate: Bs4TabsComponent['activate'];
deactivateAll: Bs4TabsComponent['deactivateAll'];
optionTabsAutoHeight: boolean;
optionTabsAngle: 'vertical' | 'horizontal';
}
export class Bs4TabsComponent extends Component {
export class Bs4TabsComponent extends TemplatesComponent {
public static tagName: string = 'bs4-tabs';
public static tagName = 'bs4-tabs';
protected templateAttributes = [
{
name: 'title',
required: true,
},
{
name: 'handle',
required: false,
},
{
name: 'type',
required: false,
},
{
name: 'active',
required: false,
},
{
name: 'index',
required: false,
},
];
protected scope: Scope = {
tabs: new Array<Tab>(),
items: new Array<Tab>(),
activate: this.activate,
deactivate: this.deactivate,
deactivateAll:this.deactivateAll,
optionTabsAutoHeight: false,
optionTabsAngle: 'horizontal',
};

@@ -36,2 +69,3 @@

'option-tabs-auto-height',
'option-tabs-angle',
'tab-0-title', 'tab-0-content', 'tab-0-handle',

@@ -62,7 +96,2 @@ 'tab-1-title', 'tab-1-content', 'tab-1-handle',

super(element);
this.addTabsByTemplate();
this.initTabs();
this.activateFirstTab();
this.init(Bs4TabsComponent.observedAttributes);
}

@@ -108,10 +137,26 @@

public deactivateAll() {
for (const tab of this.scope.tabs) {
tab.active = false;
for (let index = 0; index < this.scope.items.length; index++) {
const tab = this.scope.items[index];
this.deactivate(tab);
}
}
public activate(tab: Tab, binding?: Binding, event?: Event) {
public deactivate(tab: Tab) {
tab.active = false;
const firstTabContentChild = this.getTabContentChildByIndex(tab.index);
if (firstTabContentChild) {
this.triggerVisibilityChangedForElement(firstTabContentChild, tab.active);
}
}
public activate(tab: Tab) {
this.deactivateAll();
tab.active = true;
const firstTabContentChild = this.getTabContentChildByIndex(tab.index);
if (firstTabContentChild) {
this.triggerVisibilityChangedForElement(firstTabContentChild as Element, tab.active);
}
if (event) {

@@ -122,8 +167,32 @@ event.preventDefault();

public activateFirstTab() {
if (this.scope.tabs.length > 0) {
this.activate(this.scope.tabs[0]);
protected activateFirstTab() {
if (this.scope.items.length > 0) {
this.activate(this.scope.items[0]);
}
}
protected getTabContentChildByIndex(index: number) {
return this.el.querySelector(`.tab-content .tab-pane:nth-child(${index + 1}) > *`) || undefined;
}
/**
* Trigger `visibility-changed` for components that need to update if visibility changes.
* E.g. this event is used the bs4-slideshow component
* @param element
* @param visibile
*/
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}}));
}, 200);
}
protected connectedCallback() {
super.connectedCallback();
this.initTabs();
this.activateFirstTab();
this.init(Bs4TabsComponent.observedAttributes);
}
protected setElements() {

@@ -136,6 +205,5 @@ this.tabs = this.el.querySelectorAll('[role="tab"]');

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

@@ -157,3 +225,3 @@

protected onResizeEventHandler(event: Event) {
protected onResizeEventHandler() {
this.setHeight();

@@ -182,14 +250,15 @@ }

const index = Number(attributeName.replace(/[^0-9]/g, ''));
if (index >= this.scope.tabs.length) {
if (index >= this.scope.items.length) {
this.resizeTabsArray(index + 1);
}
this.scope.items[index].index = index;
if (attributeName.endsWith('Content')) {
this.scope.tabs[index].content = newValue;
this.scope.items[index].content = newValue;
}
if (attributeName.endsWith('Title')) {
this.scope.tabs[index].title = newValue;
this.scope.tabs[index].handle = this.scope.tabs[index].handle || handleizeFormatter.read(this.scope.tabs[index].title);
this.scope.items[index].title = newValue;
this.scope.items[index].handle = this.scope.items[index].handle || handleizeFormatter.read(this.scope.items[index].title);
}
if (attributeName.endsWith('Handle')) {
this.scope.tabs[index].handle = newValue;
this.scope.items[index].handle = newValue;
}

@@ -199,7 +268,7 @@

if (
this.scope.tabs.length > 0 &&
this.scope.tabs[0] &&
this.scope.tabs[0].content.length > 0 &&
this.scope.tabs[0].title.length > 0 &&
this.scope.tabs[0].handle.length > 0
this.scope.items.length > 0 &&
this.scope.items[0] &&
this.scope.items[0].content.length > 0 &&
this.scope.items[0].title.length > 0 &&
this.scope.items[0].handle.length > 0
) {

@@ -210,25 +279,11 @@ this.activateFirstTab();

protected addTabByTemplate(tpl: HTMLTemplateElement) {
const title = tpl.getAttribute('title');
if (!title) {
console.error(new Error('template "title" attribute is required"'));
return;
protected transformTemplateAttributes(attributes: any, index: number) {
attributes = super.transformTemplateAttributes(attributes, index);
if (!attributes.handle && attributes.title) {
attributes.handle = handleizeFormatter.read(attributes.title);
}
const handle = tpl.getAttribute('handle') || handleizeFormatter.read(title);
if (!handle) {
console.error(new Error('template "handle" attribute is required"'));
return;
}
const type = tpl.getAttribute('type') || undefined;
const content = tpl.innerHTML;
this.scope.tabs.push({title, handle, content, active: false, type });
attributes.active = attributes.active || false;
return attributes;
}
protected addTabsByTemplate() {
const templates = this.el.querySelectorAll<HTMLTemplateElement>('template');
templates.forEach((tpl) => {
this.addTabByTemplate(tpl);
});
}
protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {

@@ -251,14 +306,10 @@ super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);

protected onlyTemplateChilds() {
let allAreTemplates: boolean = true;
this.el.childNodes.forEach((child) => {
allAreTemplates = allAreTemplates && (child.nodeName === 'TEMPLATE' || child.nodeName === '#text');
});
return allAreTemplates;
}
protected template() {
// Only set the component template if there no childs or the childs are templates
if (!this.el.hasChildNodes() || this.onlyTemplateChilds()) {
return template;
if (!this.el.hasChildNodes() || this.hasOnlyTemplateChilds()) {
if (this.scope.optionTabsAngle === 'horizontal') {
return templateHorizontal;
} else {
return templateVertical;
}
} else {

@@ -265,0 +316,0 @@ return null;

@@ -15,8 +15,5 @@ import {

// TODO extend from Bs4ButtonComponent
export class Bs4ToggleButtonComponent extends Component {
public static tagName: string = 'bs4-toggle-button';
protected autobind = true;
static get observedAttributes() {

@@ -26,2 +23,6 @@ return ['target-id'];

public static tagName = 'bs4-toggle-button';
protected autobind = true;
protected eventDispatcher?: EventDispatcher;

@@ -38,3 +39,2 @@

super(element);
this.init(Bs4ToggleButtonComponent.observedAttributes);
}

@@ -48,2 +48,13 @@

protected async afterBind() {
await super.afterBind();
// Trigger init to trigger there current state of all the components that are connected to this component
return this.eventDispatcher?.trigger('init', this.scope.targetId);
}
protected connectedCallback() {
super.connectedCallback();
this.init(Bs4ToggleButtonComponent.observedAttributes);
}
protected onToggledEvent(state: State) {

@@ -60,2 +71,4 @@ this.scope.state = state;

this.eventDispatcher.on('toggled', this.onToggledEvent.bind(this));
// Triggered state triggered by `..trigger('init', ...`
this.eventDispatcher.on('state', this.onToggledEvent.bind(this));
}

@@ -62,0 +75,0 @@

@@ -6,4 +6,7 @@ export { Bs4DropdownComponent } from './bd4-dropdown/bs4-dropdown.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 { Bs4ButtonComponent } from './bs4-button/bs4-button.component';
export { Bs4AccordionComponent } from './bs4-accordion/bs4-accordion.component';

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

/**

@@ -21,26 +22,109 @@ *

SHOW : 'show',
COLLAPSE : 'collapse',
COLLAPSING : 'collapsing',
COLLAPSED : 'collapsed',
COLLAPSE : 'collapse', // hidden
COLLAPSING : 'collapsing', // animation
COLLAPSED : 'collapsed', // Button / trigger element class if collapse element is collapsed
};
private targets: NodeListOf<Element> | Array<Element>;
public static show(element: HTMLElement, animated = true) {
element.dispatchEvent(new Event(CollapseService.EVENT.SHOW));
if (animated) {
element.addEventListener('webkitTransitionEnd' as 'animationend', this.onShowTransitionEnd.bind(this, element), { once: true });
element.addEventListener('transitionend', this.onShowTransitionEnd.bind(this, element), { once: true });
element.classList.add(CollapseService.CLASSNAME.COLLAPSING);
element.classList.remove(CollapseService.CLASSNAME.COLLAPSE);
// Get and set height to start transition
setTimeout(() => {
// const duration = Utils.getTransitionDurationFromElement(element);
if (element.firstElementChild) {
const dimension = element.firstElementChild.getBoundingClientRect();
element.style.height = dimension.height + 'px';
} else {
element.style.height = 'auto';
}
});
} else {
this.onShowTransitionEnd(element);
}
}
constructor(targets: NodeListOf<Element> | Array<Element>) {
public static hide(element: HTMLElement, animated = true) {
element.dispatchEvent(new Event(CollapseService.EVENT.HIDE));
if (animated) {
element.addEventListener('webkitTransitionEnd' as 'animationend', this.onHideTransitionEnd.bind(this, element), { once: true });
element.addEventListener('transitionend', this.onHideTransitionEnd.bind(this, element), { once: true });
element.style.height = element.getBoundingClientRect().height + 'px' ;
setTimeout(() => {
element.classList.add(CollapseService.CLASSNAME.COLLAPSING);
element.classList.remove(CollapseService.CLASSNAME.COLLAPSE);
element.classList.remove(CollapseService.CLASSNAME.SHOW);
element.style.height = '0' ;
});
} else {
this.onHideTransitionEnd(element);
}
}
public static hideAll(elements: NodeListOf<HTMLElement> | Array<HTMLElement>) {
elements.forEach((element: HTMLElement) => {
this.hide(element);
});
}
public static isExpanded(element: HTMLElement) {
return element.classList.contains(CollapseService.CLASSNAME.SHOW);
}
public static isCollapsed(element: HTMLElement) {
return !this.isExpanded(element);
}
public static toggle(element: HTMLElement, animated = true) {
if (this.isCollapsed(element)) {
this.show(element, animated);
} else {
this.hide(element, animated);
}
}
protected static onShowTransitionEnd(element: HTMLElement) {
setTimeout(() => {
element.classList.add(CollapseService.CLASSNAME.COLLAPSE);
element.classList.add(CollapseService.CLASSNAME.SHOW);
element.classList.remove(CollapseService.CLASSNAME.COLLAPSING);
element.style.height = '';
element.dispatchEvent(new Event(CollapseService.EVENT.SHOWN));
});
}
protected static onHideTransitionEnd(element: HTMLElement) {
setTimeout(() => {
element.classList.add(CollapseService.CLASSNAME.COLLAPSE);
element.classList.remove(CollapseService.CLASSNAME.COLLAPSING);
element.classList.remove(CollapseService.CLASSNAME.SHOW);
element.style.height = '';
element.dispatchEvent(new Event(CollapseService.EVENT.HIDDEN));
});
}
protected targets: NodeListOf<HTMLElement> | Array<HTMLElement>;
constructor(targets: NodeListOf<HTMLElement> | Array<HTMLElement>) {
this.targets = targets;
}
public show() {
this.targets.forEach((target: Element) => {
target.classList.remove(CollapseService.CLASSNAME.COLLAPSE);
target.classList.add(CollapseService.CLASSNAME.SHOW);
target.dispatchEvent(new Event(CollapseService.EVENT.SHOWN));
/**
* Show all
*/
public show(animated = true) {
this.targets.forEach((target: HTMLElement) => {
CollapseService.show(target, animated);
});
}
public hide() {
this.targets.forEach((target: Element) => {
target.classList.remove(CollapseService.CLASSNAME.SHOW);
target.classList.add(CollapseService.CLASSNAME.COLLAPSE);
target.dispatchEvent(new Event(CollapseService.EVENT.HIDDEN));
/**
* Collapse / hide all
*/
public hide(animated = true) {
this.targets.forEach((target: HTMLElement) => {
CollapseService.hide(target, animated);
});

@@ -50,6 +134,3 @@ }

public isExpanded() {
if (this.targets.length > 0 && this.targets[0]) {
return this.targets[0].classList.contains(CollapseService.CLASSNAME.SHOW);
}
return false;
return CollapseService.isExpanded(this.targets[0]);
}

@@ -61,9 +142,9 @@

public toggle() {
public toggle(animated = true) {
if (this.isCollapsed()) {
this.show();
this.show(animated);
} else {
this.hide();
this.hide(animated);
}
}
}

@@ -111,5 +111,4 @@ import Popper from 'popper.js'; // /dist/umd/popper

public static closeAll() {
console.debug('closeAll');
const buttons = document.querySelectorAll(SELECTOR.DATA_TOGGLE);
buttons.forEach((button, index) => {
buttons.forEach((button) => {
if (button.parentElement) {

@@ -147,3 +146,3 @@ const menu = button.parentElement.querySelector(SELECTOR.MENU + '.' + CLASSNAME.SHOW) || undefined;

public static _clearMenus(event?: MouseEvent) {
public static _clearMenus() {
return this.closeAll();

@@ -290,2 +289,10 @@ }

private outsideClickListener(element: Element, event: Event) {
const target = event.target || event.srcElement || event.currentTarget;
if (target && !element.contains(target as Node)) {
this.close();
document.removeEventListener('click', this.outsideClickListener.bind(this, element));
}
}
/**

@@ -296,15 +303,3 @@ * @see https://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element

private clouseOnClickOutsite(element: Element) {
const outsideClickListener = (event: Event) => {
const target = event.target || event.srcElement || event.currentTarget;
if (target && !element.contains(target as Node)) {
this.close();
removeClickListener();
}
};
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener);
};
document.addEventListener('click', outsideClickListener);
document.addEventListener('click', this.outsideClickListener.bind(this, element));
}

@@ -311,0 +306,0 @@

@@ -5,2 +5,4 @@ import {

const MILLISECONDS_MULTIPLIER = 1000;
/**

@@ -51,2 +53,24 @@ *

}
// https://github.com/twbs/bootstrap/blob/master/dist/js/bootstrap.bundle.js#L137
public static getTransitionDurationFromElement(element: HTMLElement) {
if (!element) {
return 0;
} // Get transition-duration of the element
const _window$getComputedSt = window.getComputedStyle(element);
let transitionDuration = _window$getComputedSt.transitionDuration;
let transitionDelay = _window$getComputedSt.transitionDelay;
const floatTransitionDuration = parseFloat(transitionDuration);
const floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
if (!floatTransitionDuration && !floatTransitionDelay) {
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;
}
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./src/",
"outDir": "./lib/",
"module": "commonjs",
"target": "esnext",
"lib": ["es7", "dom"],
"moduleResolution": "node",
"typeRoots": ["./node_modules/@types", "./node_modules/@ribajs/core/src/types"],
"outDir": "dist",
"declaration": true,
"inlineSourceMap": true,
"noUnusedLocals": true,
"typeRoots": ["./node_modules/@types", "./src/types"],
"types": ["jest"]
"esModuleInterop": true,
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"allowSyntheticDefaultImports": true
},
"include": ["*.ts", "**/*.ts"]
"include": ["src"],
"exclude": ["**/*.spec.ts"],
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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