@ablogcms/tab 3.2.28-beta.0 → 3.2.29
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/dist/index.mjs +20 -23
- package/dist/index.mjs.map +1 -1
- package/dist/tab-manager.d.ts +7 -4
- package/package.json +5 -4
package/dist/index.mjs
CHANGED
|
@@ -251,45 +251,42 @@ var Tab = class _Tab {
|
|
|
251
251
|
};
|
|
252
252
|
|
|
253
253
|
// src/tab-manager.ts
|
|
254
|
+
import domReady from "@ablogcms/dom-ready";
|
|
254
255
|
var TabManager = class _TabManager {
|
|
255
256
|
static instance = null;
|
|
256
|
-
tabRepository = /* @__PURE__ */ new Map();
|
|
257
257
|
static getInstance() {
|
|
258
258
|
if (!_TabManager.instance) {
|
|
259
259
|
_TabManager.instance = new _TabManager();
|
|
260
260
|
}
|
|
261
261
|
return _TabManager.instance;
|
|
262
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* 指定コンテキスト内のタブ要素にTabインスタンスを登録する。
|
|
265
|
+
* 呼び出し元は戻り値の要素一覧を保持しておき、destroy() に渡すことで
|
|
266
|
+
* 自分が登録した要素だけを後片付けできる(他の呼び出し元の登録には影響しない)。
|
|
267
|
+
*/
|
|
263
268
|
async apply(selector, options = {}, context = document) {
|
|
264
269
|
const tabOptions = {
|
|
265
270
|
tabList: selector,
|
|
266
271
|
...options
|
|
267
272
|
};
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
return new Promise((resolve) => {
|
|
274
|
+
domReady(() => {
|
|
275
|
+
const applied = [];
|
|
276
|
+
context.querySelectorAll(SELECTOR_TAB).forEach((element) => {
|
|
277
|
+
if (element.closest(selector) !== null) {
|
|
278
|
+
Tab.getOrCreateInstance(element, tabOptions);
|
|
279
|
+
applied.push(element);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
resolve(applied);
|
|
274
283
|
});
|
|
275
284
|
});
|
|
276
285
|
}
|
|
277
|
-
destroy(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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();
|
|
286
|
+
destroy(elements) {
|
|
287
|
+
elements.forEach((element) => {
|
|
288
|
+
Tab.getOrCreateInstance(element).destroy();
|
|
289
|
+
});
|
|
293
290
|
}
|
|
294
291
|
};
|
|
295
292
|
export {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +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":[]}
|
|
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 domReady from '@ablogcms/dom-ready';\n\nimport Tab, { SELECTOR_TAB, TabOptions } from './tab';\n\nexport default class TabManager {\n private static instance: TabManager | null = null;\n\n static getInstance(): TabManager {\n if (!TabManager.instance) {\n TabManager.instance = new TabManager();\n }\n return TabManager.instance;\n }\n\n /**\n * 指定コンテキスト内のタブ要素にTabインスタンスを登録する。\n * 呼び出し元は戻り値の要素一覧を保持しておき、destroy() に渡すことで\n * 自分が登録した要素だけを後片付けできる(他の呼び出し元の登録には影響しない)。\n */\n async apply(\n selector: Extract<TabOptions['tabList'], string>,\n options: Partial<Omit<TabOptions, 'tabListSelector'>> = {},\n context: Document | HTMLElement = document\n ): Promise<HTMLElement[]> {\n const tabOptions: Partial<TabOptions> = {\n tabList: selector,\n ...options,\n };\n\n return new Promise((resolve) => {\n domReady(() => {\n const applied: HTMLElement[] = [];\n context.querySelectorAll<HTMLElement>(SELECTOR_TAB).forEach((element) => {\n if (element.closest(selector) !== null) {\n Tab.getOrCreateInstance(element, tabOptions);\n applied.push(element);\n }\n });\n resolve(applied);\n });\n });\n }\n\n destroy(elements: HTMLElement[]): void {\n elements.forEach((element) => {\n Tab.getOrCreateInstance(element).destroy();\n });\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/tab-manager.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { TabOptions } from './tab.js';
|
|
2
2
|
export default class TabManager {
|
|
3
3
|
private static instance;
|
|
4
|
-
private tabRepository;
|
|
5
4
|
static getInstance(): TabManager;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* 指定コンテキスト内のタブ要素にTabインスタンスを登録する。
|
|
7
|
+
* 呼び出し元は戻り値の要素一覧を保持しておき、destroy() に渡すことで
|
|
8
|
+
* 自分が登録した要素だけを後片付けできる(他の呼び出し元の登録には影響しない)。
|
|
9
|
+
*/
|
|
10
|
+
apply(selector: Extract<TabOptions['tabList'], string>, options?: Partial<Omit<TabOptions, 'tabListSelector'>>, context?: Document | HTMLElement): Promise<HTMLElement[]>;
|
|
11
|
+
destroy(elements: HTMLElement[]): void;
|
|
9
12
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ablogcms/tab",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.29",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Tab-switching UI controller for a-blog cms admin",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://www.a-blogcms.jp",
|
|
8
8
|
"repository": {
|
|
@@ -12,10 +12,11 @@
|
|
|
12
12
|
},
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@ablogcms/
|
|
15
|
+
"@ablogcms/dom-ready": "3.2.29",
|
|
16
|
+
"@ablogcms/utils": "3.2.29"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
|
-
"vitest": "^4.1.
|
|
19
|
+
"vitest": "^4.1.10"
|
|
19
20
|
},
|
|
20
21
|
"exports": {
|
|
21
22
|
".": {
|