carbon-custom-elements
Version:
A Carbon Design System variant that's as easy to use as native HTML elements, with no framework tax, no framework silo.
1 lines • 8.2 kB
Source Map (JSON)
{"version":3,"sources":["components/content-switcher/content-switcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAiC,UAAU,EAAE,MAAM,aAAa,CAAC;AAGxE,OAAO,QAAQ,MAAM,yBAAyB,CAAC;AAoB/C;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;CAKhC,CAAC;AAEF;;;;;;;GAOG;AACH,cACM,iBAAkB,SAAQ,UAAU;IACxC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAYpB;;;;OAIG;IACH,SAAS,CAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM;IAO/D;;;OAGG;IACH,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,UAAU;IAI7C;;;OAGG;IACH,SAAS,CAAC,cAAc,CAAC,EAAE,GAAG,EAAE,EAAE,aAAa;IAM/C;;;OAGG;IACH,SAAS,CAAC,8BAA8B,CAAC,IAAI,EAAE,QAAQ;IAsBvD;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM;IASrC;;;OAGG;IACH,SAAS,CAAC,mBAAmB,CAAC,YAAY,EAAE,QAAQ;IAYpD;;OAEG;IAEH,KAAK,SAAM;IAEX,YAAY,CAAC,iBAAiB,KAAA;IAU9B;;OAEG;IACH,MAAM,KAAK,YAAY,WAEtB;IAED;;OAEG;IACH,MAAM,KAAK,mBAAmB,WAE7B;IAED;;OAEG;IACH,MAAM,KAAK,oBAAoB,WAE9B;IAED;;;OAGG;IACH,MAAM,KAAK,iBAAiB,WAE3B;IAED;;OAEG;IACH,MAAM,KAAK,WAAW,WAErB;IAED,MAAM;IAYN,MAAM,CAAC,MAAM,MAAU;CACxB;AAED,eAAe,iBAAiB,CAAC","file":"content-switcher.d.ts","sourcesContent":["/**\n * @license\n *\n * Copyright IBM Corp. 2019, 2020\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { html, property, customElement, LitElement } from 'lit-element';\nimport settings from 'carbon-components/es/globals/js/settings';\nimport { forEach, indexOf } from '../../globals/internal/collection-helpers';\nimport BXSwitch from './content-switcher-item';\nimport styles from './content-switcher.scss';\n\nconst { prefix } = settings;\n\n/**\n * @param index The index\n * @param length The length of the array.\n * @returns The new index, adjusting overflow/underflow.\n */\nconst capIndex = (index: number, length: number) => {\n if (index < 0) {\n return length - 1;\n }\n if (index >= length) {\n return 0;\n }\n return index;\n};\n\n/**\n * Navigation direction, associated with key symbols.\n */\nexport const NAVIGATION_DIRECTION = {\n Left: -1,\n ArrowLeft: -1,\n Right: 1,\n ArrowRight: 1,\n};\n\n/**\n * Content switcher.\n * @element bx-content-switcher\n * @fires bx-content-switcher-beingselected\n * The custom event fired before a content switcher item is selected upon a user gesture.\n * Cancellation of this event stops changing the user-initiated selection.\n * @fires bx-content-switcher-selected - The custom event fired after a a content switcher item is selected upon a user gesture.\n */\n@customElement(`${prefix}-content-switcher`)\nclass BXContentSwitcher extends LitElement {\n /**\n * Handles `mouseover`/`mouseout` events on `<slot>`.\n * @param event The event.\n */\n private _handleHover({ target, type }: MouseEvent) {\n const { selectorItem } = this.constructor as typeof BXContentSwitcher;\n const items = this.querySelectorAll(selectorItem);\n const index = type !== 'mouseover' ? -1 : indexOf(items, (target as Element).closest(selectorItem)!);\n const nextIndex = index < 0 ? index : index + 1;\n forEach(this.querySelectorAll(selectorItem), (elem, i) => {\n // Specifies child `<bx-content-switcher-item>` to hide its divider instead of using CSS,\n // until `:host-context()` gets supported in all major browsers\n (elem as BXSwitch).hideDivider = i === nextIndex;\n });\n }\n\n /**\n * @param currentItem The currently selected item.\n * @param direction The navigation direction.\n * @returns The item to be selected.\n */\n protected _getNextItem(currentItem: BXSwitch, direction: number) {\n const items = this.querySelectorAll((this.constructor as typeof BXContentSwitcher).selectorItemEnabled);\n const currentIndex = indexOf(items, currentItem);\n const nextIndex = capIndex(currentIndex + direction, items.length);\n return nextIndex === currentIndex ? null : items[nextIndex];\n }\n\n /**\n * Handles `click` event on the top-level element in the shadow DOM.\n * @param event The event.\n */\n protected _handleClick({ target }: MouseEvent) {\n this._handleUserInitiatedSelectItem(target as BXSwitch);\n }\n\n /**\n * Handles `keydown` event on the top-level element in the shadow DOM.\n * @param event The event.\n */\n protected _handleKeydown({ key }: KeyboardEvent) {\n if (key in NAVIGATION_DIRECTION) {\n this._navigate(NAVIGATION_DIRECTION[key]);\n }\n }\n\n /**\n * Handles user-initiated selection of a content switcher item.\n * @param [item] The content switcher item user wants to select.\n */\n protected _handleUserInitiatedSelectItem(item: BXSwitch) {\n if (!item.disabled && item.value !== this.value) {\n const init = {\n bubbles: true,\n composed: true,\n detail: {\n item,\n },\n };\n const constructor = this.constructor as typeof BXContentSwitcher;\n const beforeSelectEvent = new CustomEvent(constructor.eventBeforeSelect, {\n ...init,\n cancelable: true,\n });\n if (this.dispatchEvent(beforeSelectEvent)) {\n this._selectionDidChange(item);\n const afterSelectEvent = new CustomEvent(constructor.eventSelect, init);\n this.dispatchEvent(afterSelectEvent);\n }\n }\n }\n\n /**\n * Navigates through content switcher items.\n * @param direction `-1` to navigate backward, `1` to navigate forward.\n */\n protected _navigate(direction: number) {\n const { selectorItemSelected } = this.constructor as typeof BXContentSwitcher;\n const nextItem = this._getNextItem(this.querySelector(selectorItemSelected) as BXSwitch, direction);\n if (nextItem) {\n this._handleUserInitiatedSelectItem(nextItem as BXSwitch);\n this.requestUpdate();\n }\n }\n\n /**\n * A callback that runs after change in content switcher selection upon user interaction is confirmed.\n * @param itemToSelect A content switcher item.\n */\n protected _selectionDidChange(itemToSelect: BXSwitch) {\n this.value = itemToSelect.value;\n forEach(this.querySelectorAll((this.constructor as typeof BXContentSwitcher).selectorItemSelected), item => {\n (item as BXSwitch).selected = false;\n });\n itemToSelect.selected = true;\n // Waits for rendering with the new state that updates `tabindex`\n Promise.resolve().then(() => {\n itemToSelect.focus();\n });\n }\n\n /**\n * The value of the selected item.\n */\n @property({ reflect: true })\n value = '';\n\n shouldUpdate(changedProperties) {\n if (changedProperties.has('value')) {\n const { selectorItem } = this.constructor as typeof BXContentSwitcher;\n forEach(this.querySelectorAll(selectorItem), elem => {\n (elem as BXSwitch).selected = (elem as BXSwitch).value === this.value;\n });\n }\n return true;\n }\n\n /**\n * A selector that will return content switcher items.\n */\n static get selectorItem() {\n return `${prefix}-content-switcher-item`;\n }\n\n /**\n * A selector that will return enabled content switcher items.\n */\n static get selectorItemEnabled() {\n return `${prefix}-content-switcher-item:not([disabled])`;\n }\n\n /**\n * A selector that will return selected items.\n */\n static get selectorItemSelected() {\n return `${prefix}-content-switcher-item[selected]`;\n }\n\n /**\n * The name of the custom event fired before a content switcher item is selected upon a user gesture.\n * Cancellation of this event stops changing the user-initiated selection.\n */\n static get eventBeforeSelect() {\n return `${prefix}-content-switcher-beingselected`;\n }\n\n /**\n * The name of the custom event fired after a a content switcher item is selected upon a user gesture.\n */\n static get eventSelect() {\n return `${prefix}-content-switcher-selected`;\n }\n\n render() {\n const { _handleHover: handleHover, _handleKeydown: handleKeydown } = this;\n return html`\n <slot\n @click=\"${this._handleClick}\"\n @keydown=\"${handleKeydown}\"\n @mouseover=\"${handleHover}\"\n @mouseout=\"${handleHover}\"\n ></slot>\n `;\n }\n\n static styles = styles;\n}\n\nexport default BXContentSwitcher;\n"]}