@todovue/tv-toc 1.0.1 → 1.0.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.
- package/LICENSE +1 -1
- package/README.md +1 -2
- package/dist/tv-toc.cjs.js +1 -1
- package/dist/tv-toc.css +1 -1
- package/dist/tv-toc.es.js +83 -41
- package/package.json +9 -8
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
A lightweight Vue 3 component to render a Table of Contents (TOC) for your articles or documentation, with smooth scrolling and nested sections support.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@todovue/tv-toc)
|
|
8
|
-
[](https://app.netlify.com/projects/tv-toc/deploys)
|
|
9
8
|
[](https://www.npmjs.com/package/@todovue/tv-toc)
|
|
10
9
|
[](https://www.npmjs.com/package/@todovue/tv-toc)
|
|
11
10
|

|
|
@@ -15,7 +14,7 @@ A lightweight Vue 3 component to render a Table of Contents (TOC) for your artic
|
|
|
15
14
|

|
|
16
15
|

|
|
17
16
|
|
|
18
|
-
> Demo: https://
|
|
17
|
+
> Demo: https://ui.todovue.blog/toc
|
|
19
18
|
|
|
20
19
|
---
|
|
21
20
|
## Table of Contents
|
package/dist/tv-toc.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),g=(r=[])=>{const a=e.ref(null),d=e.ref(null);let s=null;const u=c=>`#${c}`,v=c=>{const t=document.getElementById(c);t&&(t.scrollIntoView({behavior:"smooth"}),history.pushState(null,null,`#${c}`))},h=c=>{const t=[];return c.forEach(n=>{t.push({id:n.id,parentId:null}),n.children&&n.children.forEach(o=>{t.push({id:o.id,parentId:n.id})})}),t};return{formatId:u,scrollToId:v,activeId:a,activeParentId:d,setupObserver:()=>{if(typeof window>"u"||!r.length)return;const c=h(r),t=c.map(({id:n})=>document.getElementById(n)).filter(n=>n!==null);t.length&&(s=new IntersectionObserver(n=>{n.forEach(o=>{if(o.isIntersecting){const l=o.target.id,f=c.find(I=>I.id===l);f&&(a.value=l,d.value=f.parentId,history.replaceState(null,null,`#${l}`))}})},{rootMargin:"-20% 0px -70% 0px",threshold:0}),t.forEach(n=>s.observe(n)))},cleanup:()=>{s&&(s.disconnect(),s=null)}}},B={class:"tv-toc"},E={key:0,class:"tv-toc-title"},T={class:"tv-toc-list"},_=["href","onClick"],k={key:0,class:"tv-toc-sublist"},y=["href","onClick"],b={__name:"TvToc",props:{toc:{type:Object,required:!0}},setup(r){const a=r,{scrollToId:d,activeId:s,activeParentId:u,setupObserver:v,cleanup:h}=g(a.toc?.links||[]),m=t=>{d(t)},p=t=>s.value===t,c=t=>u.value===t;return e.onMounted(()=>{v()}),e.onUnmounted(()=>{h()}),(t,n)=>(e.openBlock(),e.createElementBlock("nav",B,[r.toc?.title?(e.openBlock(),e.createElementBlock("h3",E,e.toDisplayString(r.toc.title),1)):e.createCommentVNode("",!0),e.createElementVNode("ul",T,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.toc?.links,o=>(e.openBlock(),e.createElementBlock("li",{key:o.id,class:"tv-toc-item"},[e.createElementVNode("a",{href:`#${o.id}`,class:e.normalizeClass(["tv-toc-link",{active:p(o.id),"parent-active":c(o.id)}]),onClick:e.withModifiers(l=>m(o.id),["prevent"])},e.toDisplayString(o.text),11,_),o.children?(e.openBlock(),e.createElementBlock("ul",k,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.children,l=>(e.openBlock(),e.createElementBlock("li",{key:l.id,class:"tv-toc-subitem"},[e.createElementVNode("a",{href:`#${l.id}`,class:e.normalizeClass(["tv-toc-sublink",{active:p(l.id)}]),onClick:e.withModifiers(f=>m(l.id),["prevent"])},e.toDisplayString(l.text),11,y)]))),128))])):e.createCommentVNode("",!0)]))),128))])]))}},i=b;i.install=r=>{r.component("TvToc",i)};const C={install:i.install};exports.TvToc=i;exports.TvTocPlugin=C;exports.default=i;
|
package/dist/tv-toc.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.tv-toc{padding:1rem;background-color:#b9c4df;border-radius:8px;color:#000b14;min-width:200px}@media(prefers-color-scheme:dark){.tv-toc{background-color:#0e131f;color:#f4faff}}.tv-toc .tv-toc-title{font-size:1.2rem;font-weight:700;margin-bottom:.5rem}.tv-toc .tv-toc-list{list-style:none;padding:0;margin:0}.tv-toc .tv-toc-item{margin-bottom:.5rem}.tv-toc .tv-toc-link{text-decoration:none;color:inherit;font-weight:500;transition:
|
|
1
|
+
.tv-toc{padding:1rem;background-color:#b9c4df;border-radius:8px;color:#000b14;min-width:200px}@media(prefers-color-scheme:dark){.tv-toc{background-color:#0e131f;color:#f4faff}}.tv-toc .tv-toc-title{font-size:1.2rem;font-weight:700;margin-bottom:.5rem}.tv-toc .tv-toc-list{list-style:none;padding:0;margin:0}.tv-toc .tv-toc-item{margin-bottom:.5rem;position:relative}.tv-toc .tv-toc-item:hover .tv-toc-link,.tv-toc .tv-toc-item:hover .tv-toc-sublink{background-color:#ef233c0d}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-item:hover .tv-toc-link,.tv-toc .tv-toc-item:hover .tv-toc-sublink{background-color:#ef233c0d}}.tv-toc .tv-toc-link{display:block;text-decoration:none;color:inherit;font-weight:500;padding:.5rem .75rem;border-radius:4px;transition:all .3s ease;position:relative}.tv-toc .tv-toc-link:hover{color:#ef233c}.tv-toc .tv-toc-link.active{color:#ef233c;font-weight:700;background-color:#ef233c1a;border-left:3px solid #EF233C;padding-left:calc(1rem - 3px)}.tv-toc .tv-toc-link.parent-active{color:#ef233c;font-weight:500;border-left:2px solid rgba(239,35,60,.5);padding-left:calc(1rem - 2px)}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-link:hover{color:#ef233c}.tv-toc .tv-toc-link.active{color:#ef233c;background-color:#ef233c1a;border-left-color:#ef233c}.tv-toc .tv-toc-link.parent-active{color:#ef233c;border-left-color:#ef233c80}}.tv-toc .tv-toc-sublist{list-style:none;padding-left:1rem;margin-top:.25rem;margin-bottom:.25rem;border-left:2px solid rgba(0,11,20,.1)}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-sublist{border-left-color:#f4faff1a}}.tv-toc .tv-toc-subitem{margin-bottom:.25rem;position:relative}.tv-toc .tv-toc-sublink{display:block;text-decoration:none;color:inherit;font-size:.9rem;opacity:.8;padding:.4rem .75rem;border-radius:4px;transition:all .3s ease;position:relative}.tv-toc .tv-toc-sublink:hover{opacity:1;color:#ef233c}.tv-toc .tv-toc-sublink.active{opacity:1;color:#ef233c;font-weight:700;background-color:#ef233c1a;border-left:3px solid #EF233C;padding-left:calc(1rem - 3px)}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-sublink:hover{color:#ef233c}.tv-toc .tv-toc-sublink.active{color:#ef233c;background-color:#ef233c1a;border-left-color:#ef233c}}.light-mode .tv-toc{background-color:#b9c4df;color:#000b14}.light-mode .tv-toc .tv-toc-link:hover{color:#ef233c}.light-mode .tv-toc .tv-toc-link.active,.light-mode .tv-toc .tv-toc-link.parent-active{color:#ef233c;border-left-color:#ef233c}.light-mode .tv-toc .tv-toc-link.parent-active{border-left-color:#ef233c80}.light-mode .tv-toc .tv-toc-sublist{border-left-color:#000b141a}.light-mode .tv-toc .tv-toc-sublink:hover,.light-mode .tv-toc .tv-toc-sublink.active{color:#ef233c}.light-mode .tv-toc .tv-toc-sublink.active{border-left-color:#ef233c}
|
package/dist/tv-toc.es.js
CHANGED
|
@@ -1,17 +1,52 @@
|
|
|
1
|
-
import { createElementBlock as
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
1
|
+
import { ref as T, onMounted as O, onUnmounted as w, createElementBlock as r, openBlock as i, createCommentVNode as y, createElementVNode as I, toDisplayString as _, Fragment as E, renderList as b, withModifiers as C, normalizeClass as $ } from "vue";
|
|
2
|
+
const B = (s = []) => {
|
|
3
|
+
const a = T(null), d = T(null);
|
|
4
|
+
let l = null;
|
|
5
|
+
const u = (o) => `#${o}`, v = (o) => {
|
|
6
|
+
const t = document.getElementById(o);
|
|
7
|
+
t && (t.scrollIntoView({ behavior: "smooth" }), history.pushState(null, null, `#${o}`));
|
|
8
|
+
}, h = (o) => {
|
|
9
|
+
const t = [];
|
|
10
|
+
return o.forEach((e) => {
|
|
11
|
+
t.push({ id: e.id, parentId: null }), e.children && e.children.forEach((n) => {
|
|
12
|
+
t.push({ id: n.id, parentId: e.id });
|
|
13
|
+
});
|
|
14
|
+
}), t;
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
formatId: u,
|
|
18
|
+
scrollToId: v,
|
|
19
|
+
activeId: a,
|
|
20
|
+
activeParentId: d,
|
|
21
|
+
setupObserver: () => {
|
|
22
|
+
if (typeof window > "u" || !s.length) return;
|
|
23
|
+
const o = h(s), t = o.map(({ id: e }) => document.getElementById(e)).filter((e) => e !== null);
|
|
24
|
+
t.length && (l = new IntersectionObserver(
|
|
25
|
+
(e) => {
|
|
26
|
+
e.forEach((n) => {
|
|
27
|
+
if (n.isIntersecting) {
|
|
28
|
+
const c = n.target.id, m = o.find((x) => x.id === c);
|
|
29
|
+
m && (a.value = c, d.value = m.parentId, history.replaceState(null, null, `#${c}`));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
rootMargin: "-20% 0px -70% 0px",
|
|
35
|
+
threshold: 0
|
|
36
|
+
}
|
|
37
|
+
), t.forEach((e) => l.observe(e)));
|
|
38
|
+
},
|
|
39
|
+
cleanup: () => {
|
|
40
|
+
l && (l.disconnect(), l = null);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}, P = { class: "tv-toc" }, A = {
|
|
9
44
|
key: 0,
|
|
10
45
|
class: "tv-toc-title"
|
|
11
|
-
},
|
|
46
|
+
}, M = { class: "tv-toc-list" }, S = ["href", "onClick"], V = {
|
|
12
47
|
key: 0,
|
|
13
48
|
class: "tv-toc-sublist"
|
|
14
|
-
},
|
|
49
|
+
}, N = ["href", "onClick"], j = {
|
|
15
50
|
__name: "TvToc",
|
|
16
51
|
props: {
|
|
17
52
|
toc: {
|
|
@@ -19,47 +54,54 @@ const _ = () => ({
|
|
|
19
54
|
required: !0
|
|
20
55
|
}
|
|
21
56
|
},
|
|
22
|
-
setup(
|
|
23
|
-
const { scrollToId: d } =
|
|
24
|
-
d(
|
|
25
|
-
};
|
|
26
|
-
return (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
57
|
+
setup(s) {
|
|
58
|
+
const a = s, { scrollToId: d, activeId: l, activeParentId: u, setupObserver: v, cleanup: h } = B(a.toc?.links || []), f = (t) => {
|
|
59
|
+
d(t);
|
|
60
|
+
}, p = (t) => l.value === t, o = (t) => u.value === t;
|
|
61
|
+
return O(() => {
|
|
62
|
+
v();
|
|
63
|
+
}), w(() => {
|
|
64
|
+
h();
|
|
65
|
+
}), (t, e) => (i(), r("nav", P, [
|
|
66
|
+
s.toc?.title ? (i(), r("h3", A, _(s.toc.title), 1)) : y("", !0),
|
|
67
|
+
I("ul", M, [
|
|
68
|
+
(i(!0), r(E, null, b(s.toc?.links, (n) => (i(), r("li", {
|
|
69
|
+
key: n.id,
|
|
31
70
|
class: "tv-toc-item"
|
|
32
71
|
}, [
|
|
33
|
-
|
|
34
|
-
href: `#${
|
|
35
|
-
class: "tv-toc-link",
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
72
|
+
I("a", {
|
|
73
|
+
href: `#${n.id}`,
|
|
74
|
+
class: $(["tv-toc-link", {
|
|
75
|
+
active: p(n.id),
|
|
76
|
+
"parent-active": o(n.id)
|
|
77
|
+
}]),
|
|
78
|
+
onClick: C((c) => f(n.id), ["prevent"])
|
|
79
|
+
}, _(n.text), 11, S),
|
|
80
|
+
n.children ? (i(), r("ul", V, [
|
|
81
|
+
(i(!0), r(E, null, b(n.children, (c) => (i(), r("li", {
|
|
82
|
+
key: c.id,
|
|
41
83
|
class: "tv-toc-subitem"
|
|
42
84
|
}, [
|
|
43
|
-
|
|
44
|
-
href: `#${
|
|
45
|
-
class: "tv-toc-sublink",
|
|
46
|
-
onClick:
|
|
47
|
-
},
|
|
85
|
+
I("a", {
|
|
86
|
+
href: `#${c.id}`,
|
|
87
|
+
class: $(["tv-toc-sublink", { active: p(c.id) }]),
|
|
88
|
+
onClick: C((m) => f(c.id), ["prevent"])
|
|
89
|
+
}, _(c.text), 11, N)
|
|
48
90
|
]))), 128))
|
|
49
|
-
])) :
|
|
91
|
+
])) : y("", !0)
|
|
50
92
|
]))), 128))
|
|
51
93
|
])
|
|
52
94
|
]));
|
|
53
95
|
}
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
|
|
96
|
+
}, g = j;
|
|
97
|
+
g.install = (s) => {
|
|
98
|
+
s.component("TvToc", g);
|
|
57
99
|
};
|
|
58
|
-
const
|
|
59
|
-
install:
|
|
100
|
+
const q = {
|
|
101
|
+
install: g.install
|
|
60
102
|
};
|
|
61
103
|
export {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
104
|
+
g as TvToc,
|
|
105
|
+
q as TvTocPlugin,
|
|
106
|
+
g as default
|
|
65
107
|
};
|
package/package.json
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
"author": "Cristhian Daza",
|
|
5
5
|
"description": "A Vue 3 component to generate a table of contents (TOC) for your articles or documentation, enhancing navigation and user experience.",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.2",
|
|
8
8
|
"type": "module",
|
|
9
|
+
"homepage": "https://ui.todovue.blog/toc",
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/TODOvue/tv-toc.git"
|
|
12
|
+
"url": "git+https://github.com/TODOvue/tv-toc.git"
|
|
12
13
|
},
|
|
13
14
|
"bugs": {
|
|
14
15
|
"url": "https://github.com/TODOvue/tv-toc/issues"
|
|
@@ -56,13 +57,13 @@
|
|
|
56
57
|
"build:demo": "cp README.md public/ && cp CHANGELOG.md public/ && VITE_BUILD_TARGET=demo vite build"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
|
-
"vue": "^3.
|
|
60
|
+
"vue": "^3.5.26"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
|
-
"@todovue/tv-demo": "^1.2.
|
|
63
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
64
|
-
"sass": "^1.
|
|
65
|
-
"vite": "^7.
|
|
66
|
-
"vite-plugin-dts": "^4.
|
|
63
|
+
"@todovue/tv-demo": "^1.2.7",
|
|
64
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
65
|
+
"sass": "^1.97.1",
|
|
66
|
+
"vite": "^7.3.0",
|
|
67
|
+
"vite-plugin-dts": "^4.5.4"
|
|
67
68
|
}
|
|
68
69
|
}
|