{"version":3,"file":"BqBreadcrumbs-BvE22pZw.cjs","names":[],"sources":["../src/components/breadcrumbs/BqBreadcrumbs.ts"],"sourcesContent":["/**\r\n * Breadcrumbs navigation.\r\n * @element bq-breadcrumbs\r\n * @prop {string} separator - Separator character or text (default: /)\r\n * @slot - <a> or other link elements; the last item is automatically marked as `aria-current=\"page\"`\r\n *\r\n * @cssprop --bq-breadcrumb-separator - Override the separator string (\"/\" by default)\r\n */\r\nimport type { ComponentDefinition } from '@bquery/bquery/component';\r\nimport { component, html } from '@bquery/bquery/component';\r\nimport { t } from '../../i18n/index.js';\r\nimport { getBaseStyles } from '../../utils/styles.js';\r\n\r\ntype BqBreadcrumbsProps = { separator: string };\r\n\r\n/**\r\n * Escape a string for safe use as a CSS `content` value.\r\n * Wraps in quotes and backslash-escapes embedded backslashes / quotes.\r\n */\r\nconst cssQuote = (raw: string): string =>\r\n  `\"${raw.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\r\n\r\nconst definition: ComponentDefinition<BqBreadcrumbsProps> = {\r\n  props: {\r\n    separator: { type: String, default: '/' },\r\n  },\r\n  styles: `\r\n    ${getBaseStyles()}\r\n    *, *::before, *::after { box-sizing: border-box; }\r\n    :host { display: block; }\r\n    .breadcrumbs { display: flex; align-items: center; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; font-family: var(--bq-font-family-sans); font-size: var(--bq-font-size-sm,0.875rem); gap: 0; }\r\n    ::slotted(*) { display: inline-flex; align-items: center; }\r\n    ::slotted(*:not(:first-child))::before {\r\n      content: var(--bq-breadcrumb-separator, \"/\");\r\n      color: var(--bq-text-subtle,#94a3b8);\r\n      margin: 0 var(--bq-space-2,0.5rem);\r\n      user-select: none;\r\n      pointer-events: none;\r\n      speak: never;\r\n    }\r\n    ::slotted(a) { color: var(--bq-text-muted,#475569); text-decoration: none; transition: color var(--bq-duration-fast); }\r\n    ::slotted(a:hover) { color: var(--bq-color-primary-600,#2563eb); text-decoration: underline; }\r\n    ::slotted([aria-current=\"page\"]) { color: var(--bq-text-base,#0f172a); font-weight: var(--bq-font-weight-medium,500); pointer-events: none; }\r\n    @media (prefers-reduced-motion: reduce) {\r\n      ::slotted(a) { transition: none; }\r\n    }\r\n  `,\r\n  connected() {\r\n    const self = this;\r\n    const applyAttrs = () => {\r\n      const slot = self.shadowRoot?.querySelector(\r\n        'slot'\r\n      ) as HTMLSlotElement | null;\r\n      if (!slot) return;\r\n      const items = slot.assignedElements({ flatten: true });\r\n      items.forEach((item, i) => {\r\n        if (i === items.length - 1) item.setAttribute('aria-current', 'page');\r\n        else item.removeAttribute('aria-current');\r\n      });\r\n    };\r\n    const applySeparatorVar = () => {\r\n      // Only set an inline override when the host explicitly carries a\r\n      // `separator` attribute. This keeps the `--bq-breadcrumb-separator`\r\n      // CSS custom property externally overridable when the prop is omitted.\r\n      const attr = self.getAttribute('separator');\r\n      if (attr === null) {\r\n        self.style.removeProperty('--bq-breadcrumb-separator');\r\n        return;\r\n      }\r\n      self.style.setProperty('--bq-breadcrumb-separator', cssQuote(attr));\r\n    };\r\n    (self as unknown as Record<string, unknown>)['_applyAttrs'] = applyAttrs;\r\n    (self as unknown as Record<string, unknown>)['_applySeparatorVar'] =\r\n      applySeparatorVar;\r\n    applySeparatorVar();\r\n    queueMicrotask(() => {\r\n      const slot = self.shadowRoot?.querySelector(\r\n        'slot'\r\n      ) as HTMLSlotElement | null;\r\n      if (!slot) return;\r\n      slot.addEventListener('slotchange', applyAttrs);\r\n      (self as unknown as Record<string, unknown>)['_slot'] = slot;\r\n      applyAttrs();\r\n    });\r\n  },\r\n  disconnected() {\r\n    const self = this as unknown as Record<string, unknown>;\r\n    const applyAttrs = self['_applyAttrs'] as EventListener | undefined;\r\n    const slot = self['_slot'] as HTMLSlotElement | null | undefined;\r\n    if (slot && applyAttrs) slot.removeEventListener('slotchange', applyAttrs);\r\n  },\r\n  updated() {\r\n    const s = this as unknown as Record<string, unknown>;\r\n    (s['_applySeparatorVar'] as (() => void) | undefined)?.();\r\n    (s['_applyAttrs'] as (() => void) | undefined)?.();\r\n  },\r\n  render() {\r\n    return html`\r\n      <nav aria-label=\"${t('breadcrumbs.nav')}\" part=\"nav\">\r\n        <ol class=\"breadcrumbs\" part=\"list\">\r\n          <slot></slot>\r\n        </ol>\r\n      </nav>\r\n    `;\r\n  },\r\n};\r\n\r\ncomponent<BqBreadcrumbsProps>('bq-breadcrumbs', definition);\r\n"],"mappings":";;;;;;;;;;AAmBA,IAAM,YAAY,QAChB,IAAI,IAAI,QAAQ,OAAO,OAAO,CAAC,QAAQ,MAAM,OAAM,CAAC;AAuFtD,2BAAA,EAA8B,kBAAkB;CApF9C,OAAO,EACL,WAAW;EAAE,MAAM;EAAQ,SAAS;EAAK,EAC1C;CACD,QAAQ;MACJ,eAAA,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;CAoBpB,YAAY;EACV,MAAM,OAAO;EACb,MAAM,mBAAmB;GACvB,MAAM,OAAO,KAAK,YAAY,cAC5B,OACD;AACD,OAAI,CAAC,KAAM;GACX,MAAM,QAAQ,KAAK,iBAAiB,EAAE,SAAS,MAAM,CAAC;AACtD,SAAM,SAAS,MAAM,MAAM;AACzB,QAAI,MAAM,MAAM,SAAS,EAAG,MAAK,aAAa,gBAAgB,OAAO;QAChE,MAAK,gBAAgB,eAAe;KACzC;;EAEJ,MAAM,0BAA0B;GAI9B,MAAM,OAAO,KAAK,aAAa,YAAY;AAC3C,OAAI,SAAS,MAAM;AACjB,SAAK,MAAM,eAAe,4BAA4B;AACtD;;AAEF,QAAK,MAAM,YAAY,6BAA6B,SAAS,KAAK,CAAC;;AAEpE,OAA4C,iBAAiB;AAC7D,OAA4C,wBAC3C;AACF,qBAAmB;AACnB,uBAAqB;GACnB,MAAM,OAAO,KAAK,YAAY,cAC5B,OACD;AACD,OAAI,CAAC,KAAM;AACX,QAAK,iBAAiB,cAAc,WAAW;AAC9C,QAA4C,WAAW;AACxD,eAAY;IACZ;;CAEJ,eAAe;EACb,MAAM,OAAO;EACb,MAAM,aAAa,KAAK;EACxB,MAAM,OAAO,KAAK;AAClB,MAAI,QAAQ,WAAY,MAAK,oBAAoB,cAAc,WAAW;;CAE5E,UAAU;EACR,MAAM,IAAI;AACT,IAAE,yBAAsD;AACxD,IAAE,kBAA+C;;CAEpD,SAAS;AACP,SAAO,2BAAA,CAAI;yBACU,aAAA,EAAE,kBAAkB,CAAC;;;;;;;CASE,CAAW"}