UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

242 lines (241 loc) 7.28 kB
import { TAB_LIST_SIZES, TAB_LIST_SIZE_MODIFIERS, TAB_LIST_KIND_MODIFIERS, TAB_LIST_IMPORTANCE_MODIFIERS } from "./tabs_constants.js"; import normalizeComponent from "../../_virtual/_plugin-vue2_normalizer.js"; const _sfc_main = { name: "DtTabGroup", provide() { return { groupContext: this.provideObj, setFocus: this.setFocus }; }, props: { /** * Identifies the tab group */ label: { type: String, default: "" }, /** * The id of the selected tab panel which should be displayed */ selected: { type: String, default: "" }, /** * If true, disables the tab group * @values true, false */ disabled: { type: Boolean, default: false }, /** * If true, applies inverted styles to the tab group * @values true, false */ inverted: { type: Boolean, default: false }, /** * If true, applies borderless styles to the tab group * @values true, false */ borderless: { type: Boolean, default: false }, /** * If provided, applies size styles to the tab group * @values default, sm */ size: { type: String, default: "default", validate(size) { return TAB_LIST_SIZES.includes(size); } }, /** * Pass through classes, used to customize the tab list */ tabListClass: { type: [String, Array, Object], default: "" }, /** * Pass through props, used to customize the tab list */ tabListChildProps: { type: Object, default: () => ({}) } }, emits: [ /** * Change tab event with the arguments: selected id of the current tab and disabled value * * @event change * @type {Object} */ "change", /** * Before change tab event with the event argument, useful to perform validations and prevent changing tabs if neccessary. * * @event before-change * @type {Event} */ "before-change" ], data() { return { provideObj: { selected: "", // the currently displayed tab id disabled: false // disable group }, focusId: null, tabs: [], TAB_LIST_SIZE_MODIFIERS, TAB_LIST_KIND_MODIFIERS, TAB_LIST_IMPORTANCE_MODIFIERS }; }, watch: { disabled: { immediate: true, handler() { this.provideObj.disabled = this.disabled; } }, selected: { immediate: true, handler() { this.provideObj.selected = this.selected; } } }, mounted() { this.updateSelected(); }, beforeUpdate() { this.updateSelected(); }, methods: { updateSelected() { if (!this.provideObj.selected) { this.provideObj.selected = this.selected; } this.tabs = this.getTabChildren(); }, setFocus(focusId) { this.focusId = focusId; }, getTabChildren() { return Array.from(this.$el.querySelectorAll(".d-tab")).map((el) => { var _a, _b; return { context: el, panelId: (_a = el.getAttribute("aria-controls")) == null ? void 0 : _a.replace("dt-panel-", ""), tabId: (_b = el.getAttribute("id")) == null ? void 0 : _b.replace("dt-tab-", ""), isSelected: el.getAttribute("aria-selected") === "true" }; }); }, onChange() { this.$emit("change", { ...this.provideObj }); }, tabLeft() { const index = this.getFocusedTabIndex(); if (index === -1) return; const indexElement = index - 1 < 0 ? this.tabs.length - 1 : index - 1; this.selectFocusOnTab(indexElement); }, tabRight() { const index = this.getFocusedTabIndex(); if (index === -1) return; const indexElement = index + 1 > this.tabs.length - 1 ? 0 : index + 1; this.selectFocusOnTab(indexElement); }, selectFocusOnTab(index) { const { context } = this.tabs[index]; context.focus(); }, selectTab(event) { if (this.isSameTabClicked()) return; this.$emit("before-change", event); if (event.defaultPrevented) return; const index = this.getFocusedTabIndex(); this.selectTabByIndex(index); this.onChange(); }, selectTabByIndex(index) { const { context, panelId } = this.tabs[index]; this.provideObj.selected = panelId; context.focus(); }, getFocusedTabIndex() { return this.tabs.findIndex((context) => this.focusId ? context.tabId === `${this.focusId}` : context.isSelected); }, onHomeButton() { var _a, _b; if (this.tabs.length === 0) return; (_b = (_a = this.tabs[0]) == null ? void 0 : _a.context) == null ? void 0 : _b.focus(); }, onEndButton() { var _a, _b; if (this.tabs.length === 0) return; (_b = (_a = this.tabs[this.tabs.length - 1]) == null ? void 0 : _a.context) == null ? void 0 : _b.focus(); }, isSameTabClicked() { const tab = this.tabs[this.getFocusedTabIndex()]; return this.provideObj.selected === tab.panelId; } } }; var _sfc_render = function render() { var _vm = this, _c = _vm._self._c; return _c("div", { attrs: { "data-qa": "dt-tab-group" } }, [_c("div", _vm._b({ class: [ "d-tablist", _vm.TAB_LIST_SIZE_MODIFIERS[_vm.size], { [_vm.TAB_LIST_KIND_MODIFIERS.inverted]: _vm.inverted, [_vm.TAB_LIST_IMPORTANCE_MODIFIERS.borderless]: _vm.borderless }, _vm.tabListClass ], attrs: { "role": "tablist", "aria-label": _vm.label }, on: { "keyup": [function($event) { if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "left", 37, $event.key, ["Left", "ArrowLeft"])) return null; if ("button" in $event && $event.button !== 0) return null; return _vm.tabLeft.apply(null, arguments); }, function($event) { if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "right", 39, $event.key, ["Right", "ArrowRight"])) return null; if ("button" in $event && $event.button !== 2) return null; return _vm.tabRight.apply(null, arguments); }, function($event) { if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "enter", 13, $event.key, "Enter")) return null; return _vm.selectTab.apply(null, arguments); }, function($event) { if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "space", 32, $event.key, [" ", "Spacebar"])) return null; return _vm.selectTab.apply(null, arguments); }], "click": _vm.selectTab, "keydown": [function($event) { if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "home", void 0, $event.key, void 0)) return null; return _vm.onHomeButton.apply(null, arguments); }, function($event) { if (!$event.type.indexOf("key") && _vm._k($event.keyCode, "end", void 0, $event.key, void 0)) return null; return _vm.onEndButton.apply(null, arguments); }] } }, "div", _vm.tabListChildProps, false), [_vm._t("tabs")], 2), _vm._t("default")], 2); }; var _sfc_staticRenderFns = []; var __component__ = /* @__PURE__ */ normalizeComponent( _sfc_main, _sfc_render, _sfc_staticRenderFns ); const DtTabGroup = __component__.exports; export { DtTabGroup as default }; //# sourceMappingURL=tab_group.vue.js.map