PluginProbe
Gutenberg / 23.6.2
Gutenberg v23.6.2
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / modules / block-library / tabs / view.js

view.js in Gutenberg 23.6.2, at build/modules/block-library/tabs/view.js

166 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 );
165 //# sourceMappingURL=view.js.map
166