asciidoctor-tabs 1.0.0.alpha.12 → 1.0.0.beta.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +30 -0
- data/README.adoc +9 -2
- data/data/css/tabs.css +5 -1
- data/data/js/tabs.js +31 -17
- data/lib/asciidoctor/tabs/block.rb +3 -2
- data/lib/asciidoctor/tabs/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e0a17ea54a3c9b7c4c8e152b8cb6c80e4aceb4e7aaa9a03b7cf3dfdf5783d0c
|
4
|
+
data.tar.gz: e9f4f8844fbdf8435bbb1fc99ac600b35820cabe0a22c4b51902cf39c851e203
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e296393e9638c0131b2e4c1a20ec388944de811295d28c30548befda9d786b5131c2039c2b46096a315218bb4a5335532603b0dd9cb557388f5283af7ddc04d
|
7
|
+
data.tar.gz: e53ca031e1b78d56b80612403323254cd29ecf38c5a757af1996e3c08fb3a02bbe644ad9010c7a034c55062ec4b4752b669c02978ea6a90c9435d5568f280dce
|
data/CHANGELOG.adoc
CHANGED
@@ -4,6 +4,36 @@
|
|
4
4
|
This document provides a curated view of the changes to Asciidoctor Tabs per release.
|
5
5
|
For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub.
|
6
6
|
|
7
|
+
== 1.0.0-beta.2 (2023-01-30) - @mojavelinux
|
8
|
+
|
9
|
+
=== Changed
|
10
|
+
|
11
|
+
* Only sync congruent tabs blocks (i.e., tabs blocks that have the same tablist) (#47)
|
12
|
+
* Store sync tab selection by sync group (e.g., `preferred-tab-a|b|c`) (#47)
|
13
|
+
|
14
|
+
=== Fixed
|
15
|
+
|
16
|
+
* Turn off :focus-visible outline on tab selected by URL fragment
|
17
|
+
|
18
|
+
=== Details
|
19
|
+
|
20
|
+
{url-repo}/releases/tag/v1.0.0-beta.2[git tag] | {url-repo}/compare/v1.0.0-beta.1\...v1.0.0-beta.2[full diff]
|
21
|
+
|
22
|
+
== 1.0.0-beta.1 (2023-01-30) - @mojavelinux
|
23
|
+
|
24
|
+
=== Added
|
25
|
+
|
26
|
+
* Pass through role attribute on tabs block (#43)
|
27
|
+
* Add configuration option to save sync selection (i.e., sync ID) in local or session storage (#44)
|
28
|
+
|
29
|
+
=== Fixed
|
30
|
+
|
31
|
+
* Use correct selector to unhide panel of first tab while tabs are loading
|
32
|
+
|
33
|
+
=== Details
|
34
|
+
|
35
|
+
{url-repo}/releases/tag/v1.0.0-beta.1[git tag] | {url-repo}/compare/v1.0.0-alpha.12\...v1.0.0-beta.1[full diff]
|
36
|
+
|
7
37
|
== 1.0.0-alpha.12 (2022-12-23) - @mojavelinux
|
8
38
|
|
9
39
|
=== Fixed
|
data/README.adoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Asciidoctor Tabs
|
2
2
|
Dan Allen <https://github.com/mojavelinux[@mojavelinux]>
|
3
|
-
v1.0.0-
|
3
|
+
v1.0.0-beta.2, 2023-01-30
|
4
4
|
:idprefix:
|
5
5
|
:idseparator: -
|
6
6
|
ifndef::env-github[:icons: font]
|
@@ -85,7 +85,7 @@ The term is used as the tab's label and the description is used as the tab's con
|
|
85
85
|
The contents can be defined as primary text, attached blocks, or both.
|
86
86
|
If the attached blocks are themselves enclosed in a single open block, the open block enclosure itself is discarded upon conversion.
|
87
87
|
|
88
|
-
You may choose to extend the block delimiter length from the typical 4 characters to 6 in order to avoid conflicts with any example blocks inside the
|
88
|
+
You may choose to extend the block delimiter length from the typical 4 characters to 6 in order to avoid conflicts with any example blocks inside the tabs block (or just as a matter of style).
|
89
89
|
|
90
90
|
[,asciidoc]
|
91
91
|
----
|
@@ -125,9 +125,16 @@ Tab B:: Contents of tab B in second tabset.
|
|
125
125
|
====
|
126
126
|
----
|
127
127
|
|
128
|
+
Note that only tabs blocks with congruent tablists are synchronized.
|
129
|
+
Each unique combination of tabs implicitly creates a new sync group.
|
130
|
+
|
128
131
|
Alternately, you can set the `sync` option on each tabs block.
|
129
132
|
If you want to delist a tabs block from sync, set the `nosync` option on that block.
|
130
133
|
|
134
|
+
If you want to persist the sync selection, assign a value to the `data-sync-storage-key` attribute on the `<script>` tag.
|
135
|
+
By default, the sync selection will be assigned to the specified key in local storage.
|
136
|
+
You can set the `data-sync-storage-scope` attribute on the `<script>` tag to `session` to use session storage instead.
|
137
|
+
|
131
138
|
== Usage
|
132
139
|
|
133
140
|
=== CLI
|
data/data/css/tabs.css
CHANGED
@@ -22,6 +22,10 @@
|
|
22
22
|
position: relative;
|
23
23
|
}
|
24
24
|
|
25
|
+
.tablist > ul li:focus-visible {
|
26
|
+
outline: none;
|
27
|
+
}
|
28
|
+
|
25
29
|
.tablist.ulist,
|
26
30
|
.tablist.ulist > ul li {
|
27
31
|
margin: 0;
|
@@ -67,7 +71,7 @@
|
|
67
71
|
border-bottom: 0;
|
68
72
|
}
|
69
73
|
|
70
|
-
.tabs.is-loading .tabpanel
|
74
|
+
.tabs.is-loading .tabpanel + .tabpanel,
|
71
75
|
.tabs:not(.is-loading) .tabpanel.is-hidden {
|
72
76
|
display: none;
|
73
77
|
}
|
data/data/js/tabs.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
;(function () { /*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */
|
2
2
|
'use strict'
|
3
3
|
|
4
|
+
var config = (document.currentScript || {}).dataset || {}
|
4
5
|
var forEach = Array.prototype.forEach
|
5
6
|
|
6
7
|
init(document.querySelectorAll('.tabs'))
|
@@ -11,9 +12,10 @@
|
|
11
12
|
var syncIds = tabs.classList.contains('is-sync') ? {} : undefined
|
12
13
|
var tablist = tabs.querySelector('.tablist ul')
|
13
14
|
tablist.setAttribute('role', 'tablist')
|
15
|
+
var initial
|
14
16
|
forEach.call(tablist.querySelectorAll('li'), function (tab, idx) {
|
15
17
|
tab.setAttribute('role', (tab.className = 'tab')) // NOTE converter may not have set class on li
|
16
|
-
var id, anchor
|
18
|
+
var id, anchor, syncId
|
17
19
|
if (!(id = tab.id)) {
|
18
20
|
if (!(anchor = tab.querySelector('a[id]'))) return // invalid state
|
19
21
|
tab.id = id = anchor.parentNode.removeChild(anchor).id
|
@@ -21,22 +23,26 @@
|
|
21
23
|
var panel = tabs.querySelector('.tabpanel[aria-labelledby~="' + id + '"]')
|
22
24
|
if (!panel) return // invalid state
|
23
25
|
tab.tabIndex = -1
|
26
|
+
syncIds && (((syncId = tab.textContent.toLowerCase().trim()) in syncIds) ? (syncId = undefined) : true) &&
|
27
|
+
(syncIds[(tab.dataset.syncId = syncId)] = tab)
|
28
|
+
idx || (initial = { tab: tab, panel: panel }) && syncIds ? toggleHidden(panel, true) : toggleSelected(tab, true)
|
24
29
|
tab.setAttribute('aria-controls', panel.id)
|
25
30
|
panel.setAttribute('role', 'tabpanel')
|
26
|
-
idx ? toggleHidden(panel, true) : toggleSelected(tab, true)
|
27
31
|
forEach.call(panel.querySelectorAll('table.tableblock'), function (table) {
|
28
32
|
var container = Object.assign(document.createElement('div'), { className: 'tablecontainer' })
|
29
33
|
table.parentNode.insertBefore(container, table).appendChild(table)
|
30
34
|
})
|
31
|
-
var onClick = activateTab
|
32
|
-
|
33
|
-
var syncId
|
34
|
-
if (syncIds && !((syncId = tab.textContent.trim()) in syncIds)) {
|
35
|
-
syncIds[(tab.dataset.syncId = syncId)] = true
|
36
|
-
onClick = activateTabSync
|
37
|
-
}
|
38
|
-
tab.addEventListener('click', onClick.bind(instance))
|
35
|
+
var onClick = syncId === undefined ? activateTab : activateTabSync
|
36
|
+
tab.addEventListener('click', onClick.bind({ tabs: tabs, tab: tab, panel: panel }))
|
39
37
|
})
|
38
|
+
if (syncIds && initial) {
|
39
|
+
var syncGroup = tabs.dataset.syncGroup = Object.keys(syncIds).sort().join('|')
|
40
|
+
var preferredSyncId = 'syncStorageKey' in config &&
|
41
|
+
window[(config.syncStorageScope || 'local') + 'Storage'].getItem(config.syncStorageKey + '-' + syncGroup)
|
42
|
+
var tab = preferredSyncId && syncIds[preferredSyncId]
|
43
|
+
tab && Object.assign(initial, { tab: tab, panel: document.getElementById(tab.getAttribute('aria-controls')) })
|
44
|
+
toggleSelected(initial.tab, true) || toggleHidden(initial.panel, false)
|
45
|
+
}
|
40
46
|
})
|
41
47
|
onHashChange()
|
42
48
|
forEach.call(tabsBlocks, function (tabs) {
|
@@ -55,6 +61,10 @@
|
|
55
61
|
forEach.call(tabs.querySelectorAll('.tabpanel'), function (el) {
|
56
62
|
toggleHidden(el, el !== panel)
|
57
63
|
})
|
64
|
+
if (!this.isSync && 'syncStorageKey' in config && 'syncGroup' in tabs.dataset) {
|
65
|
+
var storageKey = config.syncStorageKey + '-' + tabs.dataset.syncGroup
|
66
|
+
window[(config.syncStorageScope || 'local') + 'Storage'].setItem(storageKey, tab.dataset.syncId)
|
67
|
+
}
|
58
68
|
if (!e) return
|
59
69
|
var loc = window.location
|
60
70
|
var hashIdx = loc.hash ? loc.href.indexOf('#') : -1
|
@@ -64,13 +74,17 @@
|
|
64
74
|
|
65
75
|
function activateTabSync (e) {
|
66
76
|
activateTab.call(this, e)
|
67
|
-
var
|
77
|
+
var thisTabs = this.tabs
|
68
78
|
var thisTab = this.tab
|
69
|
-
var initialY =
|
70
|
-
forEach.call(document.querySelectorAll('.tabs
|
71
|
-
if (
|
79
|
+
var initialY = thisTabs.getBoundingClientRect().y
|
80
|
+
forEach.call(document.querySelectorAll('.tabs'), function (tabs) {
|
81
|
+
if (tabs !== thisTabs && tabs.dataset.syncGroup === thisTabs.dataset.syncGroup) {
|
82
|
+
forEach.call(tabs.querySelectorAll('.tablist .tab'), function (tab) {
|
83
|
+
if (tab.dataset.syncId === thisTab.dataset.syncId) activateTab.call({ tabs: tabs, tab: tab, isSync: true })
|
84
|
+
})
|
85
|
+
}
|
72
86
|
})
|
73
|
-
var shiftedBy =
|
87
|
+
var shiftedBy = thisTabs.getBoundingClientRect().y - initialY
|
74
88
|
if (shiftedBy && (shiftedBy = Math.round(shiftedBy))) window.scrollBy({ top: shiftedBy, behavior: 'instant' })
|
75
89
|
}
|
76
90
|
|
@@ -79,7 +93,7 @@
|
|
79
93
|
}
|
80
94
|
|
81
95
|
function toggleSelected (el, state) {
|
82
|
-
el.setAttribute('aria-selected', state)
|
96
|
+
el.setAttribute('aria-selected', '' + state)
|
83
97
|
el.classList.toggle('is-selected', state)
|
84
98
|
el.tabIndex = state ? 0 : -1
|
85
99
|
}
|
@@ -89,6 +103,6 @@
|
|
89
103
|
if (!id) return
|
90
104
|
var tab = document.getElementById(~id.indexOf('%') ? decodeURIComponent(id) : id)
|
91
105
|
if (!(tab && tab.classList.contains('tab'))) return
|
92
|
-
tab.dataset
|
106
|
+
'syncId' in tab.dataset ? activateTabSync.call({ tab: tab }) : activateTab.call({ tab: tab })
|
93
107
|
}
|
94
108
|
})()
|
@@ -18,8 +18,9 @@ module Asciidoctor
|
|
18
18
|
end
|
19
19
|
tabs_number = doc.counter 'tabs-number'
|
20
20
|
tabs_id = attrs['id'] || (generate_id %(tabs #{tabs_number}), doc)
|
21
|
-
|
22
|
-
|
21
|
+
tabs_sync = !(block.option? 'nosync') && ((block.option? 'sync') || (doc.option? 'tabs-sync')) ? ' is-sync' : ''
|
22
|
+
tabs_role = (tabs_role = attrs['role']) ? %( #{tabs_role}) : ''
|
23
|
+
tabs = create_open_block parent, nil, { 'id' => tabs_id, 'role' => %(tabs#{tabs_sync}#{tabs_role} is-loading) }
|
23
24
|
tabs.title = attrs['title']
|
24
25
|
tablist = create_list parent, :ulist, { 'role' => 'tablist' }
|
25
26
|
panes = {}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-tabs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Allen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|