asciidoctor-tabs 1.0.0.alpha.12 → 1.0.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|