@todovue/tv-toc 1.1.1 → 1.2.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/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@ All notable changes to `@todovue/tv-toc` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.2.0] - 2026-01-30
9
+
10
+ ### Added
11
+ - Added a compact mode option to the Table of Contents component.
12
+
13
+ ### Changed
14
+ - Updated the visual styles for the Table of Contents component.
15
+
8
16
  ## [1.1.1] - 2026-01-27
9
17
 
10
18
  ### Changed
@@ -73,6 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
73
81
  - Minimal default styles and BEM-like CSS classes for easy customization.
74
82
  - Vite demo with basic and blog-like TOC examples.
75
83
 
84
+ [1.2.0]: https://github.com/TODOvue/tv-toc/pull/6/files
76
85
  [1.1.1]: https://github.com/TODOvue/tv-toc/pull/5/files
77
86
  [1.1.0]: https://github.com/TODOvue/tv-toc/pull/4/files
78
87
  [1.0.2]: https://github.com/TODOvue/tv-toc/pull/3/files
package/README.md CHANGED
@@ -177,6 +177,7 @@ import { TvToc } from '@todovue/tv-toc'
177
177
  | marker | Boolean | `false` | Whether to display a visual marker for the active item. | `false` |
178
178
  | collapsible | Boolean | `false` | Whether sublists can be collapsed/expanded. | `false` |
179
179
  | activeClass | String | `'active'` | Custom CSS class for the active item. | `false` |
180
+ | compact | Boolean | `false` | Applies a compact style similar to Nuxt Content's TOC. | `false` |
180
181
  | observerOptions | Object | `{}` | options to pass to the IntersectionObserver (rootMargin, threshold, etc). | `false` |
181
182
 
