[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/script-modules/block-library/tabs/ -> view.js (source)

   1  // packages/block-library/build-module/tabs/view.mjs
   2  import {
   3    store,
   4    getContext,
   5    getElement,
   6    withSyncEvent
   7  } from "@wordpress/interactivity";
   8  var { actions, state } = store(
   9    "core/tabs",
  10    {
  11      state: {
  12        /**
  13         * Gets a contextually aware list of tabs for the current tabs block.
  14         *
  15         * @type {Array}
  16         */
  17        get tabsList() {
  18          const context = getContext();
  19          const tabsId = context?.tabsId;
  20          const tabsList = state[tabsId];
  21          return tabsList;
  22        },
  23        /**
  24         * Gets the index of the active tab element whether it
  25         * is a tab label or tab panel.
  26         *
  27         * @type {number|null}
  28         */
  29        get tabIndex() {
  30          const { attributes } = getElement();
  31          const tabId = attributes?.id?.replace("tab__", "") || null;
  32          if (!tabId) {
  33            return null;
  34          }
  35          const { tabsList } = state;
  36          const tabIndex = tabsList.findIndex((t) => t === tabId);
  37          return tabIndex;
  38        },
  39        /**
  40         * Whether the tab panel or tab label is the active tab.
  41         *
  42         * @type {boolean}
  43         */
  44        get isActiveTab() {
  45          const { activeTabIndex } = getContext();
  46          const { tabIndex } = state;
  47          return activeTabIndex === tabIndex;
  48        },
  49        /**
  50         * The value of the tabindex attribute for tab buttons.
  51         * Only the active tab should be in the tab sequence.
  52         *
  53         * @type {number}
  54         */
  55        get tabIndexAttribute() {
  56          return state.isActiveTab ? 0 : -1;
  57        }
  58      },
  59      actions: {
  60        /**
  61         * Handles the keydown events for the tab label and tabs controller.
  62         *
  63         * @param {KeyboardEvent} event The keydown event.
  64         */
  65        handleTabKeyDown: withSyncEvent((event) => {
  66          const { tabIndex } = state;
  67          if (tabIndex === null) {
  68            return;
  69          }
  70          if (event.key === "ArrowRight") {
  71            event.preventDefault();
  72            actions.moveFocus(tabIndex + 1);
  73          } else if (event.key === "ArrowLeft") {
  74            event.preventDefault();
  75            actions.moveFocus(tabIndex - 1);
  76          }
  77        }),
  78        /**
  79         * Handles the click event for the tab label.
  80         *
  81         * @param {MouseEvent} event The click event.
  82         */
  83        handleTabClick: withSyncEvent((event) => {
  84          event.preventDefault();
  85          const { tabIndex } = state;
  86          if (tabIndex !== null) {
  87            actions.setActiveTab(tabIndex);
  88          }
  89        }),
  90        /**
  91         * Moves focus to a specific tab without activating it.
  92         *
  93         * @param {number} tabIndex The index to move focus to.
  94         */
  95        moveFocus: (tabIndex) => {
  96          const { tabsList } = state;
  97          if (!tabsList || tabsList.length === 0) {
  98            return;
  99          }
 100          let newIndex = tabIndex;
 101          if (newIndex < 0) {
 102            newIndex = tabsList.length - 1;
 103          } else if (newIndex >= tabsList.length) {
 104            newIndex = 0;
 105          }
 106          const tabId = tabsList[newIndex];
 107          const tabElement = document.getElementById("tab__" + tabId);
 108          if (tabElement) {
 109            tabElement.focus();
 110          }
 111        },
 112        /**
 113         * Sets the active tab index.
 114         *
 115         * @param {number}  tabIndex    The index of the active tab.
 116         * @param {boolean} scrollToTab Whether to scroll to the tab element.
 117         */
 118        setActiveTab: (tabIndex, scrollToTab = false) => {
 119          const { tabsList } = state;
 120          if (!tabsList || tabsList.length === 0) {
 121            return;
 122          }
 123          let newIndex = tabIndex;
 124          if (newIndex < 0) {
 125            newIndex = 0;
 126          } else if (newIndex >= tabsList.length) {
 127            newIndex = tabsList.length - 1;
 128          }
 129          const context = getContext();
 130          context.activeTabIndex = newIndex;
 131          if (scrollToTab) {
 132            const tabId = tabsList[newIndex];
 133            const tabElement = document.getElementById(tabId);
 134            if (tabElement) {
 135              setTimeout(() => {
 136                tabElement.scrollIntoView({ behavior: "smooth" });
 137              }, 100);
 138            }
 139          }
 140        }
 141      },
 142      callbacks: {
 143        /**
 144         * 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.
 145         *
 146         */
 147        onTabsInit: () => {
 148          const { tabsList } = state;
 149          if (tabsList.length === 0) {
 150            return;
 151          }
 152          const { hash } = window.location;
 153          const tabId = hash.replace("#", "");
 154          const tabIndex = tabsList.findIndex((t) => t === tabId);
 155          if (tabIndex >= 0) {
 156            actions.setActiveTab(tabIndex, true);
 157          }
 158        }
 159      }
 160    },
 161    {
 162      lock: true
 163    }
 164  );


Generated : Sat Jul 25 08:20:20 2026 Cross-referenced by PHPXref