@wordpress/block-library
Version:
Block library for the WordPress editor.
220 lines (218 loc) • 6.51 kB
JavaScript
;
// packages/block-library/src/tabs/view.js
var import_interactivity = require("@wordpress/interactivity");
function createReadOnlyProxy(obj) {
const arrayMutationMethods = /* @__PURE__ */ new Set([
"push",
"pop",
"shift",
"unshift",
"splice",
"sort",
"reverse",
"copyWithin",
"fill"
]);
return new Proxy(obj, {
get(target, prop) {
if (Array.isArray(target) && arrayMutationMethods.has(prop)) {
return () => {
};
}
const value = target[prop];
if (typeof value === "object" && value !== null) {
return createReadOnlyProxy(value);
}
return value;
},
set() {
return false;
},
deleteProperty() {
return false;
}
});
}
var { actions: privateActions, state: privateState } = (0, import_interactivity.store)(
"core/tabs/private",
{
state: {
/**
* Gets a contextually aware list of tabs for the current tabs block.
*
* @type {Array}
*/
get tabsList() {
const context = (0, import_interactivity.getContext)();
const tabsId = context?.tabsId;
const tabsList = privateState[tabsId];
return tabsList;
},
/**
* Gets the index of the active tab element whether it
* is a tab label or tab panel.
*
* @type {number|null}
*/
get tabIndex() {
const { attributes } = (0, import_interactivity.getElement)();
const tabId = attributes?.id?.replace("tab__", "") || null;
if (!tabId) {
return null;
}
const { tabsList } = privateState;
const tabIndex = tabsList.findIndex((t) => t.id === tabId);
return tabIndex;
},
/**
* Whether the tab panel or tab label is the active tab.
*
* @type {boolean}
*/
get isActiveTab() {
const { activeTabIndex } = (0, import_interactivity.getContext)();
const { tabIndex } = privateState;
return activeTabIndex === tabIndex;
},
/**
* The value of the tabindex attribute.
*
* @type {false|string}
*/
get tabIndexAttribute() {
return privateState.isActiveTab ? -1 : 0;
}
},
actions: {
/**
* Handles the keydown events for the tab label and tabs controller.
*
* @param {KeyboardEvent} event The keydown event.
*/
handleTabKeyDown: (0, import_interactivity.withSyncEvent)((event) => {
const { isVertical } = (0, import_interactivity.getContext)();
if (event.key === "Enter") {
const { tabIndex } = privateState;
if (tabIndex !== null) {
privateActions.setActiveTab(tabIndex);
}
} else if (event.key === "ArrowRight" && !isVertical) {
const { tabIndex } = privateState;
if (tabIndex !== null) {
privateActions.setActiveTab(tabIndex + 1);
}
} else if (event.key === "ArrowLeft" && !isVertical) {
const { tabIndex } = privateState;
if (tabIndex !== null) {
privateActions.setActiveTab(tabIndex - 1);
}
} else if (event.key === "ArrowDown" && isVertical) {
const { tabIndex } = privateState;
if (tabIndex !== null) {
privateActions.setActiveTab(tabIndex + 1);
}
} else if (event.key === "ArrowUp" && isVertical) {
const { tabIndex } = privateState;
if (tabIndex !== null) {
privateActions.setActiveTab(tabIndex - 1);
}
}
}),
/**
* Handles the click event for the tab label.
*
* @param {MouseEvent} event The click event.
*/
handleTabClick: (0, import_interactivity.withSyncEvent)((event) => {
event.preventDefault();
const { tabIndex } = privateState;
if (tabIndex !== null) {
privateActions.setActiveTab(tabIndex);
}
}),
/**
* Sets the active tab index (internal implementation).
*
* @param {number} tabIndex The index of the active tab.
* @param {boolean} scrollToTab Whether to scroll to the tab element.
*/
setActiveTab: (tabIndex, scrollToTab = false) => {
const context = (0, import_interactivity.getContext)();
context.activeTabIndex = tabIndex;
if (scrollToTab) {
const tabId = privateState.tabsList[tabIndex].id;
const tabElement = document.getElementById(tabId);
if (tabElement) {
setTimeout(() => {
tabElement.scrollIntoView({ behavior: "smooth" });
}, 100);
}
}
}
},
callbacks: {
/**
* When the tabs are initialized, we need to check if there is a hash in the url and if so if it exists in the current tabsList, set the active tab to that index.
*
*/
onTabsInit: () => {
const { tabsList } = privateState;
if (tabsList.length === 0) {
return;
}
const { hash } = window.location;
const tabId = hash.replace("#", "");
const tabIndex = tabsList.findIndex((t) => t.id === tabId);
if (tabIndex >= 0) {
privateActions.setActiveTab(tabIndex, true);
}
}
}
},
{
lock: true
}
);
(0, import_interactivity.store)("core/tabs", {
state: {
/**
* Gets a contextually aware list of tabs for the current tabs block.
* Public API for third-party access.
*
* @type {Array}
*/
get tabsList() {
return createReadOnlyProxy(privateState.tabsList);
},
/**
* Gets the index of the active tab element whether it
* is a tab label or tab panel.
*
* @type {number|null}
*/
get tabIndex() {
return privateState.tabIndex;
},
/**
* Whether the tab panel or tab label is the active tab.
*
* @type {boolean}
*/
get isActiveTab() {
return privateState.isActiveTab;
}
},
actions: {
/**
* Sets the active tab index.
* Public API for third-party programmatic tab activation.
*
* @param {number} tabIndex The index of the active tab.
* @param {boolean} scrollToTab Whether to scroll to the tab element.
*/
setActiveTab: (tabIndex, scrollToTab = false) => {
privateActions.setActiveTab(tabIndex, scrollToTab);
}
}
});
//# sourceMappingURL=view.js.map