@xiee/utils 1.5.6 → 1.6.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 CHANGED
@@ -131,6 +131,11 @@ KaTeX's auto-render extension.
131
131
  Right-align a `<blockquote>` footer if the footer is a `<p>` that starts with
132
132
  the em-dash.
133
133
 
134
+ ## tabsets.js
135
+
136
+ Create tabsets from section headings and their content. See [this
137
+ post](https://yihui.org/en/2023/10/heading-tabsets/) for documentation.
138
+
134
139
  ## toc.js
135
140
 
136
141
  Automatically build a table of contents (TOC) from all section headings.
@@ -0,0 +1,29 @@
1
+ .tab-link, .tab-pane {
2
+ border: 1px solid rgba(0, 0, 0, .05);
3
+ border-radius: 5px 5px 0 0;
4
+ }
5
+ .tab-link + .tab-pane.active {
6
+ border-radius: 0 5px 0 0;
7
+ }
8
+ .tab-link.active, .tab-pane.active {
9
+ border-color: rgba(0, 0, 0, .5);
10
+ }
11
+ .tab-link:not(.active):hover {
12
+ background: rgba(0, 0, 0, .05);
13
+ }
14
+ .tab-pane {
15
+ display: none;
16
+ padding: .5em;
17
+ }
18
+ .tab-pane.active {
19
+ display: block;
20
+ }
21
+ .tab-link {
22
+ display: inline-block;
23
+ margin: 0 .5em -1px 0;
24
+ padding: .5em;
25
+ cursor: pointer;
26
+ }
27
+ .tab-link.active {
28
+ border-bottom-color: white;
29
+ }
@@ -0,0 +1 @@
1
+ .tab-link,.tab-pane{border:1px solid rgba(0,0,0,.05);border-radius:5px 5px 0 0}.tab-link+.tab-pane.active{border-radius:0 5px 0 0}.tab-link.active,.tab-pane.active{border-color:rgba(0,0,0,.5)}.tab-link:not(.active):hover{background:rgba(0,0,0,.05)}.tab-pane{display:none;padding:.5em}.tab-pane.active{display:block}.tab-link{display:inline-block;margin:0 .5em -1px 0;padding:.5em;cursor:pointer}.tab-link.active{border-bottom-color:#fff}
package/js/tabsets.js ADDED
@@ -0,0 +1,52 @@
1
+ // find an element with class `tabset` and convert its subsequent headings to tabs
2
+ document.querySelectorAll('.tabset').forEach(h => {
3
+ let links = h.querySelectorAll(':scope > .tab-link'),
4
+ panes = h.querySelectorAll(':scope > .tab-pane');
5
+ // using headings to create a tabset later if it's empty
6
+ if (links.length === 0) {
7
+ links = []; panes = [];
8
+ }
9
+ function activate(i) {
10
+ function a(x, i) {
11
+ x.forEach((el, k) => el.classList[k === i ? 'add' : 'remove']('active'));
12
+ }
13
+ a(links, i); a(panes, i);
14
+ }
15
+ let n = -1, el = h.nextSibling, p;
16
+ if (links instanceof Array) while (el) {
17
+ if (el.nodeName === '#comment' && el.nodeValue.trim() === `tabset:${h.id}`)
18
+ break; // quit after <!--tabset:id-->
19
+ const t = el.tagName;
20
+ if (/^H[1-6]$/.test(t)) {
21
+ const n2 = +t.replace('H', '');
22
+ if (n2 <= n) break; // quit after a higher-level heading
23
+ if (n < 0) n = n2 - 1;
24
+ // find the next lower-level heading and start creating a tab
25
+ if (n2 === n + 1) {
26
+ p = document.createElement('div');
27
+ p.className = 'tab-pane';
28
+ el.after(p);
29
+ el.classList.add('tab-link');
30
+ el.querySelector('.anchor')?.remove();
31
+ el.outerHTML = el.outerHTML.replace(/^<h[1-6](.*)h[1-6]>$/, '<div$1div>');
32
+ el = p.previousElementSibling;
33
+ links.push(el); panes.push(p);
34
+ el = p.nextSibling;
35
+ continue;
36
+ }
37
+ }
38
+ if (p) {
39
+ p.append(el);
40
+ el = p;
41
+ }
42
+ el = el.nextSibling;
43
+ }
44
+ // activate one tab initially if none is active
45
+ let init = 0;
46
+ links.forEach((l, i) => {
47
+ i > 0 && links[i - 1].after(l); // move tab links together
48
+ l.onclick = () => activate(i); // add the click event
49
+ if (l.classList.contains('active')) init = i;
50
+ });
51
+ activate(init);
52
+ });
@@ -0,0 +1 @@
1
+ document.querySelectorAll(".tabset").forEach((e=>{let t=e.querySelectorAll(":scope > .tab-link"),a=e.querySelectorAll(":scope > .tab-pane");function n(e){function n(e,t){e.forEach(((e,a)=>e.classList[a===t?"add":"remove"]("active")))}n(t,e),n(a,e)}0===t.length&&(t=[],a=[]);let c,i=-1,l=e.nextSibling;if(t instanceof Array)for(;l&&("#comment"!==l.nodeName||l.nodeValue.trim()!==`tabset:${e.id}`);){const e=l.tagName;if(/^H[1-6]$/.test(e)){const n=+e.replace("H","");if(n<=i)break;if(i<0&&(i=n-1),n===i+1){c=document.createElement("div"),c.className="tab-pane",l.after(c),l.classList.add("tab-link"),l.querySelector(".anchor")?.remove(),l.outerHTML=l.outerHTML.replace(/^<h[1-6](.*)h[1-6]>$/,"<div$1div>"),l=c.previousElementSibling,t.push(l),a.push(c),l=c.nextSibling;continue}}c&&(c.append(l),l=c),l=l.nextSibling}let o=0;t.forEach(((e,a)=>{a>0&&t[a-1].after(e),e.onclick=()=>n(a),e.classList.contains("active")&&(o=a)})),n(o)}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiee/utils",
3
- "version": "1.5.6",
3
+ "version": "1.6.0",
4
4
  "description": "Miscellaneous tools and utilities to manipulate HTML pages",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"