Mike Phares 127634f5ab Delete self contained Thunder Tests
Back to .net8.0
api/v4/InfinityQS
ApiExplorerSettings
Wafer Counter
Color Sorting
2024-03-13 13:15:56 -07:00

302 lines
9.6 KiB
JavaScript

//ifxTabs.tsx
import { h } from "@stencil/core";
export class IfxTabs {
constructor() {
this.tabs = [];
this.orientation = "horizontal";
this.activeTabIndex = 0;
this.internalOrientation = undefined;
this.internalActiveTabIndex = 0;
this.internalFocusedTabIndex = 0;
this.tabRefs = [];
this.tabHeaderRefs = [];
this.disabledTabs = [];
this.tabObjects = [];
}
setActiveAndFocusedTab(index) {
this.internalActiveTabIndex = index;
this.internalFocusedTabIndex = index;
}
activeTabIndexChanged(newValue, oldValue) {
if (newValue !== oldValue) {
this.setActiveAndFocusedTab(newValue);
}
}
componentWillLoad() {
this.internalOrientation = this.orientation.toLowerCase() === 'vertical' ? 'vertical' : 'horizontal';
if (this.internalActiveTabIndex !== this.activeTabIndex) {
this.ifxTabChange.emit({ previousTab: this.internalActiveTabIndex, currentTab: this.activeTabIndex });
}
;
// this.internalActiveTabIndex = this.activeTabIndex;
this.internalFocusedTabIndex = this.internalActiveTabIndex;
this.updateTabStyles();
this.onSlotChange();
}
updateTabStyles() {
this.tabHeaderRefs.forEach((tab, index) => {
tab.classList.toggle('active', index === this.internalActiveTabIndex);
tab.setAttribute('aria-selected', index === this.internalActiveTabIndex ? 'true' : 'false');
});
}
// needed for smooth border transition
reRenderBorder() {
const borderElement = this.el.shadowRoot.querySelector('.active-border');
if (borderElement && this.tabHeaderRefs[this.internalActiveTabIndex]) {
if (this.orientation === 'horizontal') {
borderElement.style.left = `${this.tabHeaderRefs[this.internalActiveTabIndex].offsetLeft}px`;
borderElement.style.width = `${this.tabHeaderRefs[this.internalActiveTabIndex].offsetWidth}px`;
borderElement.style.top = '';
borderElement.style.height = '';
}
else {
borderElement.style.top = `${this.tabHeaderRefs[this.internalActiveTabIndex].offsetTop}px`;
borderElement.style.height = `${this.tabHeaderRefs[this.internalActiveTabIndex].offsetHeight}px`;
borderElement.style.left = '';
borderElement.style.width = '';
}
}
}
// when a slot is removed / added
onSlotChange() {
const tabs = this.el.querySelectorAll('ifx-tab');
this.tabObjects = Array.from(tabs).map((tab) => {
return {
header: tab === null || tab === void 0 ? void 0 : tab.header,
disabled: (tab === null || tab === void 0 ? void 0 : tab.disabled) === true
};
});
this.tabRefs = Array.from(tabs);
this.tabRefs.forEach((tab, index) => {
tab.setAttribute('slot', `tab-${index}`);
});
}
setDefaultOrientation() {
const validOrientations = ['horizontal', 'vertical'];
const lowercaseOrientation = this.orientation.toLowerCase();
if (!validOrientations.includes(lowercaseOrientation)) {
this.internalOrientation = 'horizontal';
}
else
this.internalOrientation = this.orientation;
}
componentDidLoad() {
this.updateBorderAndFocus();
// Add keyboard event listeners for each tab header
this.tabHeaderRefs.forEach((tab, index) => {
tab.addEventListener('focus', this.onTabFocus(index));
});
}
onTabFocus(index) {
return () => {
this.internalFocusedTabIndex = index;
};
}
disconnectedCallback() {
// Remove keyboard event listeners when component is unmounted
this.tabHeaderRefs.forEach((tab, index) => {
tab.removeEventListener('focus', this.onTabFocus(index));
});
}
componentDidUpdate() {
this.updateBorderAndFocus();
}
updateBorderAndFocus() {
this.reRenderBorder();
this.updateTabFocusability();
}
updateTabFocusability() {
this.tabHeaderRefs.forEach((tab, index) => {
tab.tabIndex = index === this.internalActiveTabIndex ? 0 : -1;
});
}
focusNextTab() {
let nextIndex = this.internalFocusedTabIndex + 1;
while (nextIndex < this.tabHeaderRefs.length && this.tabObjects[nextIndex].disabled) {
nextIndex++;
}
if (nextIndex >= 0 && nextIndex < this.tabHeaderRefs.length) {
this.internalFocusedTabIndex = nextIndex;
this.tabHeaderRefs[nextIndex].focus();
}
}
focusPreviousTab() {
let prevIndex = this.internalFocusedTabIndex - 1;
while ((prevIndex >= 0) && (this.tabObjects[prevIndex].disabled)) {
prevIndex--;
}
if ((prevIndex >= 0) && (prevIndex < this.tabHeaderRefs.length)) {
this.internalFocusedTabIndex = prevIndex;
this.tabHeaderRefs[prevIndex].focus();
}
}
getTabItemClass(index) {
const isActive = index === this.internalActiveTabIndex && !this.tabObjects[index].disabled;
const isDisabled = this.tabObjects[index].disabled;
return `tab-item ${isActive ? 'active' : ''} ${isDisabled ? 'disabled' : ''}`;
}
handleClick(tab, index) {
this.ifxTabChange.emit({ previousTab: this.internalActiveTabIndex, currentTab: index });
if (!tab.disabled)
this.internalActiveTabIndex = index;
}
handleKeyDown(ev) {
if (ev.key === 'Tab') {
if (ev.shiftKey) {
// Shift + Tab
if (this.internalFocusedTabIndex === 0) {
// Allow default behavior to move focus out of component
return;
}
else {
ev.preventDefault();
this.focusPreviousTab();
}
}
else {
// Tab
if (this.internalFocusedTabIndex === this.tabHeaderRefs.length - 1) {
// Allow default behavior to move focus out of component
return;
}
else {
ev.preventDefault();
this.focusNextTab();
}
}
}
else if (ev.key === 'Enter') {
if (this.internalFocusedTabIndex !== -1 && !this.tabObjects[this.internalFocusedTabIndex].disabled) {
const previouslyActiveTabIndex = this.internalActiveTabIndex;
this.internalActiveTabIndex = this.internalFocusedTabIndex;
this.ifxTabChange.emit({ previousTab: previouslyActiveTabIndex, currentTab: this.internalFocusedTabIndex });
}
}
}
render() {
var _a;
return (h("div", { "aria-label": "navigation tabs", class: `tabs ${this.internalOrientation}` }, h("ul", { role: "tablist", class: "tabs-list" }, (_a = this.tabObjects) === null || _a === void 0 ? void 0 :
_a.map((tab, index) => (h("li", { class: this.getTabItemClass(index), ref: (el) => (this.tabHeaderRefs[index] = el), tabindex: "0", onClick: () => this.handleClick(tab, index), "aria-selected": index === this.internalActiveTabIndex ? 'true' : 'false', "aria-disabled": tab.disabled ? 'true' : 'false', role: "tab" }, tab === null || tab === void 0 ? void 0 : tab.header))), h("div", { class: "active-border" })), h("div", { class: "tab-content" }, Array.from(this.tabObjects).map((_, index) => (h("div", { style: { display: index === this.internalActiveTabIndex ? 'block' : 'none' } }, h("slot", { name: `tab-${index}` })))))));
}
static get is() { return "ifx-tabs"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["tabs.scss"]
};
}
static get styleUrls() {
return {
"$": ["tabs.css"]
};
}
static get properties() {
return {
"tabs": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "{ header: string, disabled?: boolean }[]",
"resolved": "{ header: string; disabled?: boolean; }[]",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"defaultValue": "[]"
},
"orientation": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"attribute": "orientation",
"reflect": false,
"defaultValue": "\"horizontal\""
},
"activeTabIndex": {
"type": "number",
"mutable": true,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": ""
},
"attribute": "active-tab-index",
"reflect": false,
"defaultValue": "0"
}
};
}
static get states() {
return {
"internalOrientation": {},
"internalActiveTabIndex": {},
"internalFocusedTabIndex": {},
"tabRefs": {},
"tabHeaderRefs": {},
"disabledTabs": {},
"tabObjects": {}
};
}
static get events() {
return [{
"method": "ifxTabChange",
"name": "ifxTabChange",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": ""
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}];
}
static get elementRef() { return "el"; }
static get watchers() {
return [{
"propName": "activeTabIndex",
"methodName": "activeTabIndexChanged"
}];
}
static get listeners() {
return [{
"name": "slotchange",
"method": "onSlotChange",
"target": undefined,
"capture": false,
"passive": false
}, {
"name": "keydown",
"method": "handleKeyDown",
"target": undefined,
"capture": false,
"passive": false
}];
}
}
//# sourceMappingURL=tabs.js.map