@ablogcms/tab 3.2.28-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +299 -0
- package/dist/index.mjs.map +1 -0
- package/dist/tab-manager.d.ts +9 -0
- package/dist/tab.d.ts +54 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @ablogcms/tab
|
|
2
|
+
|
|
3
|
+
タブ切り替え UI(`data-tab-target` 等)を制御する `TabManager` を提供するパッケージ。
|
|
4
|
+
|
|
5
|
+
## 使い方
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { TabManager, type TabOptions } from '@ablogcms/tab';
|
|
9
|
+
|
|
10
|
+
const manager = TabManager.getInstance();
|
|
11
|
+
manager.apply(element, options);
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- `TabManager.getInstance()`: シングルトンインスタンスを取得する。
|
|
15
|
+
- `manager.apply(element, options)`: 指定した要素配下のタブ切り替えを初期化する。
|
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// src/tab.ts
|
|
2
|
+
import { getNextActiveElement, getSelector, isDisabled, hide, show } from "@ablogcms/utils/dom";
|
|
3
|
+
var ARROW_LEFT_KEY = "ArrowLeft";
|
|
4
|
+
var ARROW_RIGHT_KEY = "ArrowRight";
|
|
5
|
+
var ARROW_UP_KEY = "ArrowUp";
|
|
6
|
+
var ARROW_DOWN_KEY = "ArrowDown";
|
|
7
|
+
var HOME_KEY = "Home";
|
|
8
|
+
var END_KEY = "End";
|
|
9
|
+
var SELECTOR_OUTER = "li";
|
|
10
|
+
var SELECTOR_TAB = 'a[href^="#"], [role="tab"]';
|
|
11
|
+
var defaultOptions = {
|
|
12
|
+
tabList: ".js-acms_admin_tabs",
|
|
13
|
+
tabClass: "js-acms_tab",
|
|
14
|
+
activeClass: "js-acms_tab-active",
|
|
15
|
+
readyMark: ".js-ready-acms_tabs",
|
|
16
|
+
enableHashNavigation: false,
|
|
17
|
+
onShow: () => {
|
|
18
|
+
},
|
|
19
|
+
onHide: () => {
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var Tab = class _Tab {
|
|
23
|
+
_element;
|
|
24
|
+
_tabList;
|
|
25
|
+
_options;
|
|
26
|
+
eventRegistry = /* @__PURE__ */ new Map();
|
|
27
|
+
constructor(element, options = {}) {
|
|
28
|
+
this._options = { ...defaultOptions, ...options };
|
|
29
|
+
this._element = element;
|
|
30
|
+
const tabList = this._options.tabList instanceof HTMLElement ? this._options.tabList : this._element.closest(this._options.tabList);
|
|
31
|
+
if (!tabList) {
|
|
32
|
+
throw new TypeError(`${element.outerHTML} has not a valid parent ${this._options.tabList}`);
|
|
33
|
+
}
|
|
34
|
+
this._tabList = tabList;
|
|
35
|
+
const tabs = this._getTabs();
|
|
36
|
+
this._setInitialAttributes(this._tabList, tabs);
|
|
37
|
+
this._keydown = this._keydown.bind(this);
|
|
38
|
+
this._click = this._click.bind(this);
|
|
39
|
+
this._element.addEventListener("click", this._click);
|
|
40
|
+
this._element.addEventListener("keydown", this._keydown);
|
|
41
|
+
this.eventRegistry.set(this._element, [
|
|
42
|
+
{
|
|
43
|
+
type: "click",
|
|
44
|
+
listener: this._click
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: "keydown",
|
|
48
|
+
listener: this._keydown
|
|
49
|
+
}
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
destroy() {
|
|
53
|
+
delete this._element.Tab;
|
|
54
|
+
for (const [eventTarget, listeners] of this.eventRegistry) {
|
|
55
|
+
listeners.forEach(({ type, listener, options }) => {
|
|
56
|
+
eventTarget.removeEventListener(type, listener, options);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
this.eventRegistry.clear();
|
|
60
|
+
}
|
|
61
|
+
// Public
|
|
62
|
+
show() {
|
|
63
|
+
const tab = this._element;
|
|
64
|
+
if (this._tabIsActive(tab)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const activeTab = this._getActiveTab();
|
|
68
|
+
if (activeTab) {
|
|
69
|
+
this._deactivate(activeTab);
|
|
70
|
+
}
|
|
71
|
+
this._activate(tab);
|
|
72
|
+
const panel = this._getTargetPanel(tab);
|
|
73
|
+
if (this._enableHashNavigation() && panel && `#${panel.id}` !== location.hash) {
|
|
74
|
+
const hash = panel.id;
|
|
75
|
+
if ("history" in window) {
|
|
76
|
+
history.replaceState(null, "", `#${hash}`);
|
|
77
|
+
}
|
|
78
|
+
panel.id = hash;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
get options() {
|
|
82
|
+
return this._options;
|
|
83
|
+
}
|
|
84
|
+
// Private
|
|
85
|
+
_activate(tab) {
|
|
86
|
+
const panel = this._getTargetPanel(tab);
|
|
87
|
+
tab.classList.add(this._options.activeClass);
|
|
88
|
+
if (panel !== null) {
|
|
89
|
+
show(panel);
|
|
90
|
+
panel.setAttribute("aria-hidden", "false");
|
|
91
|
+
}
|
|
92
|
+
tab.removeAttribute("tabindex");
|
|
93
|
+
tab.setAttribute("aria-selected", "true");
|
|
94
|
+
this._options.onShow({ tab, panel });
|
|
95
|
+
}
|
|
96
|
+
_deactivate(tab) {
|
|
97
|
+
const panel = this._getTargetPanel(tab);
|
|
98
|
+
tab.classList.remove(this._options.activeClass);
|
|
99
|
+
tab.blur();
|
|
100
|
+
if (panel !== null) {
|
|
101
|
+
hide(panel);
|
|
102
|
+
panel.setAttribute("aria-hidden", "true");
|
|
103
|
+
}
|
|
104
|
+
tab.setAttribute("aria-selected", "false");
|
|
105
|
+
tab.setAttribute("tabindex", "-1");
|
|
106
|
+
this._options.onHide({ tab, panel });
|
|
107
|
+
}
|
|
108
|
+
_click(event) {
|
|
109
|
+
const { currentTarget } = event;
|
|
110
|
+
if (!(currentTarget instanceof HTMLElement)) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (["A", "AREA"].includes(currentTarget.tagName)) {
|
|
114
|
+
event.preventDefault();
|
|
115
|
+
}
|
|
116
|
+
if (isDisabled(currentTarget)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
_Tab.getOrCreateInstance(currentTarget).show();
|
|
120
|
+
}
|
|
121
|
+
_keydown(event) {
|
|
122
|
+
if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!(event.target instanceof HTMLElement)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
event.stopPropagation();
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
const activeTabs = this._getTabs().filter((tab) => !isDisabled(tab));
|
|
131
|
+
let nextActiveElement;
|
|
132
|
+
if ([HOME_KEY, END_KEY].includes(event.key)) {
|
|
133
|
+
nextActiveElement = activeTabs[event.key === HOME_KEY ? 0 : activeTabs.length - 1];
|
|
134
|
+
} else {
|
|
135
|
+
const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
|
|
136
|
+
nextActiveElement = getNextActiveElement(activeTabs, event.target, isNext, true);
|
|
137
|
+
}
|
|
138
|
+
if (nextActiveElement) {
|
|
139
|
+
nextActiveElement.focus({ preventScroll: true });
|
|
140
|
+
_Tab.getOrCreateInstance(nextActiveElement).show();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
_getTabs() {
|
|
144
|
+
return Array.from(this._tabList.querySelectorAll(SELECTOR_TAB));
|
|
145
|
+
}
|
|
146
|
+
_getActiveTab() {
|
|
147
|
+
return this._getTabs().find((tab) => this._tabIsActive(tab)) || null;
|
|
148
|
+
}
|
|
149
|
+
_getReadyTab() {
|
|
150
|
+
return this._getTabs().find((tab) => tab.matches(this._options.readyMark)) || null;
|
|
151
|
+
}
|
|
152
|
+
_getTabFromHash() {
|
|
153
|
+
return this._getTabs().find((tab) => getSelector(tab) === location.hash) || null;
|
|
154
|
+
}
|
|
155
|
+
_getInitialActiveTab() {
|
|
156
|
+
if (this._enableHashNavigation()) {
|
|
157
|
+
const hashTab = this._getTabFromHash();
|
|
158
|
+
if (hashTab) {
|
|
159
|
+
return hashTab;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const readyTab = this._getReadyTab();
|
|
163
|
+
if (readyTab) {
|
|
164
|
+
return readyTab;
|
|
165
|
+
}
|
|
166
|
+
return this._getTabs().at(0);
|
|
167
|
+
}
|
|
168
|
+
_setInitialAttributes(parent, tabs) {
|
|
169
|
+
this._setAttributeIfNotExists(parent, "role", "tablist");
|
|
170
|
+
const initialActiveTab = this._getInitialActiveTab();
|
|
171
|
+
if (initialActiveTab) {
|
|
172
|
+
this._activate(initialActiveTab);
|
|
173
|
+
}
|
|
174
|
+
for (const tab of tabs) {
|
|
175
|
+
this._setInitialAttributesOnTab(tab);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
_setInitialAttributesOnTab(tab) {
|
|
179
|
+
const isActive = this._tabIsActive(tab);
|
|
180
|
+
const outerElem = this._getOuterElement(tab);
|
|
181
|
+
const panel = this._getTargetPanel(tab);
|
|
182
|
+
tab.classList.add(this._options.tabClass);
|
|
183
|
+
tab.setAttribute("aria-selected", isActive ? "true" : "false");
|
|
184
|
+
if (outerElem !== tab) {
|
|
185
|
+
this._setAttributeIfNotExists(outerElem, "role", "presentation");
|
|
186
|
+
}
|
|
187
|
+
if (!isActive) {
|
|
188
|
+
tab.setAttribute("tabindex", "-1");
|
|
189
|
+
}
|
|
190
|
+
this._setAttributeIfNotExists(tab, "role", "tab");
|
|
191
|
+
if (panel) {
|
|
192
|
+
this._setAttributeIfNotExists(tab, "aria-controls", panel.id);
|
|
193
|
+
this._setAttributeIfNotExists(tab, "id", `${panel.id}-tab`);
|
|
194
|
+
}
|
|
195
|
+
this._setInitialAttributesOnTargetPanel(tab);
|
|
196
|
+
}
|
|
197
|
+
_setInitialAttributesOnTargetPanel(tab) {
|
|
198
|
+
const panel = this._getTargetPanel(tab);
|
|
199
|
+
if (!panel) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const isActive = this._tabIsActive(tab);
|
|
203
|
+
this._setAttributeIfNotExists(panel, "role", "tabpanel");
|
|
204
|
+
this._setAttributeIfNotExists(panel, "aria-hidden", isActive ? "false" : "true");
|
|
205
|
+
if (!isActive) {
|
|
206
|
+
panel.style.display = "none";
|
|
207
|
+
}
|
|
208
|
+
if (tab.id) {
|
|
209
|
+
this._setAttributeIfNotExists(panel, "aria-labelledby", `${tab.id}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
_getTargetPanel(tab) {
|
|
213
|
+
const selector = getSelector(tab);
|
|
214
|
+
if (!selector) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
return document.querySelector(selector);
|
|
218
|
+
}
|
|
219
|
+
_setAttributeIfNotExists(element, attribute, value) {
|
|
220
|
+
if (!element.hasAttribute(attribute)) {
|
|
221
|
+
element.setAttribute(attribute, value);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
_tabIsActive(tab) {
|
|
225
|
+
return tab.classList.contains(this._options.activeClass);
|
|
226
|
+
}
|
|
227
|
+
// Try to get the outer element (usually the .nav-item)
|
|
228
|
+
_getOuterElement(elem) {
|
|
229
|
+
return elem.closest(SELECTOR_OUTER) || elem;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* ハッシュナビゲーションを有効にするかどうかを判断する
|
|
233
|
+
*/
|
|
234
|
+
_enableHashNavigation() {
|
|
235
|
+
if (this._options.enableHashNavigation) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
if (this._options.readyMark.startsWith("#")) {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
static getOrCreateInstance(element, options = {}) {
|
|
244
|
+
if (element.Tab instanceof _Tab) {
|
|
245
|
+
return element.Tab;
|
|
246
|
+
}
|
|
247
|
+
const tab = new _Tab(element, options);
|
|
248
|
+
element.Tab = tab;
|
|
249
|
+
return tab;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// src/tab-manager.ts
|
|
254
|
+
var TabManager = class _TabManager {
|
|
255
|
+
static instance = null;
|
|
256
|
+
tabRepository = /* @__PURE__ */ new Map();
|
|
257
|
+
static getInstance() {
|
|
258
|
+
if (!_TabManager.instance) {
|
|
259
|
+
_TabManager.instance = new _TabManager();
|
|
260
|
+
}
|
|
261
|
+
return _TabManager.instance;
|
|
262
|
+
}
|
|
263
|
+
async apply(selector, options = {}, context = document) {
|
|
264
|
+
const tabOptions = {
|
|
265
|
+
tabList: selector,
|
|
266
|
+
...options
|
|
267
|
+
};
|
|
268
|
+
ACMS.Loaded(() => {
|
|
269
|
+
context.querySelectorAll(SELECTOR_TAB).forEach((element) => {
|
|
270
|
+
if (element.closest(selector) !== null) {
|
|
271
|
+
Tab.getOrCreateInstance(element, tabOptions);
|
|
272
|
+
this.tabRepository.set(selector, [...this.tabRepository.get(selector) || [], element]);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
destroy(selector) {
|
|
278
|
+
const elements = this.tabRepository.get(selector);
|
|
279
|
+
if (elements) {
|
|
280
|
+
elements.forEach((element) => {
|
|
281
|
+
Tab.getOrCreateInstance(element).destroy();
|
|
282
|
+
});
|
|
283
|
+
this.tabRepository.delete(selector);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
destroyAll() {
|
|
287
|
+
for (const [, elements] of this.tabRepository) {
|
|
288
|
+
elements.forEach((element) => {
|
|
289
|
+
Tab.getOrCreateInstance(element).destroy();
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
this.tabRepository.clear();
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
export {
|
|
296
|
+
SELECTOR_TAB,
|
|
297
|
+
TabManager
|
|
298
|
+
};
|
|
299
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tab.ts","../src/tab-manager.ts"],"sourcesContent":["import { getNextActiveElement, getSelector, isDisabled, hide, show } from '@ablogcms/utils/dom';\n\nconst ARROW_LEFT_KEY = 'ArrowLeft';\nconst ARROW_RIGHT_KEY = 'ArrowRight';\nconst ARROW_UP_KEY = 'ArrowUp';\nconst ARROW_DOWN_KEY = 'ArrowDown';\nconst HOME_KEY = 'Home';\nconst END_KEY = 'End';\n\nconst SELECTOR_OUTER = 'li';\nexport const SELECTOR_TAB = 'a[href^=\"#\"], [role=\"tab\"]';\n\nexport interface TabOptions {\n tabList: string | HTMLElement;\n tabClass: string;\n activeClass: string;\n readyMark: string;\n enableHashNavigation: boolean;\n onShow: ({ tab, panel }: { tab: HTMLElement; panel: HTMLElement | null }) => void;\n onHide: ({ tab, panel }: { tab: HTMLElement; panel: HTMLElement | null }) => void;\n}\n\nexport const defaultOptions: TabOptions = {\n tabList: '.js-acms_admin_tabs',\n tabClass: 'js-acms_tab',\n activeClass: 'js-acms_tab-active',\n readyMark: '.js-ready-acms_tabs',\n enableHashNavigation: false,\n onShow: () => {},\n onHide: () => {},\n};\n\ntype TabElement = HTMLElement & { Tab?: Tab };\n\nexport default class Tab {\n private _element: TabElement;\n\n private _tabList: HTMLElement;\n\n private _options: TabOptions;\n\n private eventRegistry: Map<\n Element | Document,\n Array<{\n type: string;\n listener: EventListener;\n options?: AddEventListenerOptions;\n }>\n > = new Map();\n\n constructor(element: TabElement, options: Partial<TabOptions> = {}) {\n this._options = { ...defaultOptions, ...options };\n this._element = element;\n const tabList =\n this._options.tabList instanceof HTMLElement\n ? this._options.tabList\n : this._element.closest<HTMLElement>(this._options.tabList);\n\n if (!tabList) {\n throw new TypeError(`${element.outerHTML} has not a valid parent ${this._options.tabList}`);\n }\n\n this._tabList = tabList;\n\n const tabs = this._getTabs();\n // Set up initial aria attributes\n this._setInitialAttributes(this._tabList, tabs);\n this._keydown = this._keydown.bind(this);\n this._click = this._click.bind(this);\n this._element.addEventListener('click', this._click);\n this._element.addEventListener('keydown', this._keydown);\n this.eventRegistry.set(this._element, [\n {\n type: 'click',\n listener: this._click as EventListener,\n },\n {\n type: 'keydown',\n listener: this._keydown as EventListener,\n },\n ]);\n }\n\n public destroy() {\n delete this._element.Tab;\n for (const [eventTarget, listeners] of this.eventRegistry) {\n listeners.forEach(({ type, listener, options }) => {\n eventTarget.removeEventListener(type, listener, options);\n });\n }\n this.eventRegistry.clear();\n }\n\n // Public\n public show() {\n // Shows this elem and deactivate the active sibling if exists\n const tab = this._element;\n if (this._tabIsActive(tab)) {\n return;\n }\n\n // Search for active tab on same parent to deactivate it\n const activeTab = this._getActiveTab();\n\n if (activeTab) {\n this._deactivate(activeTab);\n }\n\n this._activate(tab);\n const panel = this._getTargetPanel(tab);\n if (this._enableHashNavigation() && panel && `#${panel.id}` !== location.hash) {\n const hash = panel.id;\n if ('history' in window) {\n history.replaceState(null, '', `#${hash}`);\n }\n panel.id = hash;\n }\n }\n\n public get options(): TabOptions {\n return this._options;\n }\n\n // Private\n private _activate(tab: HTMLElement) {\n const panel = this._getTargetPanel(tab);\n\n tab.classList.add(this._options.activeClass);\n\n if (panel !== null) {\n show(panel);\n panel.setAttribute('aria-hidden', 'false');\n }\n\n tab.removeAttribute('tabindex');\n tab.setAttribute('aria-selected', 'true');\n\n this._options.onShow({ tab, panel });\n }\n\n private _deactivate(tab: HTMLElement) {\n const panel = this._getTargetPanel(tab);\n\n tab.classList.remove(this._options.activeClass);\n tab.blur();\n\n if (panel !== null) {\n hide(panel);\n panel.setAttribute('aria-hidden', 'true');\n }\n\n tab.setAttribute('aria-selected', 'false');\n tab.setAttribute('tabindex', '-1');\n\n this._options.onHide({ tab, panel });\n }\n\n private _click(event: MouseEvent) {\n const { currentTarget } = event;\n if (!(currentTarget instanceof HTMLElement)) {\n return;\n }\n\n if (['A', 'AREA'].includes(currentTarget.tagName)) {\n event.preventDefault();\n }\n\n if (isDisabled(currentTarget)) {\n return;\n }\n\n Tab.getOrCreateInstance(currentTarget).show();\n }\n\n private _keydown(event: KeyboardEvent) {\n if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) {\n return;\n }\n\n if (!(event.target instanceof HTMLElement)) {\n return;\n }\n\n event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page\n event.preventDefault();\n\n const activeTabs = this._getTabs().filter((tab) => !isDisabled(tab));\n let nextActiveElement;\n\n if ([HOME_KEY, END_KEY].includes(event.key)) {\n nextActiveElement = activeTabs[event.key === HOME_KEY ? 0 : activeTabs.length - 1];\n } else {\n const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);\n nextActiveElement = getNextActiveElement(activeTabs, event.target, isNext, true);\n }\n\n if (nextActiveElement) {\n nextActiveElement.focus({ preventScroll: true });\n Tab.getOrCreateInstance(nextActiveElement).show();\n }\n }\n\n private _getTabs() {\n return Array.from(this._tabList.querySelectorAll<HTMLElement>(SELECTOR_TAB));\n }\n\n private _getActiveTab() {\n return this._getTabs().find((tab) => this._tabIsActive(tab)) || null;\n }\n\n private _getReadyTab() {\n return this._getTabs().find((tab) => tab.matches(this._options.readyMark)) || null;\n }\n\n private _getTabFromHash() {\n return this._getTabs().find((tab) => getSelector(tab) === location.hash) || null;\n }\n\n private _getInitialActiveTab() {\n if (this._enableHashNavigation()) {\n const hashTab = this._getTabFromHash();\n if (hashTab) {\n return hashTab;\n }\n }\n const readyTab = this._getReadyTab();\n if (readyTab) {\n return readyTab;\n }\n return this._getTabs().at(0);\n }\n\n private _setInitialAttributes(parent: HTMLElement, tabs: HTMLElement[]) {\n this._setAttributeIfNotExists(parent, 'role', 'tablist');\n\n const initialActiveTab = this._getInitialActiveTab();\n if (initialActiveTab) {\n this._activate(initialActiveTab);\n }\n\n for (const tab of tabs) {\n this._setInitialAttributesOnTab(tab);\n }\n }\n\n private _setInitialAttributesOnTab(tab: HTMLElement) {\n const isActive = this._tabIsActive(tab);\n const outerElem = this._getOuterElement(tab);\n const panel = this._getTargetPanel(tab);\n\n tab.classList.add(this._options.tabClass);\n tab.setAttribute('aria-selected', isActive ? 'true' : 'false');\n\n if (outerElem !== tab) {\n this._setAttributeIfNotExists(outerElem, 'role', 'presentation');\n }\n\n if (!isActive) {\n tab.setAttribute('tabindex', '-1');\n }\n\n this._setAttributeIfNotExists(tab, 'role', 'tab');\n\n if (panel) {\n this._setAttributeIfNotExists(tab, 'aria-controls', panel.id);\n this._setAttributeIfNotExists(tab, 'id', `${panel.id}-tab`);\n }\n\n // set attributes to the related panel too\n this._setInitialAttributesOnTargetPanel(tab);\n }\n\n private _setInitialAttributesOnTargetPanel(tab: HTMLElement) {\n const panel = this._getTargetPanel(tab);\n\n if (!panel) {\n return;\n }\n\n const isActive = this._tabIsActive(tab);\n this._setAttributeIfNotExists(panel, 'role', 'tabpanel');\n this._setAttributeIfNotExists(panel, 'aria-hidden', isActive ? 'false' : 'true');\n if (!isActive) {\n panel.style.display = 'none';\n }\n\n if (tab.id) {\n this._setAttributeIfNotExists(panel, 'aria-labelledby', `${tab.id}`);\n }\n }\n\n private _getTargetPanel(tab: HTMLElement): HTMLElement | null {\n const selector = getSelector(tab);\n if (!selector) {\n return null;\n }\n return document.querySelector(selector);\n }\n\n private _setAttributeIfNotExists(element: HTMLElement, attribute: string, value: string) {\n if (!element.hasAttribute(attribute)) {\n element.setAttribute(attribute, value);\n }\n }\n\n private _tabIsActive(tab: HTMLElement) {\n return tab.classList.contains(this._options.activeClass);\n }\n\n // Try to get the outer element (usually the .nav-item)\n private _getOuterElement(elem: HTMLElement) {\n return elem.closest(SELECTOR_OUTER) || elem;\n }\n\n /**\n * ハッシュナビゲーションを有効にするかどうかを判断する\n */\n private _enableHashNavigation() {\n if (this._options.enableHashNavigation) {\n return true;\n }\n\n if (this._options.readyMark.startsWith('#')) {\n // readyMarkにハッシュが含まれている場合はハッシュナビゲーションを有効にする\n return true;\n }\n return false;\n }\n\n static getOrCreateInstance(element: HTMLElement & { Tab?: Tab }, options: Partial<TabOptions> = {}): Tab {\n if (element.Tab instanceof Tab) {\n return element.Tab;\n }\n const tab = new Tab(element, options);\n element.Tab = tab;\n return tab;\n }\n}\n","import Tab, { SELECTOR_TAB, TabOptions } from './tab';\n\nexport default class TabManager {\n private static instance: TabManager | null = null;\n\n private tabRepository: Map<TabOptions['tabList'], HTMLElement[]> = new Map();\n\n static getInstance(): TabManager {\n if (!TabManager.instance) {\n TabManager.instance = new TabManager();\n }\n return TabManager.instance;\n }\n\n async apply(\n selector: Extract<TabOptions['tabList'], string>,\n options: Partial<Omit<TabOptions, 'tabListSelector'>> = {},\n context: Document | HTMLElement = document\n ): Promise<void> {\n const tabOptions: Partial<TabOptions> = {\n tabList: selector,\n ...options,\n };\n\n ACMS.Loaded(() => {\n context.querySelectorAll<HTMLElement>(SELECTOR_TAB).forEach((element) => {\n if (element.closest(selector) !== null) {\n Tab.getOrCreateInstance(element, tabOptions);\n this.tabRepository.set(selector, [...(this.tabRepository.get(selector) || []), element]);\n }\n });\n });\n }\n\n destroy(selector: Extract<TabOptions['tabList'], string>): void {\n const elements = this.tabRepository.get(selector);\n if (elements) {\n elements.forEach((element) => {\n Tab.getOrCreateInstance(element).destroy();\n });\n this.tabRepository.delete(selector);\n }\n }\n\n destroyAll(): void {\n for (const [, elements] of this.tabRepository) {\n elements.forEach((element) => {\n Tab.getOrCreateInstance(element).destroy();\n });\n }\n this.tabRepository.clear();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TabOptions } from './tab.js';
|
|
2
|
+
export default class TabManager {
|
|
3
|
+
private static instance;
|
|
4
|
+
private tabRepository;
|
|
5
|
+
static getInstance(): TabManager;
|
|
6
|
+
apply(selector: Extract<TabOptions['tabList'], string>, options?: Partial<Omit<TabOptions, 'tabListSelector'>>, context?: Document | HTMLElement): Promise<void>;
|
|
7
|
+
destroy(selector: Extract<TabOptions['tabList'], string>): void;
|
|
8
|
+
destroyAll(): void;
|
|
9
|
+
}
|
package/dist/tab.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const SELECTOR_TAB = "a[href^=\"#\"], [role=\"tab\"]";
|
|
2
|
+
export interface TabOptions {
|
|
3
|
+
tabList: string | HTMLElement;
|
|
4
|
+
tabClass: string;
|
|
5
|
+
activeClass: string;
|
|
6
|
+
readyMark: string;
|
|
7
|
+
enableHashNavigation: boolean;
|
|
8
|
+
onShow: ({ tab, panel }: {
|
|
9
|
+
tab: HTMLElement;
|
|
10
|
+
panel: HTMLElement | null;
|
|
11
|
+
}) => void;
|
|
12
|
+
onHide: ({ tab, panel }: {
|
|
13
|
+
tab: HTMLElement;
|
|
14
|
+
panel: HTMLElement | null;
|
|
15
|
+
}) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare const defaultOptions: TabOptions;
|
|
18
|
+
type TabElement = HTMLElement & {
|
|
19
|
+
Tab?: Tab;
|
|
20
|
+
};
|
|
21
|
+
export default class Tab {
|
|
22
|
+
private _element;
|
|
23
|
+
private _tabList;
|
|
24
|
+
private _options;
|
|
25
|
+
private eventRegistry;
|
|
26
|
+
constructor(element: TabElement, options?: Partial<TabOptions>);
|
|
27
|
+
destroy(): void;
|
|
28
|
+
show(): void;
|
|
29
|
+
get options(): TabOptions;
|
|
30
|
+
private _activate;
|
|
31
|
+
private _deactivate;
|
|
32
|
+
private _click;
|
|
33
|
+
private _keydown;
|
|
34
|
+
private _getTabs;
|
|
35
|
+
private _getActiveTab;
|
|
36
|
+
private _getReadyTab;
|
|
37
|
+
private _getTabFromHash;
|
|
38
|
+
private _getInitialActiveTab;
|
|
39
|
+
private _setInitialAttributes;
|
|
40
|
+
private _setInitialAttributesOnTab;
|
|
41
|
+
private _setInitialAttributesOnTargetPanel;
|
|
42
|
+
private _getTargetPanel;
|
|
43
|
+
private _setAttributeIfNotExists;
|
|
44
|
+
private _tabIsActive;
|
|
45
|
+
private _getOuterElement;
|
|
46
|
+
/**
|
|
47
|
+
* ハッシュナビゲーションを有効にするかどうかを判断する
|
|
48
|
+
*/
|
|
49
|
+
private _enableHashNavigation;
|
|
50
|
+
static getOrCreateInstance(element: HTMLElement & {
|
|
51
|
+
Tab?: Tab;
|
|
52
|
+
}, options?: Partial<TabOptions>): Tab;
|
|
53
|
+
}
|
|
54
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ablogcms/tab",
|
|
3
|
+
"version": "3.2.28-beta.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "タブ切り替え UI の制御",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://www.a-blogcms.jp",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+ssh://git@bitbucket.org:appleple/ablogcms.git",
|
|
11
|
+
"directory": "packages/frontend/tab"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@ablogcms/utils": "3.2.28-beta.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"vitest": "^4.1.9"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.mjs",
|
|
24
|
+
"default": "./dist/index.mjs"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "node ../../../tools/build-package.mjs"
|
|
35
|
+
}
|
|
36
|
+
}
|