182
183
  ### `toc` shape
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),B=(n=[],a={})=>{const p=e.ref(null),h=e.ref(null);let d=null;const k=r=>`#${r}`,y=r=>{const c=document.getElementById(r);c&&(c.scrollIntoView({behavior:"smooth"}),history.pushState(null,null,`#${r}`))},u=r=>{const c=[];return r.forEach(s=>{c.push({id:s.id,parentId:null}),s.children&&s.children.forEach(v=>{c.push({id:v.id,parentId:s.id})})}),c};return{formatId:k,scrollToId:y,activeId:p,activeParentId:h,setupObserver:()=>{if(typeof window>"u"||!n.length)return;const r=u(n),c=r.map(({id:s})=>document.getElementById(s)).filter(s=>s!==null);c.length&&(d=new IntersectionObserver(s=>{s.forEach(v=>{if(v.isIntersecting){const m=v.target.id,t=r.find(l=>l.id===m);t&&(p.value=m,h.value=t.parentId,history.replaceState(null,null,`#${m}`))}})},{rootMargin:"-20% 0px -70% 0px",threshold:0,...a}),c.forEach(s=>d.observe(s)))},cleanup:()=>{d&&(d.disconnect(),d=null)}}},b={class:"tv-toc"},w={key:0,class:"tv-toc-progress-container"},C={key:1,class:"tv-toc-title"},I={class:"tv-toc-list"},T={class:"tv-toc-item-content"},S=["href","onClick"],x=["onClick"],V={class:"tv-toc-sublist"},N=["href","onClick"],O={__name:"TvToc",props:{toc:{type:Object,required:!0},marker:{type:Boolean,default:!1},activeClass:{type:String,default:"active"},observerOptions:{type:Object,default:()=>({})},collapsible:{type:Boolean,default:!1}},setup(n){const a=n,{scrollToId:p,activeId:h,activeParentId:d,setupObserver:k,cleanup:y}=B(a.toc?.links||[],a.observerOptions),u=e.ref(new Set),E=t=>{const l=new Set(u.value);l.has(t)?l.delete(t):l.add(t),u.value=l},g=t=>!a.collapsible||u.value.has(t),r=t=>{p(t)},c=t=>h.value===t,s=t=>d.value===t;e.watch(d,t=>{if(a.collapsible&&t&&!u.value.has(t)){const l=new Set(u.value);l.add(t),u.value=l}});const v=e.ref(0),m=e.computed(()=>{const t=[],l=o=>{if(o)for(const i of o)t.push(i.id),i.children&&l(i.children)};return l(a.toc?.links),t});return e.watch(h,t=>{if(!t)return;const l=m.value.indexOf(t);if(l!==-1){const o=m.value.length;o>0&&(v.value=(l+1)/o*100)}},{immediate:!0}),e.onMounted(()=>{a.collapsible&&d.value&&E(d.value),k()}),e.onUnmounted(()=>{y()}),(t,l)=>(e.openBlock(),e.createElementBlock("nav",b,[n.toc?.links?.length?(e.openBlock(),e.createElementBlock("div",w,[e.createElementVNode("div",{class:"tv-toc-progress-bar",style:e.normalizeStyle({height:`${v.value}%`})},null,4)])):e.createCommentVNode("",!0),n.toc?.title?(e.openBlock(),e.createElementBlock("h3",C,e.toDisplayString(n.toc.title),1)):e.createCommentVNode("",!0),e.createElementVNode("ul",I,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.toc?.links,o=>(e.openBlock(),e.createElementBlock("li",{key:o.id,class:"tv-toc-item"},[e.createElementVNode("div",T,[e.createElementVNode("a",{href:`#${o.id}`,class:e.normalizeClass(["tv-toc-link",{[a.activeClass]:c(o.id),"parent-active":s(o.id),"tv-toc-marker":n.marker&&c(o.id)}]),onClick:e.withModifiers(i=>r(o.id),["prevent"])},e.toDisplayString(o.text),11,S),n.collapsible&&o.children&&o.children.length?(e.openBlock(),e.createElementBlock("button",{key:0,class:e.normalizeClass(["tv-toc-toggle",{"is-expanded":g(o.id)}]),onClick:e.withModifiers(i=>E(o.id),["stop"]),"aria-label":"Toggle section"},[...l[0]||(l[0]=[e.createElementVNode("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[e.createElementVNode("polyline",{points:"6 9 12 15 18 9"})],-1)])],10,x)):e.createCommentVNode("",!0)]),o.children?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["tv-toc-sublist-wrapper",{"is-collapsed":n.collapsible&&!g(o.id)}]),style:e.normalizeStyle(n.collapsible?{"--content-height":g(o.id)?"1000px":"0px"}:{})},[e.createElementVNode("ul",V,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.children,i=>(e.openBlock(),e.createElementBlock("li",{key:i.id,class:"tv-toc-subitem"},[e.createElementVNode("a",{href:`#${i.id}`,class:e.normalizeClass(["tv-toc-sublink",{[a.activeClass]:c(i.id),"tv-toc-marker":n.marker&&c(i.id)}]),onClick:e.withModifiers(M=>r(i.id),["prevent"])},e.toDisplayString(i.text),11,N)]))),128))])],6)):e.createCommentVNode("",!0)]))),128))])]))}},f=O;f.install=n=>{n.component("TvToc",f)};const $={install:f.install};exports.TvToc=f;exports.TvTocPlugin=$;exports.default=f;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),B=(n=[],i={})=>{const p=e.ref(null),h=e.ref(null);let d=null;const y=r=>`#${r}`,E=r=>{const c=document.getElementById(r);c&&(c.scrollIntoView({behavior:"smooth"}),history.pushState(null,null,`#${r}`))},u=r=>{const c=[];return r.forEach(s=>{c.push({id:s.id,parentId:null}),s.children&&s.children.forEach(v=>{c.push({id:v.id,parentId:s.id})})}),c};return{formatId:y,scrollToId:E,activeId:p,activeParentId:h,setupObserver:()=>{if(typeof window>"u"||!n.length)return;const r=u(n),c=r.map(({id:s})=>document.getElementById(s)).filter(s=>s!==null);c.length&&(d=new IntersectionObserver(s=>{s.forEach(v=>{if(v.isIntersecting){const m=v.target.id,t=r.find(l=>l.id===m);t&&(p.value=m,h.value=t.parentId,history.replaceState(null,null,`#${m}`))}})},{rootMargin:"-20% 0px -70% 0px",threshold:0,...i}),c.forEach(s=>d.observe(s)))},cleanup:()=>{d&&(d.disconnect(),d=null)}}},b={key:0,class:"tv-toc-title"},C={class:"tv-toc-body"},w={key:0,class:"tv-toc-progress-container"},I={class:"tv-toc-list"},T={class:"tv-toc-item-content"},S=["href","onClick"],x=["onClick"],V={class:"tv-toc-sublist"},N=["href","onClick"],O={__name:"TvToc",props:{toc:{type:Object,required:!0},marker:{type:Boolean,default:!1},activeClass:{type:String,default:"active"},observerOptions:{type:Object,default:()=>({})},collapsible:{type:Boolean,default:!1},compact:{type:Boolean,default:!1}},setup(n){const i=n,{scrollToId:p,activeId:h,activeParentId:d,setupObserver:y,cleanup:E}=B(i.toc?.links||[],i.observerOptions),u=e.ref(new Set),k=t=>{const l=new Set(u.value);l.has(t)?l.delete(t):l.add(t),u.value=l},g=t=>!i.collapsible||u.value.has(t),r=t=>{p(t)},c=t=>h.value===t,s=t=>d.value===t;e.watch(d,t=>{if(i.collapsible&&t&&!u.value.has(t)){const l=new Set(u.value);l.add(t),u.value=l}});const v=e.ref(0),m=e.computed(()=>{const t=[],l=o=>{if(o)for(const a of o)t.push(a.id),a.children&&l(a.children)};return l(i.toc?.links),t});return e.watch(h,t=>{if(!t)return;const l=m.value.indexOf(t);if(l!==-1){const o=m.value.length;o>0&&(v.value=(l+1)/o*100)}},{immediate:!0}),e.onMounted(()=>{i.collapsible&&d.value&&k(d.value),y()}),e.onUnmounted(()=>{E()}),(t,l)=>(e.openBlock(),e.createElementBlock("nav",{class:e.normalizeClass(["tv-toc",{compact:n.compact}])},[n.toc?.title?(e.openBlock(),e.createElementBlock("h3",b,e.toDisplayString(n.toc.title),1)):e.createCommentVNode("",!0),e.createElementVNode("div",C,[n.toc?.links?.length?(e.openBlock(),e.createElementBlock("div",w,[e.createElementVNode("div",{class:"tv-toc-progress-bar",style:e.normalizeStyle({height:`${v.value}%`})},null,4)])):e.createCommentVNode("",!0),e.createElementVNode("ul",I,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.toc?.links,o=>(e.openBlock(),e.createElementBlock("li",{key:o.id,class:"tv-toc-item"},[e.createElementVNode("div",T,[e.createElementVNode("a",{href:`#${o.id}`,class:e.normalizeClass(["tv-toc-link",{[i.activeClass]:c(o.id),"parent-active":s(o.id),"tv-toc-marker":n.marker&&c(o.id)}]),onClick:e.withModifiers(a=>r(o.id),["prevent"])},e.toDisplayString(o.text),11,S),n.collapsible&&o.children&&o.children.length?(e.openBlock(),e.createElementBlock("button",{key:0,class:e.normalizeClass(["tv-toc-toggle",{"is-expanded":g(o.id)}]),onClick:e.withModifiers(a=>k(o.id),["stop"]),"aria-label":"Toggle section"},[...l[0]||(l[0]=[e.createElementVNode("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[e.createElementVNode("polyline",{points:"6 9 12 15 18 9"})],-1)])],10,x)):e.createCommentVNode("",!0)]),o.children?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["tv-toc-sublist-wrapper",{"is-collapsed":n.collapsible&&!g(o.id)}]),style:e.normalizeStyle(n.collapsible?{"--content-height":g(o.id)?"1000px":"0px"}:{})},[e.createElementVNode("ul",V,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.children,a=>(e.openBlock(),e.createElementBlock("li",{key:a.id,class:"tv-toc-subitem"},[e.createElementVNode("a",{href:`#${a.id}`,class:e.normalizeClass(["tv-toc-sublink",{[i.activeClass]:c(a.id),"tv-toc-marker":n.marker&&c(a.id)}]),onClick:e.withModifiers(z=>r(a.id),["prevent"])},e.toDisplayString(a.text),11,N)]))),128))])],6)):e.createCommentVNode("",!0)]))),128))])])],2))}},f=O;f.install=n=>{n.component("TvToc",f)};const $={install:f.install};exports.TvToc=f;exports.TvTocPlugin=$;exports.default=f;
package/dist/tv-toc.css CHANGED
@@ -1 +1 @@
1
- .tv-toc{position:relative;padding:1rem;background-color:#b9c4df;border-radius:8px;color:#000b14;min-width:200px;overflow:hidden;--toc-active-rgb: 239, 35, 60;--toc-active-color: #EF233C}@media(prefers-color-scheme:dark){.tv-toc{background-color:#0e131f;color:#f4faff;--toc-active-rgb: 239, 35, 60;--toc-active-color: #EF233C}}.tv-toc .tv-toc-progress-container{position:absolute;left:0;top:0;bottom:0;width:4px;background-color:#ef233c1a;z-index:1}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-progress-container{background-color:#ef233c1a}}.tv-toc .tv-toc-progress-bar{width:100%;background:linear-gradient(to bottom,#ef233c,#f68290);transition:height .1s linear;border-radius:0 0 4px 4px}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-progress-bar{background:linear-gradient(to bottom,#ef233c,#f68290)}}.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;opacity:0;animation:fadeSlideIn .5s ease forwards}.tv-toc .tv-toc-item:nth-child(1){animation-delay:.05s}.tv-toc .tv-toc-item:nth-child(2){animation-delay:.1s}.tv-toc .tv-toc-item:nth-child(3){animation-delay:.15s}.tv-toc .tv-toc-item:nth-child(4){animation-delay:.2s}.tv-toc .tv-toc-item:nth-child(5){animation-delay:.25s}.tv-toc .tv-toc-item:nth-child(6){animation-delay:.3s}.tv-toc .tv-toc-item:nth-child(7){animation-delay:.35s}.tv-toc .tv-toc-item:nth-child(8){animation-delay:.4s}.tv-toc .tv-toc-item:nth-child(9){animation-delay:.45s}.tv-toc .tv-toc-item:nth-child(10){animation-delay:.5s}.tv-toc .tv-toc-item:nth-child(11){animation-delay:.55s}.tv-toc .tv-toc-item:nth-child(12){animation-delay:.6s}.tv-toc .tv-toc-item:nth-child(13){animation-delay:.65s}.tv-toc .tv-toc-item:nth-child(14){animation-delay:.7s}.tv-toc .tv-toc-item:nth-child(15){animation-delay:.75s}.tv-toc .tv-toc-item:nth-child(16){animation-delay:.8s}.tv-toc .tv-toc-item:nth-child(17){animation-delay:.85s}.tv-toc .tv-toc-item:nth-child(18){animation-delay:.9s}.tv-toc .tv-toc-item:nth-child(19){animation-delay:.95s}.tv-toc .tv-toc-item:nth-child(20){animation-delay:1s}.tv-toc .tv-toc-item .tv-toc-item-content{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.tv-toc .tv-toc-item .tv-toc-item-content .tv-toc-link{flex:1}.tv-toc .tv-toc-item .tv-toc-toggle{background:transparent;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:inherit;opacity:.6;transition:all .2s ease;border-radius:4px;margin-right:4px}.tv-toc .tv-toc-item .tv-toc-toggle:hover{background-color:#ef233c1a;opacity:1}.tv-toc .tv-toc-item .tv-toc-toggle svg{transition:transform .3s ease}.tv-toc .tv-toc-item .tv-toc-toggle.is-expanded svg{transform:rotate(180deg)}.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-item .tv-toc-toggle:hover{background-color:#ef233c1a}}.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;padding-left:1rem;position:relative;animation:toc-pulse 2s infinite}.tv-toc .tv-toc-link.active:before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(180deg,var(--toc-active-color),rgba(var(--toc-active-rgb),.2),var(--toc-active-color));background-size:100% 200%;animation:border-flow 2s linear infinite;border-radius:4px 0 0 4px}.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}.tv-toc .tv-toc-link.parent-active{color:#ef233c;border-left-color:#ef233c80}}.tv-toc .tv-toc-sublist-wrapper{overflow:hidden;transition:opacity .3s ease,max-height .3s ease;max-height:1000px;opacity:1}.tv-toc .tv-toc-sublist-wrapper.is-collapsed{max-height:0;opacity:0;margin-bottom:0}.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;opacity:0;animation:fadeSlideIn .5s ease forwards}.tv-toc .tv-toc-subitem:nth-child(1){animation-delay:.35s}.tv-toc .tv-toc-subitem:nth-child(2){animation-delay:.4s}.tv-toc .tv-toc-subitem:nth-child(3){animation-delay:.45s}.tv-toc .tv-toc-subitem:nth-child(4){animation-delay:.5s}.tv-toc .tv-toc-subitem:nth-child(5){animation-delay:.55s}.tv-toc .tv-toc-subitem:nth-child(6){animation-delay:.6s}.tv-toc .tv-toc-subitem:nth-child(7){animation-delay:.65s}.tv-toc .tv-toc-subitem:nth-child(8){animation-delay:.7s}.tv-toc .tv-toc-subitem:nth-child(9){animation-delay:.75s}.tv-toc .tv-toc-subitem:nth-child(10){animation-delay:.8s}.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;padding-left:1rem;position:relative;animation:toc-pulse 2s infinite}.tv-toc .tv-toc-sublink.active:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--toc-active-color),rgba(var(--toc-active-rgb),.2),var(--toc-active-color));background-size:100% 200%;animation:border-flow 2s linear infinite;border-radius:4px 0 0 4px}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-sublink:hover{color:#ef233c}.tv-toc .tv-toc-sublink.active{color:#ef233c;background-color:#ef233c1a}}.light-mode .tv-toc{background-color:#b9c4df;color:#000b14;--toc-active-rgb: 239, 35, 60;--toc-active-color: #EF233C}.light-mode .tv-toc .tv-toc-link:hover,.light-mode .tv-toc .tv-toc-link.active,.light-mode .tv-toc .tv-toc-link.parent-active{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}.tv-toc-marker{border-left:2px solid var(--tv-toc-active-color, #3b82f6);padding-left:8px;transition:all .2s ease}@keyframes fadeSlideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes toc-pulse{0%{box-shadow:0 0 rgba(var(--toc-active-rgb),.4)}70%{box-shadow:0 0 0 6px rgba(var(--toc-active-rgb),0)}to{box-shadow:0 0 rgba(var(--toc-active-rgb),0)}}@keyframes border-flow{0%{background-position:0 0}to{background-position:0 200%}}
1
+ .tv-toc{position:relative;padding:0;background-color:#b9c4df;border-radius:8px;color:#000b14;min-width:200px;overflow:hidden;--toc-active-rgb: 239, 35, 60;--toc-active-color: #EF233C}@media(prefers-color-scheme:dark){.tv-toc{background-color:#0e131f;color:#f4faff;--toc-active-rgb: 239, 35, 60;--toc-active-color: #EF233C}}.tv-toc .tv-toc-title{font-size:1.2rem;font-weight:700;margin:1rem 1rem .5rem;padding-left:0}.tv-toc .tv-toc-body{position:relative;padding:0 1rem 1rem}.tv-toc .tv-toc-progress-container{position:absolute;left:0;top:0;bottom:0;width:4px;background-color:#ef233c1a;z-index:1}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-progress-container{background-color:#ef233c1a}}.tv-toc .tv-toc-progress-bar{width:100%;background:linear-gradient(to bottom,#ef233c,#f68290);transition:height .1s linear;border-radius:0 0 4px 4px}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-progress-bar{background:linear-gradient(to bottom,#ef233c,#f68290)}}.tv-toc .tv-toc-list .tv-toc-list{list-style:none;padding:0;margin:0}.tv-toc .tv-toc-list .tv-toc-item{margin-bottom:.5rem;position:relative;opacity:0;animation:fadeSlideIn .5s ease forwards}.tv-toc .tv-toc-list .tv-toc-item:nth-child(1){animation-delay:.05s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(2){animation-delay:.1s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(3){animation-delay:.15s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(4){animation-delay:.2s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(5){animation-delay:.25s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(6){animation-delay:.3s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(7){animation-delay:.35s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(8){animation-delay:.4s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(9){animation-delay:.45s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(10){animation-delay:.5s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(11){animation-delay:.55s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(12){animation-delay:.6s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(13){animation-delay:.65s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(14){animation-delay:.7s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(15){animation-delay:.75s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(16){animation-delay:.8s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(17){animation-delay:.85s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(18){animation-delay:.9s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(19){animation-delay:.95s}.tv-toc .tv-toc-list .tv-toc-item:nth-child(20){animation-delay:1s}.tv-toc .tv-toc-list .tv-toc-item .tv-toc-item-content{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.tv-toc .tv-toc-list .tv-toc-item .tv-toc-item-content .tv-toc-link{flex:1}.tv-toc .tv-toc-list .tv-toc-item .tv-toc-toggle{background:transparent;border:none;cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;color:inherit;opacity:.6;transition:all .2s ease;border-radius:4px;margin-right:4px}.tv-toc .tv-toc-list .tv-toc-item .tv-toc-toggle:hover{background-color:#ef233c1a;opacity:1}.tv-toc .tv-toc-list .tv-toc-item .tv-toc-toggle svg{transition:transform .3s ease}.tv-toc .tv-toc-list .tv-toc-item .tv-toc-toggle.is-expanded svg{transform:rotate(180deg)}.tv-toc .tv-toc-list .tv-toc-item:hover .tv-toc-link,.tv-toc .tv-toc-list .tv-toc-item:hover .tv-toc-sublink{background-color:#ef233c0d}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-list .tv-toc-item:hover .tv-toc-link,.tv-toc .tv-toc-list .tv-toc-item:hover .tv-toc-sublink{background-color:#ef233c0d}.tv-toc .tv-toc-list .tv-toc-item .tv-toc-toggle:hover{background-color:#ef233c1a}}.tv-toc .tv-toc-list .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-list .tv-toc-link:hover{color:#ef233c}.tv-toc .tv-toc-list .tv-toc-link.active{color:#ef233c;font-weight:700;background-color:#ef233c1a;padding-left:1rem;position:relative;animation:toc-pulse 2s infinite}.tv-toc .tv-toc-list .tv-toc-link.active:before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(180deg,var(--toc-active-color),rgba(var(--toc-active-rgb),.2),var(--toc-active-color));background-size:100% 200%;animation:border-flow 2s linear infinite;border-radius:4px 0 0 4px}.tv-toc .tv-toc-list .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-list .tv-toc-link:hover{color:#ef233c}.tv-toc .tv-toc-list .tv-toc-link.active{color:#ef233c;background-color:#ef233c1a}.tv-toc .tv-toc-list .tv-toc-link.parent-active{color:#ef233c;border-left-color:#ef233c80}}.tv-toc .tv-toc-list .tv-toc-sublist-wrapper{overflow:hidden;transition:opacity .3s ease,max-height .3s ease;max-height:1000px;opacity:1}.tv-toc .tv-toc-list .tv-toc-sublist-wrapper.is-collapsed{max-height:0;opacity:0;margin-bottom:0}.tv-toc .tv-toc-list .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-list .tv-toc-sublist{border-left-color:#f4faff1a}}.tv-toc .tv-toc-list .tv-toc-subitem{margin-bottom:.25rem;position:relative;opacity:0;animation:fadeSlideIn .5s ease forwards}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(1){animation-delay:.35s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(2){animation-delay:.4s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(3){animation-delay:.45s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(4){animation-delay:.5s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(5){animation-delay:.55s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(6){animation-delay:.6s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(7){animation-delay:.65s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(8){animation-delay:.7s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(9){animation-delay:.75s}.tv-toc .tv-toc-list .tv-toc-subitem:nth-child(10){animation-delay:.8s}.tv-toc .tv-toc-list .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-list .tv-toc-sublink:hover{opacity:1;color:#ef233c}.tv-toc .tv-toc-list .tv-toc-sublink.active{opacity:1;color:#ef233c;font-weight:700;background-color:#ef233c1a;padding-left:1rem;position:relative;animation:toc-pulse 2s infinite}.tv-toc .tv-toc-list .tv-toc-sublink.active:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--toc-active-color),rgba(var(--toc-active-rgb),.2),var(--toc-active-color));background-size:100% 200%;animation:border-flow 2s linear infinite;border-radius:4px 0 0 4px}@media(prefers-color-scheme:dark){.tv-toc .tv-toc-list .tv-toc-sublink:hover{color:#ef233c}.tv-toc .tv-toc-list .tv-toc-sublink.active{color:#ef233c;background-color:#ef233c1a}}.tv-toc.compact{background-color:transparent;padding:0;border-radius:0;min-width:auto}.tv-toc.compact .tv-toc-title{font-size:1rem;margin:0 0 .5rem;padding-left:0;opacity:.8}.tv-toc.compact .tv-toc-body{padding:0}.tv-toc.compact .tv-toc-progress-container{width:2px;left:0;background-color:#000b141a}@media(prefers-color-scheme:dark){.tv-toc.compact .tv-toc-progress-container{background-color:#f4faff1a}}.tv-toc.compact .tv-toc-progress-bar{border-radius:0;background:#ef233c}@media(prefers-color-scheme:dark){.tv-toc.compact .tv-toc-progress-bar{background:#ef233c}}.tv-toc.compact .tv-toc-list{margin:0}.tv-toc.compact .tv-toc-item{margin-bottom:0;animation:none;opacity:1}.tv-toc.compact .tv-toc-item .tv-toc-link{padding:.35rem 1rem;font-size:.9rem}.tv-toc.compact .tv-toc-item .tv-toc-link:hover{background-color:transparent;color:#ef233c}.tv-toc.compact .tv-toc-item .tv-toc-link.active{background-color:transparent;animation:none;padding-left:1rem;font-weight:600;color:#ef233c}.tv-toc.compact .tv-toc-item .tv-toc-link.active:before{display:none}.tv-toc.compact .tv-toc-item .tv-toc-link.parent-active{border-left:none;padding-left:1rem;color:#ef233c}@media(prefers-color-scheme:dark){.tv-toc.compact .tv-toc-item .tv-toc-link:hover,.tv-toc.compact .tv-toc-item .tv-toc-link.active,.tv-toc.compact .tv-toc-item .tv-toc-link.parent-active{color:#ef233c}}.tv-toc.compact .tv-toc-sublist{border-left:none;padding-left:0;margin:0}.tv-toc.compact .tv-toc-sublist .tv-toc-subitem{margin-bottom:0;animation:none;opacity:1}.tv-toc.compact .tv-toc-sublist .tv-toc-sublink{padding:.25rem 1rem .25rem 1.5rem;font-size:.85rem}.tv-toc.compact .tv-toc-sublist .tv-toc-sublink:hover{background-color:transparent;color:#ef233c}.tv-toc.compact .tv-toc-sublist .tv-toc-sublink.active{background-color:transparent;animation:none;padding-left:1.5rem;font-weight:600;color:#ef233c}.tv-toc.compact .tv-toc-sublist .tv-toc-sublink.active:before{display:none}@media(prefers-color-scheme:dark){.tv-toc.compact .tv-toc-sublist .tv-toc-sublink:hover,.tv-toc.compact .tv-toc-sublist .tv-toc-sublink.active{color:#ef233c}}.light-mode .tv-toc{background-color:#b9c4df;color:#000b14;--toc-active-rgb: 239, 35, 60;--toc-active-color: #EF233C}.light-mode .tv-toc .tv-toc-link:hover,.light-mode .tv-toc .tv-toc-link.active,.light-mode .tv-toc .tv-toc-link.parent-active{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}.tv-toc-marker{border-left:2px solid var(--tv-toc-active-color, #3b82f6);padding-left:8px;transition:all .2s ease}@keyframes fadeSlideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes toc-pulse{0%{box-shadow:0 0 rgba(var(--toc-active-rgb),.4)}70%{box-shadow:0 0 0 6px rgba(var(--toc-active-rgb),0)}to{box-shadow:0 0 rgba(var(--toc-active-rgb),0)}}@keyframes border-flow{0%{background-position:0 0}to{background-position:0 200%}}
package/dist/tv-toc.es.js CHANGED
@@ -1,11 +1,11 @@
1
- import { ref as w, watch as $, computed as _, onMounted as j, onUnmounted as A, createElementBlock as d, openBlock as u, createCommentVNode as y, createElementVNode as h, normalizeStyle as k, toDisplayString as O, Fragment as B, renderList as P, withModifiers as S, normalizeClass as I } from "vue";
2
- const M = (l = [], i = {}) => {
3
- const g = w(null), m = w(null);
1
+ import { ref as w, watch as $, computed as j, onMounted as A, onUnmounted as M, createElementBlock as d, openBlock as u, normalizeClass as g, createCommentVNode as I, createElementVNode as v, toDisplayString as O, normalizeStyle as k, Fragment as B, renderList as P, withModifiers as S } from "vue";
2
+ const V = (l = [], r = {}) => {
3
+ const y = w(null), m = w(null);
4
4
  let a = null;
5
5
  const x = (c) => `#${c}`, C = (c) => {
6
6
  const s = document.getElementById(c);
7
7
  s && (s.scrollIntoView({ behavior: "smooth" }), history.pushState(null, null, `#${c}`));
8
- }, v = (c) => {
8
+ }, h = (c) => {
9
9
  const s = [];
10
10
  return c.forEach((n) => {
11
11
  s.push({ id: n.id, parentId: null }), n.children && n.children.forEach((f) => {
@@ -16,24 +16,24 @@ const M = (l = [], i = {}) => {
16
16
  return {
17
17
  formatId: x,
18
18
  scrollToId: C,
19
- activeId: g,
19
+ activeId: y,
20
20
  activeParentId: m,
21
21
  setupObserver: () => {
22
22
  if (typeof window > "u" || !l.length) return;
23
- const c = v(l), s = c.map(({ id: n }) => document.getElementById(n)).filter((n) => n !== null);
23
+ const c = h(l), s = c.map(({ id: n }) => document.getElementById(n)).filter((n) => n !== null);
24
24
  s.length && (a = new IntersectionObserver(
25
25
  (n) => {
26
26
  n.forEach((f) => {
27
27
  if (f.isIntersecting) {
28
28
  const p = f.target.id, e = c.find((o) => o.id === p);
29
- e && (g.value = p, m.value = e.parentId, history.replaceState(null, null, `#${p}`));
29
+ e && (y.value = p, m.value = e.parentId, history.replaceState(null, null, `#${p}`));
30
30
  }
31
31
  });
32
32
  },
33
33
  {
34
34
  rootMargin: "-20% 0px -70% 0px",
35
35
  threshold: 0,
36
- ...i
36
+ ...r
37
37
  }
38
38
  ), s.forEach((n) => a.observe(n)));
39
39
  },
@@ -41,12 +41,12 @@ const M = (l = [], i = {}) => {
41
41
  a && (a.disconnect(), a = null);
42
42
  }
43
43
  };
44
- }, V = { class: "tv-toc" }, z = {
44
+ }, z = {
45
45
  key: 0,
46
- class: "tv-toc-progress-container"
47
- }, N = {
48
- key: 1,
49
46
  class: "tv-toc-title"
47
+ }, N = { class: "tv-toc-body" }, _ = {
48
+ key: 0,
49
+ class: "tv-toc-progress-container"
50
50
  }, q = { class: "tv-toc-list" }, D = { class: "tv-toc-item-content" }, F = ["href", "onClick"], U = ["onClick"], G = { class: "tv-toc-sublist" }, H = ["href", "onClick"], J = {
51
51
  __name: "TvToc",
52
52
  props: {
@@ -69,28 +69,32 @@ const M = (l = [], i = {}) => {
69
69
  collapsible: {
70
70
  type: Boolean,
71
71
  default: !1
72
+ },
73
+ compact: {
74
+ type: Boolean,
75
+ default: !1
72
76
  }
73
77
  },
74
78
  setup(l) {
75
- const i = l, { scrollToId: g, activeId: m, activeParentId: a, setupObserver: x, cleanup: C } = M(i.toc?.links || [], i.observerOptions), v = w(/* @__PURE__ */ new Set()), T = (e) => {
76
- const o = new Set(v.value);
77
- o.has(e) ? o.delete(e) : o.add(e), v.value = o;
78
- }, b = (e) => !i.collapsible || v.value.has(e), c = (e) => {
79
- g(e);
79
+ const r = l, { scrollToId: y, activeId: m, activeParentId: a, setupObserver: x, cleanup: C } = V(r.toc?.links || [], r.observerOptions), h = w(/* @__PURE__ */ new Set()), T = (e) => {
80
+ const o = new Set(h.value);
81
+ o.has(e) ? o.delete(e) : o.add(e), h.value = o;
82
+ }, b = (e) => !r.collapsible || h.value.has(e), c = (e) => {
83
+ y(e);
80
84
  }, s = (e) => m.value === e, n = (e) => a.value === e;
81
85
  $(a, (e) => {
82
- if (i.collapsible && e && !v.value.has(e)) {
83
- const o = new Set(v.value);
84
- o.add(e), v.value = o;
86
+ if (r.collapsible && e && !h.value.has(e)) {
87
+ const o = new Set(h.value);
88
+ o.add(e), h.value = o;
85
89
  }
86
90
  });
87
- const f = w(0), p = _(() => {
91
+ const f = w(0), p = j(() => {
88
92
  const e = [], o = (t) => {
89
93
  if (t)
90
- for (const r of t)
91
- e.push(r.id), r.children && o(r.children);
94
+ for (const i of t)
95
+ e.push(i.id), i.children && o(i.children);
92
96
  };
93
- return o(i.toc?.links), e;
97
+ return o(r.toc?.links), e;
94
98
  });
95
99
  return $(m, (e) => {
96
100
  if (!e) return;
@@ -99,78 +103,82 @@ const M = (l = [], i = {}) => {
99
103
  const t = p.value.length;
100
104
  t > 0 && (f.value = (o + 1) / t * 100);
101
105
  }
102
- }, { immediate: !0 }), j(() => {
103
- i.collapsible && a.value && T(a.value), x();
104
- }), A(() => {
106
+ }, { immediate: !0 }), A(() => {
107
+ r.collapsible && a.value && T(a.value), x();
108
+ }), M(() => {
105
109
  C();
106
- }), (e, o) => (u(), d("nav", V, [
107
- l.toc?.links?.length ? (u(), d("div", z, [
108
- h("div", {
109
- class: "tv-toc-progress-bar",
110
- style: k({ height: `${f.value}%` })
111
- }, null, 4)
112
- ])) : y("", !0),
113
- l.toc?.title ? (u(), d("h3", N, O(l.toc.title), 1)) : y("", !0),
114
- h("ul", q, [
115
- (u(!0), d(B, null, P(l.toc?.links, (t) => (u(), d("li", {
116
- key: t.id,
117
- class: "tv-toc-item"
118
- }, [
119
- h("div", D, [
120
- h("a", {
121
- href: `#${t.id}`,
122
- class: I(["tv-toc-link", {
123
- [i.activeClass]: s(t.id),
124
- "parent-active": n(t.id),
125
- "tv-toc-marker": l.marker && s(t.id)
126
- }]),
127
- onClick: S((r) => c(t.id), ["prevent"])
128
- }, O(t.text), 11, F),
129
- l.collapsible && t.children && t.children.length ? (u(), d("button", {
130
- key: 0,
131
- class: I(["tv-toc-toggle", { "is-expanded": b(t.id) }]),
132
- onClick: S((r) => T(t.id), ["stop"]),
133
- "aria-label": "Toggle section"
134
- }, [...o[0] || (o[0] = [
135
- h("svg", {
136
- xmlns: "http://www.w3.org/2000/svg",
137
- width: "16",
138
- height: "16",
139
- viewBox: "0 0 24 24",
140
- fill: "none",
141
- stroke: "currentColor",
142
- "stroke-width": "2",
143
- "stroke-linecap": "round",
144
- "stroke-linejoin": "round"
145
- }, [
146
- h("polyline", { points: "6 9 12 15 18 9" })
147
- ], -1)
148
- ])], 10, U)) : y("", !0)
149
- ]),
150
- t.children ? (u(), d("div", {
151
- key: 0,
152
- class: I(["tv-toc-sublist-wrapper", { "is-collapsed": l.collapsible && !b(t.id) }]),
153
- style: k(l.collapsible ? { "--content-height": b(t.id) ? "1000px" : "0px" } : {})
110
+ }), (e, o) => (u(), d("nav", {
111
+ class: g(["tv-toc", { compact: l.compact }])
112
+ }, [
113
+ l.toc?.title ? (u(), d("h3", z, O(l.toc.title), 1)) : I("", !0),
114
+ v("div", N, [
115
+ l.toc?.links?.length ? (u(), d("div", _, [
116
+ v("div", {
117
+ class: "tv-toc-progress-bar",
118
+ style: k({ height: `${f.value}%` })
119
+ }, null, 4)
120
+ ])) : I("", !0),
121
+ v("ul", q, [
122
+ (u(!0), d(B, null, P(l.toc?.links, (t) => (u(), d("li", {
123
+ key: t.id,
124
+ class: "tv-toc-item"
154
125
  }, [
155
- h("ul", G, [
156
- (u(!0), d(B, null, P(t.children, (r) => (u(), d("li", {
157
- key: r.id,
158
- class: "tv-toc-subitem"
159
- }, [
160
- h("a", {
161
- href: `#${r.id}`,
162
- class: I(["tv-toc-sublink", {
163
- [i.activeClass]: s(r.id),
164
- "tv-toc-marker": l.marker && s(r.id)
165
- }]),
166
- onClick: S((K) => c(r.id), ["prevent"])
167
- }, O(r.text), 11, H)
168
- ]))), 128))
169
- ])
170
- ], 6)) : y("", !0)
171
- ]))), 128))
126
+ v("div", D, [
127
+ v("a", {
128
+ href: `#${t.id}`,
129
+ class: g(["tv-toc-link", {
130
+ [r.activeClass]: s(t.id),
131
+ "parent-active": n(t.id),
132
+ "tv-toc-marker": l.marker && s(t.id)
133
+ }]),
134
+ onClick: S((i) => c(t.id), ["prevent"])
135
+ }, O(t.text), 11, F),
136
+ l.collapsible && t.children && t.children.length ? (u(), d("button", {
137
+ key: 0,
138
+ class: g(["tv-toc-toggle", { "is-expanded": b(t.id) }]),
139
+ onClick: S((i) => T(t.id), ["stop"]),
140
+ "aria-label": "Toggle section"
141
+ }, [...o[0] || (o[0] = [
142
+ v("svg", {
143
+ xmlns: "http://www.w3.org/2000/svg",
144
+ width: "16",
145
+ height: "16",
146
+ viewBox: "0 0 24 24",
147
+ fill: "none",
148
+ stroke: "currentColor",
149
+ "stroke-width": "2",
150
+ "stroke-linecap": "round",
151
+ "stroke-linejoin": "round"
152
+ }, [
153
+ v("polyline", { points: "6 9 12 15 18 9" })
154
+ ], -1)
155
+ ])], 10, U)) : I("", !0)
156
+ ]),
157
+ t.children ? (u(), d("div", {
158
+ key: 0,
159
+ class: g(["tv-toc-sublist-wrapper", { "is-collapsed": l.collapsible && !b(t.id) }]),
160
+ style: k(l.collapsible ? { "--content-height": b(t.id) ? "1000px" : "0px" } : {})
161
+ }, [
162
+ v("ul", G, [
163
+ (u(!0), d(B, null, P(t.children, (i) => (u(), d("li", {
164
+ key: i.id,
165
+ class: "tv-toc-subitem"
166
+ }, [
167
+ v("a", {
168
+ href: `#${i.id}`,
169
+ class: g(["tv-toc-sublink", {
170
+ [r.activeClass]: s(i.id),
171
+ "tv-toc-marker": l.marker && s(i.id)
172
+ }]),
173
+ onClick: S((K) => c(i.id), ["prevent"])
174
+ }, O(i.text), 11, H)
175
+ ]))), 128))
176
+ ])
177
+ ], 6)) : I("", !0)
178
+ ]))), 128))
179
+ ])
172
180
  ])
173
- ]));
181
+ ], 2));
174
182
  }
175
183
  }, E = J;
176
184
  E.install = (l) => {
package/package.json CHANGED
@@ -4,7 +4,7 @@
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.1.1",
7
+ "version": "1.2.0",
8
8
  "type": "module",
9
9
  "homepage": "https://ui.todovue.blog/toc",
10
10
  "repository": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  .tv-toc {
4
4
  position: relative;
5
- padding: 1rem;
5
+ padding: 0;
6
6
  background-color: $light-card-bg;
7
7
  border-radius: 8px;
8
8
  color: $light-text;
@@ -23,6 +23,18 @@
23
23
  --toc-active-color: #{$active-color-dark};
24
24
  }
25
25
 
26
+ .tv-toc-title {
27
+ font-size: 1.2rem;
28
+ font-weight: bold;
29
+ margin: 1rem 1rem 0.5rem 1rem;
30
+ padding-left: 0;
31
+ }
32
+
33
+ .tv-toc-body {
34
+ position: relative;
35
+ padding: 0 1rem 1rem 1rem;
36
+ }
37
+
26
38
  .tv-toc-progress-container {
27
39
  position: absolute;
28
40
  left: 0;
@@ -48,241 +60,370 @@
48
60
  }
49
61
  }
50
62
 
51
- .tv-toc-title {
52
- font-size: 1.2rem;
53
- font-weight: bold;
54
- margin-bottom: 0.5rem;
55
- }
56
-
57
63
  .tv-toc-list {
58
- list-style: none;
59
- padding: 0;
60
- margin: 0;
61
- }
64
+ .tv-toc-list {
65
+ list-style: none;
66
+ padding: 0;
67
+ margin: 0;
68
+ }
62
69
 
63
- .tv-toc-item {
64
- margin-bottom: 0.5rem;
65
- position: relative;
66
- opacity: 0;
67
- animation: fadeSlideIn 0.5s ease forwards;
70
+ .tv-toc-item {
71
+ margin-bottom: 0.5rem;
72
+ position: relative;
73
+ opacity: 0;
74
+ animation: fadeSlideIn 0.5s ease forwards;
68
75
 
69
- @for $i from 1 through 20 {
70
- &:nth-child(#{$i}) {
71
- animation-delay: #{$i * 0.05}s;
76
+ @for $i from 1 through 20 {
77
+ &:nth-child(#{$i}) {
78
+ animation-delay: #{$i * 0.05}s;
79
+ }
72
80
  }
73
- }
74
81
 
75
- .tv-toc-item-content {
76
- display: flex;
77
- align-items: center;
78
- justify-content: space-between;
79
- gap: 0.5rem;
82
+ .tv-toc-item-content {
83
+ display: flex;
84
+ align-items: center;
85
+ justify-content: space-between;
86
+ gap: 0.5rem;
80
87
 
81
- .tv-toc-link {
82
- flex: 1;
88
+ .tv-toc-link {
89
+ flex: 1;
90
+ }
83
91
  }
84
- }
85
92
 
86
- .tv-toc-toggle {
87
- background: transparent;
88
- border: none;
89
- cursor: pointer;
90
- padding: 4px;
91
- display: flex;
92
- align-items: center;
93
- justify-content: center;
94
- color: inherit;
95
- opacity: 0.6;
96
- transition: all 0.2s ease;
97
- border-radius: 4px;
98
- margin-right: 4px;
93
+ .tv-toc-toggle {
94
+ background: transparent;
95
+ border: none;
96
+ cursor: pointer;
97
+ padding: 4px;
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+ color: inherit;
102
+ opacity: 0.6;
103
+ transition: all 0.2s ease;
104
+ border-radius: 4px;
105
+ margin-right: 4px;
106
+
107
+ &:hover {
108
+ background-color: rgba($active-color, 0.1);
109
+ opacity: 1;
110
+ }
99
111
 
100
- &:hover {
101
- background-color: rgba($active-color, 0.1);
102
- opacity: 1;
112
+ svg {
113
+ transition: transform 0.3s ease;
114
+ }
115
+
116
+ &.is-expanded svg {
117
+ transform: rotate(180deg);
118
+ }
103
119
  }
104
120
 
105
- svg {
106
- transition: transform 0.3s ease;
121
+ &:hover {
122
+ .tv-toc-link {
123
+ background-color: rgba($active-color, 0.05);
124
+ }
125
+
126
+ .tv-toc-sublink {
127
+ background-color: rgba($active-color, 0.05);
128
+ }
107
129
  }
108
130
 
109
- &.is-expanded svg {
110
- transform: rotate(180deg);
131
+ @media (prefers-color-scheme: dark) {
132
+ &:hover {
133
+ .tv-toc-link {
134
+ background-color: rgba($active-color-dark, 0.05);
135
+ }
136
+
137
+ .tv-toc-sublink {
138
+ background-color: rgba($active-color-dark, 0.05);
139
+ }
140
+ }
141
+
142
+ .tv-toc-toggle:hover {
143
+ background-color: rgba($active-color-dark, 0.1);
144
+ }
111
145
  }
112
146
  }
113
147
 
114
- &:hover {
115
- .tv-toc-link {
116
- background-color: rgba($active-color, 0.05);
148
+ .tv-toc-link {
149
+ display: block;
150
+ text-decoration: none;
151
+ color: inherit;
152
+ font-weight: 500;
153
+ padding: 0.5rem 0.75rem;
154
+ border-radius: 4px;
155
+ transition: all 0.3s ease;
156
+ position: relative;
157
+
158
+ &:hover {
159
+ color: $active-color;
117
160
  }
118
161
 
119
- .tv-toc-sublink {
120
- background-color: rgba($active-color, 0.05);
162
+ &.active {
163
+ color: $active-color;
164
+ font-weight: 700;
165
+ background-color: rgba($active-color, 0.1);
166
+ padding-left: 1rem;
167
+ position: relative;
168
+ animation: toc-pulse 2s infinite;
169
+
170
+ &::before {
171
+ content: '';
172
+ position: absolute;
173
+ left: 0;
174
+ top: 0;
175
+ bottom: 0;
176
+ width: 4px;
177
+ background: linear-gradient(180deg, var(--toc-active-color), rgba(var(--toc-active-rgb), 0.2), var(--toc-active-color));
178
+ background-size: 100% 200%;
179
+ animation: border-flow 2s linear infinite;
180
+ border-radius: 4px 0 0 4px;
181
+ }
121
182
  }
122
- }
123
183
 
124
- @media (prefers-color-scheme: dark) {
125
- &:hover {
126
- .tv-toc-link {
127
- background-color: rgba($active-color-dark, 0.05);
184
+ &.parent-active {
185
+ color: $active-color;
186
+ font-weight: 500;
187
+ border-left: 2px solid rgba($active-color, 0.5);
188
+ padding-left: calc(1rem - 2px);
189
+ }
190
+
191
+ @media (prefers-color-scheme: dark) {
192
+ &:hover {
193
+ color: $active-color-dark;
128
194
  }
129
195
 
130
- .tv-toc-sublink {
131
- background-color: rgba($active-color-dark, 0.05);
196
+ &.active {
197
+ color: $active-color-dark;
198
+ background-color: rgba($active-color-dark, 0.1);
132
199
  }
133
- }
134
200
 
135
- .tv-toc-toggle:hover {
136
- background-color: rgba($active-color-dark, 0.1);
201
+ &.parent-active {
202
+ color: $active-color-dark;
203
+ border-left-color: rgba($active-color-dark, 0.5);
204
+ }
137
205
  }
138
206
  }
139
- }
140
207
 
141
- .tv-toc-link {
142
- display: block;
143
- text-decoration: none;
144
- color: inherit;
145
- font-weight: 500;
146
- padding: 0.5rem 0.75rem;
147
- border-radius: 4px;
148
- transition: all 0.3s ease;
149
- position: relative;
208
+ .tv-toc-sublist-wrapper {
209
+ overflow: hidden;
210
+ transition: opacity 0.3s ease, max-height 0.3s ease;
211
+ max-height: 1000px;
212
+ opacity: 1;
150
213
 
151
- &:hover {
152
- color: $active-color;
214
+ &.is-collapsed {
215
+ max-height: 0;
216
+ opacity: 0;
217
+ margin-bottom: 0;
218
+ }
153
219
  }
154
220
 
155
- &.active {
156
- color: $active-color;
157
- font-weight: 700;
158
- background-color: rgba($active-color, 0.1);
221
+ .tv-toc-sublist {
222
+ list-style: none;
159
223
  padding-left: 1rem;
160
- position: relative;
161
- animation: toc-pulse 2s infinite;
162
-
163
- &::before {
164
- content: '';
165
- position: absolute;
166
- left: 0;
167
- top: 0;
168
- bottom: 0;
169
- width: 4px;
170
- background: linear-gradient(180deg, var(--toc-active-color), rgba(var(--toc-active-rgb), 0.2), var(--toc-active-color));
171
- background-size: 100% 200%;
172
- animation: border-flow 2s linear infinite;
173
- border-radius: 4px 0 0 4px;
224
+ margin-top: 0.25rem;
225
+ margin-bottom: 0.25rem;
226
+ border-left: 2px solid rgba($light-text, 0.1);
227
+
228
+ @media (prefers-color-scheme: dark) {
229
+ border-left-color: rgba($dark-text, 0.1);
174
230
  }
175
231
  }
176
232
 
177
- &.parent-active {
178
- color: $active-color;
179
- font-weight: 500;
180
- border-left: 2px solid rgba($active-color, 0.5);
181
- padding-left: calc(1rem - 2px);
233
+ .tv-toc-subitem {
234
+ margin-bottom: 0.25rem;
235
+ position: relative;
236
+ opacity: 0;
237
+ animation: fadeSlideIn 0.5s ease forwards;
238
+
239
+ @for $i from 1 through 10 {
240
+ &:nth-child(#{$i}) {
241
+ animation-delay: #{$i * 0.05 + 0.3}s;
242
+ }
243
+ }
182
244
  }
183
245
 
184
- @media (prefers-color-scheme: dark) {
246
+ .tv-toc-sublink {
247
+ display: block;
248
+ text-decoration: none;
249
+ color: inherit;
250
+ font-size: 0.9rem;
251
+ opacity: 0.8;
252
+ padding: 0.4rem 0.75rem;
253
+ border-radius: 4px;
254
+ transition: all 0.3s ease;
255
+ position: relative;
256
+
185
257
  &:hover {
186
- color: $active-color-dark;
258
+ opacity: 1;
259
+ color: $active-color;
187
260
  }
188
261
 
189
262
  &.active {
190
- color: $active-color-dark;
191
- background-color: rgba($active-color-dark, 0.1);
263
+ opacity: 1;
264
+ color: $active-color;
265
+ font-weight: 700;
266
+ background-color: rgba($active-color, 0.1);
267
+ padding-left: 1rem;
268
+ position: relative;
269
+ animation: toc-pulse 2s infinite;
270
+
271
+ &::before {
272
+ content: '';
273
+ position: absolute;
274
+ left: 0;
275
+ top: 0;
276
+ bottom: 0;
277
+ width: 3px;
278
+ background: linear-gradient(180deg, var(--toc-active-color), rgba(var(--toc-active-rgb), 0.2), var(--toc-active-color));
279
+ background-size: 100% 200%;
280
+ animation: border-flow 2s linear infinite;
281
+ border-radius: 4px 0 0 4px;
282
+ }
192
283
  }
193
284
 
194
- &.parent-active {
195
- color: $active-color-dark;
196
- border-left-color: rgba($active-color-dark, 0.5);
285
+ @media (prefers-color-scheme: dark) {
286
+ &:hover {
287
+ color: $active-color-dark;
288
+ }
289
+
290
+ &.active {
291
+ color: $active-color-dark;
292
+ background-color: rgba($active-color-dark, 0.1);
293
+ }
197
294
  }
198
295
  }
199
296
  }
200
297
 
201
- .tv-toc-sublist-wrapper {
202
- overflow: hidden;
203
- transition: opacity 0.3s ease, max-height 0.3s ease;
204
- max-height: 1000px;
205
- opacity: 1;
298
+ &.compact {
299
+ background-color: transparent;
300
+ padding: 0;
301
+ border-radius: 0;
302
+ min-width: auto;
303
+
304
+ .tv-toc-title {
305
+ font-size: 1rem;
306
+ margin: 0 0 0.5rem 0;
307
+ padding-left: 0;
308
+ opacity: 0.8;
309
+ }
206
310
 
207
- &.is-collapsed {
208
- max-height: 0;
209
- opacity: 0;
210
- margin-bottom: 0;
311
+ .tv-toc-body {
312
+ padding: 0;
211
313
  }
212
- }
213
314
 
214
- .tv-toc-sublist {
215
- list-style: none;
216
- padding-left: 1rem;
217
- margin-top: 0.25rem;
218
- margin-bottom: 0.25rem;
219
- border-left: 2px solid rgba($light-text, 0.1);
315
+ .tv-toc-progress-container {
316
+ width: 2px;
317
+ left: 0;
318
+ background-color: rgba($light-text, 0.1);
220
319
 
221
- @media (prefers-color-scheme: dark) {
222
- border-left-color: rgba($dark-text, 0.1);
320
+ @media (prefers-color-scheme: dark) {
321
+ background-color: rgba($dark-text, 0.1);
322
+ }
223
323
  }
224
- }
225
324
 
226
- .tv-toc-subitem {
227
- margin-bottom: 0.25rem;
228
- position: relative;
229
- opacity: 0;
230
- animation: fadeSlideIn 0.5s ease forwards;
325
+ .tv-toc-progress-bar {
326
+ border-radius: 0;
327
+ background: $active-color;
231
328
 
232
- @for $i from 1 through 10 {
233
- &:nth-child(#{$i}) {
234
- animation-delay: #{$i * 0.05 + 0.3}s;
329
+ @media (prefers-color-scheme: dark) {
330
+ background: $active-color-dark;
235
331
  }
236
332
  }
237
- }
238
333
 
239
- .tv-toc-sublink {
240
- display: block;
241
- text-decoration: none;
242
- color: inherit;
243
- font-size: 0.9rem;
244
- opacity: 0.8;
245
- padding: 0.4rem 0.75rem;
246
- border-radius: 4px;
247
- transition: all 0.3s ease;
248
- position: relative;
249
-
250
- &:hover {
251
- opacity: 1;
252
- color: $active-color;
334
+ .tv-toc-list {
335
+ margin: 0;
253
336
  }
254
337
 
255
- &.active {
338
+ .tv-toc-item {
339
+ margin-bottom: 0;
340
+ animation: none;
256
341
  opacity: 1;
257
- color: $active-color;
258
- font-weight: 700;
259
- background-color: rgba($active-color, 0.1);
260
- padding-left: 1rem;
261
- position: relative;
262
- animation: toc-pulse 2s infinite;
263
-
264
- &::before {
265
- content: '';
266
- position: absolute;
267
- left: 0;
268
- top: 0;
269
- bottom: 0;
270
- width: 3px;
271
- background: linear-gradient(180deg, var(--toc-active-color), rgba(var(--toc-active-rgb), 0.2), var(--toc-active-color));
272
- background-size: 100% 200%;
273
- animation: border-flow 2s linear infinite;
274
- border-radius: 4px 0 0 4px;
342
+
343
+ .tv-toc-link {
344
+ padding: 0.35rem 1rem;
345
+ font-size: 0.9rem;
346
+
347
+ &:hover {
348
+ background-color: transparent;
349
+ color: $active-color;
350
+ }
351
+
352
+ &.active {
353
+ background-color: transparent;
354
+ animation: none;
355
+ padding-left: 1rem;
356
+ font-weight: 600;
357
+ color: $active-color;
358
+
359
+ &::before {
360
+ display: none;
361
+ }
362
+ }
363
+
364
+ &.parent-active {
365
+ border-left: none;
366
+ padding-left: 1rem;
367
+ color: $active-color;
368
+ }
369
+ }
370
+
371
+ @media (prefers-color-scheme: dark) {
372
+ .tv-toc-link:hover {
373
+ color: $active-color-dark;
374
+ }
375
+
376
+ .tv-toc-link.active {
377
+ color: $active-color-dark;
378
+ }
379
+
380
+ .tv-toc-link.parent-active {
381
+ color: $active-color-dark;
382
+ }
275
383
  }
276
384
  }
277
385
 
278
- @media (prefers-color-scheme: dark) {
279
- &:hover {
280
- color: $active-color-dark;
386
+ .tv-toc-sublist {
387
+ border-left: none;
388
+ padding-left: 0;
389
+ margin: 0;
390
+
391
+ .tv-toc-subitem {
392
+ margin-bottom: 0;
393
+ animation: none;
394
+ opacity: 1;
281
395
  }
282
396
 
283
- &.active {
284
- color: $active-color-dark;
285
- background-color: rgba($active-color-dark, 0.1);
397
+ .tv-toc-sublink {
398
+ padding: 0.25rem 1rem 0.25rem 1.5rem;
399
+ font-size: 0.85rem;
400
+
401
+ &:hover {
402
+ background-color: transparent;
403
+ color: $active-color;
404
+ }
405
+
406
+ &.active {
407
+ background-color: transparent;
408
+ animation: none;
409
+ padding-left: 1.5rem;
410
+ font-weight: 600;
411
+ color: $active-color;
412
+
413
+ &::before {
414
+ display: none;
415
+ }
416
+ }
417
+ }
418
+
419
+ @media (prefers-color-scheme: dark) {
420
+ .tv-toc-sublink:hover {
421
+ color: $active-color-dark;
422
+ }
423
+
424
+ .tv-toc-sublink.active {
425
+ color: $active-color-dark;
426
+ }
286
427
  }
287
428
  }
288
429
  }
@@ -22,6 +22,10 @@ const props = defineProps({
22
22
  collapsible: {
23
23
  type: Boolean,
24
24
  default: false
25
+ },
26
+ compact: {
27
+ type: Boolean,
28
+ default: false
25
29
  }
26
30
  })
27
31
 
@@ -104,75 +108,77 @@ onUnmounted(() => {
104
108
  </script>
105
109
 
106
110
  <template>
107
- <nav class="tv-toc">
108
- <div class="tv-toc-progress-container" v-if="toc?.links?.length">
109
- <div
110
- class="tv-toc-progress-bar"
111
- :style="{ height: `${scrollProgress}%` }"
112
- ></div>
113
- </div>
111
+ <nav class="tv-toc" :class="{ compact }">
114
112
  <h3 v-if="toc?.title" class="tv-toc-title">{{ toc.title }}</h3>
115
- <ul class="tv-toc-list">
116
- <li v-for="link in toc?.links" :key="link.id" class="tv-toc-item">
117
- <div class="tv-toc-item-content">
118
- <a
119
- :href="`#${link.id}`"
120
- class="tv-toc-link"
121
- :class="{
122
- [props.activeClass]: isActive(link.id),
123
- 'parent-active': isParentOfActive(link.id),
124
- 'tv-toc-marker': marker && isActive(link.id)
125
- }"
126
- @click.prevent="handleClick(link.id)"
127
- >
128
- {{ link.text }}
129
- </a>
130
- <button
131
- v-if="collapsible && link.children && link.children.length"
132
- class="tv-toc-toggle"
133
- :class="{ 'is-expanded': isExpanded(link.id) }"
134
- @click.stop="toggle(link.id)"
135
- aria-label="Toggle section"
136
- >
137
- <svg
138
- xmlns="http://www.w3.org/2000/svg"
139
- width="16"
140
- height="16"
141
- viewBox="0 0 24 24"
142
- fill="none"
143
- stroke="currentColor"
144
- stroke-width="2"
145
- stroke-linecap="round"
146
- stroke-linejoin="round"
147
- >
148
- <polyline points="6 9 12 15 18 9"></polyline>
149
- </svg>
150
- </button>
151
- </div>
152
-
113
+ <div class="tv-toc-body">
114
+ <div class="tv-toc-progress-container" v-if="toc?.links?.length">
153
115
  <div
154
- v-if="link.children"
155
- class="tv-toc-sublist-wrapper"
156
- :class="{ 'is-collapsed': collapsible && !isExpanded(link.id) }"
157
- :style="collapsible ? { '--content-height': isExpanded(link.id) ? '1000px' : '0px' } : {}"
158
- >
159
- <ul class="tv-toc-sublist">
160
- <li v-for="subLink in link.children" :key="subLink.id" class="tv-toc-subitem">
161
- <a
162
- :href="`#${subLink.id}`"
163
- class="tv-toc-sublink"
164
- :class="{
165
- [props.activeClass]: isActive(subLink.id),
166
- 'tv-toc-marker': marker && isActive(subLink.id)
167
- }"
168
- @click.prevent="handleClick(subLink.id)"
116
+ class="tv-toc-progress-bar"
117
+ :style="{ height: `${scrollProgress}%` }"
118
+ ></div>
119
+ </div>
120
+ <ul class="tv-toc-list">
121
+ <li v-for="link in toc?.links" :key="link.id" class="tv-toc-item">
122
+ <div class="tv-toc-item-content">
123
+ <a
124
+ :href="`#${link.id}`"
125
+ class="tv-toc-link"
126
+ :class="{
127
+ [props.activeClass]: isActive(link.id),
128
+ 'parent-active': isParentOfActive(link.id),
129
+ 'tv-toc-marker': marker && isActive(link.id)
130
+ }"
131
+ @click.prevent="handleClick(link.id)"
132
+ >
133
+ {{ link.text }}
134
+ </a>
135
+ <button
136
+ v-if="collapsible && link.children && link.children.length"
137
+ class="tv-toc-toggle"
138
+ :class="{ 'is-expanded': isExpanded(link.id) }"
139
+ @click.stop="toggle(link.id)"
140
+ aria-label="Toggle section"
141
+ >
142
+ <svg
143
+ xmlns="http://www.w3.org/2000/svg"
144
+ width="16"
145
+ height="16"
146
+ viewBox="0 0 24 24"
147
+ fill="none"
148
+ stroke="currentColor"
149
+ stroke-width="2"
150
+ stroke-linecap="round"
151
+ stroke-linejoin="round"
169
152
  >
170
- {{ subLink.text }}
171
- </a>
172
- </li>
173
- </ul>
174
- </div>
175
- </li>
176
- </ul>
153
+ <polyline points="6 9 12 15 18 9"></polyline>
154
+ </svg>
155
+ </button>
156
+ </div>
157
+
158
+ <div
159
+ v-if="link.children"
160
+ class="tv-toc-sublist-wrapper"
161
+ :class="{ 'is-collapsed': collapsible && !isExpanded(link.id) }"
162
+ :style="collapsible ? { '--content-height': isExpanded(link.id) ? '1000px' : '0px' } : {}"
163
+ >
164
+ <ul class="tv-toc-sublist">
165
+ <li v-for="subLink in link.children" :key="subLink.id" class="tv-toc-subitem">
166
+ <a
167
+ :href="`#${subLink.id}`"
168
+ class="tv-toc-sublink"
169
+ :class="{
170
+ [props.activeClass]: isActive(subLink.id),
171
+ 'tv-toc-marker': marker && isActive(subLink.id)
172
+ }"
173
+ @click.prevent="handleClick(subLink.id)"
174
+ >
175
+ {{ subLink.text }}
176
+ </a>
177
+ </li>
178
+ </ul>
179
+ </div>
180
+ </li>
181
+ </ul>
182
+ </div>
177
183
  </nav>
178
184
  </template>
package/src/demo/Demo.vue CHANGED
@@ -15,6 +15,6 @@ const TvToc = defineAsyncComponent(/* webpackChunkName: "tvToc" */() => import('
15
15
  npm-install="@todovue/tv-toc"
16
16
  source-link="https://github.com/TODOvue/tv-toc"
17
17
  url-clone="https://github.com/TODOvue/tv-toc.git"
18
- version="1.1.1"
18
+ version="1.2.0"
19
19
  />
20
20
  </template>
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <TvToc
3
+ :toc="toc"
4
+ compact
5
+ />
6
+ </template>
7
+
8
+ <script setup>
9
+ import { TvToc } from '@todovue/tv-toc'
10
+ import '@todovue/tv-toc/style.css'
11
+
12
+ const toc = {
13
+ "title": "Table of Contents",
14
+ "searchDepth": 2,
15
+ "depth": 2,
16
+ "links": [
17
+ {
18
+ "id": "what-is-todovue",
19
+ "depth": 2,
20
+ "text": "What is TODOvue?"
21
+ },
22
+ {
23
+ "id": "the-first-component-tvarticle",
24
+ "depth": 2,
25
+ "text": "The First Component: TvArticle",
26
+ "children": [
27
+ {
28
+ "id": "key-features",
29
+ "depth": 3,
30
+ "text": "Key Features"
31
+ },
32
+ {
33
+ "id": "usage-example",
34
+ "depth": 3,
35
+ "text": "Usage Example"
36
+ }
37
+ ]
38
+ },
39
+ {
40
+ "id": "why-another-component-library",
41
+ "depth": 2,
42
+ "text": "Why Another Component Library?",
43
+ "children": [
44
+ {
45
+ "id": "different-philosophy",
46
+ "depth": 3,
47
+ "text": "Different Philosophy"
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ "id": "the-road-ahead",
53
+ "depth": 2,
54
+ "text": "The Road Ahead"
55
+ },
56
+ {
57
+ "id": "join-the-journey",
58
+ "depth": 2,
59
+ "text": "Join the Journey"
60
+ },
61
+ {
62
+ "id": "next-steps",
63
+ "depth": 2,
64
+ "text": "Next Steps"
65
+ }
66
+ ]
67
+ }
68
+ </script>
@@ -1,5 +1,6 @@
1
1
  import FullBlog from './demos/fullBlog.vue?raw';
2
2
  import SimpleDoc from './demos/simpleBlog.vue?raw';
3
+ import FullBlogCompact from './demos/fullBlogCompact.vue?raw';
3
4
 
4
5
  const tocExample1 = {
5
6
  "title": "Table of Contents",
@@ -138,6 +139,16 @@ export const demos = [
138
139
  },
139
140
  html: FullBlog,
140
141
  },
142
+ {
143
+ id: 5,
144
+ title: 'Full Blog Post TOC (Compact)',
145
+ description: 'Table of Contents for a full blog post layout. (Compact Version)',
146
+ propsData: {
147
+ toc: tocExample1,
148
+ compact: true,
149
+ },
150
+ html: FullBlogCompact,
151
+ },
141
152
  {
142
153
  id: 2,
143
154
  title: 'Simple Documentation TOC',