@todovue/tv-breadcrumbs 1.0.0 → 1.1.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
@@ -1,12 +1,19 @@
1
- <p align="center"><img width="150" src="https://firebasestorage.googleapis.com/v0/b/todovue-blog.appspot.com/o/logo.png?alt=media&token=d8eb592f-e4a9-4b02-8aff-62d337745f41" alt="TODOvue logo">
1
+ <p align="center"><img width="150" src="https://res.cloudinary.com/dcdfhi8qz/image/upload/v1763663056/uqqtkgp1lg3xdplutpga.png" alt="TODOvue logo">
2
2
  </p>
3
3
 
4
4
  # TODOvue Breadcrumbs (TvBreadcrumbs)
5
5
  A flexible, framework‑agnostic Vue 3 breadcrumb navigation component with auto-generation from routes, custom separators, max items control, and full customization. Works seamlessly in Single Page Apps or Server-Side Rendered (SSR) environments (e.g. Nuxt 3).
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/@todovue/tv-breadcrumbs.svg)](https://www.npmjs.com/package/@todovue/tv-breadcrumbs)
8
+ [![Netlify Status](https://api.netlify.com/api/v1/badges/8c4e2401-fefe-4f40-ae83-40681ecc36a5/deploy-status)](https://app.netlify.com/projects/tv-breadcrumbs/deploys)
8
9
  [![npm downloads](https://img.shields.io/npm/dm/@todovue/tv-breadcrumbs.svg)](https://www.npmjs.com/package/@todovue/tv-breadcrumbs)
10
+ [![npm total downloads](https://img.shields.io/npm/dt/@todovue/tv-breadcrumbs.svg)](https://www.npmjs.com/package/@todovue/tv-breadcrumbs)
9
11
  ![License](https://img.shields.io/github/license/TODOvue/tv-breadcrumbs)
12
+ ![Release Date](https://img.shields.io/github/release-date/TODOvue/tv-breadcrumbs)
13
+ ![Bundle Size](https://img.shields.io/bundlephobia/minzip/@todovue/tv-breadcrumbs)
14
+ ![Node Version](https://img.shields.io/node/v/@todovue/tv-breadcrumbs)
15
+ ![Last Commit](https://img.shields.io/github/last-commit/TODOvue/tv-breadcrumbs)
16
+ ![Stars](https://img.shields.io/github/stars/TODOvue/tv-breadcrumbs?style=social)
10
17
 
11
18
  > Demo: https://tv-breadcrumbs.netlify.app/
12
19
 
@@ -64,6 +71,7 @@ Global registration (main.js / main.ts):
64
71
  import { createApp } from 'vue'
65
72
  import App from './App.vue'
66
73
  import { TvBreadcrumbs } from '@todovue/tv-breadcrumbs'
74
+ import '@todovue/tv-breadcrumbs/style.css' // import styles
67
75
 
68
76
  createApp(App)
69
77
  .use(TvBreadcrumbs) // enables <TvBreadcrumbs /> globally
@@ -93,7 +101,17 @@ function onItemClick({ item, index, event }) {
93
101
 
94
102
  ---
95
103
  ## Nuxt 3 / SSR Usage
96
- Create a plugin file: `plugins/tv-breadcrumbs.client.ts` (or without `.client` suffix as it's SSR-safe):
104
+ First, add the stylesheet to your Nuxt config:
105
+ ```ts
106
+ // nuxt.config.ts
107
+ export default defineNuxtConfig({
108
+ modules: [
109
+ '@todovue/tv-breadcrumbs/nuxt'
110
+ ]
111
+ })
112
+ ```
113
+
114
+ Then create a plugin file: `plugins/tv-breadcrumbs.client.ts` (or without `.client` suffix as it's SSR-safe):
97
115
  ```ts
98
116
  import { defineNuxtPlugin } from '#app'
99
117
  import { TvBreadcrumbs } from '@todovue/tv-breadcrumbs'
package/dist/entry.d.ts CHANGED
@@ -1,6 +1,11 @@
1
- import { default as TvBreadcrumbs } from './components/TvBreadcrumbs.vue';
2
- export declare const TvBreadcrumbsPlugin: {
3
- install(app: any): void;
4
- };
1
+ import { Plugin } from 'vue';
2
+ import { default as _TvBreadcrumbs } from './components/TvBreadcrumbs.vue';
3
+ declare const TvBreadcrumbs: typeof _TvBreadcrumbs & Plugin;
5
4
  export { TvBreadcrumbs };
5
+ export declare const TvBreadcrumbsPlugin: Plugin;
6
6
  export default TvBreadcrumbs;
7
+ declare module 'vue' {
8
+ interface GlobalComponents {
9
+ TvBreadcrumbs: typeof TvBreadcrumbs;
10
+ }
11
+ }
@@ -1,2 +1 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode('@charset "UTF-8";[data-v-d1c54a52]{box-sizing:border-box;margin:0;padding:0}.tv-breadcrumb.tv-breadcrumb-root.tv-breadcrumb-container[data-v-d1c54a52]{width:100%;overflow-x:auto}.tv-breadcrumb .tv-breadcrumb-list[data-v-d1c54a52]{display:flex;align-items:center;gap:.5rem;list-style:none;padding:0;margin:0;white-space:nowrap}.tv-breadcrumb .tv-breadcrumb-item[data-v-d1c54a52]{display:inline-flex;align-items:center;gap:.5rem}.tv-breadcrumb .tv-breadcrumb-item--link .tv-breadcrumb-link[data-v-d1c54a52]{text-decoration:none;transition:opacity .16s ease,text-decoration-color .16s ease}.tv-breadcrumb .tv-breadcrumb-item--current .tv-breadcrumb-current[data-v-d1c54a52]{font-weight:600;cursor:default}.tv-breadcrumb .tv-breadcrumb-item--disabled .tv-breadcrumb-link[data-v-d1c54a52]{cursor:not-allowed;opacity:.5;pointer-events:none}.tv-breadcrumb .tv-breadcrumb-separator[data-v-d1c54a52]{-webkit-user-select:none;user-select:none;opacity:.7}.light-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]{color:#000b14;text-decoration:underline;text-underline-offset:2px;text-decoration-color:#000b144d}.light-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:hover{opacity:.85;text-decoration-color:#000b1499}.light-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:focus-visible{outline:2px solid rgba(0,11,20,.4);outline-offset:2px;border-radius:6px}.light-mode .tv-breadcrumb .tv-breadcrumb-current[data-v-d1c54a52],.light-mode .tv-breadcrumb .tv-breadcrumb-separator[data-v-d1c54a52]{color:#000b14}.dark-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]{color:#f4faff;text-decoration:underline;text-underline-offset:2px;text-decoration-color:#f4faff40}.dark-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:hover{opacity:.9;text-decoration-color:#f4faff8c}.dark-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:focus-visible{outline:2px solid rgba(244,250,255,.35);outline-offset:2px;border-radius:6px}.dark-mode .tv-breadcrumb .tv-breadcrumb-current[data-v-d1c54a52]{color:#f4faff}.dark-mode .tv-breadcrumb .tv-breadcrumb-separator[data-v-d1c54a52]{color:#f4faff;opacity:.75}')),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
2
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");function B(t,r){const u=e.getCurrentInstance()?.appContext?.config?.globalProperties||{},l=e.computed(()=>u.$route||null),d=u.$router||null,f=e.computed(()=>{if(!t.autoGenerate)return[];const n=e.unref(l);if(!n)return[];const i=(n.matched||[]).map(b=>{const m=b.meta?.breadcrumb;return m?typeof m=="function"?m(n):Array.isArray(m)?m:typeof m=="string"?[{label:m,href:b.path}]:null:null}).filter(Boolean).flat();if(i.length>0)return v(i);const g=String(n.path||"").split("/").filter(Boolean);if(g.length===0)return v([{label:t.homeLabel,href:"/"}]);const k=[];let _="";for(const b of g)_+=`/${b}`,k.push({label:S(b),href:_});return v([{label:t.homeLabel,href:"/"},...k])}),y=e.computed(()=>Array.isArray(t.items)&&t.items.length>0?v(t.items):f.value),a=e.computed(()=>{const n=y.value,s=Number(t.maxItems||0);if(!s||n.length<=s)return n;const i=Math.max(1,s-2),h=n[0],g=n.slice(-i);return[h,{label:"…",href:null,key:"__ellipsis__",disabled:!0},...g]});function o(n,s,i){if(!s||s.disabled){n.preventDefault();return}r("item-click",{item:s,index:i,event:n});const h=i===a.value.length-1;if(!s.href||h){n.preventDefault();return}d&&typeof d.push=="function"&&(n.preventDefault(),d.push(s.href),r("navigate",{to:s.href,item:s,index:i}))}return{itemsToRender:a,handleClick:o}}function S(t){return t.replace(/[-_]+/g," ").replace(/\b\w/g,r=>r.toUpperCase())}function v(t){return t.filter(Boolean).map((r,c)=>{if(typeof r=="string")return{label:r,href:null,key:`i-${c}`};const u=r.label!=null?String(r.label):"",l=r.href!=null&&r.href!==""?r.href:null,d=r.key!=null?r.key:`i-${c}`;return{...r,label:u,href:l,key:d}})}const T=(t,r)=>{const c=t.__vccOpts||t;for(const[u,l]of r)c[u]=l;return c},E=["aria-label"],N={class:"tv-breadcrumb-list",role:"list"},C=["itemscope","itemtype"],I=["href","aria-disabled","tabindex","onClick"],L={itemprop:"name"},V=["content"],$={class:"tv-breadcrumb-separator","aria-hidden":"true"},D={key:1,class:"tv-breadcrumb-current","aria-current":"page"},A={__name:"TvBreadcrumbs",props:{items:{type:Array,default:()=>[]},separator:{type:String,default:"›"},maxItems:{type:Number,default:0},autoGenerate:{type:Boolean,default:!1},homeLabel:{type:String,default:"Home"},ariaLabel:{type:String,default:"Breadcrumb"}},emits:["item-click","navigate"],setup(t,{emit:r}){const c=t,u=r,{itemsToRender:l,handleClick:d}=B(c,u);return(f,y)=>(e.openBlock(),e.createElementBlock("nav",{class:"tv-breadcrumb tv-breadcrumb-root tv-breadcrumb-container","aria-label":t.ariaLabel},[e.createElementVNode("ol",N,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(l),(a,o)=>(e.openBlock(),e.createElementBlock("li",{key:a.key||o,class:e.normalizeClass(["tv-breadcrumb-item",{"tv-breadcrumb-item--current":o===e.unref(l).length-1,"tv-breadcrumb-item--link":o!==e.unref(l).length-1,"tv-breadcrumb-item--disabled":a.disabled}]),itemscope:o===e.unref(l).length-1?void 0:!0,itemtype:o===e.unref(l).length-1?void 0:"https://schema.org/ListItem"},[o!==e.unref(l).length-1?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createElementVNode("a",{class:"tv-breadcrumb-link",href:a.disabled?void 0:a.href||"#","aria-disabled":a.disabled?"true":void 0,tabindex:a.disabled?-1:void 0,itemprop:"item",onClick:n=>e.unref(d)(n,a,o)},[e.createElementVNode("span",L,[e.renderSlot(f.$slots,"item",{item:a,index:o},()=>[e.createTextVNode(e.toDisplayString(a.label),1)],!0)])],8,I),e.createElementVNode("meta",{itemprop:"position",content:String(o+1)},null,8,V),e.createElementVNode("span",$,[e.renderSlot(f.$slots,"separator",{},()=>[e.createTextVNode(e.toDisplayString(t.separator),1)],!0)])],64)):(e.openBlock(),e.createElementBlock("span",D,[e.renderSlot(f.$slots,"current",{item:a,index:o},()=>[e.createTextVNode(e.toDisplayString(a.label),1)],!0)]))],10,C))),128))])],8,E))}},p=T(A,[["__scopeId","data-v-d1c54a52"]]);p.install=t=>{t.component("TvBreadcrumbs",p)};const M={install(t){t.component("TvBreadcrumbs",p)}};exports.TvBreadcrumbs=p;exports.TvBreadcrumbsPlugin=M;exports.default=p;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue");function _(t,r){const d=e.getCurrentInstance()?.appContext?.config?.globalProperties||{},s=e.computed(()=>d.$route||null),u=d.$router||null,f=e.computed(()=>{if(!t.autoGenerate)return[];const n=e.unref(s);if(!n)return[];const c=(n.matched||[]).map(b=>{const i=b.meta?.breadcrumb;return i?typeof i=="function"?i(n):Array.isArray(i)?i:typeof i=="string"?[{label:i,href:b.path}]:null:null}).filter(Boolean).flat();if(c.length>0)return y(c);const g=String(n.path||"").split("/").filter(Boolean);if(g.length===0)return y([{label:t.homeLabel,href:"/"}]);const v=[];let B="";for(const b of g)B+=`/${b}`,v.push({label:S(b),href:B});return y([{label:t.homeLabel,href:"/"},...v])}),k=e.computed(()=>Array.isArray(t.items)&&t.items.length>0?y(t.items):f.value),a=e.computed(()=>{const n=k.value,o=Number(t.maxItems||0);if(!o||n.length<=o)return n;const c=Math.max(1,o-2),p=n[0],g=n.slice(-c);return[p,{label:"…",href:null,key:"__ellipsis__",disabled:!0},...g]});function l(n,o,c){if(!o||o.disabled){n.preventDefault();return}r("item-click",{item:o,index:c,event:n});const p=c===a.value.length-1;if(!o.href||p){n.preventDefault();return}u&&typeof u.push=="function"&&(n.preventDefault(),u.push(o.href),r("navigate",{to:o.href,item:o,index:c}))}return{itemsToRender:a,handleClick:l}}function S(t){return t.replace(/[-_]+/g," ").replace(/\b\w/g,r=>r.toUpperCase())}function y(t){return t.filter(Boolean).map((r,m)=>{if(typeof r=="string")return{label:r,href:null,key:`i-${m}`};const d=r.label!=null?String(r.label):"",s=r.href!=null&&r.href!==""?r.href:null,u=r.key!=null?r.key:`i-${m}`;return{...r,label:d,href:s,key:u}})}const T=["aria-label"],E={class:"tv-breadcrumb-list",role:"list"},N=["itemscope","itemtype"],C=["href","aria-disabled","tabindex","onClick"],I={itemprop:"name"},L=["content"],V={class:"tv-breadcrumb-separator","aria-hidden":"true"},$={key:1,class:"tv-breadcrumb-current","aria-current":"page"},D={__name:"TvBreadcrumbs",props:{items:{type:Array,default:()=>[]},separator:{type:String,default:"›"},maxItems:{type:Number,default:0},autoGenerate:{type:Boolean,default:!1},homeLabel:{type:String,default:"Home"},ariaLabel:{type:String,default:"Breadcrumb"}},emits:["item-click","navigate"],setup(t,{emit:r}){const m=t,d=r,{itemsToRender:s,handleClick:u}=_(m,d);return(f,k)=>(e.openBlock(),e.createElementBlock("nav",{class:"tv-breadcrumb tv-breadcrumb-root tv-breadcrumb-container","aria-label":t.ariaLabel},[e.createElementVNode("ol",E,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(s),(a,l)=>(e.openBlock(),e.createElementBlock("li",{key:a.key||l,class:e.normalizeClass(["tv-breadcrumb-item",{"tv-breadcrumb-item--current":l===e.unref(s).length-1,"tv-breadcrumb-item--link":l!==e.unref(s).length-1,"tv-breadcrumb-item--disabled":a.disabled}]),itemscope:l===e.unref(s).length-1?void 0:!0,itemtype:l===e.unref(s).length-1?void 0:"https://schema.org/ListItem"},[l!==e.unref(s).length-1?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createElementVNode("a",{class:"tv-breadcrumb-link",href:a.disabled?void 0:a.href||"#","aria-disabled":a.disabled?"true":void 0,tabindex:a.disabled?-1:void 0,itemprop:"item",onClick:n=>e.unref(u)(n,a,l)},[e.createElementVNode("span",I,[e.renderSlot(f.$slots,"item",{item:a,index:l},()=>[e.createTextVNode(e.toDisplayString(a.label),1)])])],8,C),e.createElementVNode("meta",{itemprop:"position",content:String(l+1)},null,8,L),e.createElementVNode("span",V,[e.renderSlot(f.$slots,"separator",{},()=>[e.createTextVNode(e.toDisplayString(t.separator),1)])])],64)):(e.openBlock(),e.createElementBlock("span",$,[e.renderSlot(f.$slots,"current",{item:a,index:l},()=>[e.createTextVNode(e.toDisplayString(a.label),1)])]))],10,N))),128))])],8,T))}},h=D;h.install=t=>{t.component("TvBreadcrumbs",h)};const A={install:h.install};exports.TvBreadcrumbs=h;exports.TvBreadcrumbsPlugin=A;exports.default=h;
@@ -0,0 +1 @@
1
+ @charset "UTF-8";*{box-sizing:border-box;margin:0;padding:0}.tv-breadcrumb.tv-breadcrumb-root.tv-breadcrumb-container{width:100%;overflow-x:auto}.tv-breadcrumb .tv-breadcrumb-list{display:flex;align-items:center;gap:.5rem;list-style:none;padding:0;margin:0;white-space:nowrap}.tv-breadcrumb .tv-breadcrumb-item{display:inline-flex;align-items:center;gap:.5rem}.tv-breadcrumb .tv-breadcrumb-item--link .tv-breadcrumb-link{text-decoration:none;transition:opacity .16s ease,text-decoration-color .16s ease}.tv-breadcrumb .tv-breadcrumb-item--current .tv-breadcrumb-current{font-weight:600;cursor:default}.tv-breadcrumb .tv-breadcrumb-item--disabled .tv-breadcrumb-link{cursor:not-allowed;opacity:.5;pointer-events:none}.tv-breadcrumb .tv-breadcrumb-separator{-webkit-user-select:none;user-select:none;opacity:.7}.light-mode .tv-breadcrumb .tv-breadcrumb-link{color:#000b14;text-decoration:underline;text-underline-offset:2px;text-decoration-color:#000b144d}.light-mode .tv-breadcrumb .tv-breadcrumb-link:hover{opacity:.85;text-decoration-color:#000b1499}.light-mode .tv-breadcrumb .tv-breadcrumb-link:focus-visible{outline:2px solid rgba(0,11,20,.4);outline-offset:2px;border-radius:6px}.light-mode .tv-breadcrumb .tv-breadcrumb-current,.light-mode .tv-breadcrumb .tv-breadcrumb-separator{color:#000b14}.dark-mode .tv-breadcrumb .tv-breadcrumb-link{color:#f4faff;text-decoration:underline;text-underline-offset:2px;text-decoration-color:#f4faff40}.dark-mode .tv-breadcrumb .tv-breadcrumb-link:hover{opacity:.9;text-decoration-color:#f4faff8c}.dark-mode .tv-breadcrumb .tv-breadcrumb-link:focus-visible{outline:2px solid rgba(244,250,255,.35);outline-offset:2px;border-radius:6px}.dark-mode .tv-breadcrumb .tv-breadcrumb-current{color:#f4faff}.dark-mode .tv-breadcrumb .tv-breadcrumb-separator{color:#f4faff;opacity:.75}
@@ -1,89 +1,83 @@
1
- (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode('@charset "UTF-8";[data-v-d1c54a52]{box-sizing:border-box;margin:0;padding:0}.tv-breadcrumb.tv-breadcrumb-root.tv-breadcrumb-container[data-v-d1c54a52]{width:100%;overflow-x:auto}.tv-breadcrumb .tv-breadcrumb-list[data-v-d1c54a52]{display:flex;align-items:center;gap:.5rem;list-style:none;padding:0;margin:0;white-space:nowrap}.tv-breadcrumb .tv-breadcrumb-item[data-v-d1c54a52]{display:inline-flex;align-items:center;gap:.5rem}.tv-breadcrumb .tv-breadcrumb-item--link .tv-breadcrumb-link[data-v-d1c54a52]{text-decoration:none;transition:opacity .16s ease,text-decoration-color .16s ease}.tv-breadcrumb .tv-breadcrumb-item--current .tv-breadcrumb-current[data-v-d1c54a52]{font-weight:600;cursor:default}.tv-breadcrumb .tv-breadcrumb-item--disabled .tv-breadcrumb-link[data-v-d1c54a52]{cursor:not-allowed;opacity:.5;pointer-events:none}.tv-breadcrumb .tv-breadcrumb-separator[data-v-d1c54a52]{-webkit-user-select:none;user-select:none;opacity:.7}.light-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]{color:#000b14;text-decoration:underline;text-underline-offset:2px;text-decoration-color:#000b144d}.light-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:hover{opacity:.85;text-decoration-color:#000b1499}.light-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:focus-visible{outline:2px solid rgba(0,11,20,.4);outline-offset:2px;border-radius:6px}.light-mode .tv-breadcrumb .tv-breadcrumb-current[data-v-d1c54a52],.light-mode .tv-breadcrumb .tv-breadcrumb-separator[data-v-d1c54a52]{color:#000b14}.dark-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]{color:#f4faff;text-decoration:underline;text-underline-offset:2px;text-decoration-color:#f4faff40}.dark-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:hover{opacity:.9;text-decoration-color:#f4faff8c}.dark-mode .tv-breadcrumb .tv-breadcrumb-link[data-v-d1c54a52]:focus-visible{outline:2px solid rgba(244,250,255,.35);outline-offset:2px;border-radius:6px}.dark-mode .tv-breadcrumb .tv-breadcrumb-current[data-v-d1c54a52]{color:#f4faff}.dark-mode .tv-breadcrumb .tv-breadcrumb-separator[data-v-d1c54a52]{color:#f4faff;opacity:.75}')),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
2
- import { getCurrentInstance as D, computed as _, unref as i, createElementBlock as h, openBlock as p, createElementVNode as g, Fragment as A, renderList as N, normalizeClass as z, renderSlot as B, createTextVNode as S, toDisplayString as C } from "vue";
1
+ import { getCurrentInstance as D, computed as _, unref as u, createElementBlock as h, openBlock as p, createElementVNode as g, Fragment as A, renderList as N, normalizeClass as z, renderSlot as B, createTextVNode as S, toDisplayString as C } from "vue";
3
2
  function R(e, t) {
4
- const c = D()?.appContext?.config?.globalProperties || {}, a = _(() => c.$route || null), d = c.$router || null, f = _(() => {
3
+ const d = D()?.appContext?.config?.globalProperties || {}, s = _(() => d.$route || null), i = d.$router || null, f = _(() => {
5
4
  if (!e.autoGenerate) return [];
6
- const r = i(a);
5
+ const r = u(s);
7
6
  if (!r) return [];
8
- const u = (r.matched || []).map((b) => {
9
- const m = b.meta?.breadcrumb;
10
- return m ? typeof m == "function" ? m(r) : Array.isArray(m) ? m : typeof m == "string" ? [{ label: m, href: b.path }] : null : null;
7
+ const o = (r.matched || []).map((b) => {
8
+ const c = b.meta?.breadcrumb;
9
+ return c ? typeof c == "function" ? c(r) : Array.isArray(c) ? c : typeof c == "string" ? [{ label: c, href: b.path }] : null : null;
11
10
  }).filter(Boolean).flat();
12
- if (u.length > 0)
13
- return k(u);
11
+ if (o.length > 0)
12
+ return k(o);
14
13
  const v = String(r.path || "").split("/").filter(Boolean);
15
14
  if (v.length === 0)
16
15
  return k([{ label: e.homeLabel, href: "/" }]);
17
- const T = [];
18
- let $ = "";
16
+ const $ = [];
17
+ let T = "";
19
18
  for (const b of v)
20
- $ += `/${b}`, T.push({
19
+ T += `/${b}`, $.push({
21
20
  label: E(b),
22
- href: $
21
+ href: T
23
22
  });
24
- return k([{ label: e.homeLabel, href: "/" }, ...T]);
23
+ return k([{ label: e.homeLabel, href: "/" }, ...$]);
25
24
  }), L = _(() => Array.isArray(e.items) && e.items.length > 0 ? k(e.items) : f.value), n = _(() => {
26
- const r = L.value, s = Number(e.maxItems || 0);
27
- if (!s || r.length <= s)
25
+ const r = L.value, l = Number(e.maxItems || 0);
26
+ if (!l || r.length <= l)
28
27
  return r;
29
- const u = Math.max(1, s - 2), y = r[0], v = r.slice(-u);
28
+ const o = Math.max(1, l - 2), y = r[0], v = r.slice(-o);
30
29
  return [
31
30
  y,
32
31
  { label: "…", href: null, key: "__ellipsis__", disabled: !0 },
33
32
  ...v
34
33
  ];
35
34
  });
36
- function l(r, s, u) {
37
- if (!s || s.disabled) {
35
+ function a(r, l, o) {
36
+ if (!l || l.disabled) {
38
37
  r.preventDefault();
39
38
  return;
40
39
  }
41
40
  t("item-click", {
42
- item: s,
43
- index: u,
41
+ item: l,
42
+ index: o,
44
43
  event: r
45
44
  });
46
- const y = u === n.value.length - 1;
47
- if (!s.href || y) {
45
+ const y = o === n.value.length - 1;
46
+ if (!l.href || y) {
48
47
  r.preventDefault();
49
48
  return;
50
49
  }
51
- d && typeof d.push == "function" && (r.preventDefault(), d.push(s.href), t("navigate", {
52
- to: s.href,
53
- item: s,
54
- index: u
50
+ i && typeof i.push == "function" && (r.preventDefault(), i.push(l.href), t("navigate", {
51
+ to: l.href,
52
+ item: l,
53
+ index: o
55
54
  }));
56
55
  }
57
56
  return {
58
57
  itemsToRender: n,
59
- handleClick: l
58
+ handleClick: a
60
59
  };
61
60
  }
62
61
  function E(e) {
63
62
  return e.replace(/[-_]+/g, " ").replace(/\b\w/g, (t) => t.toUpperCase());
64
63
  }
65
64
  function k(e) {
66
- return e.filter(Boolean).map((t, o) => {
65
+ return e.filter(Boolean).map((t, m) => {
67
66
  if (typeof t == "string")
68
- return { label: t, href: null, key: `i-${o}` };
69
- const c = t.label != null ? String(t.label) : "", a = t.href != null && t.href !== "" ? t.href : null, d = t.key != null ? t.key : `i-${o}`;
67
+ return { label: t, href: null, key: `i-${m}` };
68
+ const d = t.label != null ? String(t.label) : "", s = t.href != null && t.href !== "" ? t.href : null, i = t.key != null ? t.key : `i-${m}`;
70
69
  return {
71
70
  ...t,
72
- label: c,
73
- href: a,
74
- key: d
71
+ label: d,
72
+ href: s,
73
+ key: i
75
74
  };
76
75
  });
77
76
  }
78
- const G = (e, t) => {
79
- const o = e.__vccOpts || e;
80
- for (const [c, a] of t)
81
- o[c] = a;
82
- return o;
83
- }, M = ["aria-label"], P = {
77
+ const G = ["aria-label"], M = {
84
78
  class: "tv-breadcrumb-list",
85
79
  role: "list"
86
- }, V = ["itemscope", "itemtype"], w = ["href", "aria-disabled", "tabindex", "onClick"], F = { itemprop: "name" }, H = ["content"], O = {
80
+ }, P = ["itemscope", "itemtype"], V = ["href", "aria-disabled", "tabindex", "onClick"], w = { itemprop: "name" }, F = ["content"], H = {
87
81
  class: "tv-breadcrumb-separator",
88
82
  "aria-hidden": "true"
89
83
  }, U = {
@@ -120,69 +114,67 @@ const G = (e, t) => {
120
114
  },
121
115
  emits: ["item-click", "navigate"],
122
116
  setup(e, { emit: t }) {
123
- const o = e, c = t, { itemsToRender: a, handleClick: d } = R(o, c);
117
+ const m = e, d = t, { itemsToRender: s, handleClick: i } = R(m, d);
124
118
  return (f, L) => (p(), h("nav", {
125
119
  class: "tv-breadcrumb tv-breadcrumb-root tv-breadcrumb-container",
126
120
  "aria-label": e.ariaLabel
127
121
  }, [
128
- g("ol", P, [
129
- (p(!0), h(A, null, N(i(a), (n, l) => (p(), h("li", {
130
- key: n.key || l,
122
+ g("ol", M, [
123
+ (p(!0), h(A, null, N(u(s), (n, a) => (p(), h("li", {
124
+ key: n.key || a,
131
125
  class: z(["tv-breadcrumb-item", {
132
- "tv-breadcrumb-item--current": l === i(a).length - 1,
133
- "tv-breadcrumb-item--link": l !== i(a).length - 1,
126
+ "tv-breadcrumb-item--current": a === u(s).length - 1,
127
+ "tv-breadcrumb-item--link": a !== u(s).length - 1,
134
128
  "tv-breadcrumb-item--disabled": n.disabled
135
129
  }]),
136
- itemscope: l === i(a).length - 1 ? void 0 : !0,
137
- itemtype: l === i(a).length - 1 ? void 0 : "https://schema.org/ListItem"
130
+ itemscope: a === u(s).length - 1 ? void 0 : !0,
131
+ itemtype: a === u(s).length - 1 ? void 0 : "https://schema.org/ListItem"
138
132
  }, [
139
- l !== i(a).length - 1 ? (p(), h(A, { key: 0 }, [
133
+ a !== u(s).length - 1 ? (p(), h(A, { key: 0 }, [
140
134
  g("a", {
141
135
  class: "tv-breadcrumb-link",
142
136
  href: n.disabled ? void 0 : n.href || "#",
143
137
  "aria-disabled": n.disabled ? "true" : void 0,
144
138
  tabindex: n.disabled ? -1 : void 0,
145
139
  itemprop: "item",
146
- onClick: (r) => i(d)(r, n, l)
140
+ onClick: (r) => u(i)(r, n, a)
147
141
  }, [
148
- g("span", F, [
142
+ g("span", w, [
149
143
  B(f.$slots, "item", {
150
144
  item: n,
151
- index: l
145
+ index: a
152
146
  }, () => [
153
147
  S(C(n.label), 1)
154
- ], !0)
148
+ ])
155
149
  ])
156
- ], 8, w),
150
+ ], 8, V),
157
151
  g("meta", {
158
152
  itemprop: "position",
159
- content: String(l + 1)
160
- }, null, 8, H),
161
- g("span", O, [
153
+ content: String(a + 1)
154
+ }, null, 8, F),
155
+ g("span", H, [
162
156
  B(f.$slots, "separator", {}, () => [
163
157
  S(C(e.separator), 1)
164
- ], !0)
158
+ ])
165
159
  ])
166
160
  ], 64)) : (p(), h("span", U, [
167
161
  B(f.$slots, "current", {
168
162
  item: n,
169
- index: l
163
+ index: a
170
164
  }, () => [
171
165
  S(C(n.label), 1)
172
- ], !0)
166
+ ])
173
167
  ]))
174
- ], 10, V))), 128))
168
+ ], 10, P))), 128))
175
169
  ])
176
- ], 8, M));
170
+ ], 8, G));
177
171
  }
178
- }, I = /* @__PURE__ */ G(j, [["__scopeId", "data-v-d1c54a52"]]);
172
+ }, I = j;
179
173
  I.install = (e) => {
180
174
  e.component("TvBreadcrumbs", I);
181
175
  };
182
176
  const J = {
183
- install(e) {
184
- e.component("TvBreadcrumbs", I);
185
- }
177
+ install: I.install
186
178
  };
187
179
  export {
188
180
  I as TvBreadcrumbs,
package/nuxt.js ADDED
@@ -0,0 +1,14 @@
1
+ import { defineNuxtModule } from '@nuxt/kit'
2
+
3
+ export default defineNuxtModule({
4
+ meta: {
5
+ name: '@todovue/tv-breadcrumbs',
6
+ configKey: 'tvBreadcrumbs'
7
+ },
8
+ setup(_options, nuxt) {
9
+ const cssPath = '@todovue/tv-breadcrumbs/style.css';
10
+ if (!nuxt.options.css.includes(cssPath)) {
11
+ nuxt.options.css.push(cssPath);
12
+ }
13
+ }
14
+ })
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "author": "Cristhian Daza",
5
5
  "description": "A simple and customizable Vue 3 breadcrumbs component for your applications.",
6
6
  "license": "MIT",
7
- "version": "1.0.0",
7
+ "version": "1.1.0",
8
8
  "type": "module",
9
9
  "repository": {
10
10
  "type": "git",
@@ -29,7 +29,9 @@
29
29
  ".": {
30
30
  "import": "./dist/tv-breadcrumbs.es.js",
31
31
  "require": "./dist/tv-breadcrumbs.cjs.js"
32
- }
32
+ },
33
+ "./style.css": "./dist/tv-breadcrumbs.css",
34
+ "./nuxt": "./nuxt.js"
33
35
  },
34
36
  "main": "dist/tv-breadcrumbs.cjs.js",
35
37
  "module": "dist/tv-breadcrumbs.es.js",
@@ -37,7 +39,13 @@
37
39
  "files": [
38
40
  "dist",
39
41
  "LICENSE",
40
- "README.md"
42
+ "README.md",
43
+ "nuxt.js"
44
+ ],
45
+ "sideEffects": [
46
+ "*.css",
47
+ "*.scss",
48
+ "dist/*.css"
41
49
  ],
42
50
  "engines": {
43
51
  "node": ">=20.19.0"
@@ -45,17 +53,16 @@
45
53
  "scripts": {
46
54
  "dev": "vite",
47
55
  "build": "vite build",
48
- "build:demo": "cp README.md public/ && VITE_BUILD_TARGET=demo vite build"
56
+ "build:demo": "cp README.md public/ && cp CHANGELOG.md public/ && VITE_BUILD_TARGET=demo vite build"
49
57
  },
50
58
  "peerDependencies": {
51
59
  "vue": "^3.0.0"
52
60
  },
53
61
  "devDependencies": {
54
- "@todovue/tv-demo": "^1.0.0",
62
+ "@todovue/tv-demo": "^1.2.1",
55
63
  "@vitejs/plugin-vue": "^6.0.0",
56
64
  "sass": "^1.0.0",
57
65
  "vite": "^7.0.0",
58
- "vite-plugin-css-injected-by-js": "^3.0.0",
59
66
  "vite-plugin-dts": "^4.0.0"
60
67
  }
61
68
  }