@digital-realty/ix-tabs 1.1.8 → 1.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/IxTabs.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare class IxTabs extends LitElement {
12
12
  alignLeft: boolean;
13
13
  private enableLeftScroll;
14
14
  private enableRightScroll;
15
+ withoutBorderBottom: boolean;
15
16
  private tabContainer;
16
17
  get activeTabIndex(): number;
17
18
  set activeTabIndex(index: number);
package/dist/IxTabs.js CHANGED
@@ -12,6 +12,7 @@ export class IxTabs extends LitElement {
12
12
  this.alignLeft = false;
13
13
  this.enableLeftScroll = true;
14
14
  this.enableRightScroll = true;
15
+ this.withoutBorderBottom = false;
15
16
  this.tabContainer = null;
16
17
  this.updateScrollButtonState = () => {
17
18
  clearTimeout(this.debounceEvent);
@@ -43,6 +44,8 @@ export class IxTabs extends LitElement {
43
44
  }
44
45
  async slotChange() {
45
46
  var _a;
47
+ // Free event loop for next frame
48
+ await 0;
46
49
  (_a = this.querySelector('ix-primary-tab[active]')) === null || _a === void 0 ? void 0 : _a.scrollIntoView();
47
50
  if (!this.tabContainer)
48
51
  return;
@@ -93,21 +96,29 @@ export class IxTabs extends LitElement {
93
96
  render() {
94
97
  return html `
95
98
  ${this.scrollButtons
96
- ? html `<ix-icon-button
97
- icon="chevron_left"
98
- @click=${() => this.scrollTabs('left')}
99
- ?disabled=${!this.enableLeftScroll}
100
- ></ix-icon-button>`
99
+ ? html `<div
100
+ class="gradient left ${!this.enableLeftScroll ? 'disabled' : ''}"
101
+ >
102
+ <ix-icon-button
103
+ icon="chevron_left"
104
+ @click=${() => this.scrollTabs('left')}
105
+ ?disabled=${!this.enableLeftScroll}
106
+ ></ix-icon-button>
107
+ </div>`
101
108
  : nothing}
102
- <md-tabs>
109
+ <md-tabs .withoutBorderBottom="${this.withoutBorderBottom}">
103
110
  <slot @slotchange=${this.slotChange}></slot>
104
111
  </md-tabs>
105
112
  ${this.scrollButtons
106
- ? html `<ix-icon-button
107
- icon="chevron_right"
108
- @click=${() => this.scrollTabs('right')}
109
- ?disabled=${!this.enableRightScroll}
110
- ></ix-icon-button>`
113
+ ? html `<div
114
+ class="gradient right ${!this.enableRightScroll ? 'disabled' : ''}"
115
+ >
116
+ <ix-icon-button
117
+ icon="chevron_right"
118
+ @click=${() => this.scrollTabs('right')}
119
+ ?disabled=${!this.enableRightScroll}
120
+ ></ix-icon-button>
121
+ </div>`
111
122
  : nothing}
112
123
  `;
113
124
  }
@@ -141,6 +152,42 @@ IxTabs.styles = css `
141
152
  .scroll {
142
153
  cursor: pointer;
143
154
  }
155
+
156
+ .gradient {
157
+ position: relative;
158
+ }
159
+
160
+ .gradient.left {
161
+ margin-right: -10px;
162
+ }
163
+
164
+ .gradient.right {
165
+ margin-left: -10px;
166
+ }
167
+
168
+ .gradient::before {
169
+ content: '';
170
+ width: 20px;
171
+ height: calc(100% + 2px);
172
+ position: absolute;
173
+ top: -2px;
174
+ background: linear-gradient(to right, white, transparent);
175
+ z-index: 10;
176
+ pointer-events: none;
177
+ }
178
+
179
+ .gradient.left::before {
180
+ left: 30px;
181
+ }
182
+
183
+ .gradient.right::before {
184
+ right: 30px;
185
+ transform: rotate(180deg);
186
+ }
187
+
188
+ .gradient.disabled::before {
189
+ display: none;
190
+ }
144
191
  `;
145
192
  __decorate([
146
193
  query('md-Tabs')
@@ -166,6 +213,9 @@ __decorate([
166
213
  __decorate([
167
214
  property({ type: Boolean })
168
215
  ], IxTabs.prototype, "enableRightScroll", void 0);
216
+ __decorate([
217
+ property({ type: Boolean })
218
+ ], IxTabs.prototype, "withoutBorderBottom", void 0);
169
219
  __decorate([
170
220
  state()
171
221
  ], IxTabs.prototype, "tabContainer", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"IxTabs.js","sourceRoot":"","sources":["../src/IxTabs.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, nothing, LitElement, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport './mdtabs/tabs.js';\nimport type { MdTabs } from './mdtabs/tabs.js';\nimport '@digital-realty/ix-icon-button/ix-icon-button.js';\n\ntype ScrollDirection = 'left' | 'right';\n\nexport class IxTabs extends LitElement {\n static styles = css`\n :host {\n max-width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n }\n :host(ix-tabs[inline]) {\n display: inline-flex;\n }\n :host(ix-tabs[inline]) ix-icon-button[disabled] {\n display: none;\n }\n md-tabs {\n flex-grow: 1;\n --md-primary-tab-container-color: transparent;\n }\n ix-icon-button {\n --md-icon-button-hover-state-layer-opacity: 0;\n --md-icon-button-pressed-state-layer-opacity: 0;\n --md-icon-button-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-pressed-state-layer-color: var(\n --md-sys-text-color-secondary\n );\n }\n .scroll {\n cursor: pointer;\n }\n `;\n\n @query('md-Tabs') mdTabs!: MdTabs;\n\n @query('ix-primary-tab[active]') activeTab!: Element;\n\n @property({ type: Boolean }) scrollButtons = false;\n\n @property({ type: Boolean }) hideScrollBar = false;\n\n @property({ type: Boolean, reflect: true }) inline = false;\n\n @property({ type: Boolean, attribute: 'left-align' }) alignLeft = false;\n\n @property({ type: Boolean }) private enableLeftScroll = true;\n\n @property({ type: Boolean }) private enableRightScroll = true;\n\n @state() private tabContainer: HTMLElement | null | undefined = null;\n\n get activeTabIndex() {\n return this.mdTabs.activeTabIndex;\n }\n\n set activeTabIndex(index: number) {\n this.mdTabs.activeTabIndex = index;\n }\n\n private calculateScrollButtonsEnabled() {\n if (!this.tabContainer) return;\n\n const { clientWidth, scrollWidth, scrollLeft } = this.tabContainer;\n this.enableLeftScroll = scrollLeft !== 0;\n this.enableRightScroll = scrollLeft !== scrollWidth - clientWidth;\n\n if (this.alignLeft) {\n const parent = this.parentElement?.clientWidth;\n if (parent && scrollWidth > parent) {\n this.inline = false;\n } else {\n this.inline = true;\n }\n }\n }\n\n private debounceEvent: ReturnType<typeof setTimeout> | undefined;\n\n private updateScrollButtonState = () => {\n clearTimeout(this.debounceEvent);\n this.debounceEvent = setTimeout(\n this.calculateScrollButtonsEnabled.bind(this),\n 100\n );\n };\n\n async slotChange() {\n this.querySelector('ix-primary-tab[active]')?.scrollIntoView();\n\n if (!this.tabContainer) return;\n\n if (this.scrollButtons && this.hideScrollBar) {\n this.tabContainer.classList.add('no-scrollbar');\n }\n\n if (this.scrollButtons) {\n this.calculateScrollButtonsEnabled();\n window.addEventListener('resize', this.updateScrollButtonState);\n this.tabContainer.addEventListener(\n 'scroll',\n this.updateScrollButtonState\n );\n }\n\n await this.updateComplete;\n\n if (this.tabContainer && this.alignLeft) {\n const { clientWidth, scrollWidth } = this.tabContainer;\n this.inline = scrollWidth <= clientWidth;\n }\n }\n\n protected firstUpdated(_changedProperties: PropertyValues) {\n super.firstUpdated(_changedProperties);\n\n requestAnimationFrame(() => {\n this.tabContainer = this.mdTabs.shadowRoot?.querySelector('.tabs');\n this.slotChange();\n });\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n if (this.scrollButtons) {\n window.removeEventListener('resize', this.updateScrollButtonState);\n this.tabContainer?.removeEventListener(\n 'scroll',\n this.updateScrollButtonState\n );\n }\n }\n\n private scrollTabs(direction: ScrollDirection = 'left', scrollAmount = 0.75) {\n if (this.tabContainer) {\n const { clientWidth, scrollLeft } = this.tabContainer;\n const offset =\n direction === 'left'\n ? clientWidth * -scrollAmount\n : clientWidth * scrollAmount;\n const scrollToPosition = scrollLeft + offset;\n this.tabContainer.scrollTo({\n top: 0,\n left: scrollToPosition,\n behavior: 'smooth',\n });\n }\n }\n\n render() {\n return html`\n ${this.scrollButtons\n ? html`<ix-icon-button\n icon=\"chevron_left\"\n @click=${() => this.scrollTabs('left')}\n ?disabled=${!this.enableLeftScroll}\n ></ix-icon-button>`\n : nothing}\n <md-tabs>\n <slot @slotchange=${this.slotChange}></slot>\n </md-tabs>\n ${this.scrollButtons\n ? html`<ix-icon-button\n icon=\"chevron_right\"\n @click=${() => this.scrollTabs('right')}\n ?disabled=${!this.enableRightScroll}\n ></ix-icon-button>`\n : nothing}\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"IxTabs.js","sourceRoot":"","sources":["../src/IxTabs.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, nothing, LitElement, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport './mdtabs/tabs.js';\nimport type { MdTabs } from './mdtabs/tabs.js';\nimport '@digital-realty/ix-icon-button/ix-icon-button.js';\n\ntype ScrollDirection = 'left' | 'right';\n\nexport class IxTabs extends LitElement {\n static styles = css`\n :host {\n max-width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n }\n :host(ix-tabs[inline]) {\n display: inline-flex;\n }\n :host(ix-tabs[inline]) ix-icon-button[disabled] {\n display: none;\n }\n md-tabs {\n flex-grow: 1;\n --md-primary-tab-container-color: transparent;\n }\n ix-icon-button {\n --md-icon-button-hover-state-layer-opacity: 0;\n --md-icon-button-pressed-state-layer-opacity: 0;\n --md-icon-button-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-pressed-state-layer-color: var(\n --md-sys-text-color-secondary\n );\n }\n .scroll {\n cursor: pointer;\n }\n\n .gradient {\n position: relative;\n }\n\n .gradient.left {\n margin-right: -10px;\n }\n\n .gradient.right {\n margin-left: -10px;\n }\n\n .gradient::before {\n content: '';\n width: 20px;\n height: calc(100% + 2px);\n position: absolute;\n top: -2px;\n background: linear-gradient(to right, white, transparent);\n z-index: 10;\n pointer-events: none;\n }\n\n .gradient.left::before {\n left: 30px;\n }\n\n .gradient.right::before {\n right: 30px;\n transform: rotate(180deg);\n }\n\n .gradient.disabled::before {\n display: none;\n }\n `;\n\n @query('md-Tabs') mdTabs!: MdTabs;\n\n @query('ix-primary-tab[active]') activeTab!: Element;\n\n @property({ type: Boolean }) scrollButtons = false;\n\n @property({ type: Boolean }) hideScrollBar = false;\n\n @property({ type: Boolean, reflect: true }) inline = false;\n\n @property({ type: Boolean, attribute: 'left-align' }) alignLeft = false;\n\n @property({ type: Boolean }) private enableLeftScroll = true;\n\n @property({ type: Boolean }) private enableRightScroll = true;\n\n @property({ type: Boolean }) withoutBorderBottom = false;\n\n @state() private tabContainer: HTMLElement | null | undefined = null;\n\n get activeTabIndex() {\n return this.mdTabs.activeTabIndex;\n }\n\n set activeTabIndex(index: number) {\n this.mdTabs.activeTabIndex = index;\n }\n\n private calculateScrollButtonsEnabled() {\n if (!this.tabContainer) return;\n\n const { clientWidth, scrollWidth, scrollLeft } = this.tabContainer;\n this.enableLeftScroll = scrollLeft !== 0;\n this.enableRightScroll = scrollLeft !== scrollWidth - clientWidth;\n\n if (this.alignLeft) {\n const parent = this.parentElement?.clientWidth;\n if (parent && scrollWidth > parent) {\n this.inline = false;\n } else {\n this.inline = true;\n }\n }\n }\n\n private debounceEvent: ReturnType<typeof setTimeout> | undefined;\n\n private updateScrollButtonState = () => {\n clearTimeout(this.debounceEvent);\n this.debounceEvent = setTimeout(\n this.calculateScrollButtonsEnabled.bind(this),\n 100\n );\n };\n\n async slotChange() {\n // Free event loop for next frame\n await 0;\n this.querySelector('ix-primary-tab[active]')?.scrollIntoView();\n\n if (!this.tabContainer) return;\n\n if (this.scrollButtons && this.hideScrollBar) {\n this.tabContainer.classList.add('no-scrollbar');\n }\n\n if (this.scrollButtons) {\n this.calculateScrollButtonsEnabled();\n window.addEventListener('resize', this.updateScrollButtonState);\n this.tabContainer.addEventListener(\n 'scroll',\n this.updateScrollButtonState\n );\n }\n\n await this.updateComplete;\n\n if (this.tabContainer && this.alignLeft) {\n const { clientWidth, scrollWidth } = this.tabContainer;\n this.inline = scrollWidth <= clientWidth;\n }\n }\n\n protected firstUpdated(_changedProperties: PropertyValues) {\n super.firstUpdated(_changedProperties);\n\n requestAnimationFrame(() => {\n this.tabContainer = this.mdTabs.shadowRoot?.querySelector('.tabs');\n this.slotChange();\n });\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n if (this.scrollButtons) {\n window.removeEventListener('resize', this.updateScrollButtonState);\n this.tabContainer?.removeEventListener(\n 'scroll',\n this.updateScrollButtonState\n );\n }\n }\n\n private scrollTabs(direction: ScrollDirection = 'left', scrollAmount = 0.75) {\n if (this.tabContainer) {\n const { clientWidth, scrollLeft } = this.tabContainer;\n const offset =\n direction === 'left'\n ? clientWidth * -scrollAmount\n : clientWidth * scrollAmount;\n const scrollToPosition = scrollLeft + offset;\n this.tabContainer.scrollTo({\n top: 0,\n left: scrollToPosition,\n behavior: 'smooth',\n });\n }\n }\n\n render() {\n return html`\n ${this.scrollButtons\n ? html`<div\n class=\"gradient left ${!this.enableLeftScroll ? 'disabled' : ''}\"\n >\n <ix-icon-button\n icon=\"chevron_left\"\n @click=${() => this.scrollTabs('left')}\n ?disabled=${!this.enableLeftScroll}\n ></ix-icon-button>\n </div>`\n : nothing}\n <md-tabs .withoutBorderBottom=\"${this.withoutBorderBottom}\">\n <slot @slotchange=${this.slotChange}></slot>\n </md-tabs>\n ${this.scrollButtons\n ? html`<div\n class=\"gradient right ${!this.enableRightScroll ? 'disabled' : ''}\"\n >\n <ix-icon-button\n icon=\"chevron_right\"\n @click=${() => this.scrollTabs('right')}\n ?disabled=${!this.enableRightScroll}\n ></ix-icon-button>\n </div>`\n : nothing}\n `;\n }\n}\n"]}
@@ -1,3 +1,3 @@
1
- import{__decorate}from"tslib";import{LitElement,isServer,html,nothing,css}from"lit";import{property,query,state,queryAssignedNodes,queryAssignedElements,customElement}from"lit/decorators.js";import{styles}from"@material/web/tabs/internal/tabs-styles.css.js";import"@material/web/divider/divider.js";import"@material/web/elevation/elevation.js";import"@material/web/focus/md-focus-ring.js";import"@material/web/ripple/ripple.js";import{classMap}from"lit/directives/class-map.js";import{EASING}from"@material/web/internal/motion/animation.js";import"@digital-realty/ix-icon-button/ix-icon-button.js";var _a;let INDICATOR=Symbol("indicator"),ANIMATE_INDICATOR=Symbol("animateIndicator");function shouldReduceMotion(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}class Tab extends LitElement{get selected(){return this.active}set selected(t){this.active=t}constructor(){super(),this.isTab=!0,this.active=!1,this.hasIcon=!1,this.iconOnly=!1,this.fullWidthIndicator=!0,this.internals=this.attachInternals(),isServer||(this.internals.role="tab",this.addEventListener("keydown",this.handleKeydown.bind(this)))}render(){var t=html`<div class="indicator"></div>`;return html`<div class="button" role="presentation" @click="${this.handleContentClick}"><md-focus-ring part="focus-ring" inward .control="${this}"></md-focus-ring><md-elevation></md-elevation><md-ripple .control="${this}"></md-ripple><div class="content ${classMap(this.getContentClasses())}" role="presentation"><slot name="icon" @slotchange="${this.handleIconSlotChange}"></slot><slot @slotchange="${this.handleSlotChange}"></slot>${this.fullWidthIndicator?nothing:t}</div>${this.fullWidthIndicator?t:nothing}</div>`}getContentClasses(){return{"has-icon":this.hasIcon,"has-label":!this.iconOnly}}updated(){this.internals.ariaSelected=String(this.active)}async handleKeydown(t){await 0,t.defaultPrevented||"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.click())}handleContentClick(t){t.stopPropagation(),this.click()}[(_a=INDICATOR,ANIMATE_INDICATOR)](t){this[INDICATOR]&&(this[INDICATOR].getAnimations().forEach(t=>{t.cancel()}),t=null==(t=null==t?void 0:t.shadowRoot)?void 0:t.querySelector("*"),null!==(t=this.getKeyframes(t)))&&this[INDICATOR].animate(t,{duration:250,easing:EASING.EMPHASIZED})}getKeyframes(t){var e,a,i,o,s=shouldReduceMotion();return this.active?(e={},a=(t=null!=(t=null==(t=t[INDICATOR])?void 0:t.getBoundingClientRect())?t:{}).left,t=t.width,o=(i=this[INDICATOR].getBoundingClientRect()).left,t=t/i.width,!s&&void 0!==a&&void 0!==o&&Number(t)?e.transform=`translateX(${(a-o).toFixed(4)}px) scaleX(${t.toFixed(4)})`:e.opacity=0,[e,{transform:"none"}]):s?[{opacity:1},{transform:"none"}]:null}handleSlotChange(){this.iconOnly=!1;for(var t of this.assignedDefaultNodes){var e=t.nodeType===Node.TEXT_NODE&&!!t.wholeText.match(/\S/);if(t.nodeType===Node.ELEMENT_NODE||e)return}this.iconOnly=!0}handleIconSlotChange(){this.hasIcon=0<this.assignedIcons.length}}function isTab(t){return t instanceof HTMLElement&&("IX-PRIMARY-TAB"===t.tagName||"IX-SECONDARY-TAB"===t.tagName)}__decorate([property({type:Boolean,reflect:!0,attribute:"md-tab"})],Tab.prototype,"isTab",void 0),__decorate([property({type:Boolean,reflect:!0})],Tab.prototype,"active",void 0),__decorate([property({type:Boolean})],Tab.prototype,"selected",null),__decorate([property({type:Boolean,attribute:"has-icon"})],Tab.prototype,"hasIcon",void 0),__decorate([property({type:Boolean,attribute:"icon-only"})],Tab.prototype,"iconOnly",void 0),__decorate([query(".indicator")],Tab.prototype,_a,void 0),__decorate([state()],Tab.prototype,"fullWidthIndicator",void 0),__decorate([queryAssignedNodes({flatten:!0})],Tab.prototype,"assignedDefaultNodes",void 0),__decorate([queryAssignedElements({slot:"icon",flatten:!0})],Tab.prototype,"assignedIcons",void 0);class Tabs extends LitElement{get activeTab(){var t;return null!=(t=this.tabs.find(t=>t.active))?t:null}set activeTab(t){t&&this.activateTab(t)}get activeTabIndex(){return this.tabs.findIndex(t=>t.active)}set activeTabIndex(e){var t=()=>{var t=this.tabs[e];t&&this.activateTab(t)};this.slotElement?t():this.updateComplete.then(t)}get focusedTab(){return this.tabs.find(t=>t.matches(":focus-within"))}constructor(){super(),this.autoActivate=!1,this.internals=this.attachInternals(),isServer||(this.internals.role="tablist",this.addEventListener("keydown",this.handleKeydown.bind(this)),this.addEventListener("keyup",this.handleKeyup.bind(this)),this.addEventListener("focusout",this.handleFocusout.bind(this)))}async scrollToTab(t){await this.updateComplete;var e=this.tabs;if((t=null!=t?t:this.activeTab)&&e.includes(t)){for(var a of this.tabs)await a.updateComplete;var e=t.offsetLeft,t=t.offsetWidth,i=this.scrollLeft,o=this.offsetWidth,e=Math.min(e-48,Math.max(e+t-o+48,i)),t=this.focusedTab?"instant":"smooth";this.scrollTo({behavior:t,top:0,left:e})}}render(){return html`<div class="tabs"><slot @slotchange="${this.handleSlotChange}" @click="${this.handleTabClick}" @keydown="${this.handleTabClick}"></slot></div><md-divider part="divider"></md-divider>`}async handleTabClick(t){var e=t.target;await 0,t.defaultPrevented||!isTab(e)||e.active||this.activateTab(e)}activateTab(t){var e=this.tabs,a=this.activeTab;if(e.includes(t)&&a!==t){for(var i of e){i.active=i===t;var o=null==(o=i.shadowRoot)?void 0:o.querySelector("*");o&&(o.active=i.active)}if(a){if(!this.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0,composed:!0}))){for(var s of e)s.active=s===a;return}(null==(e=t.shadowRoot)?void 0:e.querySelector("*"))[ANIMATE_INDICATOR](a)}this.updateFocusableTab(t),this.scrollToTab(t)}}updateFocusableTab(t){for(var e of this.tabs)e.tabIndex=e===t?0:-1}async handleKeydown(e){await 0;var a="ArrowLeft"===e.key,i="ArrowRight"===e.key,o="Home"===e.key,s="End"===e.key;if(!e.defaultPrevented&&(a||i||o||s)){var n=this.tabs;if(!(n.length<2)){e.preventDefault();let t;o||s?t=o?0:n.length-1:(e="rtl"===getComputedStyle(this).direction?a:i,s=this.focusedTab,s?(o=this.tabs.indexOf(s),(t=e?o+1:o-1)>=n.length?t=0:t<0&&(t=n.length-1)):t=e?0:n.length-1);a=n[t];a.focus(),this.autoActivate?this.activateTab(a):this.updateFocusableTab(a)}}}handleKeyup(){var t;this.scrollToTab(null!=(t=this.focusedTab)?t:this.activeTab)}handleFocusout(){var t;this.matches(":focus-within")||(t=this.activeTab,t&&this.updateFocusableTab(t))}handleSlotChange(){var t=this.tabs[0];!this.activeTab&&t&&this.activateTab(t),this.scrollToTab(this.activeTab)}}__decorate([queryAssignedElements({flatten:!0})],Tabs.prototype,"tabs",void 0),__decorate([property({type:Boolean,attribute:"auto-activate"})],Tabs.prototype,"autoActivate",void 0),__decorate([query("slot")],Tabs.prototype,"slotElement",void 0);let MdTabs=class extends Tabs{};MdTabs.styles=[styles,css`.tabs.no-scrollbar::-webkit-scrollbar{display:none}`],MdTabs=__decorate([customElement("md-tabs")],MdTabs);class IxTabs extends LitElement{constructor(){super(...arguments),this.scrollButtons=!1,this.hideScrollBar=!1,this.inline=!1,this.alignLeft=!1,this.enableLeftScroll=!0,this.enableRightScroll=!0,this.tabContainer=null,this.updateScrollButtonState=()=>{clearTimeout(this.debounceEvent),this.debounceEvent=setTimeout(this.calculateScrollButtonsEnabled.bind(this),100)}}get activeTabIndex(){return this.mdTabs.activeTabIndex}set activeTabIndex(t){this.mdTabs.activeTabIndex=t}calculateScrollButtonsEnabled(){var t,e,a;this.tabContainer&&({clientWidth:a,scrollWidth:t,scrollLeft:e}=this.tabContainer,this.enableLeftScroll=0!==e,this.enableRightScroll=e!==t-a,this.alignLeft)&&(a=null==(e=this.parentElement)?void 0:e.clientWidth,this.inline=!(a&&a<t))}async slotChange(){var t,e;null!=(t=this.querySelector("ix-primary-tab[active]"))&&t.scrollIntoView(),this.tabContainer&&(this.scrollButtons&&this.hideScrollBar&&this.tabContainer.classList.add("no-scrollbar"),this.scrollButtons&&(this.calculateScrollButtonsEnabled(),window.addEventListener("resize",this.updateScrollButtonState),this.tabContainer.addEventListener("scroll",this.updateScrollButtonState)),await this.updateComplete,this.tabContainer)&&this.alignLeft&&({clientWidth:t,scrollWidth:e}=this.tabContainer,this.inline=e<=t)}firstUpdated(t){super.firstUpdated(t),requestAnimationFrame(()=>{var t;this.tabContainer=null==(t=this.mdTabs.shadowRoot)?void 0:t.querySelector(".tabs"),this.slotChange()})}disconnectedCallback(){var t;super.disconnectedCallback(),this.scrollButtons&&(window.removeEventListener("resize",this.updateScrollButtonState),null!=(t=this.tabContainer))&&t.removeEventListener("scroll",this.updateScrollButtonState)}scrollTabs(t="left",e=.75){var a,i;this.tabContainer&&({clientWidth:a,scrollLeft:i}=this.tabContainer,this.tabContainer.scrollTo({top:0,left:i+("left"===t?a*-e:a*e),behavior:"smooth"}))}render(){return html`${this.scrollButtons?html`<ix-icon-button icon="chevron_left" @click="${()=>this.scrollTabs("left")}" ?disabled="${!this.enableLeftScroll}"></ix-icon-button>`:nothing}<md-tabs><slot @slotchange="${this.slotChange}"></slot></md-tabs>${this.scrollButtons?html`<ix-icon-button icon="chevron_right" @click="${()=>this.scrollTabs("right")}" ?disabled="${!this.enableRightScroll}"></ix-icon-button>`:nothing}`}}IxTabs.styles=css`:host{max-width:100%;display:flex;align-items:center;justify-content:center;overflow:hidden}:host(ix-tabs[inline]){display:inline-flex}:host(ix-tabs[inline]) ix-icon-button[disabled]{display:none}md-tabs{flex-grow:1;--md-primary-tab-container-color:transparent}ix-icon-button{--md-icon-button-hover-state-layer-opacity:0;--md-icon-button-pressed-state-layer-opacity:0;--md-icon-button-icon-color:var(--md-sys-text-color-secondary);--md-icon-button-pressed-state-layer-color:var(
1
+ import{__decorate}from"tslib";import{LitElement,isServer,html,nothing,css}from"lit";import{property,query,state,queryAssignedNodes,queryAssignedElements,customElement}from"lit/decorators.js";import{styles}from"@material/web/tabs/internal/tabs-styles.css.js";import"@material/web/divider/divider.js";import"@material/web/elevation/elevation.js";import"@material/web/focus/md-focus-ring.js";import"@material/web/ripple/ripple.js";import{classMap}from"lit/directives/class-map.js";import{EASING}from"@material/web/internal/motion/animation.js";import"@digital-realty/ix-icon-button/ix-icon-button.js";var _a;let INDICATOR=Symbol("indicator"),ANIMATE_INDICATOR=Symbol("animateIndicator");function shouldReduceMotion(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}class Tab extends LitElement{get selected(){return this.active}set selected(t){this.active=t}constructor(){super(),this.isTab=!0,this.active=!1,this.hasIcon=!1,this.iconOnly=!1,this.fullWidthIndicator=!0,this.internals=this.attachInternals(),isServer||(this.internals.role="tab",this.addEventListener("keydown",this.handleKeydown.bind(this)))}render(){var t=html`<div class="indicator"></div>`;return html`<div class="button" role="presentation" @click="${this.handleContentClick}"><md-focus-ring part="focus-ring" inward .control="${this}"></md-focus-ring><md-elevation></md-elevation><md-ripple .control="${this}"></md-ripple><div class="content ${classMap(this.getContentClasses())}" role="presentation"><slot name="icon" @slotchange="${this.handleIconSlotChange}"></slot><slot @slotchange="${this.handleSlotChange}"></slot>${this.fullWidthIndicator?nothing:t}</div>${this.fullWidthIndicator?t:nothing}</div>`}getContentClasses(){return{"has-icon":this.hasIcon,"has-label":!this.iconOnly}}updated(){this.internals.ariaSelected=String(this.active)}async handleKeydown(t){await 0,t.defaultPrevented||"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.click())}handleContentClick(t){t.stopPropagation(),this.click()}[(_a=INDICATOR,ANIMATE_INDICATOR)](t){this[INDICATOR]&&(this[INDICATOR].getAnimations().forEach(t=>{t.cancel()}),t=null==(t=null==t?void 0:t.shadowRoot)?void 0:t.querySelector("*"),null!==(t=this.getKeyframes(t)))&&this[INDICATOR].animate(t,{duration:250,easing:EASING.EMPHASIZED})}getKeyframes(t){var e,i,a,o,s=shouldReduceMotion();return this.active?(e={},i=(t=null!=(t=null==(t=t[INDICATOR])?void 0:t.getBoundingClientRect())?t:{}).left,t=t.width,o=(a=this[INDICATOR].getBoundingClientRect()).left,t=t/a.width,!s&&void 0!==i&&void 0!==o&&Number(t)?e.transform=`translateX(${(i-o).toFixed(4)}px) scaleX(${t.toFixed(4)})`:e.opacity=0,[e,{transform:"none"}]):s?[{opacity:1},{transform:"none"}]:null}handleSlotChange(){this.iconOnly=!1;for(var t of this.assignedDefaultNodes){var e=t.nodeType===Node.TEXT_NODE&&!!t.wholeText.match(/\S/);if(t.nodeType===Node.ELEMENT_NODE||e)return}this.iconOnly=!0}handleIconSlotChange(){this.hasIcon=0<this.assignedIcons.length}}function isTab(t){return t instanceof HTMLElement&&("IX-PRIMARY-TAB"===t.tagName||"IX-SECONDARY-TAB"===t.tagName)}__decorate([property({type:Boolean,reflect:!0,attribute:"md-tab"})],Tab.prototype,"isTab",void 0),__decorate([property({type:Boolean,reflect:!0})],Tab.prototype,"active",void 0),__decorate([property({type:Boolean})],Tab.prototype,"selected",null),__decorate([property({type:Boolean,attribute:"has-icon"})],Tab.prototype,"hasIcon",void 0),__decorate([property({type:Boolean,attribute:"icon-only"})],Tab.prototype,"iconOnly",void 0),__decorate([query(".indicator")],Tab.prototype,_a,void 0),__decorate([state()],Tab.prototype,"fullWidthIndicator",void 0),__decorate([queryAssignedNodes({flatten:!0})],Tab.prototype,"assignedDefaultNodes",void 0),__decorate([queryAssignedElements({slot:"icon",flatten:!0})],Tab.prototype,"assignedIcons",void 0);class Tabs extends LitElement{get activeTab(){var t;return null!=(t=this.tabs.find(t=>t.active))?t:null}set activeTab(t){t&&this.activateTab(t)}get activeTabIndex(){return this.tabs.findIndex(t=>t.active)}set activeTabIndex(e){var t=()=>{var t=this.tabs[e];t&&this.activateTab(t)};this.slotElement?t():this.updateComplete.then(t)}get focusedTab(){return this.tabs.find(t=>t.matches(":focus-within"))}constructor(){super(),this.withoutBorderBottom=!1,this.autoActivate=!1,this.internals=this.attachInternals(),isServer||(this.internals.role="tablist",this.addEventListener("keydown",this.handleKeydown.bind(this)),this.addEventListener("keyup",this.handleKeyup.bind(this)),this.addEventListener("focusout",this.handleFocusout.bind(this)))}async scrollToTab(t){await this.updateComplete;var e=this.tabs;if((t=null!=t?t:this.activeTab)&&e.includes(t)){for(var i of this.tabs)await i.updateComplete;var e=t.offsetLeft,t=t.offsetWidth,a=this.scrollLeft,o=this.offsetWidth,e=Math.min(e-48,Math.max(e+t-o+48,a)),t=this.focusedTab?"instant":"smooth";this.scrollTo({behavior:t,top:0,left:e})}}render(){return html`<div class="tabs"><slot @slotchange="${this.handleSlotChange}" @click="${this.handleTabClick}" @keydown="${this.handleTabClick}"></slot></div>${this.withoutBorderBottom?"":html`<md-divider></md-divider>`}`}async handleTabClick(t){var e=t.target;await 0,t.defaultPrevented||!isTab(e)||e.active||this.activateTab(e)}activateTab(t){var e=this.tabs,i=this.activeTab;if(e.includes(t)&&i!==t){for(var a of e){a.active=a===t;var o=null==(o=a.shadowRoot)?void 0:o.querySelector("*");o&&(o.active=a.active)}if(i){if(!this.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0,composed:!0}))){for(var s of e)s.active=s===i;return}(null==(e=t.shadowRoot)?void 0:e.querySelector("*"))[ANIMATE_INDICATOR](i)}this.updateFocusableTab(t),this.scrollToTab(t)}}updateFocusableTab(t){for(var e of this.tabs)e.tabIndex=e===t?0:-1}async handleKeydown(e){await 0;var i="ArrowLeft"===e.key,a="ArrowRight"===e.key,o="Home"===e.key,s="End"===e.key;if(!e.defaultPrevented&&(i||a||o||s)){var n=this.tabs;if(!(n.length<2)){e.preventDefault();let t;o||s?t=o?0:n.length-1:(e="rtl"===getComputedStyle(this).direction?i:a,s=this.focusedTab,s?(o=this.tabs.indexOf(s),(t=e?o+1:o-1)>=n.length?t=0:t<0&&(t=n.length-1)):t=e?0:n.length-1);i=n[t];i.focus(),this.autoActivate?this.activateTab(i):this.updateFocusableTab(i)}}}handleKeyup(){var t;this.scrollToTab(null!=(t=this.focusedTab)?t:this.activeTab)}handleFocusout(){var t;this.matches(":focus-within")||(t=this.activeTab,t&&this.updateFocusableTab(t))}handleSlotChange(){var t=this.tabs[0];!this.activeTab&&t&&this.activateTab(t),this.scrollToTab(this.activeTab)}}__decorate([queryAssignedElements({flatten:!0})],Tabs.prototype,"tabs",void 0),__decorate([property({type:Boolean})],Tabs.prototype,"withoutBorderBottom",void 0),__decorate([property({type:Boolean,attribute:"auto-activate"})],Tabs.prototype,"autoActivate",void 0),__decorate([query("slot")],Tabs.prototype,"slotElement",void 0);let MdTabs=class extends Tabs{};MdTabs.styles=[styles,css`.tabs.no-scrollbar::-webkit-scrollbar{display:none}`],MdTabs=__decorate([customElement("md-tabs")],MdTabs);class IxTabs extends LitElement{constructor(){super(...arguments),this.scrollButtons=!1,this.hideScrollBar=!1,this.inline=!1,this.alignLeft=!1,this.enableLeftScroll=!0,this.enableRightScroll=!0,this.withoutBorderBottom=!1,this.tabContainer=null,this.updateScrollButtonState=()=>{clearTimeout(this.debounceEvent),this.debounceEvent=setTimeout(this.calculateScrollButtonsEnabled.bind(this),100)}}get activeTabIndex(){return this.mdTabs.activeTabIndex}set activeTabIndex(t){this.mdTabs.activeTabIndex=t}calculateScrollButtonsEnabled(){var t,e,i;this.tabContainer&&({clientWidth:i,scrollWidth:t,scrollLeft:e}=this.tabContainer,this.enableLeftScroll=0!==e,this.enableRightScroll=e!==t-i,this.alignLeft)&&(i=null==(e=this.parentElement)?void 0:e.clientWidth,this.inline=!(i&&i<t))}async slotChange(){var t,e;await 0,null!=(t=this.querySelector("ix-primary-tab[active]"))&&t.scrollIntoView(),this.tabContainer&&(this.scrollButtons&&this.hideScrollBar&&this.tabContainer.classList.add("no-scrollbar"),this.scrollButtons&&(this.calculateScrollButtonsEnabled(),window.addEventListener("resize",this.updateScrollButtonState),this.tabContainer.addEventListener("scroll",this.updateScrollButtonState)),await this.updateComplete,this.tabContainer)&&this.alignLeft&&({clientWidth:t,scrollWidth:e}=this.tabContainer,this.inline=e<=t)}firstUpdated(t){super.firstUpdated(t),requestAnimationFrame(()=>{var t;this.tabContainer=null==(t=this.mdTabs.shadowRoot)?void 0:t.querySelector(".tabs"),this.slotChange()})}disconnectedCallback(){var t;super.disconnectedCallback(),this.scrollButtons&&(window.removeEventListener("resize",this.updateScrollButtonState),null!=(t=this.tabContainer))&&t.removeEventListener("scroll",this.updateScrollButtonState)}scrollTabs(t="left",e=.75){var i,a;this.tabContainer&&({clientWidth:i,scrollLeft:a}=this.tabContainer,this.tabContainer.scrollTo({top:0,left:a+("left"===t?i*-e:i*e),behavior:"smooth"}))}render(){return html`${this.scrollButtons?html`<div class="gradient left ${this.enableLeftScroll?"":"disabled"}"><ix-icon-button icon="chevron_left" @click="${()=>this.scrollTabs("left")}" ?disabled="${!this.enableLeftScroll}"></ix-icon-button></div>`:nothing}<md-tabs .withoutBorderBottom="${this.withoutBorderBottom}"><slot @slotchange="${this.slotChange}"></slot></md-tabs>${this.scrollButtons?html`<div class="gradient right ${this.enableRightScroll?"":"disabled"}"><ix-icon-button icon="chevron_right" @click="${()=>this.scrollTabs("right")}" ?disabled="${!this.enableRightScroll}"></ix-icon-button></div>`:nothing}`}}IxTabs.styles=css`:host{max-width:100%;display:flex;align-items:center;justify-content:center;overflow:hidden}:host(ix-tabs[inline]){display:inline-flex}:host(ix-tabs[inline]) ix-icon-button[disabled]{display:none}md-tabs{flex-grow:1;--md-primary-tab-container-color:transparent}ix-icon-button{--md-icon-button-hover-state-layer-opacity:0;--md-icon-button-pressed-state-layer-opacity:0;--md-icon-button-icon-color:var(--md-sys-text-color-secondary);--md-icon-button-pressed-state-layer-color:var(
2
2
  --md-sys-text-color-secondary
3
- )}.scroll{cursor:pointer}`,__decorate([query("md-Tabs")],IxTabs.prototype,"mdTabs",void 0),__decorate([query("ix-primary-tab[active]")],IxTabs.prototype,"activeTab",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"scrollButtons",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"hideScrollBar",void 0),__decorate([property({type:Boolean,reflect:!0})],IxTabs.prototype,"inline",void 0),__decorate([property({type:Boolean,attribute:"left-align"})],IxTabs.prototype,"alignLeft",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"enableLeftScroll",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"enableRightScroll",void 0),__decorate([state()],IxTabs.prototype,"tabContainer",void 0),window.customElements.define("ix-tabs",IxTabs);
3
+ )}.scroll{cursor:pointer}.gradient{position:relative}.gradient.left{margin-right:-10px}.gradient.right{margin-left:-10px}.gradient::before{content:'';width:20px;height:calc(100% + 2px);position:absolute;top:-2px;background:linear-gradient(to right,#fff,transparent);z-index:10;pointer-events:none}.gradient.left::before{left:30px}.gradient.right::before{right:30px;transform:rotate(180deg)}.gradient.disabled::before{display:none}`,__decorate([query("md-Tabs")],IxTabs.prototype,"mdTabs",void 0),__decorate([query("ix-primary-tab[active]")],IxTabs.prototype,"activeTab",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"scrollButtons",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"hideScrollBar",void 0),__decorate([property({type:Boolean,reflect:!0})],IxTabs.prototype,"inline",void 0),__decorate([property({type:Boolean,attribute:"left-align"})],IxTabs.prototype,"alignLeft",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"enableLeftScroll",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"enableRightScroll",void 0),__decorate([property({type:Boolean})],IxTabs.prototype,"withoutBorderBottom",void 0),__decorate([state()],IxTabs.prototype,"tabContainer",void 0),window.customElements.define("ix-tabs",IxTabs);
@@ -35,6 +35,7 @@ export declare class Tabs extends LitElement {
35
35
  * The tabs of this tab bar.
36
36
  */
37
37
  readonly tabs: Tab[];
38
+ withoutBorderBottom: boolean;
38
39
  /**
39
40
  * The currently selected tab, `null` only when there are no tab children.
40
41
  */
@@ -91,6 +91,7 @@ export class Tabs extends LitElement {
91
91
  }
92
92
  constructor() {
93
93
  super();
94
+ this.withoutBorderBottom = false;
94
95
  /**
95
96
  * Whether or not to automatically select a tab when it is focused.
96
97
  */
@@ -147,7 +148,7 @@ export class Tabs extends LitElement {
147
148
  @keydown=${this.handleTabClick}
148
149
  ></slot>
149
150
  </div>
150
- <md-divider part="divider"></md-divider>
151
+ ${this.withoutBorderBottom ? '' : html `<md-divider></md-divider>`}
151
152
  `;
152
153
  }
153
154
  async handleTabClick(event) {
@@ -281,6 +282,9 @@ export class Tabs extends LitElement {
281
282
  __decorate([
282
283
  queryAssignedElements({ flatten: true })
283
284
  ], Tabs.prototype, "tabs", void 0);
285
+ __decorate([
286
+ property({ type: Boolean })
287
+ ], Tabs.prototype, "withoutBorderBottom", void 0);
284
288
  __decorate([
285
289
  property({ type: Boolean, attribute: 'auto-activate' })
286
290
  ], Tabs.prototype, "autoActivate", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../src/mdtabs/internal/tabs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '@material/web/divider/divider.js';\n\nimport { html, isServer, LitElement } from 'lit';\nimport { property, query, queryAssignedElements } from 'lit/decorators.js';\n\nimport { ANIMATE_INDICATOR, Tab } from './tab.js';\n\nfunction isTab(element: unknown): element is Tab {\n return (\n element instanceof HTMLElement &&\n (element.tagName === 'IX-PRIMARY-TAB' ||\n element.tagName === 'IX-SECONDARY-TAB')\n );\n}\n\n/**\n * @fires change Fired when the selected tab changes. The target's selected or\n * selectedItem and previousSelected or previousSelectedItem provide information\n * about the selection change. The change event is fired when a user interaction\n * like a space/enter key or click cause a selection change. The tab selection\n * based on these actions can be cancelled by calling preventDefault on the\n * triggering `keydown` or `click` event.\n *\n * @example\n * // perform an action if a tab is clicked\n * tabs.addEventListener('change', (event: Event) => {\n * if (event.target.selected === 2)\n * takeAction();\n * }\n * });\n *\n * // prevent a click from triggering tab selection under some condition\n * tabs.addEventListener('click', (event: Event) => {\n * if (notReady)\n * event.preventDefault();\n * }\n * });\n *\n */\nexport class Tabs extends LitElement {\n /**\n * The tabs of this tab bar.\n */\n @queryAssignedElements({ flatten: true })\n readonly tabs!: Tab[];\n\n /**\n * The currently selected tab, `null` only when there are no tab children.\n */\n get activeTab() {\n return this.tabs.find(tab => tab.active) ?? null;\n }\n\n set activeTab(tab: Tab | null) {\n // Ignore setting activeTab to null. As long as there are children, one tab\n // must be selected.\n if (tab) {\n this.activateTab(tab);\n }\n }\n\n /**\n * The index of the currently selected tab.\n */\n get activeTabIndex() {\n return this.tabs.findIndex(tab => tab.active);\n }\n\n set activeTabIndex(index: number) {\n const activateTabAtIndex = () => {\n const tab = this.tabs[index];\n // Ignore out-of-bound indices.\n if (tab) {\n this.activateTab(tab);\n }\n };\n\n if (!this.slotElement) {\n // This is needed to support setting the activeTabIndex via a lit property\n // binding.\n //\n // ```ts\n // html`\n // <md-tabs .activeTabIndex=${1}>\n // <md-tab>First</md-tab>\n // <md-tab>Second</md-tab>\n // </md-tabs>\n // `;\n // ```\n //\n // It's needed since lit's rendering lifecycle is asynchronous, and the\n // `<slot>` element hasn't rendered, so `tabs` is empty.\n this.updateComplete.then(activateTabAtIndex);\n return;\n }\n\n activateTabAtIndex();\n }\n\n /**\n * Whether or not to automatically select a tab when it is focused.\n */\n @property({ type: Boolean, attribute: 'auto-activate' }) autoActivate = false;\n\n @query('slot') private readonly slotElement!: HTMLSlotElement | null;\n\n private get focusedTab() {\n return this.tabs.find(tab => tab.matches(':focus-within'));\n }\n\n private readonly internals = (this as HTMLElement) /* needed for closure */\n .attachInternals();\n\n constructor() {\n super();\n if (!isServer) {\n this.internals.role = 'tablist';\n this.addEventListener('keydown', this.handleKeydown.bind(this));\n this.addEventListener('keyup', this.handleKeyup.bind(this));\n this.addEventListener('focusout', this.handleFocusout.bind(this));\n }\n }\n\n /**\n * Scrolls the toolbar, if overflowing, to the active tab, or the provided\n * tab.\n *\n * @param tabToScrollTo The tab that should be scrolled to. Defaults to the\n * active tab.\n * @return A Promise that resolves after the tab has been scrolled to.\n */\n async scrollToTab(tabToScrollTo?: Tab | null) {\n await this.updateComplete;\n const { tabs } = this;\n // eslint-disable-next-line\n tabToScrollTo ??= this.activeTab;\n if (!tabToScrollTo || !tabs.includes(tabToScrollTo)) {\n return;\n }\n\n // wait for tabs to render.\n for (const tab of this.tabs) {\n // eslint-disable-next-line\n await tab.updateComplete;\n }\n\n const offset = tabToScrollTo.offsetLeft;\n const extent = tabToScrollTo.offsetWidth;\n const scroll = this.scrollLeft;\n const hostExtent = this.offsetWidth;\n const scrollMargin = 48;\n const min = offset - scrollMargin;\n const max = offset + extent - hostExtent + scrollMargin;\n const to = Math.min(min, Math.max(max, scroll));\n // TODO(b/299934312): improve focus smoothness\n const behavior = !this.focusedTab ? 'smooth' : ('instant' as const);\n // @ts-ignore\n this.scrollTo({ behavior, top: 0, left: to });\n }\n\n protected override render() {\n return html`\n <div class=\"tabs\">\n <slot\n @slotchange=${this.handleSlotChange}\n @click=${this.handleTabClick}\n @keydown=${this.handleTabClick}\n ></slot>\n </div>\n <md-divider part=\"divider\"></md-divider>\n `;\n }\n\n private async handleTabClick(event: Event) {\n const tab = event.target;\n // Allow event to bubble\n await 0;\n if (event.defaultPrevented || !isTab(tab) || tab.active) {\n return;\n }\n\n this.activateTab(tab);\n }\n\n private activateTab(activeTab: Tab) {\n const { tabs } = this;\n const previousTab = this.activeTab;\n if (!tabs.includes(activeTab) || previousTab === activeTab) {\n // Ignore setting activeTab to a tab element that is not a child.\n return;\n }\n\n for (const tab of tabs) {\n tab.active = tab === activeTab;\n const innerTab = tab.shadowRoot?.querySelector('*') as Tab;\n if (innerTab) {\n innerTab.active = tab.active;\n }\n }\n\n if (previousTab) {\n // Don't dispatch a change event if activating a tab when no previous tabs\n // were selected, such as when md-tabs auto-selects the first tab.\n const defaultPrevented = !this.dispatchEvent(\n new Event('change', { bubbles: true, cancelable: true, composed: true })\n );\n if (defaultPrevented) {\n for (const tab of tabs) {\n tab.active = tab === previousTab;\n }\n return;\n }\n\n const activeTabInner = activeTab.shadowRoot?.querySelector('*') as Tab;\n\n activeTabInner[ANIMATE_INDICATOR](previousTab);\n }\n\n this.updateFocusableTab(activeTab);\n this.scrollToTab(activeTab);\n }\n\n private updateFocusableTab(focusableTab: Tab) {\n for (const tab of this.tabs) {\n tab.tabIndex = tab === focusableTab ? 0 : -1;\n }\n }\n\n // focus item on keydown and optionally select it\n private async handleKeydown(event: KeyboardEvent) {\n // Allow event to bubble.\n await 0;\n const isLeft = event.key === 'ArrowLeft';\n const isRight = event.key === 'ArrowRight';\n const isHome = event.key === 'Home';\n const isEnd = event.key === 'End';\n // Ignore non-navigation keys\n if (event.defaultPrevented || (!isLeft && !isRight && !isHome && !isEnd)) {\n return;\n }\n\n const { tabs } = this;\n // Don't try to select another tab if there aren't any.\n if (tabs.length < 2) {\n return;\n }\n\n // Prevent default interactions, such as scrolling.\n event.preventDefault();\n\n let indexToFocus: number;\n if (isHome || isEnd) {\n indexToFocus = isHome ? 0 : tabs.length - 1;\n } else {\n // Check if moving forwards or backwards\n const isRtl = getComputedStyle(this).direction === 'rtl';\n const forwards = isRtl ? isLeft : isRight;\n const { focusedTab } = this;\n if (!focusedTab) {\n // If there is not already a tab focused, select the first or last tab\n // based on the direction we're traveling.\n indexToFocus = forwards ? 0 : tabs.length - 1;\n } else {\n const focusedIndex = this.tabs.indexOf(focusedTab);\n indexToFocus = forwards ? focusedIndex + 1 : focusedIndex - 1;\n if (indexToFocus >= tabs.length) {\n // Return to start if moving past the last item.\n indexToFocus = 0;\n } else if (indexToFocus < 0) {\n // Go to end if moving before the first item.\n indexToFocus = tabs.length - 1;\n }\n }\n }\n\n const tabToFocus = tabs[indexToFocus];\n tabToFocus.focus();\n if (this.autoActivate) {\n this.activateTab(tabToFocus);\n } else {\n this.updateFocusableTab(tabToFocus);\n }\n }\n\n // scroll to item on keyup.\n private handleKeyup() {\n this.scrollToTab(this.focusedTab ?? this.activeTab);\n }\n\n private handleFocusout() {\n // restore focus to selected item when blurring the tab bar.\n if (this.matches(':focus-within')) {\n return;\n }\n\n const { activeTab } = this;\n if (activeTab) {\n this.updateFocusableTab(activeTab);\n }\n }\n\n private handleSlotChange() {\n const firstTab = this.tabs[0];\n if (!this.activeTab && firstTab) {\n // If the active tab was removed, auto-select the first one. There should\n // always be a selected tab while the bar has children.\n this.activateTab(firstTab);\n }\n\n // When children shift, ensure the active tab is visible. For example, if\n // many children are added before the active tab, it'd be pushed off screen.\n // This ensures it stays visible.\n this.scrollToTab(this.activeTab);\n }\n}\n"]}
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../../src/mdtabs/internal/tabs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '@material/web/divider/divider.js';\n\nimport { html, isServer, LitElement } from 'lit';\nimport { property, query, queryAssignedElements } from 'lit/decorators.js';\n\nimport { ANIMATE_INDICATOR, Tab } from './tab.js';\n\nfunction isTab(element: unknown): element is Tab {\n return (\n element instanceof HTMLElement &&\n (element.tagName === 'IX-PRIMARY-TAB' ||\n element.tagName === 'IX-SECONDARY-TAB')\n );\n}\n\n/**\n * @fires change Fired when the selected tab changes. The target's selected or\n * selectedItem and previousSelected or previousSelectedItem provide information\n * about the selection change. The change event is fired when a user interaction\n * like a space/enter key or click cause a selection change. The tab selection\n * based on these actions can be cancelled by calling preventDefault on the\n * triggering `keydown` or `click` event.\n *\n * @example\n * // perform an action if a tab is clicked\n * tabs.addEventListener('change', (event: Event) => {\n * if (event.target.selected === 2)\n * takeAction();\n * }\n * });\n *\n * // prevent a click from triggering tab selection under some condition\n * tabs.addEventListener('click', (event: Event) => {\n * if (notReady)\n * event.preventDefault();\n * }\n * });\n *\n */\nexport class Tabs extends LitElement {\n /**\n * The tabs of this tab bar.\n */\n @queryAssignedElements({ flatten: true })\n readonly tabs!: Tab[];\n\n @property({ type: Boolean }) withoutBorderBottom = false;\n\n /**\n * The currently selected tab, `null` only when there are no tab children.\n */\n get activeTab() {\n return this.tabs.find(tab => tab.active) ?? null;\n }\n\n set activeTab(tab: Tab | null) {\n // Ignore setting activeTab to null. As long as there are children, one tab\n // must be selected.\n if (tab) {\n this.activateTab(tab);\n }\n }\n\n /**\n * The index of the currently selected tab.\n */\n get activeTabIndex() {\n return this.tabs.findIndex(tab => tab.active);\n }\n\n set activeTabIndex(index: number) {\n const activateTabAtIndex = () => {\n const tab = this.tabs[index];\n // Ignore out-of-bound indices.\n if (tab) {\n this.activateTab(tab);\n }\n };\n\n if (!this.slotElement) {\n // This is needed to support setting the activeTabIndex via a lit property\n // binding.\n //\n // ```ts\n // html`\n // <md-tabs .activeTabIndex=${1}>\n // <md-tab>First</md-tab>\n // <md-tab>Second</md-tab>\n // </md-tabs>\n // `;\n // ```\n //\n // It's needed since lit's rendering lifecycle is asynchronous, and the\n // `<slot>` element hasn't rendered, so `tabs` is empty.\n this.updateComplete.then(activateTabAtIndex);\n return;\n }\n\n activateTabAtIndex();\n }\n\n /**\n * Whether or not to automatically select a tab when it is focused.\n */\n @property({ type: Boolean, attribute: 'auto-activate' }) autoActivate = false;\n\n @query('slot') private readonly slotElement!: HTMLSlotElement | null;\n\n private get focusedTab() {\n return this.tabs.find(tab => tab.matches(':focus-within'));\n }\n\n private readonly internals = (this as HTMLElement) /* needed for closure */\n .attachInternals();\n\n constructor() {\n super();\n if (!isServer) {\n this.internals.role = 'tablist';\n this.addEventListener('keydown', this.handleKeydown.bind(this));\n this.addEventListener('keyup', this.handleKeyup.bind(this));\n this.addEventListener('focusout', this.handleFocusout.bind(this));\n }\n }\n\n /**\n * Scrolls the toolbar, if overflowing, to the active tab, or the provided\n * tab.\n *\n * @param tabToScrollTo The tab that should be scrolled to. Defaults to the\n * active tab.\n * @return A Promise that resolves after the tab has been scrolled to.\n */\n async scrollToTab(tabToScrollTo?: Tab | null) {\n await this.updateComplete;\n const { tabs } = this;\n // eslint-disable-next-line\n tabToScrollTo ??= this.activeTab;\n if (!tabToScrollTo || !tabs.includes(tabToScrollTo)) {\n return;\n }\n\n // wait for tabs to render.\n for (const tab of this.tabs) {\n // eslint-disable-next-line\n await tab.updateComplete;\n }\n\n const offset = tabToScrollTo.offsetLeft;\n const extent = tabToScrollTo.offsetWidth;\n const scroll = this.scrollLeft;\n const hostExtent = this.offsetWidth;\n const scrollMargin = 48;\n const min = offset - scrollMargin;\n const max = offset + extent - hostExtent + scrollMargin;\n const to = Math.min(min, Math.max(max, scroll));\n // TODO(b/299934312): improve focus smoothness\n const behavior = !this.focusedTab ? 'smooth' : ('instant' as const);\n // @ts-ignore\n this.scrollTo({ behavior, top: 0, left: to });\n }\n\n protected override render() {\n return html`\n <div class=\"tabs\">\n <slot\n @slotchange=${this.handleSlotChange}\n @click=${this.handleTabClick}\n @keydown=${this.handleTabClick}\n ></slot>\n </div>\n ${this.withoutBorderBottom ? '' : html`<md-divider></md-divider>`}\n `;\n }\n\n private async handleTabClick(event: Event) {\n const tab = event.target;\n // Allow event to bubble\n await 0;\n if (event.defaultPrevented || !isTab(tab) || tab.active) {\n return;\n }\n\n this.activateTab(tab);\n }\n\n private activateTab(activeTab: Tab) {\n const { tabs } = this;\n const previousTab = this.activeTab;\n if (!tabs.includes(activeTab) || previousTab === activeTab) {\n // Ignore setting activeTab to a tab element that is not a child.\n return;\n }\n\n for (const tab of tabs) {\n tab.active = tab === activeTab;\n const innerTab = tab.shadowRoot?.querySelector('*') as Tab;\n if (innerTab) {\n innerTab.active = tab.active;\n }\n }\n\n if (previousTab) {\n // Don't dispatch a change event if activating a tab when no previous tabs\n // were selected, such as when md-tabs auto-selects the first tab.\n const defaultPrevented = !this.dispatchEvent(\n new Event('change', { bubbles: true, cancelable: true, composed: true })\n );\n if (defaultPrevented) {\n for (const tab of tabs) {\n tab.active = tab === previousTab;\n }\n return;\n }\n\n const activeTabInner = activeTab.shadowRoot?.querySelector('*') as Tab;\n\n activeTabInner[ANIMATE_INDICATOR](previousTab);\n }\n\n this.updateFocusableTab(activeTab);\n this.scrollToTab(activeTab);\n }\n\n private updateFocusableTab(focusableTab: Tab) {\n for (const tab of this.tabs) {\n tab.tabIndex = tab === focusableTab ? 0 : -1;\n }\n }\n\n // focus item on keydown and optionally select it\n private async handleKeydown(event: KeyboardEvent) {\n // Allow event to bubble.\n await 0;\n const isLeft = event.key === 'ArrowLeft';\n const isRight = event.key === 'ArrowRight';\n const isHome = event.key === 'Home';\n const isEnd = event.key === 'End';\n // Ignore non-navigation keys\n if (event.defaultPrevented || (!isLeft && !isRight && !isHome && !isEnd)) {\n return;\n }\n\n const { tabs } = this;\n // Don't try to select another tab if there aren't any.\n if (tabs.length < 2) {\n return;\n }\n\n // Prevent default interactions, such as scrolling.\n event.preventDefault();\n\n let indexToFocus: number;\n if (isHome || isEnd) {\n indexToFocus = isHome ? 0 : tabs.length - 1;\n } else {\n // Check if moving forwards or backwards\n const isRtl = getComputedStyle(this).direction === 'rtl';\n const forwards = isRtl ? isLeft : isRight;\n const { focusedTab } = this;\n if (!focusedTab) {\n // If there is not already a tab focused, select the first or last tab\n // based on the direction we're traveling.\n indexToFocus = forwards ? 0 : tabs.length - 1;\n } else {\n const focusedIndex = this.tabs.indexOf(focusedTab);\n indexToFocus = forwards ? focusedIndex + 1 : focusedIndex - 1;\n if (indexToFocus >= tabs.length) {\n // Return to start if moving past the last item.\n indexToFocus = 0;\n } else if (indexToFocus < 0) {\n // Go to end if moving before the first item.\n indexToFocus = tabs.length - 1;\n }\n }\n }\n\n const tabToFocus = tabs[indexToFocus];\n tabToFocus.focus();\n if (this.autoActivate) {\n this.activateTab(tabToFocus);\n } else {\n this.updateFocusableTab(tabToFocus);\n }\n }\n\n // scroll to item on keyup.\n private handleKeyup() {\n this.scrollToTab(this.focusedTab ?? this.activeTab);\n }\n\n private handleFocusout() {\n // restore focus to selected item when blurring the tab bar.\n if (this.matches(':focus-within')) {\n return;\n }\n\n const { activeTab } = this;\n if (activeTab) {\n this.updateFocusableTab(activeTab);\n }\n }\n\n private handleSlotChange() {\n const firstTab = this.tabs[0];\n if (!this.activeTab && firstTab) {\n // If the active tab was removed, auto-select the first one. There should\n // always be a selected tab while the bar has children.\n this.activateTab(firstTab);\n }\n\n // When children shift, ensure the active tab is visible. For example, if\n // many children are added before the active tab, it'd be pushed off screen.\n // This ensures it stays visible.\n this.scrollToTab(this.activeTab);\n }\n}\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent ix-tabs following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "Digital Realty",
6
- "version": "1.1.8",
6
+ "version": "1.1.9",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.js",
@@ -105,5 +105,5 @@
105
105
  "README.md",
106
106
  "LICENSE"
107
107
  ],
108
- "gitHead": "04150e3af2bfe53d1e9dffb86f7c6c13f0e735c8"
108
+ "gitHead": "88d71dc777dfb338bb137b04f0ec54489600ee26"
109
109
  }