Socket
Socket
Sign inDemoInstall

@ribajs/bs4

Package Overview
Dependencies
Maintainers
1
Versions
78
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.1.5 to 1.2.0

16

package.json
{
"name": "@ribajs/bs4",
"description": "Bootstrap 4 module for Riba.js",
"version": "1.1.5",
"version": "1.2.0",
"author": "Pascal Garber <pascal@jumplink.eu>",

@@ -28,8 +28,8 @@ "contributors": [],

"devDependencies": {
"@babel/cli": "^7.6.0",
"@babel/core": "^7.6.0",
"@babel/cli": "^7.6.2",
"@babel/core": "^7.6.2",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-object-rest-spread": "^7.5.5",
"@babel/plugin-transform-runtime": "^7.6.0",
"@babel/preset-env": "^7.6.0",
"@babel/plugin-proposal-object-rest-spread": "^7.6.2",
"@babel/plugin-transform-runtime": "^7.6.2",
"@babel/preset-env": "^7.6.2",
"@babel/preset-typescript": "^7.6.0",

@@ -41,7 +41,7 @@ "@types/jquery": "^3.3.28",

"typescript": "^3.6.3",
"webpack": "^4.40.2",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
},
"dependencies": {
"@ribajs/core": "^1.1.5",
"@ribajs/core": "^1.2.0",
"@types/jquery": "^3.3.31",

@@ -48,0 +48,0 @@ "bootstrap": "^4.3.1",

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

/* tslint:disable:max-classes-per-file */
import { Component, Debug, JQuery as $ } from '@ribajs/core';
import { Component, Debug, Binding } from '@ribajs/core';
import template from './tabs.component.html';
interface Tab {
title: string;
content: string;
handle: string;
}
interface Scope {
tabs: Tab[];
activate: TabsComponent['activate'];
}
export class TabsComponent extends Component {

@@ -9,12 +20,35 @@

protected debug = Debug('component:bs4-tabs');
protected scope: any = {};
protected scope: Scope = {
tabs: [],
activate: this.activate,
};
private $el: JQuery<HTMLElement>;
private $tabs: JQuery<HTMLElement>;
private $tabPanes: JQuery<HTMLElement>;
private $scrollable: JQuery<HTMLElement>;
private tabs: NodeListOf<Element>;
private tabPanes: NodeListOf<Element>;
private scrollable: Element | null;
private tabsSameHeight = true;
static get observedAttributes() {
return [];
return [
'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',
];
}

@@ -24,33 +58,47 @@

super(element);
const self = this;
this.$el = $(this.el);
this.$tabs = this.$el.find('.nav-link');
this.$tabPanes = this.$el.find('.tab-pane');
this.$scrollable = this.$el.find('[scrollable]');
this.debug('constructor', this.$el, this.$tabs, this.$tabPanes);
// Bind static template
this.tabs = this.el.querySelectorAll('[role="tab"]');
this.tabPanes = this.el.querySelectorAll('.tab-pane');
this.scrollable = this.el.querySelector('[scrollable]');
this.$tabs.on('click', function(event) {
event.preventDefault();
const $tab = $(this);
self.activate($tab);
});
this.debug('constructor', this.el, this.tabs, this.tabPanes);
this.$tabs.off('shown.bs.tab').on('shown.bs.tab', (event) => {
const $tab = $(event.target);
if (this.$scrollable.length) {
const tabScrollPosition = $tab[0].getBoundingClientRect();
const scrollLeftTo = this.$scrollable.scrollLeft() || 0 + tabScrollPosition.left;
this.$scrollable.animate({ scrollLeft: scrollLeftTo}, 'slow');
}
});
this.tabs.forEach((tab => {
// TODO use `rv-on-click="activate"` instead?
tab.addEventListener('click', (event) => {
this.activateByTabElement(tab, event);
});
this.activate(this.$tabs.first());
tab.addEventListener('shown.bs.tab', (event) => {
const tab = (event.target || event.srcElement) as Element | null;
if (!tab) {
return;
}
if (this.scrollable) {
const tabScrollPosition = tab.getBoundingClientRect();
const scrollLeftTo = this.scrollable.scrollLeft || 0 + tabScrollPosition.left;
// TODO animate
// this.scrollable.animate({ scrollLeft: scrollLeftTo}, 'slow');
this.scrollable.scrollLeft = scrollLeftTo;
}
});
tab.addEventListener('shown.bs.tab', (event) => {
if (this.scrollable) {
const tabScrollPosition = tab.getBoundingClientRect();
const scrollLeftTo = this.scrollable.scrollLeft || 0 + tabScrollPosition.left;
// TODO animate
// this.$scrollable.animate({ scrollLeft: scrollLeftTo}, 'slow');
this.scrollable.scrollLeft = scrollLeftTo;
}
});
}));
if (this.tabsSameHeight) {
$(window).on('resize', () => {
window.addEventListener('resize', () => {
this.setHeight();
});
}
this.init(TabsComponent.observedAttributes);

@@ -64,6 +112,9 @@ }

let heigest = 0;
this.$tabPanes.each(function() {
const $tabPane = $(this);
$tabPane.css('height', 'auto');
const height = $tabPane.height() || 0;
this.tabPanes.forEach((tabPane) => {
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;
if (height > heigest) {

@@ -73,5 +124,11 @@ heigest = height;

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

@@ -81,35 +138,126 @@ }

public deactivateAll() {
this.$tabs.each(function() {
const $tab = $(this);
$tab.removeClass('active');
// static
this.tabs.forEach((tabEl) => {
tabEl.classList.remove('active', 'show');
});
this.$tabPanes.each(function() {
const $tabPane = $(this);
$tabPane.removeClass('active show');
this.tabPanes.forEach((tabPaneEl) => {
tabPaneEl.classList.remove('active', 'show');
});
// dynamic
this.scope.tabs.forEach((tab) => {
const tabEl = this.el.querySelector('#tab-title-' + tab.handle);
const tabPaneEl = this.el.querySelector('#tab-content-' + tab.handle);
if (tabEl) tabEl.classList.remove('active', 'show');
if (tabPaneEl) tabPaneEl.classList.remove('active', 'show');
});
}
public activate($tab: JQuery<HTMLElement>) {
const target = $tab.attr('href');
this.debug('activate', target, this.$el.find(target || ''));
if (target) {
const $target = this.$el.find(target);
this.deactivateAll();
$target.addClass('active');
setTimeout(() => {
$target.addClass('show');
$tab.addClass('active');
$target.trigger('shown.bs.tab');
$tab.trigger('shown.bs.tab');
}, 0);
/**
* Used for static templates
*/
public activateByTabElement(tab: Element, event?: Event) {
if (event) {
event.preventDefault();
}
const target = tab.getAttribute('href');
if (!target) {
console.warn('The href attribute to find the target is required!');
return;
}
const targetEl = this.el.querySelector(target);
if (!targetEl) {
console.warn(`Target not found with selector "${target}" not found!`);
return;
}
this.debug('activate', target, targetEl);
this.deactivateAll();
targetEl.classList.add('active');
targetEl.classList.add('show');
tab.classList.add("active");
targetEl.dispatchEvent(new Event('shown.bs.tab'));
tab.dispatchEvent(new Event('shown.bs.tab'));
}
public activate(binding: Binding, event: Event, model: any, el: HTMLElement) {
this.activateByTabElement(el, event);
}
public activateByHandle(handle: string) {
const tabEl = this.el.querySelector('#tab-title-' + handle);
if (tabEl) {
this.activateByTabElement(tabEl);
}
}
public activateFirstTab() {
const tabEl = this.el.querySelector('[role="tab"]');
if (tabEl) {
this.activateByTabElement(tabEl);
}
}
protected resizeTabs(newSize: number) {
while(newSize > this.scope.tabs.length) {
this.scope.tabs.push({handle: '', title: '', content: ''});
}
this.scope.tabs.length = newSize;
}
protected parsedAttributeChangedCallback(attributeName: string, oldValue: any, newValue: any, namespace: string | null) {
super.parsedAttributeChangedCallback(attributeName, oldValue, newValue, namespace);
if (attributeName.startsWith('tab')) {
const index = Number(attributeName.replace(/[^0-9]/g, ''));
this.debug('index', index);
if (index >= this.scope.tabs.length) {
this.resizeTabs(index + 1);
}
if (attributeName.endsWith('Content')) {
this.scope.tabs[index].content = newValue;
}
if (attributeName.endsWith('Title')) {
this.scope.tabs[index].title = newValue;
}
if (attributeName.endsWith('Handle')) {
this.scope.tabs[index].handle = newValue;
}
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.activateFirstTab();
}
if (this.tabsSameHeight) {
this.setHeight();
}
}
}
protected async afterBind(): Promise<any> {
this.setHeight();
// Workaround
setTimeout(() => {
if (this.tabs.length > 0) {
this.activateFirstTab();
}
if (this.tabsSameHeight) {
this.setHeight();
}
}, 200);
}
protected template() {
return null;
// Only set the component template if there no childs already
if (this.el.hasChildNodes()) {
this.debug('Do not use template, because element has child nodes');
return null;
} else {
this.debug('Use template', template);
return template;
}
}
}

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