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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 601c6ff5abe598efcbd05754237c29ee0d75412553ab59596a1f44f798f8e340
4
- data.tar.gz: 2dc954003e7c3d180c610d5faf0d5e1c29bb49e73434275a81305de55793a170
3
+ metadata.gz: 0e0a17ea54a3c9b7c4c8e152b8cb6c80e4aceb4e7aaa9a03b7cf3dfdf5783d0c
4
+ data.tar.gz: e9f4f8844fbdf8435bbb1fc99ac600b35820cabe0a22c4b51902cf39c851e203
5
5
  SHA512:
6
- metadata.gz: 61ead4d57a662a73f3b754450127ff9ec16dc4ed40ae3a3997e0ce8562cdf3b501cba83bdc6f3c6d32d2dcc08c63900031010c1aeadad1b731f67c838848f8d0
7
- data.tar.gz: e2eed95c99e32fbcd9630126ab6b9b73f88181a07f874c4f1aaf8f0b013dde42b873059ac9926b25c7127e800f1c68deddd6a88690a5650631a43a61ade848ca
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-alpha.12, 2022-12-23
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 tab block (or just as a matter of style).
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:not(:first-child),
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
- var instance = { tabs: tabs, tab: tab, panel: panel }
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 tabs = this.tabs
77
+ var thisTabs = this.tabs
68
78
  var thisTab = this.tab
69
- var initialY = tabs.getBoundingClientRect().y
70
- forEach.call(document.querySelectorAll('.tabs .tablist .tab'), function (tab) {
71
- if (tab !== thisTab && tab.dataset.syncId === thisTab.dataset.syncId) activateTab.call({ tab: tab })
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 = tabs.getBoundingClientRect().y - initialY
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.syncId ? activateTabSync.call({ tab: tab }) : activateTab.call({ tab: tab })
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
- sync = !(block.option? 'nosync') && ((block.option? 'sync') || (doc.option? 'tabs-sync')) ? ' is-sync' : nil
22
- tabs = create_open_block parent, nil, { 'id' => tabs_id, 'role' => %(tabs#{sync || ''} is-loading) }
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 = {}
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Asciidoctor
4
4
  module Tabs
5
- VERSION = '1.0.0.alpha.12'
5
+ VERSION = '1.0.0.beta.2'
6
6
  end
7
7
  end
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.alpha.12
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: 2022-12-23 00:00:00.000000000 Z
11
+ date: 2023-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor